diff --git a/assets/controllers/elements/project_select_controller.js b/assets/controllers/elements/project_select_controller.js deleted file mode 100644 index 98702d41..00000000 --- a/assets/controllers/elements/project_select_controller.js +++ /dev/null @@ -1,70 +0,0 @@ -import {Controller} from "@hotwired/stimulus"; - -import "tom-select/dist/css/tom-select.bootstrap5.css"; -import '../../css/components/tom-select_extensions.css'; -import TomSelect from "tom-select"; -import {marked} from "marked"; - -export default class extends Controller { - _tomSelect; - - connect() { - - let settings = { - allowEmptyOption: true, - plugins: ['dropdown_input', 'clear_button'], - searchField: ["name", "description", "category", "footprint"], - valueField: "id", - labelField: "name", - preload: "focus", - render: { - item: (data, escape) => { - return '' + (data.image ? "" : "") + escape(data.name) + ''; - }, - option: (data, escape) => { - if(data.text) { - return '' + escape(data.text) + ''; - } - - let tmp = '
' + - "
" + - (data.image ? "" : "") + - "
" + - "
" + - '
' + escape(data.name) + '
' + - (data.description ? '

' + marked.parseInline(data.description) + '

' : "") + - (data.category ? '

' + escape(data.category) : ""); - - return tmp + '

' + - '
'; - } - } - }; - - - if (this.element.dataset.autocomplete) { - const base_url = this.element.dataset.autocomplete; - settings.valueField = "id"; - settings.load = (query, callback) => { - const url = base_url.replace('__QUERY__', encodeURIComponent(query)); - - fetch(url) - .then(response => response.json()) - .then(json => {callback(json);}) - .catch(() => { - callback() - }); - }; - - - this._tomSelect = new TomSelect(this.element, settings); - //this._tomSelect.clearOptions(); - } - } - - disconnect() { - super.disconnect(); - //Destroy the TomSelect instance - this._tomSelect.destroy(); - } -} \ No newline at end of file diff --git a/migrations/Version20250304154507.php b/migrations/Version20250304154507.php index 649e9c0a..18692991 100644 --- a/migrations/Version20250304154507.php +++ b/migrations/Version20250304154507.php @@ -6,7 +6,6 @@ namespace DoctrineMigrations; use App\Migration\AbstractMultiPlatformMigration; use Doctrine\DBAL\Schema\Schema; -use Doctrine\Migrations\AbstractMigration; final class Version20250304154507 extends AbstractMultiPlatformMigration { @@ -26,6 +25,8 @@ final class Version20250304154507 extends AbstractMultiPlatformMigration $this->addSql(<<<'SQL' CREATE UNIQUE INDEX UNIQ_6940A7FECC660B3C ON parts (built_assembly_id) SQL); + + // reverted in Version20251016124311, because built_assembly_id isn't required after testing time } public function mySQLDown(Schema $schema): void @@ -43,382 +44,21 @@ final class Version20250304154507 extends AbstractMultiPlatformMigration public function sqLiteUp(Schema $schema): void { - $this->addSql(<<<'SQL' - CREATE TEMPORARY TABLE __temp__parts AS - SELECT - id, - id_preview_attachment, - id_category, - id_footprint, - id_part_unit, - id_manufacturer, - order_orderdetails_id, - built_project_id, - datetime_added, - name, - last_modified, - needs_review, - tags, - mass, - description, - comment, - visible, - favorite, - minamount, - manufacturer_product_url, - manufacturer_product_number, - manufacturing_status, - order_quantity, - manual_order, - ipn, - provider_reference_provider_key, - provider_reference_provider_id, - provider_reference_provider_url, - provider_reference_last_updated, - eda_info_reference_prefix, - eda_info_value, - eda_info_invisible, - eda_info_exclude_from_bom, - eda_info_exclude_from_board, - eda_info_exclude_from_sim, - eda_info_kicad_symbol, - eda_info_kicad_footprint - FROM parts - SQL); - $this->addSql('DROP TABLE parts'); - - $this->addSql(<<<'SQL' - CREATE TABLE "parts" - ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - id_preview_attachment INTEGER DEFAULT NULL, - id_category INTEGER NOT NULL, - id_footprint INTEGER DEFAULT NULL, - id_part_unit INTEGER DEFAULT NULL, - id_manufacturer INTEGER DEFAULT NULL, - order_orderdetails_id INTEGER DEFAULT NULL, - built_project_id INTEGER DEFAULT NULL, - built_assembly_id INTEGER DEFAULT NULL, - datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, - name VARCHAR(255) NOT NULL, - last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, - needs_review BOOLEAN NOT NULL, - tags CLOB NOT NULL, - mass DOUBLE PRECISION DEFAULT NULL, - description CLOB NOT NULL, - comment CLOB NOT NULL, - visible BOOLEAN NOT NULL, - favorite BOOLEAN NOT NULL, - minamount DOUBLE PRECISION NOT NULL, - manufacturer_product_url CLOB NOT NULL, - manufacturer_product_number VARCHAR(255) NOT NULL, - manufacturing_status VARCHAR(255) DEFAULT NULL, - order_quantity INTEGER NOT NULL, - manual_order BOOLEAN NOT NULL, - ipn VARCHAR(100) DEFAULT NULL, - provider_reference_provider_key VARCHAR(255) DEFAULT NULL, - provider_reference_provider_id VARCHAR(255) DEFAULT NULL, - provider_reference_provider_url VARCHAR(255) DEFAULT NULL, - provider_reference_last_updated DATETIME DEFAULT NULL, - eda_info_reference_prefix VARCHAR(255) DEFAULT NULL, - eda_info_value VARCHAR(255) DEFAULT NULL, - eda_info_invisible BOOLEAN DEFAULT NULL, - eda_info_exclude_from_bom BOOLEAN DEFAULT NULL, - eda_info_exclude_from_board BOOLEAN DEFAULT NULL, - eda_info_exclude_from_sim BOOLEAN DEFAULT NULL, - eda_info_kicad_symbol VARCHAR(255) DEFAULT NULL, - eda_info_kicad_footprint VARCHAR(255) DEFAULT NULL, - CONSTRAINT FK_6940A7FEEA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE5697F554 FOREIGN KEY (id_category) REFERENCES "categories" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE7E371A10 FOREIGN KEY (id_footprint) REFERENCES "footprints" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE2626CEF9 FOREIGN KEY (id_part_unit) REFERENCES "measurement_units" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE1ECB93AE FOREIGN KEY (id_manufacturer) REFERENCES "manufacturers" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE81081E9B FOREIGN KEY (order_orderdetails_id) REFERENCES "orderdetails" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FEE8AE70D9 FOREIGN KEY (built_project_id) REFERENCES projects (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FECC660B3C FOREIGN KEY (built_assembly_id) REFERENCES assemblies (id) NOT DEFERRABLE INITIALLY IMMEDIATE - ) - SQL); - - $this->addSql(<<<'SQL' - INSERT INTO parts ( - id, - id_preview_attachment, - id_category, - id_footprint, - id_part_unit, - id_manufacturer, - order_orderdetails_id, - built_project_id, - datetime_added, - name, - last_modified, - needs_review, - tags, - mass, - description, - comment, - visible, - favorite, - minamount, - manufacturer_product_url, - manufacturer_product_number, - manufacturing_status, - order_quantity, - manual_order, - ipn, - provider_reference_provider_key, - provider_reference_provider_id, - provider_reference_provider_url, - provider_reference_last_updated, - eda_info_reference_prefix, - eda_info_value, - eda_info_invisible, - eda_info_exclude_from_bom, - eda_info_exclude_from_board, - eda_info_exclude_from_sim, - eda_info_kicad_symbol, - eda_info_kicad_footprint - ) SELECT * FROM __temp__parts - SQL); - $this->addSql('DROP TABLE __temp__parts'); - - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FE1ECB93AE ON "parts" (id_manufacturer) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FE2626CEF9 ON "parts" (id_part_unit) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FE5697F554 ON "parts" (id_category) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FE7E371A10 ON "parts" (id_footprint) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FEEA7100A1 ON "parts" (id_preview_attachment) - SQL); - $this->addSql(<<<'SQL' - CREATE UNIQUE INDEX UNIQ_6940A7FE3D721C14 ON "parts" (ipn) - SQL); - $this->addSql(<<<'SQL' - CREATE UNIQUE INDEX UNIQ_6940A7FE81081E9B ON "parts" (order_orderdetails_id) - SQL); - $this->addSql(<<<'SQL' - CREATE UNIQUE INDEX UNIQ_6940A7FEE8AE70D9 ON "parts" (built_project_id) - SQL); - $this->addSql(<<<'SQL' - CREATE UNIQUE INDEX UNIQ_6940A7FECC660B3C ON "parts" (built_assembly_id) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX parts_idx_datet_name_last_id_needs ON "parts" (datetime_added, name, last_modified, id, needs_review) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX parts_idx_ipn ON "parts" (ipn) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX parts_idx_name ON "parts" (name) - SQL); + // nothing do to, built_assembly_id not required } public function sqLiteDown(Schema $schema): void { - $this->addSql(<<<'SQL' - CREATE TEMPORARY TABLE __temp__parts AS - SELECT - id, - id_preview_attachment, - id_category, - id_footprint, - id_part_unit, - id_manufacturer, - order_orderdetails_id, - built_project_id, - datetime_added, - name, - last_modified, - needs_review, - tags, - mass, - description, - comment, - visible, - favorite, - minamount, - manufacturer_product_url, - manufacturer_product_number, - manufacturing_status, - order_quantity, - manual_order, - ipn, - provider_reference_provider_key, - provider_reference_provider_id, - provider_reference_provider_url, - provider_reference_last_updated, - eda_info_reference_prefix, - eda_info_value, - eda_info_invisible, - eda_info_exclude_from_bom, - eda_info_exclude_from_board, - eda_info_exclude_from_sim, - eda_info_kicad_symbol, - eda_info_kicad_footprint - FROM parts - SQL); - - $this->addSql('DROP TABLE parts'); - - $this->addSql(<<<'SQL' - CREATE TABLE "parts" - ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - id_preview_attachment INTEGER DEFAULT NULL, - id_category INTEGER NOT NULL, - id_footprint INTEGER DEFAULT NULL, - id_part_unit INTEGER DEFAULT NULL, - id_manufacturer INTEGER DEFAULT NULL, - order_orderdetails_id INTEGER DEFAULT NULL, - built_project_id INTEGER DEFAULT NULL, - datetime_added DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, - name VARCHAR(255) NOT NULL, - last_modified DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL, - needs_review BOOLEAN NOT NULL, - tags CLOB NOT NULL, - mass DOUBLE PRECISION DEFAULT NULL, - description CLOB NOT NULL, - comment CLOB NOT NULL, - visible BOOLEAN NOT NULL, - favorite BOOLEAN NOT NULL, - minamount DOUBLE PRECISION NOT NULL, - manufacturer_product_url CLOB NOT NULL, - manufacturer_product_number VARCHAR(255) NOT NULL, - manufacturing_status VARCHAR(255) DEFAULT NULL, - order_quantity INTEGER NOT NULL, - manual_order BOOLEAN NOT NULL, - ipn VARCHAR(100) DEFAULT NULL, - provider_reference_provider_key VARCHAR(255) DEFAULT NULL, - provider_reference_provider_id VARCHAR(255) DEFAULT NULL, - provider_reference_provider_url VARCHAR(255) DEFAULT NULL, - provider_reference_last_updated DATETIME DEFAULT NULL, - eda_info_reference_prefix VARCHAR(255) DEFAULT NULL, - eda_info_value VARCHAR(255) DEFAULT NULL, - eda_info_invisible BOOLEAN DEFAULT NULL, - eda_info_exclude_from_bom BOOLEAN DEFAULT NULL, - eda_info_exclude_from_board BOOLEAN DEFAULT NULL, - eda_info_exclude_from_sim BOOLEAN DEFAULT NULL, - eda_info_kicad_symbol VARCHAR(255) DEFAULT NULL, - eda_info_kicad_footprint VARCHAR(255) DEFAULT NULL, - CONSTRAINT FK_6940A7FEEA7100A1 FOREIGN KEY (id_preview_attachment) REFERENCES "attachments" (id) ON DELETE SET NULL NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE5697F554 FOREIGN KEY (id_category) REFERENCES "categories" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE7E371A10 FOREIGN KEY (id_footprint) REFERENCES "footprints" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE2626CEF9 FOREIGN KEY (id_part_unit) REFERENCES "measurement_units" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE1ECB93AE FOREIGN KEY (id_manufacturer) REFERENCES "manufacturers" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FE81081E9B FOREIGN KEY (order_orderdetails_id) REFERENCES "orderdetails" (id) NOT DEFERRABLE INITIALLY IMMEDIATE, - CONSTRAINT FK_6940A7FEE8AE70D9 FOREIGN KEY (built_project_id) REFERENCES projects (id) NOT DEFERRABLE INITIALLY IMMEDIATE - ) - SQL); - - $this->addSql(<<<'SQL' - INSERT INTO parts ( - id, - id_preview_attachment, - id_category, - id_footprint, - id_part_unit, - id_manufacturer, - order_orderdetails_id, - built_project_id, - datetime_added, - name, - last_modified, - needs_review, - tags, - mass, - description, - comment, - visible, - favorite, - minamount, - manufacturer_product_url, - manufacturer_product_number, - manufacturing_status, - order_quantity, - manual_order, - ipn, - provider_reference_provider_key, - provider_reference_provider_id, - provider_reference_provider_url, - provider_reference_last_updated, - eda_info_reference_prefix, - eda_info_value, - eda_info_invisible, - eda_info_exclude_from_bom, - eda_info_exclude_from_board, - eda_info_exclude_from_sim, - eda_info_kicad_symbol, - eda_info_kicad_footprint - ) SELECT * FROM __temp__parts - SQL); - - $this->addSql('DROP TABLE __temp__parts'); - - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FE1ECB93AE ON "parts" (id_manufacturer) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FE2626CEF9 ON "parts" (id_part_unit) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FE5697F554 ON "parts" (id_category) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FE7E371A10 ON "parts" (id_footprint) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX IDX_6940A7FEEA7100A1 ON "parts" (id_preview_attachment) - SQL); - $this->addSql(<<<'SQL' - CREATE UNIQUE INDEX UNIQ_6940A7FE3D721C14 ON "parts" (ipn) - SQL); - $this->addSql(<<<'SQL' - CREATE UNIQUE INDEX UNIQ_6940A7FE81081E9B ON "parts" (order_orderdetails_id) - SQL); - $this->addSql(<<<'SQL' - CREATE UNIQUE INDEX UNIQ_6940A7FEE8AE70D9 ON "parts" (built_project_id) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX parts_idx_datet_name_last_id_needs ON "parts" (datetime_added, name, last_modified, id, needs_review) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX parts_idx_ipn ON "parts" (ipn) - SQL); - $this->addSql(<<<'SQL' - CREATE INDEX parts_idx_name ON "parts" (name) - SQL); + // nothing do to, built_assembly_id not required } public function postgreSQLUp(Schema $schema): void { - $this->addSql(<<<'SQL' - ALTER TABLE parts ADD built_assembly_id INT DEFAULT NULL - SQL); - $this->addSql(<<<'SQL' - ALTER TABLE parts ADD CONSTRAINT FK_6940A7FECC660B3C FOREIGN KEY (built_assembly_id) REFERENCES assemblies (id) NOT DEFERRABLE INITIALLY IMMEDIATE - SQL); - $this->addSql(<<<'SQL' - CREATE UNIQUE INDEX UNIQ_6940A7FECC660B3C ON parts (built_assembly_id) - SQL); + // nothing do to, built_assembly_id not required } public function postgreSQLDown(Schema $schema): void { - $this->addSql(<<<'SQL' - ALTER TABLE "parts" DROP CONSTRAINT FK_6940A7FECC660B3C - SQL); - $this->addSql(<<<'SQL' - DROP INDEX UNIQ_6940A7FECC660B3C - SQL); - $this->addSql(<<<'SQL' - ALTER TABLE "parts" DROP built_assembly_id - SQL); + // nothing do to, built_assembly_id not required } } diff --git a/migrations/Version20251016124311.php b/migrations/Version20251016124311.php new file mode 100644 index 00000000..7e580b66 --- /dev/null +++ b/migrations/Version20251016124311.php @@ -0,0 +1,54 @@ +addSql(<<<'SQL' + ALTER TABLE parts DROP FOREIGN KEY FK_6940A7FECC660B3C + SQL); + $this->addSql(<<<'SQL' + DROP INDEX UNIQ_6940A7FECC660B3C ON parts + SQL); + $this->addSql(<<<'SQL' + ALTER TABLE `parts` DROP built_assembly_id + SQL); + } + + public function mySQLDown(Schema $schema): void + { + // nothing do to, built_assembly_id not required + } + + public function sqLiteUp(Schema $schema): void + { + // nothing do to, built_assembly_id not required, already removed from Version20250304154507 + } + + public function sqLiteDown(Schema $schema): void + { + // nothing do to, built_assembly_id not required, already removed from Version20250304154507 + } + + public function postgreSQLUp(Schema $schema): void + { + // nothing do to, built_assembly_id not required, already removed from Version20250304154507 + } + + public function postgreSQLDown(Schema $schema): void + { + // nothing do to, built_assembly_id not required, already removed from Version20250304154507 + } +} diff --git a/src/Controller/AssemblyController.php b/src/Controller/AssemblyController.php index 5d821121..be97045b 100644 --- a/src/Controller/AssemblyController.php +++ b/src/Controller/AssemblyController.php @@ -31,11 +31,8 @@ use App\Entity\AssemblySystem\AssemblyBOMEntry; use App\Entity\Parts\Part; use App\Exceptions\InvalidRegexException; use App\Form\AssemblySystem\AssemblyAddPartsType; -use App\Form\AssemblySystem\AssemblyBuildType; use App\Form\Filters\AssemblyFilterType; -use App\Helpers\Assemblies\AssemblyBuildRequest; use App\Services\ImportExportSystem\BOMImporter; -use App\Services\AssemblySystem\AssemblyBuildHelper; use App\Services\Trees\NodesListBuilder; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\DBAL\Exception\DriverException; @@ -132,7 +129,7 @@ class AssemblyController extends AbstractController } #[Route(path: '/{id}/info', name: 'assembly_info', requirements: ['id' => '\d+'])] - public function info(Assembly $assembly, Request $request, AssemblyBuildHelper $buildHelper): Response + public function info(Assembly $assembly, Request $request): Response { $this->denyAccessUnlessGranted('read', $assembly); @@ -144,56 +141,11 @@ class AssemblyController extends AbstractController } return $this->render('assemblies/info/info.html.twig', [ - 'buildHelper' => $buildHelper, 'datatable' => $table, 'assembly' => $assembly, ]); } - #[Route(path: '/{id}/build', name: 'assembly_build', requirements: ['id' => '\d+'])] - public function build(Assembly $assembly, Request $request, AssemblyBuildHelper $buildHelper, EntityManagerInterface $entityManager): Response - { - $this->denyAccessUnlessGranted('read', $assembly); - - //If no number of builds is given (or it is invalid), just assume 1 - $number_of_builds = $request->query->getInt('n', 1); - if ($number_of_builds < 1) { - $number_of_builds = 1; - } - - $assemblyBuildRequest = new AssemblyBuildRequest($assembly, $number_of_builds); - $form = $this->createForm(AssemblyBuildType::class, $assemblyBuildRequest); - - $form->handleRequest($request); - if ($form->isSubmitted()) { - if ($form->isValid()) { - //Ensure that the user can withdraw stock from all parts - $this->denyAccessUnlessGranted('@parts_stock.withdraw'); - - //We have to do a flush already here, so that the newly created partLot gets an ID and can be logged to DB later. - $entityManager->flush(); - $buildHelper->doBuild($assemblyBuildRequest); - $entityManager->flush(); - $this->addFlash('success', 'assembly.build.flash.success'); - - return $this->redirect( - $request->get('_redirect', - $this->generateUrl('assembly_info', ['id' => $assembly->getID()] - ))); - } - - $this->addFlash('error', 'assembly.build.flash.invalid_input'); - } - - return $this->render('assemblies/build/build.html.twig', [ - 'buildHelper' => $buildHelper, - 'assembly' => $assembly, - 'build_request' => $assemblyBuildRequest, - 'number_of_builds' => $number_of_builds, - 'form' => $form, - ]); - } - #[Route(path: '/{id}/import_bom', name: 'assembly_import_bom', requirements: ['id' => '\d+'])] public function importBOM(Request $request, EntityManagerInterface $entityManager, Assembly $assembly, BOMImporter $BOMImporter, ValidatorInterface $validator): Response diff --git a/src/Controller/PartController.php b/src/Controller/PartController.php index 1175ddb3..e5c64a11 100644 --- a/src/Controller/PartController.php +++ b/src/Controller/PartController.php @@ -46,7 +46,6 @@ use App\Services\LogSystem\TimeTravel; use App\Services\Parameters\ParameterExtractor; use App\Services\Parts\PartLotWithdrawAddHelper; use App\Services\Parts\PricedetailHelper; -use App\Services\AssemblySystem\AssemblyBuildPartHelper; use App\Services\ProjectSystem\ProjectBuildPartHelper; use App\Settings\BehaviorSettings\PartInfoSettings; use App\Settings\MiscSettings\IpnSuggestSettings; @@ -209,17 +208,14 @@ final class PartController extends AbstractController #[Route(path: '/new', name: 'part_new')] #[Route(path: '/{id}/clone', name: 'part_clone')] #[Route(path: '/new_build_part_project/{project_id}', name: 'part_new_build_part_project')] - #[Route(path: '/new_build_part_assembly/{assembly_id}', name: 'part_new_build_part_assembly')] public function new( Request $request, EntityManagerInterface $em, TranslatorInterface $translator, AttachmentSubmitHandler $attachmentSubmitHandler, ProjectBuildPartHelper $projectBuildPartHelper, - AssemblyBuildPartHelper $assemblyBuildPartHelper, #[MapEntity(mapping: ['id' => 'id'])] ?Part $part = null, - #[MapEntity(mapping: ['project_id' => 'id'])] ?Project $project = null, - #[MapEntity(mapping: ['assembly_id' => 'id'])] ?Assembly $assembly = null + #[MapEntity(mapping: ['project_id' => 'id'])] ?Project $project = null ): Response { if ($part instanceof Part) { @@ -233,14 +229,6 @@ final class PartController extends AbstractController return $this->redirectToRoute('part_edit', ['id' => $project->getBuildPart()->getID()]); } $new_part = $projectBuildPartHelper->getPartInitialization($project); - } elseif ($assembly instanceof Assembly) { - //Initialize a new part for a build part from the given assembly - //Ensure that the assembly has not already a build part - if ($assembly->getBuildPart() instanceof Part) { - $this->addFlash('error', 'part.new_build_part.error.build_part_already_exists'); - return $this->redirectToRoute('part_edit', ['id' => $project->getBuildPart()->getID()]); - } - $new_part = $assemblyBuildPartHelper->getPartInitialization($assembly); } else { //Create an empty part from scratch $new_part = new Part(); } diff --git a/src/Controller/TypeaheadController.php b/src/Controller/TypeaheadController.php index d8779962..efa17bb0 100644 --- a/src/Controller/TypeaheadController.php +++ b/src/Controller/TypeaheadController.php @@ -56,6 +56,7 @@ use Symfony\Component\Routing\Attribute\Route; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Normalizer\ObjectNormalizer; use Symfony\Component\Serializer\Serializer; +use InvalidArgumentException; /** * In this controller the endpoints for the typeaheads are collected. @@ -115,19 +116,22 @@ class TypeaheadController extends AbstractController 'group' => GroupParameter::class, 'measurement_unit' => MeasurementUnitParameter::class, 'currency' => Currency::class, - default => throw new \InvalidArgumentException('Invalid parameter type: '.$type), + default => throw new InvalidArgumentException('Invalid parameter type: '.$type), }; } #[Route(path: '/parts/search/{query}', name: 'typeahead_parts')] - public function parts(EntityManagerInterface $entityManager, PartPreviewGenerator $previewGenerator, - AttachmentURLGenerator $attachmentURLGenerator, string $query = ""): JsonResponse - { + public function parts( + EntityManagerInterface $entityManager, + PartPreviewGenerator $previewGenerator, + AttachmentURLGenerator $attachmentURLGenerator, + string $query = "" + ): JsonResponse { $this->denyAccessUnlessGranted('@parts.read'); - $repo = $entityManager->getRepository(Part::class); + $partRepository = $entityManager->getRepository(Part::class); - $parts = $repo->autocompleteSearch($query, 100); + $parts = $partRepository->autocompleteSearch($query, 100); $data = []; foreach ($parts as $part) { @@ -147,7 +151,7 @@ class TypeaheadController extends AbstractController 'footprint' => $part->getFootprint() instanceof Footprint ? $part->getFootprint()->getName() : '', 'description' => mb_strimwidth($part->getDescription(), 0, 127, '...'), 'image' => $preview_url, - ]; + ]; } return new JsonResponse($data); diff --git a/src/DataTables/AssemblyBomEntriesDataTable.php b/src/DataTables/AssemblyBomEntriesDataTable.php index 55a47584..90924cfe 100644 --- a/src/DataTables/AssemblyBomEntriesDataTable.php +++ b/src/DataTables/AssemblyBomEntriesDataTable.php @@ -91,6 +91,8 @@ class AssemblyBomEntriesDataTable implements DataTableTypeInterface return htmlspecialchars((string) $context->getName()); } + $tmp = $context->getName(); + if ($context->getPart() !== null) { $tmp = $this->partDataTableHelper->renderName($context->getPart()); $tmp = $this->translator->trans('part.table.name.value.for_part', ['%value%' => $tmp]); diff --git a/src/DataTables/Filters/AssemblySearchFilter.php b/src/DataTables/Filters/AssemblySearchFilter.php index 1627cc61..2ab33c83 100644 --- a/src/DataTables/Filters/AssemblySearchFilter.php +++ b/src/DataTables/Filters/AssemblySearchFilter.php @@ -135,17 +135,6 @@ class AssemblySearchFilter implements FilterInterface return $this; } - public function isCategory(): bool - { - return $this->category; - } - - public function setCategory(bool $category): AssemblySearchFilter - { - $this->category = $category; - return $this; - } - public function isDescription(): bool { return $this->description; diff --git a/src/Entity/AssemblySystem/Assembly.php b/src/Entity/AssemblySystem/Assembly.php index fde61cd9..20a7aa1b 100644 --- a/src/Entity/AssemblySystem/Assembly.php +++ b/src/Entity/AssemblySystem/Assembly.php @@ -141,13 +141,6 @@ class Assembly extends AbstractStructuralDBElement #[Length(max: 100)] protected ?string $ipn = null; - /** - * @var Part|null The (optional) part that represents the builds of this assembly in the stock - */ - #[ORM\OneToOne(mappedBy: 'built_assembly', targetEntity: Part::class, cascade: ['persist'], orphanRemoval: true)] - #[Groups(['assembly:read', 'assembly:write'])] - protected ?Part $build_part = null; - #[ORM\Column(type: Types::BOOLEAN)] protected bool $order_only_missing_parts = false; @@ -338,59 +331,9 @@ class Assembly extends AbstractStructuralDBElement return $this; } - /** - * Checks if this assembly has an associated part representing the builds of this assembly in the stock. - */ - public function hasBuildPart(): bool - { - return $this->build_part instanceof Part; - } - - /** - * Gets the part representing the builds of this assembly in the stock, if it is existing - */ - public function getBuildPart(): ?Part - { - return $this->build_part; - } - - /** - * Sets the part representing the builds of this assembly in the stock. - */ - public function setBuildPart(?Part $build_part): void - { - $this->build_part = $build_part; - if ($build_part instanceof Part) { - $build_part->setBuiltAssembly($this); - } - } - #[Assert\Callback] public function validate(ExecutionContextInterface $context, $payload): void { - //If this assembly has subassemblies, and these have builds part, they must be included in the BOM - foreach ($this->getChildren() as $child) { - if (!$child->getBuildPart() instanceof Part) { - continue; - } - //We have to search all bom entries for the build part - $found = false; - foreach ($this->getBomEntries() as $bom_entry) { - if ($bom_entry->getPart() === $child->getBuildPart()) { - $found = true; - break; - } - } - - //When the build part is not found, we have to add an error - if (!$found) { - $context->buildViolation('assembly.bom_has_to_include_all_subelement_parts') - ->atPath('bom_entries') - ->setParameter('%assembly_name%', $child->getName()) - ->setParameter('%part_name%', $child->getBuildPart()->getName()) - ->addViolation(); - } - } } /** diff --git a/src/Entity/AssemblySystem/AssemblyBOMEntry.php b/src/Entity/AssemblySystem/AssemblyBOMEntry.php index 56710aab..500a4401 100644 --- a/src/Entity/AssemblySystem/AssemblyBOMEntry.php +++ b/src/Entity/AssemblySystem/AssemblyBOMEntry.php @@ -326,22 +326,6 @@ class AssemblyBOMEntry extends AbstractDBElement implements UniqueValidatableInt if (!$this->part instanceof Part) { $this->quantity = round($this->quantity); } - - //Check that the part is not the build representation part of this assembly or one of its parents - if ($this->part && $this->part->getBuiltAssembly() instanceof Assembly) { - //Get the associated assembly - $associated_assembly = $this->part->getBuiltAssembly(); - //Check that it is not the same as the current assembly neither one of its parents - $current_assembly = $this->assembly; - while ($current_assembly) { - if ($associated_assembly === $current_assembly) { - $context->buildViolation('assembly.bom_entry.can_not_add_own_builds_part') - ->atPath('part') - ->addViolation(); - } - $current_assembly = $current_assembly->getParent(); - } - } } diff --git a/src/Entity/Parts/PartTraits/AssemblyTrait.php b/src/Entity/Parts/PartTraits/AssemblyTrait.php index 57f78d35..3b5f931c 100644 --- a/src/Entity/Parts/PartTraits/AssemblyTrait.php +++ b/src/Entity/Parts/PartTraits/AssemblyTrait.php @@ -18,13 +18,6 @@ trait AssemblyTrait #[ORM\OneToMany(mappedBy: 'part', targetEntity: AssemblyBOMEntry::class, cascade: ['remove'], orphanRemoval: true)] protected Collection $assembly_bom_entries; - /** - * @var Assembly|null If a assembly is set here, then this part is special and represents the builds of an assembly. - */ - #[ORM\OneToOne(inversedBy: 'build_part', targetEntity: Assembly::class)] - #[ORM\JoinColumn] - protected ?Assembly $built_assembly = null; - /** * Returns all AssemblyBOMEntry that use this part. * @@ -35,36 +28,6 @@ trait AssemblyTrait return $this->assembly_bom_entries; } - /** - * Checks whether this part represents the builds of a assembly - * @return bool True if it represents the builds, false if not - */ - #[Groups(['part:read'])] - public function isAssemblyBuildPart(): bool - { - return $this->built_assembly !== null; - } - - /** - * Returns the assembly that this part represents the builds of, or null if it doesn't - */ - public function getBuiltAssembly(): ?Assembly - { - return $this->built_assembly; - } - - - /** - * Sets the assembly that this part represents the builds of - * @param Assembly|null $built_assembly The assembly that this part represents the builds of, or null if it is not a build part - */ - public function setBuiltAssembly(?Assembly $built_assembly): self - { - $this->built_assembly = $built_assembly; - return $this; - } - - /** * Get all assemblies which uses this part. * diff --git a/src/Form/AdminPages/AssemblyAdminForm.php b/src/Form/AdminPages/AssemblyAdminForm.php index 2c2f3cc4..dd0a8038 100644 --- a/src/Form/AdminPages/AssemblyAdminForm.php +++ b/src/Form/AdminPages/AssemblyAdminForm.php @@ -37,7 +37,7 @@ class AssemblyAdminForm extends BaseEntityAdminForm public function __construct( protected Security $security, protected EventCommentNeededHelper $eventCommentNeededHelper, - protected AssemblySettings $assemblySettings, + protected ?AssemblySettings $assemblySettings = null, ) { parent::__construct($security, $eventCommentNeededHelper, $assemblySettings); } diff --git a/src/Form/AdminPages/BaseEntityAdminForm.php b/src/Form/AdminPages/BaseEntityAdminForm.php index 5ffd7f4d..35afbaa1 100644 --- a/src/Form/AdminPages/BaseEntityAdminForm.php +++ b/src/Form/AdminPages/BaseEntityAdminForm.php @@ -52,7 +52,7 @@ class BaseEntityAdminForm extends AbstractType public function __construct( protected Security $security, protected EventCommentNeededHelper $eventCommentNeededHelper, - protected AssemblySettings $assemblySettings, + protected ?AssemblySettings $assemblySettings = null, ) { } @@ -74,7 +74,7 @@ class BaseEntityAdminForm extends AbstractType ->add('name', TextType::class, [ 'empty_data' => '', 'label' => 'name.label', - 'data' => $is_new && $entity instanceof Assembly && $this->assemblySettings->useIpnPlaceholderInName ? '%%ipn%%' : $entity->getName(), + 'data' => $is_new && $entity instanceof Assembly && $this->assemblySettings !== null && $this->assemblySettings->useIpnPlaceholderInName ? '%%ipn%%' : $entity->getName(), 'attr' => [ 'placeholder' => 'part.name.placeholder', ], diff --git a/src/Form/AssemblySystem/AssemblyBOMEntryType.php b/src/Form/AssemblySystem/AssemblyBOMEntryType.php index 4ef0adec..8b56dfeb 100644 --- a/src/Form/AssemblySystem/AssemblyBOMEntryType.php +++ b/src/Form/AssemblySystem/AssemblyBOMEntryType.php @@ -9,7 +9,6 @@ use App\Form\Type\AssemblySelectType; use App\Form\Type\BigDecimalNumberType; use App\Form\Type\CurrencyEntityType; use App\Form\Type\PartSelectType; -use App\Form\Type\ProjectSelectType; use App\Form\Type\RichTextEditorType; use App\Form\Type\SIUnitType; use Symfony\Component\Form\AbstractType; diff --git a/src/Form/AssemblySystem/AssemblyBuildType.php b/src/Form/AssemblySystem/AssemblyBuildType.php deleted file mode 100644 index e87acb86..00000000 --- a/src/Form/AssemblySystem/AssemblyBuildType.php +++ /dev/null @@ -1,182 +0,0 @@ -. - */ -namespace App\Form\AssemblySystem; - -use App\Helpers\Assemblies\AssemblyBuildRequest; -use Symfony\Bundle\SecurityBundle\Security; -use App\Entity\Parts\Part; -use App\Entity\Parts\PartLot; -use App\Form\Type\PartLotSelectType; -use App\Form\Type\SIUnitType; -use Symfony\Component\Form\AbstractType; -use Symfony\Component\Form\DataMapperInterface; -use Symfony\Component\Form\Event\PreSetDataEvent; -use Symfony\Component\Form\Extension\Core\Type\CheckboxType; -use Symfony\Component\Form\Extension\Core\Type\SubmitType; -use Symfony\Component\Form\Extension\Core\Type\TextType; -use Symfony\Component\Form\FormBuilderInterface; -use Symfony\Component\Form\FormEvents; -use Symfony\Component\Form\FormInterface; -use Symfony\Component\OptionsResolver\OptionsResolver; - -class AssemblyBuildType extends AbstractType implements DataMapperInterface -{ - public function __construct(private readonly Security $security) - { - } - - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([ - 'compound' => true, - 'data_class' => AssemblyBuildRequest::class - ]); - } - - public function buildForm(FormBuilderInterface $builder, array $options): void - { - $builder->setDataMapper($this); - - $builder->add('submit', SubmitType::class, [ - 'label' => 'assembly.build.btn_build', - 'disabled' => !$this->security->isGranted('@parts_stock.withdraw'), - ]); - - $builder->add('dontCheckQuantity', CheckboxType::class, [ - 'label' => 'assembly.build.dont_check_quantity', - 'help' => 'assembly.build.dont_check_quantity.help', - 'required' => false, - 'attr' => [ - 'data-controller' => 'pages--dont-check-quantity-checkbox' - ] - ]); - - $builder->add('comment', TextType::class, [ - 'label' => 'part.info.withdraw_modal.comment', - 'help' => 'part.info.withdraw_modal.comment.hint', - 'empty_data' => '', - 'required' => false, - ]); - - //The form is initially empty, define the fields after we know the data - $builder->addEventListener(FormEvents::PRE_SET_DATA, function (PreSetDataEvent $event) { - $form = $event->getForm(); - /** @var AssemblyBuildRequest $assemblyBuildRequest */ - $assemblyBuildRequest = $event->getData(); - - $form->add('addBuildsToBuildsPart', CheckboxType::class, [ - 'label' => 'assembly.build.add_builds_to_builds_part', - 'required' => false, - 'disabled' => !$assemblyBuildRequest->getAssembly()->getBuildPart() instanceof Part, - ]); - - if ($assemblyBuildRequest->getAssembly()->getBuildPart() instanceof Part) { - $form->add('buildsPartLot', PartLotSelectType::class, [ - 'label' => 'assembly.build.builds_part_lot', - 'required' => false, - 'part' => $assemblyBuildRequest->getAssembly()->getBuildPart(), - 'placeholder' => 'assembly.build.buildsPartLot.new_lot' - ]); - } - - foreach ($assemblyBuildRequest->getPartBomEntries() as $bomEntry) { - //Every part lot has a field to specify the number of parts to take from this lot - foreach ($assemblyBuildRequest->getPartLotsForBOMEntry($bomEntry) as $lot) { - $form->add('lot_' . $lot->getID(), SIUnitType::class, [ - 'label' => false, - 'measurement_unit' => $bomEntry->getPart()->getPartUnit(), - 'max' => min($assemblyBuildRequest->getNeededAmountForBOMEntry($bomEntry), $lot->getAmount()), - 'disabled' => !$this->security->isGranted('withdraw', $lot), - ]); - } - } - - }); - } - - public function mapDataToForms($data, \Traversable $forms): void - { - if (!$data instanceof AssemblyBuildRequest) { - throw new \RuntimeException('Data must be an instance of ' . AssemblyBuildRequest::class); - } - - /** @var FormInterface[] $forms */ - $forms = iterator_to_array($forms); - foreach ($forms as $key => $form) { - //Extract the lot id from the form name - $matches = []; - if (preg_match('/^lot_(\d+)$/', $key, $matches)) { - $lot_id = (int) $matches[1]; - $form->setData($data->getLotWithdrawAmount($lot_id)); - } - } - - $forms['comment']->setData($data->getComment()); - $forms['dontCheckQuantity']->setData($data->isDontCheckQuantity()); - $forms['addBuildsToBuildsPart']->setData($data->getAddBuildsToBuildsPart()); - if (isset($forms['buildsPartLot'])) { - $forms['buildsPartLot']->setData($data->getBuildsPartLot()); - } - - } - - public function mapFormsToData(\Traversable $forms, &$data): void - { - if (!$data instanceof AssemblyBuildRequest) { - throw new \RuntimeException('Data must be an instance of ' . AssemblyBuildRequest::class); - } - - /** @var FormInterface[] $forms */ - $forms = iterator_to_array($forms); - - foreach ($forms as $key => $form) { - //Extract the lot id from the form name - $matches = []; - if (preg_match('/^lot_(\d+)$/', $key, $matches)) { - $lot_id = (int) $matches[1]; - $data->setLotWithdrawAmount($lot_id, (float) $form->getData()); - } - } - - $data->setComment($forms['comment']->getData()); - $data->setDontCheckQuantity($forms['dontCheckQuantity']->getData()); - - if (isset($forms['buildsPartLot'])) { - $lot = $forms['buildsPartLot']->getData(); - if (!$lot) { //When the user selected "Create new lot", create a new lot - $lot = new PartLot(); - $description = 'Build ' . date('Y-m-d H:i:s'); - if ($data->getComment() !== '') { - $description .= ' (' . $data->getComment() . ')'; - } - $lot->setDescription($description); - - $data->getAssembly()->getBuildPart()->addPartLot($lot); - } - - $data->setBuildsPartLot($lot); - } - //This has to be set after the builds part lot, so that it can disable the option - $data->setAddBuildsToBuildsPart($forms['addBuildsToBuildsPart']->getData()); - } -} diff --git a/src/Form/Filters/LogFilterType.php b/src/Form/Filters/LogFilterType.php index c973ad0f..4fb5bc49 100644 --- a/src/Form/Filters/LogFilterType.php +++ b/src/Form/Filters/LogFilterType.php @@ -114,6 +114,8 @@ class LogFilterType extends AbstractType LogTargetType::CATEGORY => 'category.label', LogTargetType::PROJECT => 'project.label', LogTargetType::BOM_ENTRY => 'project_bom_entry.label', + LogTargetType::ASSEMBLY => 'assembly.label', + LogTargetType::ASSEMBLY_BOM_ENTRY => 'assembly_bom_entry.label', LogTargetType::FOOTPRINT => 'footprint.label', LogTargetType::GROUP => 'group.label', LogTargetType::MANUFACTURER => 'manufacturer.label', diff --git a/src/Form/Type/ProjectSelectType.php b/src/Form/Type/ProjectSelectType.php deleted file mode 100644 index 18a10c08..00000000 --- a/src/Form/Type/ProjectSelectType.php +++ /dev/null @@ -1,124 +0,0 @@ -addEventListener(FormEvents::PRE_SET_DATA, function (PreSetDataEvent $event) { - $form = $event->getForm(); - $config = $form->getConfig()->getOptions(); - $data = $event->getData() ?? []; - - $config['compound'] = false; - $config['choices'] = is_iterable($data) ? $data : [$data]; - $config['error_bubbling'] = true; - - $form->add('autocomplete', EntityType::class, $config); - }); - - //After form submit, we have to add the selected element as choice, otherwise the form will not accept this element - $builder->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) { - $data = $event->getData(); - $form = $event->getForm(); - $options = $form->get('autocomplete')->getConfig()->getOptions(); - - - if (!isset($data['autocomplete']) || '' === $data['autocomplete'] || empty($data['autocomplete'])) { - $options['choices'] = []; - } else { - //Extract the ID from the submitted data - $id = $data['autocomplete']; - //Find the element in the database - $element = $this->em->find($options['class'], $id); - - //Add the element as choice - $options['choices'] = [$element]; - $options['error_bubbling'] = true; - $form->add('autocomplete', EntityType::class, $options); - } - }); - - $builder->setDataMapper($this); - } - - public function configureOptions(OptionsResolver $resolver): void - { - $resolver->setDefaults([ - 'class' => Project::class, - 'choice_label' => 'name', - 'compound' => true, - 'error_bubbling' => false, - ]); - - error_log($this->urlGenerator->generate('typeahead_projects', ['query' => '__QUERY__'])); - - $resolver->setDefaults([ - 'attr' => [ - 'data-controller' => 'elements--project-select', - 'data-autocomplete' => $this->urlGenerator->generate('typeahead_projects', ['query' => '__QUERY__']), - 'autocomplete' => 'off', - ], - ]); - - $resolver->setDefaults([ - //Prefill the selected choice with the needed data, so the user can see it without an additional Ajax request - 'choice_attr' => ChoiceList::attr($this, function (?Project $project) { - if($project instanceof Project) { - //Determine the picture to show: - $preview_attachment = $this->previewGenerator->getTablePreviewAttachment($project); - if ($preview_attachment instanceof Attachment) { - $preview_url = $this->attachmentURLGenerator->getThumbnailURL($preview_attachment, - 'thumbnail_sm'); - } else { - $preview_url = ''; - } - } - - return $project instanceof Project ? [ - 'data-description' => $project->getDescription() ? mb_strimwidth($project->getDescription(), 0, 127, '...') : '', - 'data-category' => '', - 'data-footprint' => '', - 'data-image' => $preview_url, - ] : []; - }) - ]); - } - - public function mapDataToForms($data, \Traversable $forms): void - { - $form = current(iterator_to_array($forms, false)); - $form->setData($data); - } - - public function mapFormsToData(\Traversable $forms, &$data): void - { - $form = current(iterator_to_array($forms, false)); - $data = $form->getData(); - } - -} diff --git a/src/Helpers/Assemblies/AssemblyBuildRequest.php b/src/Helpers/Assemblies/AssemblyBuildRequest.php deleted file mode 100644 index c33a6f61..00000000 --- a/src/Helpers/Assemblies/AssemblyBuildRequest.php +++ /dev/null @@ -1,306 +0,0 @@ -. - */ -namespace App\Helpers\Assemblies; - -use App\Entity\Parts\Part; -use App\Entity\Parts\PartLot; -use App\Entity\AssemblySystem\Assembly; -use App\Entity\AssemblySystem\AssemblyBOMEntry; -use App\Validator\Constraints\AssemblySystem\ValidAssemblyBuildRequest; - -/** - * @see \App\Tests\Helpers\Assemblies\AssemblyBuildRequestTest - */ -#[ValidAssemblyBuildRequest] -final class AssemblyBuildRequest -{ - private readonly int $number_of_builds; - - /** - * @var array - */ - private array $withdraw_amounts = []; - - private string $comment = ''; - - private ?PartLot $builds_lot = null; - - private bool $add_build_to_builds_part = false; - - private bool $dont_check_quantity = false; - - /** - * @param Assembly $assembly The assembly that should be build - * @param int $number_of_builds The number of builds that should be created - */ - public function __construct(private readonly Assembly $assembly, int $number_of_builds) - { - if ($number_of_builds < 1) { - throw new \InvalidArgumentException('Number of builds must be at least 1!'); - } - $this->number_of_builds = $number_of_builds; - - $this->initializeArray(); - - //By default, use the first available lot of builds part if there is one. - if($assembly->getBuildPart() instanceof Part) { - $this->add_build_to_builds_part = true; - foreach( $assembly->getBuildPart()->getPartLots() as $lot) { - if (!$lot->isInstockUnknown()) { - $this->builds_lot = $lot; - break; - } - } - } - } - - private function initializeArray(): void - { - //Completely reset the array - $this->withdraw_amounts = []; - - //Now create an array for each BOM entry - foreach ($this->getPartBomEntries() as $bom_entry) { - $remaining_amount = $this->getNeededAmountForBOMEntry($bom_entry); - foreach($this->getPartLotsForBOMEntry($bom_entry) as $lot) { - //If the lot has instock use it for the build - $this->withdraw_amounts[$lot->getID()] = min($remaining_amount, $lot->getAmount()); - $remaining_amount -= max(0, $this->withdraw_amounts[$lot->getID()]); - } - } - } - - /** - * Ensure that the assemblyBOMEntry belongs to the assembly, otherwise throw an exception. - */ - private function ensureBOMEntryValid(AssemblyBOMEntry $entry): void - { - if ($entry->getAssembly() !== $this->assembly) { - throw new \InvalidArgumentException('The given BOM entry does not belong to the assembly!'); - } - } - - /** - * Returns the partlot where the builds should be added to, or null if it should not be added to any lot. - */ - public function getBuildsPartLot(): ?PartLot - { - return $this->builds_lot; - } - - /** - * Return if the builds should be added to the builds part of this assembly as new stock - */ - public function getAddBuildsToBuildsPart(): bool - { - return $this->add_build_to_builds_part; - } - - /** - * Set if the builds should be added to the builds part of this assembly as new stock - * @return $this - */ - public function setAddBuildsToBuildsPart(bool $new_value): self - { - $this->add_build_to_builds_part = $new_value; - - if ($new_value === false) { - $this->builds_lot = null; - } - - return $this; - } - - /** - * Set the partlot where the builds should be added to, or null if it should not be added to any lot. - * The part lot must belong to the assembly build part, or an exception is thrown! - * @return $this - */ - public function setBuildsPartLot(?PartLot $new_part_lot): self - { - //Ensure that this new_part_lot belongs to the assembly - if (($new_part_lot instanceof PartLot && $new_part_lot->getPart() !== $this->assembly->getBuildPart()) || !$this->assembly->getBuildPart() instanceof Part) { - throw new \InvalidArgumentException('The given part lot does not belong to the assemblies build part!'); - } - - if ($new_part_lot instanceof PartLot) { - $this->setAddBuildsToBuildsPart(true); - } - - $this->builds_lot = $new_part_lot; - - return $this; - } - - /** - * Returns the comment where the user can write additional information about the build. - */ - public function getComment(): string - { - return $this->comment; - } - - /** - * Sets the comment where the user can write additional information about the build. - */ - public function setComment(string $comment): void - { - $this->comment = $comment; - } - - /** - * Returns the amount of parts that should be withdrawn from the given lot for the corresponding BOM entry. - * @param PartLot|int $lot The part lot (or the ID of the part lot) for which the withdrawal amount should be got - */ - public function getLotWithdrawAmount(PartLot|int $lot): float - { - $lot_id = $lot instanceof PartLot ? $lot->getID() : $lot; - - if (! array_key_exists($lot_id, $this->withdraw_amounts)) { - throw new \InvalidArgumentException('The given lot is not in the withdraw amounts array!'); - } - - return $this->withdraw_amounts[$lot_id]; - } - - /** - * Sets the amount of parts that should be withdrawn from the given lot for the corresponding BOM entry. - * @param PartLot|int $lot The part lot (or the ID of the part lot) for which the withdrawal amount should be got - * @return $this - */ - public function setLotWithdrawAmount(PartLot|int $lot, float $amount): self - { - if ($lot instanceof PartLot) { - $lot_id = $lot->getID(); - } elseif (is_int($lot)) { - $lot_id = $lot; - } else { - throw new \InvalidArgumentException('The given lot must be an instance of PartLot or an ID of a PartLot!'); - } - - $this->withdraw_amounts[$lot_id] = $amount; - - return $this; - } - - /** - * Returns the sum of all withdraw amounts for the given BOM entry. - */ - public function getWithdrawAmountSum(AssemblyBOMEntry $entry): float - { - $this->ensureBOMEntryValid($entry); - - $sum = 0; - foreach ($this->getPartLotsForBOMEntry($entry) as $lot) { - $sum += $this->getLotWithdrawAmount($lot); - } - - if ($entry->getPart() && !$entry->getPart()->useFloatAmount()) { - $sum = round($sum); - } - - return $sum; - } - - /** - * Returns the number of available lots to take stock from for the given BOM entry. - * @return PartLot[]|null Returns null if the entry is a non-part BOM entry - */ - public function getPartLotsForBOMEntry(AssemblyBOMEntry $assemblyBOMEntry): ?array - { - $this->ensureBOMEntryValid($assemblyBOMEntry); - - if (!$assemblyBOMEntry->getPart() instanceof Part) { - return null; - } - - //Filter out all lots which have unknown instock - return $assemblyBOMEntry->getPart()->getPartLots()->filter(fn (PartLot $lot) => !$lot->isInstockUnknown())->toArray(); - } - - /** - * Returns the needed amount of parts for the given BOM entry. - */ - public function getNeededAmountForBOMEntry(AssemblyBOMEntry $entry): float - { - $this->ensureBOMEntryValid($entry); - - return $entry->getQuantity() * $this->number_of_builds; - } - - /** - * Returns the list of all bom entries. - * @return AssemblyBOMEntry[] - */ - public function getBomEntries(): array - { - return $this->assembly->getBomEntries()->toArray(); - } - - /** - * Returns all part bom entries. - * @return AssemblyBOMEntry[] - */ - public function getPartBomEntries(): array - { - return $this->assembly->getBomEntries()->filter(fn(AssemblyBOMEntry $entry) => $entry->isPartBomEntry())->toArray(); - } - - /** - * Returns which assembly should be build - */ - public function getAssembly(): Assembly - { - return $this->assembly; - } - - /** - * Returns the number of builds that should be created. - */ - public function getNumberOfBuilds(): int - { - return $this->number_of_builds; - } - - /** - * If Set to true, the given withdraw amounts are used without any checks for requirements. - * @return bool - */ - public function isDontCheckQuantity(): bool - { - return $this->dont_check_quantity; - } - - /** - * Set to true, the given withdraw amounts are used without any checks for requirements. - * @param bool $dont_check_quantity - * @return $this - */ - public function setDontCheckQuantity(bool $dont_check_quantity): AssemblyBuildRequest - { - $this->dont_check_quantity = $dont_check_quantity; - return $this; - } - - -} diff --git a/src/Repository/AssemblyRepository.php b/src/Repository/AssemblyRepository.php index 031e6e82..eef36690 100644 --- a/src/Repository/AssemblyRepository.php +++ b/src/Repository/AssemblyRepository.php @@ -45,7 +45,7 @@ use App\Entity\AssemblySystem\Assembly; /** * @template TEntityClass of Assembly - * @extends DBElementRepository + * @extends StructuralDBElementRepository */ class AssemblyRepository extends StructuralDBElementRepository { @@ -66,4 +66,4 @@ class AssemblyRepository extends StructuralDBElementRepository return $qb->getQuery()->getResult(); } -} \ No newline at end of file +} diff --git a/src/Repository/Parts/DeviceRepository.php b/src/Repository/Parts/DeviceRepository.php index c714523a..442c91e5 100644 --- a/src/Repository/Parts/DeviceRepository.php +++ b/src/Repository/Parts/DeviceRepository.php @@ -51,22 +51,4 @@ class DeviceRepository extends StructuralDBElementRepository //Prevent user from deleting devices, to not accidentally remove filled devices from old versions return 1; } - - /** - * @return Project[] - */ - public function autocompleteSearch(string $query, int $max_limits = 50): array - { - $qb = $this->createQueryBuilder('project'); - $qb->select('project') - ->where('ILIKE(project.name, :query) = TRUE') - ->orWhere('ILIKE(project.description, :query) = TRUE'); - - $qb->setParameter('query', '%'.$query.'%'); - - $qb->setMaxResults($max_limits); - $qb->orderBy('NATSORT(project.name)', 'ASC'); - - return $qb->getQuery()->getResult(); - } } diff --git a/src/Services/AssemblySystem/AssemblyBuildHelper.php b/src/Services/AssemblySystem/AssemblyBuildHelper.php deleted file mode 100644 index 9180f3e8..00000000 --- a/src/Services/AssemblySystem/AssemblyBuildHelper.php +++ /dev/null @@ -1,166 +0,0 @@ -. - */ -namespace App\Services\AssemblySystem; - -use App\Entity\AssemblySystem\Assembly; -use App\Entity\AssemblySystem\AssemblyBOMEntry; -use App\Entity\Parts\Part; -use App\Helpers\Assemblies\AssemblyBuildRequest; -use App\Services\Parts\PartLotWithdrawAddHelper; - -/** - * @see \App\Tests\Services\AssemblySystem\AssemblyBuildHelperTest - */ -class AssemblyBuildHelper -{ - public function __construct( - private readonly PartLotWithdrawAddHelper $withdraw_add_helper - ) { - } - - /** - * Returns the maximum buildable amount of the given BOM entry based on the stock of the used parts. - * This function only works for BOM entries that are associated with a part. - */ - public function getMaximumBuildableCountForBOMEntry(AssemblyBOMEntry $assemblyBOMEntry): int - { - $part = $assemblyBOMEntry->getPart(); - - if (!$part instanceof Part) { - throw new \InvalidArgumentException('This function cannot determine the maximum buildable count for a BOM entry without a part!'); - } - - if ($assemblyBOMEntry->getQuantity() <= 0) { - throw new \RuntimeException('The quantity of the BOM entry must be greater than 0!'); - } - - $amount_sum = $part->getAmountSum(); - - return (int) floor($amount_sum / $assemblyBOMEntry->getQuantity()); - } - - /** - * Returns the maximum buildable amount of the given assembly, based on the stock of the used parts in the BOM. - */ - public function getMaximumBuildableCount(Assembly $assembly): int - { - $maximum_buildable_count = PHP_INT_MAX; - /** @var AssemblyBOMEntry $bom_entry */ - foreach ($assembly->getBomEntries() as $bom_entry) { - //Skip BOM entries without a part (as we can not determine that) - if (!$bom_entry->isPartBomEntry() && !$bom_entry->isAssemblyBomEntry()) { - continue; - } - - //The maximum buildable count for the whole assembly is the minimum of all BOM entries - if ($bom_entry->getPart() !== null) { - $maximum_buildable_count = min($maximum_buildable_count, $this->getMaximumBuildableCountForBOMEntry($bom_entry)); - } elseif ($bom_entry->getReferencedAssembly() !== null) { - $maximum_buildable_count = min($maximum_buildable_count, $this->getMaximumBuildableCount($bom_entry->getReferencedAssembly())); - } - } - - return $maximum_buildable_count; - } - - /** - * Checks if the given assembly can be built with the current stock. - * This means that the maximum buildable count is greater or equal than the requested $number_of_assemblies - * @param int $number_of_builds - */ - public function isAssemblyBuildable(Assembly $assembly, int $number_of_builds = 1): bool - { - return $this->getMaximumBuildableCount($assembly) >= $number_of_builds; - } - - /** - * Check if the given BOM entry can be built with the current stock. - * This means that the maximum buildable count is greater or equal than the requested $number_of_assemblies - */ - public function isBOMEntryBuildable(AssemblyBOMEntry $bom_entry, int $number_of_builds = 1): bool - { - return $this->getMaximumBuildableCountForBOMEntry($bom_entry) >= $number_of_builds; - } - - /** - * Returns the referenced assembly BOM entries for which parts are missing in the stock for the given number of builds - * @param Assembly $assembly The assembly for which the BOM entries should be checked - * @param int $number_of_builds How often should the assembly be build? - * @return AssemblyBOMEntry[] - */ - public function getNonBuildableAssemblyBomEntries(Assembly $assembly, int $number_of_builds = 1): array - { - if ($number_of_builds < 1) { - throw new \InvalidArgumentException('The number of builds must be greater than 0!'); - } - - $nonBuildableEntries = []; - - /** @var AssemblyBOMEntry $bomEntry */ - foreach ($assembly->getBomEntries() as $bomEntry) { - $part = $bomEntry->getPart(); - - //Skip BOM entries without a part (as we can not determine that) - if (!$part instanceof Part && $bomEntry->getReferencedAssembly() === null) { - continue; - } - - if ($bomEntry->getPart() !== null) { - $amount_sum = $part->getAmountSum(); - - if ($amount_sum < $bomEntry->getQuantity() * $number_of_builds) { - $nonBuildableEntries[] = $bomEntry; - } - } elseif ($bomEntry->getReferencedAssembly() !== null) { - $nonBuildableAssemblyEntries = $this->getNonBuildableAssemblyBomEntries($bomEntry->getReferencedAssembly(), $number_of_builds); - $nonBuildableEntries = array_merge($nonBuildableEntries, $nonBuildableAssemblyEntries); - } - } - - return $nonBuildableEntries; - } - - /** - * Withdraw the parts from the stock using the given AssemblyBuildRequest and create the build parts entries, if needed. - * The AssemblyBuildRequest has to be validated before!! - * You have to flush changes to DB afterward - */ - public function doBuild(AssemblyBuildRequest $buildRequest): void - { - $message = $buildRequest->getComment(); - $message .= ' (Assembly build: '.$buildRequest->getAssembly()->getName().')'; - - foreach ($buildRequest->getPartBomEntries() as $bom_entry) { - foreach ($buildRequest->getPartLotsForBOMEntry($bom_entry) as $part_lot) { - $amount = $buildRequest->getLotWithdrawAmount($part_lot); - if ($amount > 0) { - $this->withdraw_add_helper->withdraw($part_lot, $amount, $message); - } - } - } - - if ($buildRequest->getAddBuildsToBuildsPart()) { - $this->withdraw_add_helper->add($buildRequest->getBuildsPartLot(), $buildRequest->getNumberOfBuilds(), $message); - } - } -} diff --git a/src/Services/AssemblySystem/AssemblyBuildPartHelper.php b/src/Services/AssemblySystem/AssemblyBuildPartHelper.php deleted file mode 100644 index 9a550350..00000000 --- a/src/Services/AssemblySystem/AssemblyBuildPartHelper.php +++ /dev/null @@ -1,40 +0,0 @@ -setBuiltAssembly($assembly); - - //Set the name of the part to the name of the assembly - $part->setName($assembly->getName()); - - //Set the description of the part to the description of the assembly - $part->setDescription($assembly->getDescription()); - - //Add a tag to the part that indicates that it is a build part - $part->setTags('assembly-build'); - - //Associate the part with the assembly - $assembly->setBuildPart($part); - - return $part; - } -} diff --git a/src/Services/Attachments/ProjectPreviewGenerator.php b/src/Services/Attachments/ProjectPreviewGenerator.php deleted file mode 100644 index 9929dbd3..00000000 --- a/src/Services/Attachments/ProjectPreviewGenerator.php +++ /dev/null @@ -1,93 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace App\Services\Attachments; - -use App\Entity\Attachments\Attachment; -use App\Entity\ProjectSystem\Project; - -class ProjectPreviewGenerator -{ - public function __construct(protected AttachmentManager $attachmentHelper) - { - } - - /** - * Returns a list of attachments that can be used for previewing the project ordered by priority. - * - * @param Project $project the project for which the attachments should be determined - * - * @return (Attachment|null)[] - * - * @psalm-return list - */ - public function getPreviewAttachments(Project $project): array - { - $list = []; - - //Master attachment has top priority - $attachment = $project->getMasterPictureAttachment(); - if ($this->isAttachmentValidPicture($attachment)) { - $list[] = $attachment; - } - - //Then comes the other images of the project - foreach ($project->getAttachments() as $attachment) { - //Dont show the master attachment twice - if ($this->isAttachmentValidPicture($attachment) && $attachment !== $project->getMasterPictureAttachment()) { - $list[] = $attachment; - } - } - - return $list; - } - - /** - * Determines what attachment should be used for previewing a project (especially in project table). - * The returned attachment is guaranteed to be existing and be a picture. - * - * @param Project $project The project for which the attachment should be determined - */ - public function getTablePreviewAttachment(Project $project): ?Attachment - { - $attachment = $project->getMasterPictureAttachment(); - if ($this->isAttachmentValidPicture($attachment)) { - return $attachment; - } - - return null; - } - - /** - * Checks if a attachment is exising and a valid picture. - * - * @param Attachment|null $attachment the attachment that should be checked - * - * @return bool true if the attachment is valid - */ - protected function isAttachmentValidPicture(?Attachment $attachment): bool - { - return $attachment instanceof Attachment - && $attachment->isPicture() - && $this->attachmentHelper->isFileExisting($attachment); - } -} diff --git a/src/Services/ImportExportSystem/BOMImporter.php b/src/Services/ImportExportSystem/BOMImporter.php index cf495a89..fc0791ee 100644 --- a/src/Services/ImportExportSystem/BOMImporter.php +++ b/src/Services/ImportExportSystem/BOMImporter.php @@ -513,8 +513,10 @@ class BOMImporter //Convert column name into hierarchy $path = explode('_', $column); + /** @var array $temp */ $temp = &$entry; + /** @var lowercase-string $step */ foreach ($path as $step) { if (!isset($temp[$step])) { $temp[$step] = []; @@ -526,7 +528,7 @@ class BOMImporter //If there is no value, skip if (isset($values[$index]) && $values[$index] !== '') { //Check whether the value is numerical - if (is_numeric($values[$index]) && !in_array($column, ['name','description','manufacturer','designator'])) { + if (is_numeric($values[$index]) && !in_array($column, ['name','description','manufacturer','designator'], true)) { //Convert to integer or float $temp = (str_contains($values[$index], '.')) ? floatval($values[$index]) @@ -577,7 +579,7 @@ class BOMImporter $bomEntry->setMountnames(trim($entry['designator']) === '' ? '' : trim($entry['designator'])); } - $bomEntry->setQuantity((float) $entry['quantity'] ?? 0); + $bomEntry->setQuantity((float) $entry['quantity']); $result->addBomEntry($bomEntry); } @@ -706,7 +708,7 @@ class BOMImporter $result->addViolation($this->buildJsonViolation( 'validator.bom_importer.json_csv.parameter.array', 'entry[$key].part.manufacturer', - $entry['part']['manufacturer']) ?? null + $entry['part']['manufacturer']) ); } @@ -728,8 +730,8 @@ class BOMImporter if (($manufacturerIdValid || $manufacturerNameValid) && $manufacturer === null) { $value = sprintf( 'manufacturer.id: %s, manufacturer.name: %s', - isset($entry['part']['manufacturer']['id']) && $entry['part']['manufacturer']['id'] !== null ? '' . $entry['part']['manufacturer']['id'] . '' : '-', - isset($entry['part']['manufacturer']['name']) && $entry['part']['manufacturer']['name'] !== null ? '' . $entry['part']['manufacturer']['name'] . '' : '-' + isset($entry['part']['manufacturer']['id']) && $entry['part']['manufacturer']['id'] != null ? '' . $entry['part']['manufacturer']['id'] . '' : '-', + isset($entry['part']['manufacturer']['name']) && $entry['part']['manufacturer']['name'] != null ? '' . $entry['part']['manufacturer']['name'] . '' : '-' ); $result->addViolation($this->buildJsonViolation( @@ -760,7 +762,7 @@ class BOMImporter $result->addViolation($this->buildJsonViolation( 'validator.bom_importer.json_csv.parameter.array', 'entry[$key].part.category', - $entry['part']['category']) ?? null + $entry['part']['category']) ); } @@ -782,8 +784,8 @@ class BOMImporter if (($categoryIdValid || $categoryNameValid)) { $value = sprintf( 'category.id: %s, category.name: %s', - isset($entry['part']['category']['id']) && $entry['part']['category']['id'] !== null ? '' . $entry['part']['category']['id'] . '' : '-', - isset($entry['part']['category']['name']) && $entry['part']['category']['name'] !== null ? '' . $entry['part']['category']['name'] . '' : '-' + isset($entry['part']['category']['id']) && $entry['part']['category']['id'] != null ? '' . $entry['part']['category']['id'] . '' : '-', + isset($entry['part']['category']['name']) && $entry['part']['category']['name'] != null ? '' . $entry['part']['category']['name'] . '' : '-' ); $result->addViolation($this->buildJsonViolation( @@ -816,11 +818,13 @@ class BOMImporter $part->setDescription($partDescription); } + /** @var Manufacturer|null $manufacturer */ if ($manufacturer !== null && $manufacturer->getID() !== $part->getManufacturer()->getID()) { //When updating the associated parts, take over to a assembly of the manufacturer of the part. $part->setManufacturer($manufacturer); } + /** @var Category|null $category */ if ($category !== null && $category->getID() !== $part->getCategory()->getID()) { //When updating the associated parts to a assembly, take over the category of the part. $part->setCategory($category); diff --git a/src/Services/ImportExportSystem/EntityExporter.php b/src/Services/ImportExportSystem/EntityExporter.php index 7db3f5eb..028a537e 100644 --- a/src/Services/ImportExportSystem/EntityExporter.php +++ b/src/Services/ImportExportSystem/EntityExporter.php @@ -414,7 +414,7 @@ class EntityExporter 'ProjectFullName' => $this->getFullName($entity), //BOM relevant attributes - 'Quantity' => $bomEntry->getQuantity() ?? '', + 'Quantity' => $bomEntry->getQuantity(), 'PartId' => $bomEntry->getPart()?->getId() ?? '', 'PartName' => $bomEntry->getPart()?->getName() ?? '', 'Ipn' => $bomEntry->getPart()?->getIpn() ?? '', @@ -582,7 +582,7 @@ class EntityExporter 'AssemblyFullName' => $this->getFullName($assembly), //BOM relevant attributes - 'Quantity' => $bomEntry->getQuantity() ?? '', + 'Quantity' => $bomEntry->getQuantity(), 'PartId' => $bomEntry->getPart()?->getId() ?? '-', 'PartName' => $bomEntry->getPart()?->getName() ?? '-', 'Ipn' => $bomEntry->getPart()?->getIpn() ?? '-', diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php index 4f4d8dff..c8fd18d3 100644 --- a/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php +++ b/src/Validator/Constraints/AssemblySystem/AssemblyCycleValidator.php @@ -132,10 +132,10 @@ class AssemblyCycleValidator extends ConstraintValidator * The process involves reflection to access private or protected properties of violation objects. * * @param mixed $value The value that triggered the violation. - * @param Constraint $constraint The constraint containing the validation details. + * @param AssemblyCycle $constraint The constraint containing the validation details. * */ - private function addViolation(mixed $value, Constraint $constraint): void + private function addViolation(mixed $value, AssemblyCycle $constraint): void { /** @var ConstraintViolationBuilder $buildViolation */ $buildViolation = $this->context->buildViolation($constraint->message) diff --git a/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntryValidator.php b/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntryValidator.php index 276c865e..e563fa8d 100644 --- a/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntryValidator.php +++ b/src/Validator/Constraints/AssemblySystem/AssemblyInvalidBomEntryValidator.php @@ -97,19 +97,6 @@ class AssemblyInvalidBomEntryValidator extends ConstraintValidator } - private function isOnSameLevel(Assembly $assembly1, Assembly $assembly2): bool - { - $parent1 = $assembly1->getParent(); - $parent2 = $assembly2->getParent(); - - if ($parent1 === null || $parent2 === null) { - return false; - } - - // Beide Assemblies teilen denselben Parent - return $parent1 !== null && $parent2 !== null && $parent1->getId() === $parent2->getId(); - } - /** * Adds a violation to the current context if it hasn’t already been added. * @@ -117,11 +104,11 @@ class AssemblyInvalidBomEntryValidator extends ConstraintValidator * already exists in the context. If such a violation is found, the current violation is not added again. * The process involves reflection to access private or protected properties of violation objects. * - * @param mixed $value The value that triggered the violation. - * @param Constraint $constraint The constraint containing the validation details. + * @param mixed $value The value that triggered the violation. + * @param AssemblyInvalidBomEntry $constraint The constraint containing the validation details. * */ - private function addViolation($value, Constraint $constraint): void + private function addViolation($value, AssemblyInvalidBomEntry $constraint): void { /** @var ConstraintViolationBuilder $buildViolation */ $buildViolation = $this->context->buildViolation($constraint->message) @@ -152,4 +139,4 @@ class AssemblyInvalidBomEntryValidator extends ConstraintValidator $buildViolation->addViolation(); } } -} \ No newline at end of file +} diff --git a/src/Validator/Constraints/AssemblySystem/UniqueReferencedAssemblyValidator.php b/src/Validator/Constraints/AssemblySystem/UniqueReferencedAssemblyValidator.php index 0e58c066..0b3eb395 100644 --- a/src/Validator/Constraints/AssemblySystem/UniqueReferencedAssemblyValidator.php +++ b/src/Validator/Constraints/AssemblySystem/UniqueReferencedAssemblyValidator.php @@ -30,6 +30,7 @@ class UniqueReferencedAssemblyValidator extends ConstraintValidator public function validate($value, Constraint $constraint) { $assemblies = []; + foreach ($value as $entry) { $referencedAssemblyId = $entry->getReferencedAssembly()?->getId(); if ($referencedAssemblyId === null) { @@ -37,6 +38,7 @@ class UniqueReferencedAssemblyValidator extends ConstraintValidator } if (isset($assemblies[$referencedAssemblyId])) { + /** @var UniqueReferencedAssembly $constraint */ $this->context->buildViolation($constraint->message) ->atPath('referencedAssembly') ->addViolation(); @@ -45,4 +47,4 @@ class UniqueReferencedAssemblyValidator extends ConstraintValidator $assemblies[$referencedAssemblyId] = true; } } -} \ No newline at end of file +} diff --git a/src/Validator/Constraints/AssemblySystem/ValidAssemblyBuildRequest.php b/src/Validator/Constraints/AssemblySystem/ValidAssemblyBuildRequest.php deleted file mode 100644 index dd3bc19e..00000000 --- a/src/Validator/Constraints/AssemblySystem/ValidAssemblyBuildRequest.php +++ /dev/null @@ -1,37 +0,0 @@ -. - */ -namespace App\Validator\Constraints\AssemblySystem; - -use Symfony\Component\Validator\Constraint; - -/** - * This constraint checks that the given ValidAssemblyBuildRequest is valid. - */ -#[\Attribute(\Attribute::TARGET_CLASS)] -class ValidAssemblyBuildRequest extends Constraint -{ - public function getTargets(): string - { - return self::CLASS_CONSTRAINT; - } -} diff --git a/src/Validator/Constraints/AssemblySystem/ValidAssemblyBuildRequestValidator.php b/src/Validator/Constraints/AssemblySystem/ValidAssemblyBuildRequestValidator.php deleted file mode 100644 index 9d8c2e56..00000000 --- a/src/Validator/Constraints/AssemblySystem/ValidAssemblyBuildRequestValidator.php +++ /dev/null @@ -1,84 +0,0 @@ -. - */ -namespace App\Validator\Constraints\AssemblySystem; - -use App\Entity\Parts\PartLot; -use App\Helpers\Assemblies\AssemblyBuildRequest; -use Symfony\Component\Validator\Constraint; -use Symfony\Component\Validator\ConstraintValidator; -use Symfony\Component\Validator\Exception\UnexpectedTypeException; -use Symfony\Component\Validator\Violation\ConstraintViolationBuilderInterface; - -class ValidAssemblyBuildRequestValidator extends ConstraintValidator -{ - private function buildViolationForLot(PartLot $partLot, string $message): ConstraintViolationBuilderInterface - { - return $this->context->buildViolation($message) - ->atPath('lot_' . $partLot->getID()) - ->setParameter('{{ lot }}', $partLot->getName()); - } - - public function validate($value, Constraint $constraint): void - { - if (!$constraint instanceof ValidAssemblyBuildRequest) { - throw new UnexpectedTypeException($constraint, ValidAssemblyBuildRequest::class); - } - - if (null === $value || '' === $value) { - return; - } - - if (!$value instanceof AssemblyBuildRequest) { - throw new UnexpectedTypeException($value, AssemblyBuildRequest::class); - } - - foreach ($value->getPartBomEntries() as $bom_entry) { - $withdraw_sum = $value->getWithdrawAmountSum($bom_entry); - $needed_amount = $value->getNeededAmountForBOMEntry($bom_entry); - - foreach ($value->getPartLotsForBOMEntry($bom_entry) as $lot) { - $withdraw_amount = $value->getLotWithdrawAmount($lot); - - if ($withdraw_amount < 0) { - $this->buildViolationForLot($lot, 'validator.assembly_build.lot_must_not_smaller_0') - ->addViolation(); - } - - if ($withdraw_amount > $lot->getAmount()) { - $this->buildViolationForLot($lot, 'validator.assembly_build.lot_must_not_bigger_than_stock') - ->addViolation(); - } - - if ($withdraw_sum > $needed_amount && $value->isDontCheckQuantity() === false) { - $this->buildViolationForLot($lot, 'validator.assembly_build.lot_bigger_than_needed') - ->addViolation(); - } - - if ($withdraw_sum < $needed_amount && $value->isDontCheckQuantity() === false) { - $this->buildViolationForLot($lot, 'validator.assembly_build.lot_smaller_than_needed') - ->addViolation(); - } - } - } - } -} diff --git a/templates/assemblies/build/_form.html.twig b/templates/assemblies/build/_form.html.twig deleted file mode 100644 index aaaa7824..00000000 --- a/templates/assemblies/build/_form.html.twig +++ /dev/null @@ -1,90 +0,0 @@ -{% import "helper.twig" as helper %} - -{{ form_start(form) }} - - - - - - - - - - - - {% for bom_entry in build_request.bomEntries %} - {# 1st row basic infos about the BOM entry #} - - - - - - - - - - {% endfor %} - -
-
- -
-
{% trans %}part.table.name{% endtrans %}{% trans %}assembly.bom.mountnames{% endtrans %}{% trans %}assembly.build.required_qty{% endtrans %}
-
- - {#
-
- {% if bom_entry.part %} - {{ bom_entry.part.name }} {% if bom_entry.name %}({{ bom_entry.name }}){% endif %} - {% elseif bom_entry.referencedAssembly %} - {{ 'assembly.build.form.referencedAssembly'|trans({'%name%': bom_entry.referencedAssembly.name}) }} {% if bom_entry.name %}({{ bom_entry.name }}){% endif %} - {% else %} - {{ bom_entry.name }} - {% endif %} - - {% for tag in bom_entry.mountnames|split(',') %} - {{ tag | trim }} - {% endfor %} - - {{ build_request.neededAmountForBOMEntry(bom_entry) | format_amount(bom_entry.part.partUnit ?? null) }} {% trans %}assembly.builds.needed{% endtrans %} - (= {{ number_of_builds }} x {{ bom_entry.quantity | format_amount(bom_entry.part.partUnit ?? null) }}) -
- {% set lots = build_request.partLotsForBOMEntry(bom_entry) %} - {% if lots is not null %} - {% for lot in lots %} - {# @var lot \App\Entity\Parts\PartLot #} -
- -
- {{ form_errors(form["lot_"~lot.id]) }} - {{ form_widget(form["lot_"~lot.id]) }} -
-
- / {{ lot.amount | format_amount(lot.part.partUnit) }} {% trans %}assembly.builds.stocked{% endtrans %} -
-
- {% endfor %} - {% endif %} -
- -{{ form_row(form.comment) }} -
-{{ form_row(form.dontCheckQuantity) }} -
- -{{ form_row(form.addBuildsToBuildsPart) }} -{% if form.buildsPartLot is defined %} - {{ form_row(form.buildsPartLot) }} -{% endif %} - -{{ form_row(form.submit) }} - -{{ form_end(form) }} diff --git a/templates/assemblies/build/build.html.twig b/templates/assemblies/build/build.html.twig deleted file mode 100644 index 8f01607c..00000000 --- a/templates/assemblies/build/build.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{% extends "main_card.html.twig" %} - -{% block title %}{% trans %}assembly.info.builds.label{% endtrans %}: {{ number_of_builds }}x {{ assembly.name }}{% endblock %} - -{% block card_title %} - - {% trans %}assembly.info.builds.label{% endtrans %}: {{ number_of_builds }}x {{ assembly.name }} -{% endblock %} - -{% block card_content %} - {% set can_build = buildHelper.assemblyBuildable(assembly, number_of_builds) %} - {% import "components/assemblies.macro.html.twig" as assembly_macros %} - - {% if assembly.status is not empty and assembly.status != "in_production" %} - - {% endif %} - - - -

{% trans %}assembly.build.help{% endtrans %}

- - {% include 'assemblies/build/_form.html.twig' %} - - -{% endblock %} \ No newline at end of file diff --git a/templates/assemblies/info/_builds.html.twig b/templates/assemblies/info/_builds.html.twig deleted file mode 100644 index 780c8c60..00000000 --- a/templates/assemblies/info/_builds.html.twig +++ /dev/null @@ -1,40 +0,0 @@ -{% set can_build = buildHelper.assemblyBuildable(assembly) %} - -{% import "components/assemblies.macro.html.twig" as assembly_macros %} - -{% if assembly.status is not empty and assembly.status != "in_production" %} - -{% endif %} - - - -
-
-
-
- - - -
-
-
-
- -{% if assembly.buildPart %} -

{% trans %}assembly.builds.no_stocked_builds{% endtrans %}: {{ assembly.buildPart.amountSum }}

-{% endif %} \ No newline at end of file diff --git a/templates/components/assemblies.macro.html.twig b/templates/components/assemblies.macro.html.twig deleted file mode 100644 index d59005e0..00000000 --- a/templates/components/assemblies.macro.html.twig +++ /dev/null @@ -1,8 +0,0 @@ -{% macro assembly_bom_entry_with_missing_instock(assembly_bom_entry, number_of_builds = 1) %} - {# @var \App\Entity\AssemblySystem\AssemblyBOMEntry assembly_bom_entry #} - {{ assembly_bom_entry.part.name }} - {% if assembly_bom_entry.name %} ({{ assembly_bom_entry.name }}){% endif %}: - {{ assembly_bom_entry.part.amountSum | format_amount(assembly_bom_entry.part.partUnit) }} {% trans %}assembly.builds.stocked{% endtrans %} - / - {{ (assembly_bom_entry.quantity * number_of_builds) | format_amount(assembly_bom_entry.part.partUnit) }} {% trans %}assembly.builds.needed{% endtrans %} -{% endmacro %} \ No newline at end of file diff --git a/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php b/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php deleted file mode 100644 index 210e3301..00000000 --- a/tests/Helpers/Assemblies/AssemblyBuildRequestTest.php +++ /dev/null @@ -1,177 +0,0 @@ -. - */ -namespace App\Tests\Helpers\Assemblies; - -use App\Entity\Parts\MeasurementUnit; -use App\Entity\Parts\Part; -use App\Entity\Parts\PartLot; -use App\Entity\AssemblySystem\Assembly; -use App\Entity\AssemblySystem\AssemblyBOMEntry; -use App\Helpers\Assemblies\AssemblyBuildRequest; -use PHPUnit\Framework\TestCase; - -class AssemblyBuildRequestTest extends TestCase -{ - - /** @var MeasurementUnit $float_unit */ - private MeasurementUnit $float_unit; - - /** @var Assembly */ - private Assembly $assembly1; - /** @var AssemblyBOMEntry */ - private AssemblyBOMEntry $bom_entry1a; - /** @var AssemblyBOMEntry */ - private AssemblyBOMEntry $bom_entry1b; - /** @var AssemblyBOMEntry */ - private AssemblyBOMEntry $bom_entry1c; - - private PartLot $lot1a; - private PartLot $lot1b; - private PartLot $lot2; - - /** @var Part */ - private Part $part1; - /** @var Part */ - private Part $part2; - - - public function setUp(): void - { - $this->float_unit = new MeasurementUnit(); - $this->float_unit->setName('float'); - $this->float_unit->setUnit('f'); - $this->float_unit->setIsInteger(false); - $this->float_unit->setUseSIPrefix(true); - - //Setup some example parts and part lots - $this->part1 = new Part(); - $this->part1->setName('Part 1'); - $this->lot1a = new class extends PartLot { - public function getID(): ?int - { - return 1; - } - }; - $this->part1->addPartLot($this->lot1a); - $this->lot1a->setAmount(10); - $this->lot1a->setDescription('Lot 1a'); - - $this->lot1b = new class extends PartLot { - public function getID(): ?int - { - return 2; - } - }; - $this->part1->addPartLot($this->lot1b); - $this->lot1b->setAmount(20); - $this->lot1b->setDescription('Lot 1b'); - - $this->part2 = new Part(); - - $this->part2->setName('Part 2'); - $this->part2->setPartUnit($this->float_unit); - $this->lot2 = new PartLot(); - $this->part2->addPartLot($this->lot2); - $this->lot2->setAmount(2.5); - $this->lot2->setDescription('Lot 2'); - - $this->bom_entry1a = new AssemblyBOMEntry(); - $this->bom_entry1a->setPart($this->part1); - $this->bom_entry1a->setQuantity(2); - - $this->bom_entry1b = new AssemblyBOMEntry(); - $this->bom_entry1b->setPart($this->part2); - $this->bom_entry1b->setQuantity(1.5); - - $this->bom_entry1c = new AssemblyBOMEntry(); - $this->bom_entry1c->setName('Non-part BOM entry'); - $this->bom_entry1c->setQuantity(4); - - - $this->assembly1 = new Assembly(); - $this->assembly1->setName('Assembly 1'); - $this->assembly1->addBomEntry($this->bom_entry1a); - $this->assembly1->addBomEntry($this->bom_entry1b); - $this->assembly1->addBomEntry($this->bom_entry1c); - } - - public function testInitialization(): void - { - //The values should be already prefilled correctly - $request = new AssemblyBuildRequest($this->assembly1, 10); - //We need totally 20: Take 10 from the first (maximum 10) and 10 from the second (maximum 20) - $this->assertEqualsWithDelta(10.0, $request->getLotWithdrawAmount($this->lot1a), PHP_FLOAT_EPSILON); - $this->assertEqualsWithDelta(10.0, $request->getLotWithdrawAmount($this->lot1b), PHP_FLOAT_EPSILON); - - //If the needed amount is higher than the maximum, we should get the maximum - $this->assertEqualsWithDelta(2.5, $request->getLotWithdrawAmount($this->lot2), PHP_FLOAT_EPSILON); - } - - public function testGetNumberOfBuilds(): void - { - $build_request = new AssemblyBuildRequest($this->assembly1, 5); - $this->assertSame(5, $build_request->getNumberOfBuilds()); - } - - public function testGetAssembly(): void - { - $build_request = new AssemblyBuildRequest($this->assembly1, 5); - $this->assertEquals($this->assembly1, $build_request->getAssembly()); - } - - public function testGetNeededAmountForBOMEntry(): void - { - $build_request = new AssemblyBuildRequest($this->assembly1, 5); - $this->assertEqualsWithDelta(10.0, $build_request->getNeededAmountForBOMEntry($this->bom_entry1a), PHP_FLOAT_EPSILON); - $this->assertEqualsWithDelta(7.5, $build_request->getNeededAmountForBOMEntry($this->bom_entry1b), PHP_FLOAT_EPSILON); - $this->assertEqualsWithDelta(20.0, $build_request->getNeededAmountForBOMEntry($this->bom_entry1c), PHP_FLOAT_EPSILON); - } - - public function testGetSetLotWithdrawAmount(): void - { - $build_request = new AssemblyBuildRequest($this->assembly1, 5); - - //We can set the amount for a lot either via the lot object or via the ID - $build_request->setLotWithdrawAmount($this->lot1a, 2); - $build_request->setLotWithdrawAmount($this->lot1b->getID(), 3); - - //And it should be possible to get the amount via the lot object or via the ID - $this->assertEqualsWithDelta(2.0, $build_request->getLotWithdrawAmount($this->lot1a->getID()), PHP_FLOAT_EPSILON); - $this->assertEqualsWithDelta(3.0, $build_request->getLotWithdrawAmount($this->lot1b), PHP_FLOAT_EPSILON); - } - - public function testGetWithdrawAmountSum(): void - { - //The sum of all withdraw amounts for an BOM entry (over all lots of the associated part) should be correct - $build_request = new AssemblyBuildRequest($this->assembly1, 5); - - $build_request->setLotWithdrawAmount($this->lot1a, 2); - $build_request->setLotWithdrawAmount($this->lot1b, 3); - - $this->assertEqualsWithDelta(5.0, $build_request->getWithdrawAmountSum($this->bom_entry1a), PHP_FLOAT_EPSILON); - $build_request->setLotWithdrawAmount($this->lot2, 1.5); - $this->assertEqualsWithDelta(1.5, $build_request->getWithdrawAmountSum($this->bom_entry1b), PHP_FLOAT_EPSILON); - } - - -} diff --git a/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php b/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php deleted file mode 100644 index c513ed8d..00000000 --- a/tests/Services/AssemblySystem/AssemblyBuildHelperTest.php +++ /dev/null @@ -1,117 +0,0 @@ -. - */ -namespace App\Tests\Services\AssemblySystem; - -use App\Entity\AssemblySystem\Assembly; -use App\Entity\AssemblySystem\AssemblyBOMEntry; -use App\Entity\Parts\Part; -use App\Entity\Parts\PartLot; -use App\Services\AssemblySystem\AssemblyBuildHelper; -use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; - -class AssemblyBuildHelperTest extends WebTestCase -{ - /** @var AssemblyBuildHelper */ - protected $service; - - protected function setUp(): void - { - self::bootKernel(); - $this->service = self::getContainer()->get(AssemblyBuildHelper::class); - } - - public function testGetMaximumBuildableCountForBOMEntryNonPartBomEntry(): void - { - $bom_entry = new AssemblyBOMEntry(); - $bom_entry->setPart(null); - $bom_entry->setQuantity(10); - $bom_entry->setName('Test'); - - $this->expectException(\InvalidArgumentException::class); - $this->service->getMaximumBuildableCountForBOMEntry($bom_entry); - } - - public function testGetMaximumBuildableCountForBOMEntry(): void - { - $assembly_bom_entry = new AssemblyBOMEntry(); - $assembly_bom_entry->setQuantity(10); - - $part = new Part(); - $lot1 = new PartLot(); - $lot1->setAmount(120); - $lot2 = new PartLot(); - $lot2->setAmount(5); - $part->addPartLot($lot1); - $part->addPartLot($lot2); - - $assembly_bom_entry->setPart($part); - - //We have 125 parts in stock, so we can build 12 times the assembly (125 / 10 = 12.5) - $this->assertSame(12, $this->service->getMaximumBuildableCountForBOMEntry($assembly_bom_entry)); - - - $lot1->setAmount(0); - //We have 5 parts in stock, so we can build 0 times the assembly (5 / 10 = 0.5) - $this->assertSame(0, $this->service->getMaximumBuildableCountForBOMEntry($assembly_bom_entry)); - } - - public function testGetMaximumBuildableCount(): void - { - $assembly = new Assembly(); - - $assembly_bom_entry1 = new AssemblyBOMEntry(); - $assembly_bom_entry1->setQuantity(10); - $part = new Part(); - $lot1 = new PartLot(); - $lot1->setAmount(120); - $lot2 = new PartLot(); - $lot2->setAmount(5); - $part->addPartLot($lot1); - $part->addPartLot($lot2); - $assembly_bom_entry1->setPart($part); - $assembly->addBomEntry($assembly_bom_entry1); - - $assembly_bom_entry2 = new AssemblyBOMEntry(); - $assembly_bom_entry2->setQuantity(5); - $part2 = new Part(); - $lot3 = new PartLot(); - $lot3->setAmount(10); - $part2->addPartLot($lot3); - $assembly_bom_entry2->setPart($part2); - $assembly->addBomEntry($assembly_bom_entry2); - - $assembly->addBomEntry((new AssemblyBOMEntry())->setName('Non part entry')->setQuantity(1)); - - //Restricted by the few parts in stock of part2 - $this->assertSame(2, $this->service->getMaximumBuildableCount($assembly)); - - $lot3->setAmount(1000); - //Now the build count is restricted by the few parts in stock of part1 - $this->assertSame(12, $this->service->getMaximumBuildableCount($assembly)); - - $lot3->setAmount(0); - //Now the build count must be 0, as we have no parts in stock - $this->assertSame(0, $this->service->getMaximumBuildableCount($assembly)); - - } -} diff --git a/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php b/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php deleted file mode 100644 index b8aa0ddc..00000000 --- a/tests/Services/AssemblySystem/AssemblyBuildPartHelperTest.php +++ /dev/null @@ -1,52 +0,0 @@ -. - */ -namespace App\Tests\Services\AssemblySystem; - -use App\Entity\AssemblySystem\Assembly; -use App\Services\AssemblySystem\AssemblyBuildPartHelper; -use Symfony\Bundle\FrameworkBundle\Test\WebTestCase; - -class AssemblyBuildPartHelperTest extends WebTestCase -{ - /** @var AssemblyBuildPartHelper */ - protected $service; - - protected function setUp(): void - { - self::bootKernel(); - $this->service = self::getContainer()->get(AssemblyBuildPartHelper::class); - } - - public function testGetPartInitialization(): void - { - $assembly = new Assembly(); - $assembly->setName('Assembly 1'); - $assembly->setDescription('Description 1'); - - $part = $this->service->getPartInitialization($assembly); - $this->assertSame('Assembly 1', $part->getName()); - $this->assertSame('Description 1', $part->getDescription()); - $this->assertSame($assembly, $part->getBuiltAssembly()); - $this->assertSame($part, $assembly->getBuildPart()); - } -} diff --git a/translations/messages.cs.xlf b/translations/messages.cs.xlf index 9e3a0b61..b03cdc4a 100644 --- a/translations/messages.cs.xlf +++ b/translations/messages.cs.xlf @@ -13774,24 +13774,6 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz Nová sestava - - - assembly.edit.associated_build_part - Přidružená součást - - - - - assembly.edit.associated_build_part.add - Přidat součást - - - - - assembly.edit.associated_build.hint - Tato součást představuje vyrobené instance sestavy. Zadejte, pokud jsou vyrobené instance potřeba. Pokud ne, počet součástí bude použit až při sestavení daného projektu. - - assembly.edit.bom.import_bom @@ -13900,60 +13882,6 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz Přidat součásti - - - assembly.builds.check_assembly_status - "%assembly_status%". Měli byste zkontrolovat, zda opravdu chcete sestavu postavit s tímto stavem!]]> - - - - - assembly.builds.build_not_possible - Sestavení není možné: Nedostatek součástí - - - - - assembly.builds.following_bom_entries_miss_instock - Není dostatek součástí na skladě pro postavení tohoto projektu %number_of_builds% krát. Následující součásti nejsou skladem v dostatečném množství. - - - - - assembly.builds.build_possible - Sestavení je možné - - - - - assembly.builds.number_of_builds_possible - %max_builds% kusů této sestavy.]]> - - - - - assembly.builds.number_of_builds - Počet sestavení - - - - - assembly.build.btn_build - Sestavit - - - - - assembly.build.form.referencedAssembly - Sestava "%name%" - - - - - assembly.builds.no_stocked_builds - Počet skladovaných vyrobených instancí - - assembly.info.bom_entries_count @@ -13966,18 +13894,6 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz Podskupiny - - - assembly.builds.stocked - skladem - - - - - assembly.builds.needed - potřebné - - assembly.bom.delete.confirm @@ -14026,24 +13942,6 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz Poznámky - - - assembly.builds.following_bom_entries_miss_instock_n - Není dostatek součástí na skladě pro sestavení této sestavy %number_of_builds% krát. Následující součásti nejsou skladem: - - - - - assembly.build.help - Vyberte, ze kterých zásob se mají brát potřebné součásti pro sestavení (a v jakém množství). Zaškrtněte políčko u každého dílu, pokud jste jej odebrali, nebo použijte horní políčko k výběru všech naráz. - - - - - assembly.build.required_qty - Požadované množství - - assembly.import_bom @@ -14074,24 +13972,6 @@ Vezměte prosím na vědomí, že se nemůžete vydávat za uživatele se zakáz Cena - - - assembly.build.dont_check_quantity - Neověřovat množství - - - - - assembly.build.dont_check_quantity.help - Pokud je tato volba vybrána, budou vybraná množství odstraněna ze skladu bez ohledu na to, zda je méně nebo více součástí, než je skutečně potřeba pro sestavení sestavy. - - - - - assembly.build.add_builds_to_builds_part - Přidat vyrobené instance do součásti sestavy - - assembly.bom_import.type diff --git a/translations/messages.da.xlf b/translations/messages.da.xlf index 1caa65e9..e3c24a09 100644 --- a/translations/messages.da.xlf +++ b/translations/messages.da.xlf @@ -12779,24 +12779,6 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver Ny samling - - - assembly.edit.associated_build_part - Tilknyttet komponent - - - - - assembly.edit.associated_build_part.add - Tilføj komponent - - - - - assembly.edit.associated_build.hint - Denne komponent repræsenterer de fremstillede instanser af samlingen. Angiv, hvis fremstillede instanser er påkrævet. Hvis ikke, vil antallet af komponenter først blive anvendt ved opbygning af det pågældende projekt. - - assembly.edit.bom.import_bom @@ -12905,60 +12887,6 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver Tilføj dele - - - assembly.builds.check_assembly_status - "%assembly_status%". Du bør kontrollere, om du virkelig ønsker at bygge samlingen med denne status!]]> - - - - - assembly.builds.build_not_possible - Opbygning ikke mulig: Ikke nok komponenter til rådighed - - - - - assembly.builds.following_bom_entries_miss_instock - Der er ikke nok dele på lager til at bygge dette projekt %number_of_builds% gange. Følgende dele mangler på lager: - - - - - assembly.builds.build_possible - Byggeri muligt - - - - - assembly.builds.number_of_builds_possible - %max_builds% eksemplarer af denne samling.]]> - - - - - assembly.builds.number_of_builds - Antal opbygninger - - - - - assembly.build.btn_build - Byg - - - - - assembly.build.form.referencedAssembly - Samling "%name%" - - - - - assembly.builds.no_stocked_builds - Antal lagrede byggede enheder - - assembly.info.bom_entries_count @@ -12971,18 +12899,6 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver Undergrupper - - - assembly.builds.stocked - på lager - - - - - assembly.builds.needed - nødvendig - - assembly.bom.delete.confirm @@ -13031,24 +12947,6 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver Notater - - - assembly.builds.following_bom_entries_miss_instock_n - Der er ikke nok dele på lager til at bygge denne samling %number_of_builds% gange. Følgende dele mangler på lager: - - - - - assembly.build.help - Vælg, hvilke lagre de nødvendige dele til bygningen skal tages fra (og i hvilken mængde). Marker afkrydsningsfeltet for hver delpost, når du har fjernet delene, eller brug det øverste afkrydsningsfelt for at markere alle på én gang. - - - - - assembly.build.required_qty - Krævet antal - - assembly.import_bom @@ -13079,24 +12977,6 @@ Bemærk venligst, at du ikke kan kopiere fra deaktiveret bruger. Hvis du prøver Pris - - - assembly.build.dont_check_quantity - Tjek ikke mængder - - - - - assembly.build.dont_check_quantity.help - Hvis denne mulighed vælges, fjernes de valgte mængder fra lageret, uanset om der er mere eller mindre end nødvendigt for at bygge samlingen. - - - - - assembly.build.add_builds_to_builds_part - Tilføj byggede enheder til assemblies del - - assembly.bom_import.type diff --git a/translations/messages.de.xlf b/translations/messages.de.xlf index 602dfaf3..b88ee813 100644 --- a/translations/messages.de.xlf +++ b/translations/messages.de.xlf @@ -13608,24 +13608,6 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön Neue Baugruppe - - - assembly.edit.associated_build_part - Verknüpftes Bauteil - - - - - assembly.edit.associated_build_part.add - Bauteil hinzufügen - - - - - assembly.edit.associated_build.hint - Dieses Bauteil repräsentiert die gebauten Instanzen der Baugruppe. Anzugeben, sofern gebaute Instanzen benötigt werden. Wenn nein, werden die Stückzahlen bzgl. der Baugruppe erst beim Build des jeweiligen Projektes herangezogen. - - assembly.edit.bom.import_bom @@ -13734,60 +13716,6 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön Bauteile hinzufügen - - - assembly.builds.check_assembly_status - "%assembly_status%". Sie sollten überprüfen, ob sie die Baugruppe mit diesem Status wirklich bauen wollen!]]> - - - - - assembly.builds.build_not_possible - Bau nicht möglich: Nicht genügend Bauteile vorhanden - - - - - assembly.builds.following_bom_entries_miss_instock - Es sind nicht genügend Bauteile auf Lager, um dieses Projekt %number_of_builds% mal zu bauen. Von folgenden Bauteilen ist nicht genügend auf Lager. - - - - - assembly.builds.build_possible - Bau möglich - - - - - assembly.builds.number_of_builds_possible - %max_builds% Exemplare dieser Baugruppe zu bauen.]]> - - - - - assembly.builds.number_of_builds - Zu bauende Anzahl - - - - - assembly.build.btn_build - Bauen - - - - - asssembly.build.form.referencedAssembly - Baugruppe "%name%" - - - - - assembly.builds.no_stocked_builds - Anzahl gelagerter gebauter Instanzen - - assembly.info.bom_entries_count @@ -13800,18 +13728,6 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön Untergruppen - - - assembly.builds.stocked - vorhanden - - - - - assembly.builds.needed - benötigt - - assembly.bom.delete.confirm @@ -13860,24 +13776,6 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön Notizen - - - assembly.builds.following_bom_entries_miss_instock_n - Es sind nicht genügend Bauteile auf Lager, um diese Baugruppe %number_of_builds% mal zu bauen. Von folgenden Bauteilen ist nicht genügend auf Lager: - - - - - assembly.build.help - Wählen Sie aus, aus welchen Beständen die zum Bau notwendigen Bauteile genommen werden sollen (und in welcher Anzahl). Setzen Sie den Haken für jeden Part Eintrag, wenn sie die Bauteile entnommen haben, oder nutzen Sie die oberste Checkbox, um alle Haken auf einmal zu setzen. - - - - - assembly.build.required_qty - Benötigte Anzahl - - assembly.import_bom @@ -13908,24 +13806,6 @@ Bitte beachten Sie, dass Sie sich nicht als deaktivierter Benutzer ausgeben kön Preis - - - assembly.build.dont_check_quantity - Mengen nicht überprüfen - - - - - assembly.build.dont_check_quantity.help - Wenn diese Option gewählt wird, werden die gewählten Mengen aus dem Lager entfernt, egal ob mehr oder weniger Bauteile sind, als für den Bau der Baugruppe eigentlich benötigt werden. - - - - - assembly.build.add_builds_to_builds_part - Gebaute Instanzen zum Bauteil der Baugruppe hinzufügen - - assembly.bom_import.type diff --git a/translations/messages.el.xlf b/translations/messages.el.xlf index 206787dd..42094d65 100644 --- a/translations/messages.el.xlf +++ b/translations/messages.el.xlf @@ -1703,24 +1703,6 @@ Νέο σύνολο - - - assembly.edit.associated_build_part - Σχετικό μέρος - - - - - assembly.edit.associated_build_part.add - Προσθήκη μέρους - - - - - assembly.edit.associated_build.hint - Αυτό το μέρος αντιπροσωπεύει τις κατασκευασμένες εκδόσεις του συνόλου. Καταχωρίστε το εάν απαιτούνται κατασκευασμένες εκδόσεις. Εάν όχι, οι ποσότητες θα χρησιμοποιηθούν μόνο κατά την κατασκευή του εκάστοτε έργου. - - assembly.edit.bom.import_bom @@ -1817,60 +1799,6 @@ Προσθήκη εξαρτημάτων - - - assembly.builds.check_assembly_status - «%assembly_status%». Ελέγξτε εάν θέλετε πραγματικά να κατασκευάσετε τη συναρμολόγηση με αυτήν την κατάσταση!]]> - - - - - assembly.builds.build_not_possible - Η κατασκευή δεν είναι δυνατή: Δεν υπάρχουν αρκετά διαθέσιμα εξαρτήματα - - - - - assembly.builds.following_bom_entries_miss_instock - Δεν υπάρχουν αρκετά εξαρτήματα σε απόθεμα για να κατασκευαστεί αυτό το έργο %number_of_builds% φορές. Λείπουν τα ακόλουθα εξαρτήματα: - - - - - assembly.builds.build_possible - Κατασκευή δυνατή - - - - - assembly.builds.number_of_builds_possible - %max_builds% μονάδες αυτής της συναρμολόγησης.]]> - - - - - assembly.builds.number_of_builds - Αριθμός κατασκευών - - - - - assembly.build.btn_build - Κατασκευή - - - - - assembly.build.form.referencedAssembly - Συναρμολόγηση "%name%" - - - - - assembly.builds.no_stocked_builds - Αποθηκευμένα κατασκευασμένα κομμάτια - - assembly.info.bom_entries_count @@ -1883,18 +1811,6 @@ Υποομάδες - - - assembly.builds.stocked - σε απόθεμα - - - - - assembly.builds.needed - απαιτούμενο - - assembly.bom.delete.confirm @@ -1937,24 +1853,6 @@ Σχόλια - - - assembly.builds.following_bom_entries_miss_instock_n - Δεν υπάρχουν αρκετά εξαρτήματα σε απόθεμα για να κατασκευαστεί αυτή η συναρμολόγηση %number_of_builds% φορές. Λείπουν τα ακόλουθα εξαρτήματα: - - - - - assembly.build.help - Επιλέξτε από ποια αποθέματα θα αφαιρεθούν τα αναγκαία για την κατασκευή εξαρτήματα (και σε ποια ποσότητα). Σημειώστε το πλαίσιο επιλογής για κάθε εξάρτημα όταν αφαιρέσετε τα εξαρτήματα ή χρησιμοποιήστε το ανώτερο πλαίσιο επιλογής για να τα ελέγξετε όλα ταυτόχρονα. - - - - - assembly.build.required_qty - Απαιτούμενη ποσότητα - - assembly.import_bom @@ -1979,24 +1877,6 @@ Τιμή - - - assembly.build.dont_check_quantity - Μην ελέγχετε την ποσότητα - - - - - assembly.build.dont_check_quantity.help - Εάν επιλεγεί αυτή η επιλογή, οι επιλεγμένες ποσότητες θα αφαιρεθούν από το απόθεμα ανεξάρτητα από το αν είναι περισσότερο ή λιγότερο από το απαιτούμενο για την κατασκευή της συναρμολόγησης. - - - - - assembly.build.add_builds_to_builds_part - Προσθήκη κατασκευασμένων κομματιών στο τμήμα συναρμολόγησης - - assembly.bom_import.type diff --git a/translations/messages.en.xlf b/translations/messages.en.xlf index db5050ae..5346f19b 100644 --- a/translations/messages.en.xlf +++ b/translations/messages.en.xlf @@ -13609,24 +13609,6 @@ Please note, that you can not impersonate a disabled user. If you try you will g New assembly - - - assembly.edit.associated_build_part - Associated builds part - - - - - assembly.edit.associated_build_part.add - Add builds part - - - - - assembly.edit.associated_build.hint - This part represents the builds of this assembly. To indicate if built instances are required. If not, the number of pieces regarding the assembly are only used for the build of the respective project. - - assembly.edit.bom.import_bom @@ -13735,60 +13717,6 @@ Please note, that you can not impersonate a disabled user. If you try you will g Add part entries - - - assembly.builds.check_assembly_status - "%assembly_status%". You should check if you really want to build the assembly with this status!]]> - - - - - assembly.builds.build_not_possible - Build not possible: Parts not stocked - - - - - assembly.builds.following_bom_entries_miss_instock - You do not have enough parts stocked to build this assembly %number_of_builds% times. The following parts have missing instock: - - - - - assembly.builds.build_possible - Build possible - - - - - assembly.builds.number_of_builds_possible - %max_builds% builds of this assembly.]]> - - - - - assembly.builds.number_of_builds - Build amount - - - - - assembly.build.btn_build - Build - - - - - assembly.build.form.referencedAssembly - Assembly "%name%" - - - - - assembly.builds.no_stocked_builds - Number of stocked builds - - assembly.info.bom_entries_count @@ -13801,18 +13729,6 @@ Please note, that you can not impersonate a disabled user. If you try you will g Sub-assemblies - - - assembly.builds.stocked - stocked - - - - - assembly.builds.needed - needed - - assembly.bom.delete.confirm @@ -13861,24 +13777,6 @@ Please note, that you can not impersonate a disabled user. If you try you will g Notes - - - assembly.builds.following_bom_entries_miss_instock_n - You do not have enough parts stocked to build this assembly %number_of_builds% times. The following parts have missing instock: - - - - - assembly.build.help - Choose from which part lots the stock to build this assembly should be taken (and in which amount). Check the checkbox for each part, when you are finished withdrawing the parts, or use the top checkbox to check all boxes at once. - - - - - assembly.build.required_qty - Required quantity - - assembly.import_bom @@ -13909,24 +13807,6 @@ Please note, that you can not impersonate a disabled user. If you try you will g Price - - - assembly.build.dont_check_quantity - Do not check quantities - - - - - assembly.build.dont_check_quantity.help - If this option is selected, the given withdraw quantities are used as given, no matter if more or less parts are actually required to build this assembly. - - - - - assembly.build.add_builds_to_builds_part - Add builds to assembly builds part - - assembly.bom_import.type diff --git a/translations/messages.es.xlf b/translations/messages.es.xlf index b4e1a081..9fc0e75e 100644 --- a/translations/messages.es.xlf +++ b/translations/messages.es.xlf @@ -12927,24 +12927,6 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S Nuevo ensamblaje - - - assembly.edit.associated_build_part - Componente asociado - - - - - assembly.edit.associated_build_part.add - Añadir componente - - - - - assembly.edit.associated_build.hint - Este componente representa las instancias fabricadas del ensamblaje. Indique si se necesitan instancias fabricadas. De lo contrario, las cantidades del componente solo se utilizarán cuando se construya el proyecto correspondiente. - - assembly.edit.bom.import_bom @@ -13053,60 +13035,6 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S Añadir piezas - - - assembly.builds.check_assembly_status - "%assembly_status%". ¡Por favor, verifica si realmente deseas construir el ensamblaje con este estado!]]> - - - - - assembly.builds.build_not_possible - Construcción no posible: No hay suficientes componentes disponibles - - - - - assembly.builds.following_bom_entries_miss_instock - No hay suficientes piezas en stock para construir este proyecto %number_of_builds% veces. Faltan las siguientes piezas: - - - - - assembly.builds.build_possible - Construcción posible - - - - - assembly.builds.number_of_builds_possible - %max_builds% unidades de este ensamblaje.]]> - - - - - assembly.builds.number_of_builds - Número de construcciones - - - - - assembly.build.btn_build - Construir - - - - - assembly.build.form.referencedAssembly - Ensamblaje "%name%" - - - - - assembly.builds.no_stocked_builds - Unidades construidas almacenadas - - assembly.info.bom_entries_count @@ -13119,18 +13047,6 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S Subconjuntos - - - assembly.builds.stocked - en stock - - - - - assembly.builds.needed - necesario - - assembly.bom.delete.confirm @@ -13179,24 +13095,6 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S Comentarios - - - assembly.builds.following_bom_entries_miss_instock_n - No hay suficientes piezas en stock para construir este ensamblaje %number_of_builds% veces. Faltan las siguientes piezas: - - - - - assembly.build.help - Seleccione de qué almacenes se tomarán las piezas necesarias para la construcción (y en qué cantidad). Marque la casilla de cada entrada una vez que haya quitado las piezas, o use la casilla superior para marcarlas todas a la vez. - - - - - assembly.build.required_qty - Cantidad requerida - - assembly.import_bom @@ -13227,24 +13125,6 @@ Por favor ten en cuenta que no puedes personificar a un usuario deshabilitado. S Precio - - - assembly.build.dont_check_quantity - No verificar cantidades - - - - - assembly.build.dont_check_quantity.help - Si se selecciona esta opción, las cantidades seleccionadas se quitarán del inventario independientemente de si hay más o menos de lo necesario para construir el ensamblaje. - - - - - assembly.build.add_builds_to_builds_part - Añadir unidades construidas a la parte del ensamblaje - - assembly.bom_import.type diff --git a/translations/messages.fr.xlf b/translations/messages.fr.xlf index 24ac7ca3..08f5254d 100644 --- a/translations/messages.fr.xlf +++ b/translations/messages.fr.xlf @@ -9319,24 +9319,6 @@ exemple de ville Nouvel assemblage - - - assembly.edit.associated_build_part - Composant associé - - - - - assembly.edit.associated_build_part.add - Ajouter un composant - - - - - assembly.edit.associated_build.hint - Ce composant représente les instances fabriquées de l'assemblage. Indiquez si des instances fabriquées sont nécessaires. Sinon, les quantités des composants ne seront appliquées que lors de la construction du projet correspondant. - - assembly.edit.bom.import_bom @@ -9445,60 +9427,6 @@ exemple de ville Ajouter des pièces - - - assembly.builds.check_assembly_status - "%assembly_status%". Vérifiez bien si vous souhaitez construire l'assemblage avec ce statut !]]> - - - - - assembly.builds.build_not_possible - Construction impossible : pièces insuffisantes disponibles - - - - - assembly.builds.following_bom_entries_miss_instock - Il n'y a pas suffisamment de pièces en stock pour construire ce projet %number_of_builds% fois. Les pièces suivantes manquent en stock : - - - - - assembly.builds.build_possible - Construction possible - - - - - assembly.builds.number_of_builds_possible - %max_builds% unités de cet assemblage.]]> - - - - - assembly.builds.number_of_builds - Nombre d'assemblages à construire - - - - - assembly.build.btn_build - Construire - - - - - assembly.build.form.referencedAssembly - Assemblage "%name%" - - - - - assembly.builds.no_stocked_builds - Nombre d'instances construites en stock - - assembly.info.bom_entries_count @@ -9511,18 +9439,6 @@ exemple de ville Sous-ensembles - - - assembly.builds.stocked - en stock - - - - - assembly.builds.needed - nécessaire - - assembly.bom.delete.confirm @@ -9571,24 +9487,6 @@ exemple de ville Commentaires - - - assembly.builds.following_bom_entries_miss_instock_n - Il n'y a pas suffisamment de pièces en stock pour construire cet assemblage %number_of_builds% fois. Les pièces suivantes manquent en stock : - - - - - assembly.build.help - Sélectionnez les stocks à partir desquels les pièces nécessaires à la construction seront prises (et en quelle quantité). Vérifiez chaque pièce en les retirant, ou utilisez la case supérieure pour les sélectionner toutes à la fois. - - - - - assembly.build.required_qty - Quantité requise - - assembly.import_bom @@ -9619,24 +9517,6 @@ exemple de ville Prix - - - assembly.build.dont_check_quantity - Ne pas vérifier les quantités - - - - - assembly.build.dont_check_quantity.help - Si cette option est activée, les quantités sélectionnées seront retirées du stock, quelle que soit leur suffisance pour l’assemblage. - - - - - assembly.build.add_builds_to_builds_part - Ajouter les unités construites à la pièce assemblée - - assembly.bom_import.type diff --git a/translations/messages.it.xlf b/translations/messages.it.xlf index 12daaf86..7b9f5c8d 100644 --- a/translations/messages.it.xlf +++ b/translations/messages.it.xlf @@ -12929,24 +12929,6 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a Nuovo assemblaggio - - - assembly.edit.associated_build_part - Componente associato - - - - - assembly.edit.associated_build_part.add - Aggiungi componente - - - - - assembly.edit.associated_build.hint - Questo componente rappresenta le istanze fabbricate dell'assemblaggio. Specificare se sono necessarie istanze fabbricate. In caso contrario, le quantità di componenti verranno utilizzate solo durante la costruzione del progetto corrispondente. - - assembly.edit.bom.import_bom @@ -13055,60 +13037,6 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a Aggiungi componenti - - - assembly.builds.check_assembly_status - "%assembly_status%". Controlla se vuoi davvero costruire il gruppo con questo stato!]]> - - - - - assembly.builds.build_not_possible - Costruzione impossibile: componenti insufficienti disponibili - - - - - assembly.builds.following_bom_entries_miss_instock - Non ci sono abbastanza componenti in magazzino per costruire questo progetto %number_of_builds% volte. Mancano i seguenti componenti: - - - - - assembly.builds.build_possible - Costruzione possibile - - - - - assembly.builds.number_of_builds_possible - %max_builds% unità di questo gruppo.]]> - - - - - assembly.builds.number_of_builds - Numero di gruppi da costruire - - - - - assembly.build.btn_build - Costruire - - - - - assembly.build.form.referencedAssembly - Gruppo "%name%" - - - - - assembly.builds.no_stocked_builds - Numero di istanze costruite in magazzino - - assembly.info.bom_entries_count @@ -13121,18 +13049,6 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a Sotto-gruppi - - - assembly.builds.stocked - disponibile - - - - - assembly.builds.needed - necessari - - assembly.bom.delete.confirm @@ -13181,24 +13097,6 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a Commenti - - - assembly.builds.following_bom_entries_miss_instock_n - Non ci sono abbastanza componenti in magazzino per costruire questo gruppo %number_of_builds% volte. Mancano i seguenti componenti: - - - - - assembly.build.help - Seleziona i magazzini da cui prelevare i componenti necessari per la costruzione (e in che quantità). Spunta ciascun componente una volta prelevato, oppure utilizza la casella superiore per selezionare tutto in una volta. - - - - - assembly.build.required_qty - Quantità necessaria - - assembly.import_bom @@ -13229,24 +13127,6 @@ Notare che non è possibile impersonare un utente disattivato. Quando si prova a Prezzo - - - assembly.build.dont_check_quantity - Non controllare le quantità - - - - - assembly.build.dont_check_quantity.help - Se abilitata, le quantità selezionate verranno rimosse dal magazzino indipendentemente dalla loro sufficienza per il gruppo. - - - - - assembly.build.add_builds_to_builds_part - Aggiungi istanze costruite al gruppo componenti - - assembly.bom_import.type diff --git a/translations/messages.ja.xlf b/translations/messages.ja.xlf index 94383f3d..bccf43c9 100644 --- a/translations/messages.ja.xlf +++ b/translations/messages.ja.xlf @@ -9056,24 +9056,6 @@ Exampletown 新しいアセンブリ - - - assembly.edit.associated_build_part - 関連コンポーネント - - - - - assembly.edit.associated_build_part.add - コンポーネントを追加 - - - - - assembly.edit.associated_build.hint - このコンポーネントは、アセンブリの製造されたインスタンスを表します。製造されたインスタンスが必要な場合は登録してください。それ以外の場合、コンポーネントの数量は該当するプロジェクトを構築する際にのみ使用されます。 - - assembly.edit.bom.import_bom @@ -9182,60 +9164,6 @@ Exampletown 部品を追加 - - - assembly.builds.check_assembly_status - "%assembly_status%"です。この状態でビルドを続行してよろしいですか?]]> - - - - - assembly.builds.build_not_possible - ビルド不可能: 必要な部品が不足しています - - - - - assembly.builds.following_bom_entries_miss_instock - %number_of_builds% 回のビルドを行うのに十分な部品在庫がありません。不足している部品: - - - - - assembly.builds.build_possible - ビルド可能 - - - - - assembly.builds.number_of_builds_possible - %max_builds% 回のアセンブリをビルドできます。]]> - - - - - assembly.builds.number_of_builds - ビルドするアセンブリ数 - - - - - assembly.build.btn_build - ビルド - - - - - assembly.build.form.referencedAssembly - アセンブリ「%name%」 - - - - - assembly.builds.no_stocked_builds - 在庫のビルド済みアセンブリ数 - - assembly.info.bom_entries_count @@ -9248,18 +9176,6 @@ Exampletown サブアセンブリ - - - assembly.builds.stocked - 在庫あり - - - - - assembly.builds.needed - 必要数量 - - assembly.bom.delete.confirm @@ -9308,24 +9224,6 @@ Exampletown コメント - - - assembly.builds.following_bom_entries_miss_instock_n - このアセンブリを%number_of_builds%回作成するための部品が十分に在庫にありません。以下の部品が不足しています: - - - - - assembly.build.help - どの在庫から必要な部品を取り出すか(およびその数量)を選択してください。部品を取り出した場合は、各項目のチェックをオンにするか、最上部のチェックボックスを使って一括でオンにすることができます。 - - - - - assembly.build.required_qty - 必要な数量 - - assembly.import_bom @@ -9344,36 +9242,12 @@ Exampletown 識別子 - - - assembly.build.yes_button - はい - - - - - assembly.build.no_button - いいえ - - assembly.confirmation.required - - - assembly.build.success - ビルドが正常に完了しました! - - - - - assembly.build.cancelled - ビルドがキャンセルされました。 - - assembly.bom_import.type diff --git a/translations/messages.nl.xlf b/translations/messages.nl.xlf index 4dbffbf8..4c7df57e 100644 --- a/translations/messages.nl.xlf +++ b/translations/messages.nl.xlf @@ -892,24 +892,6 @@ Nieuwe assemblage - - - assembly.edit.associated_build_part - Geassocieerd onderdeel - - - - - assembly.edit.associated_build_part.add - Onderdeel toevoegen - - - - - assembly.edit.associated_build.hint - Dit onderdeel vertegenwoordigt de vervaardigde exemplaren van de assemblage. Geef aan of vervaardigde exemplaren nodig zijn. Zo niet, dan worden de aantallen onderdelen alleen gebruikt bij het bouwen van het bijbehorende project. - - assembly.edit.bom.import_bom @@ -1018,60 +1000,6 @@ Onderdelen toevoegen - - - assembly.builds.check_assembly_status - "%assembly_status%". Bevestig dat je hiermee wilt doorgaan!]]> - - - - - assembly.builds.build_not_possible - Bouwen is niet mogelijk: niet voldoende onderdelen beschikbaar - - - - - assembly.builds.following_bom_entries_miss_instock - Er zijn niet voldoende onderdelen in voorraad om %number_of_builds% keer te bouwen. De volgende onderdelen ontbreken: - - - - - assembly.builds.build_possible - Bouwen mogelijk - - - - - assembly.builds.number_of_builds_possible - %max_builds% assemblages te bouwen.]]> - - - - - assembly.builds.number_of_builds - Aantal te bouwen assemblages - - - - - assembly.build.btn_build - Bouwen - - - - - assembly.build.form.referencedAssembly - Assemblage "%name%" - - - - - assembly.builds.no_stocked_builds - Aantal geassembleerde onderdelen op voorraad - - assembly.info.bom_entries_count @@ -1084,18 +1012,6 @@ Subgroepen - - - assembly.builds.stocked - Op voorraad - - - - - assembly.builds.needed - Nodig - - assembly.bom.delete.confirm @@ -1144,24 +1060,6 @@ Notities - - - assembly.builds.following_bom_entries_miss_instock_n - Er zijn niet genoeg onderdelen op voorraad om deze assemblage %number_of_builds% keer te bouwen. Van de volgende onderdelen is er niet genoeg op voorraad: - - - - - assembly.build.help - Selecteer uit welke voorraden de benodigde onderdelen voor de bouw gehaald moeten worden (en in welke hoeveelheid). Vink elk onderdeel afzonderlijk aan als het is verwijderd, of gebruik de bovenste selectievak om alle selectievakjes in één keer aan te vinken. - - - - - assembly.build.required_qty - Benodigde hoeveelheid - - assembly.import_bom @@ -1192,60 +1090,12 @@ Prijs - - - assembly.build.dont_check_quantity - Hoeveelheden niet controleren - - - - - assembly.build.dont_check_quantity.help - Als deze optie is geselecteerd, worden de geselecteerde hoeveelheden uit de voorraad verwijderd, ongeacht of er meer of minder onderdelen zijn dan nodig is voor de assemblage. - - - - - assembly.build.add_builds_to_builds_part - Gemaakte instanties toevoegen aan onderdeel van assemblage - - - - - assembly.build.required_qty - Benodigd aantal - - - - - assembly.build.yes_button - Ja - - - - - assembly.build.no_button - Nee - - assembly.confirmation.required - - - assembly.build.success - De assemblage is succesvol gebouwd! - - - - - assembly.build.cancelled - De assemblage is geannuleerd. - - assembly.bom_import.type diff --git a/translations/messages.pl.xlf b/translations/messages.pl.xlf index 5d175e0a..a228faa1 100644 --- a/translations/messages.pl.xlf +++ b/translations/messages.pl.xlf @@ -12806,24 +12806,6 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli Nowy zespół - - - assembly.edit.associated_build_part - Powiązany komponent - - - - - assembly.edit.associated_build_part.add - Dodaj komponent - - - - - assembly.edit.associated_build.hint - Ten komponent reprezentuje wyprodukowane instancje zespołu. Określ, czy są potrzebne wyprodukowane instancje. W przeciwnym razie ilości komponentów zostaną zastosowane tylko podczas budowy odpowiedniego projektu. - - assembly.edit.bom.import_bom @@ -12932,60 +12914,6 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli Dodaj części - - - assembly.builds.check_assembly_status - "%assembly_status%". Upewnij się, że chcesz zbudować zespół w tym statusie!]]> - - - - - assembly.builds.build_not_possible - Budowa niemożliwa: niewystarczająca ilość części - - - - - assembly.builds.following_bom_entries_miss_instock - Brakuje wystarczającej ilości części na magazynie, aby zbudować ten projekt %number_of_builds% razy. Brakujące części to: - - - - - assembly.builds.build_possible - Budowa możliwa - - - - - assembly.builds.number_of_builds_possible - %max_builds% egzemplarzy tego zespołu.]]> - - - - - assembly.builds.number_of_builds - Liczba budowanych egzemplarzy - - - - - assembly.build.btn_build - Zbuduj - - - - - assembly.build.form.referencedAssembly - Zespół "%name%" - - - - - assembly.builds.no_stocked_builds - Liczba zbudowanych i zmagazynowanych egzemplarzy - - assembly.info.bom_entries_count @@ -12998,18 +12926,6 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli Podzespoły - - - assembly.builds.stocked - na magazynie - - - - - assembly.builds.needed - potrzebne - - assembly.bom.delete.confirm @@ -13058,24 +12974,6 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli Uwagi - - - assembly.builds.following_bom_entries_miss_instock_n - Brakuje wystarczającej ilości części na magazynie, aby zbudować ten zespół %number_of_builds% razy. Brakujące części to: - - - - - assembly.build.help - Wybierz, z których magazynów mają być pobrane części potrzebne do budowy (i w jakiej ilości). Zaznacz każdą pozycję, jeśli części zostały pobrane, lub użyj głównego pola wyboru, aby zaznaczyć wszystkie na raz. - - - - - assembly.build.required_qty - Wymagana ilość - - assembly.import_bom @@ -13106,24 +13004,6 @@ Należy pamiętać, że nie możesz udawać nieaktywnych użytkowników. Jeśli Cena - - - assembly.build.dont_check_quantity - Nie sprawdzaj ilości - - - - - assembly.build.dont_check_quantity.help - Jeśli opcja jest wybrana, zadeklarowana ilość zostanie odjęta z magazynu, niezależnie od tego, czy jest wystarczająca do budowy zespołu. - - - - - assembly.build.add_builds_to_builds_part - Dodaj zbudowane egzemplarze jako część zespołu - - assembly.bom_import.type diff --git a/translations/messages.ru.xlf b/translations/messages.ru.xlf index 6b9a215e..9058286a 100644 --- a/translations/messages.ru.xlf +++ b/translations/messages.ru.xlf @@ -12906,24 +12906,6 @@ Новая сборка - - - assembly.edit.associated_build_part - Связанный компонент - - - - - assembly.edit.associated_build_part.add - Добавить компонент - - - - - assembly.edit.associated_build.hint - Этот компонент представляет изготовленные экземпляры сборки. Укажите, нужны ли изготовленные экземпляры. В противном случае количество компонентов будет использоваться только при создании соответствующего проекта. - - assembly.edit.bom.import_bom @@ -13032,60 +13014,6 @@ Добавить детали - - - assembly.builds.check_assembly_status - "%assembly_status%". Убедитесь, что действительно хотите выполнить сборку с этим статусом!]]> - - - - - assembly.builds.build_not_possible - Сборка невозможна: недостаточно деталей - - - - - assembly.builds.following_bom_entries_miss_instock - Недостаточно деталей на складе для сборки %number_of_builds% экземпляров. Следующие детали отсутствуют в достаточном количестве: - - - - - assembly.builds.build_possible - Сборка возможна - - - - - assembly.builds.number_of_builds_possible - %max_builds% экземпляров.]]> - - - - - assembly.builds.number_of_builds - Количество сборок - - - - - assembly.build.btn_build - Собрать - - - - - assembly.build.form.referencedAssembly - Сборка "%name%" - - - - - assembly.builds.no_stocked_builds - Собранные экземпляры на складе - - assembly.info.bom_entries_count @@ -13098,18 +13026,6 @@ Подсборки - - - assembly.builds.stocked - На складе - - - - - assembly.builds.needed - Необходимо - - assembly.bom.delete.confirm @@ -13158,24 +13074,6 @@ Примечания - - - assembly.builds.following_bom_entries_miss_instock_n - Недостаточно деталей на складе для сборки %number_of_builds% экземпляров. У следующих деталей недостаточное количество: - - - - - assembly.build.help - Выберите, из каких запасов брать необходимые для сборки детали (и в каком количестве). Установите галочку для каждой позиции, если детали были взяты, или используйте основную галочку, чтобы отметить все позиции сразу. - - - - - assembly.build.required_qty - Необходимое количество - - assembly.import_bom @@ -13206,24 +13104,6 @@ Цена - - - assembly.build.dont_check_quantity - Не проверять количество - - - - - assembly.build.dont_check_quantity.help - Если выбрано, указанные количества будут списаны со склада независимо от того, достаточно их или нет для указанной сборки. - - - - - assembly.build.add_builds_to_builds_part - Добавить собранные экземпляры как компонент для подсборки - - assembly.bom_import.type diff --git a/translations/messages.zh.xlf b/translations/messages.zh.xlf index 6a3521ee..7e978641 100644 --- a/translations/messages.zh.xlf +++ b/translations/messages.zh.xlf @@ -12791,24 +12791,6 @@ Element 3 新装配 - - - assembly.edit.associated_build_part - 关联组件 - - - - - assembly.edit.associated_build_part.add - 添加组件 - - - - - assembly.edit.associated_build.hint - 此组件表示装配的生产实例。指定是否需要生产实例。如果不需要,则组件数量仅在构建相关项目时使用。 - - assembly.edit.bom.import_bom @@ -12917,60 +12899,6 @@ Element 3 添加零件 - - - assembly.builds.check_assembly_status - "%assembly_status%"。请确认您是否要在该状态下构建组件!]]> - - - - - assembly.builds.build_not_possible - 无法构建:零件数量不足 - - - - - assembly.builds.following_bom_entries_miss_instock - 库存中缺少足够的零件,无法构建 %number_of_builds% 次。缺少的零件包括: - - - - - assembly.builds.build_possible - 可以构建 - - - - - assembly.builds.number_of_builds_possible - %max_builds% 个该组件。]]> - - - - - assembly.builds.number_of_builds - 构建数量 - - - - - assembly.build.btn_build - 构建 - - - - - assembly.build.form.referencedAssembly - 组件“%name%” - - - - - assembly.builds.no_stocked_builds - 已构建并库存的数量 - - assembly.info.bom_entries_count @@ -12983,18 +12911,6 @@ Element 3 子组件 - - - assembly.builds.stocked - 库存中 - - - - - assembly.builds.needed - 需要 - - assembly.bom.delete.confirm @@ -13043,24 +12959,6 @@ Element 3 备注 - - - assembly.builds.following_bom_entries_miss_instock_n - 库存不足,无法构建 %number_of_builds% 次。缺少零件包括: - - - - - assembly.build.help - 选择部分库存零件及数量用于构建。每项零件使用复选框,如果零件已提取,也可以使用主复选框来选择所有项目。 - - - - - assembly.build.required_qty - 所需数量 - - assembly.import_bom @@ -13091,24 +12989,6 @@ Element 3 价格 - - - assembly.build.dont_check_quantity - 不检查数量 - - - - - assembly.build.dont_check_quantity.help - 如果选中,即使库存不足,系统也会从库存中扣除声明的数量。 - - - - - assembly.build.add_builds_to_builds_part - 将已构建的零件添加到组件 - - assembly.bom_import.type