From ee7ea685dc3a0551370077d2c057af2978f1e3ed Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 28 Aug 2023 08:28:37 -0500 Subject: [PATCH 01/44] Fixes for participant summary page layout. --- templates/program/nph/participant/index.html.twig | 10 ++++++---- web/assets/css/nph.css | 4 ++++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/templates/program/nph/participant/index.html.twig b/templates/program/nph/participant/index.html.twig index 630ce7a09..1ce609056 100644 --- a/templates/program/nph/participant/index.html.twig +++ b/templates/program/nph/participant/index.html.twig @@ -80,7 +80,7 @@ {% set modulePanelDisplay = 'hidden' %} {% endif %}
-
+

NPH Module {{ moduleNumber }} Collections

{% include 'program/nph/participant/partials/hair-nail-optin-badge.html.twig' %}
@@ -96,19 +96,20 @@ {% set textDivSize = 'col-md-12' %} {% set dlwDiet = false %} {% endif %} -
+
-
+
{% if participant.dob %}
+
{% if participantDietStatus == constant('App\\Helper\\NphParticipant::DIET_STARTED') %} - Generate Orders and Print Labels @@ -149,6 +150,7 @@
{% endif %} +
{% set displayedOrderIDS = [] %} {% set displayedTimePointHeaders = [] %} diff --git a/web/assets/css/nph.css b/web/assets/css/nph.css index 5675c6aa8..38c2ba8ea 100644 --- a/web/assets/css/nph.css +++ b/web/assets/css/nph.css @@ -173,6 +173,10 @@ div.order-row { .navbar-inverse .navbar-toggler { background-color: #FFFFFF; } +.generate-orders-button { + margin-bottom: 15px; + margin-top: 10px; +} .visit-diet-details:after { font-family: "Font Awesome 5 Free"; From 6396c1d5af9c3fe2c69aa250dbe77b115a28a2de Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 31 Aug 2023 08:10:16 -0500 Subject: [PATCH 02/44] hide dlw unless diet assigned, ordertype displayname --- src/Entity/NphOrder.php | 12 ++++++++++++ src/Form/DlwType.php | 4 ---- .../order-participant-details-barcode.html.twig | 2 +- templates/program/nph/participant/index.html.twig | 2 +- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/src/Entity/NphOrder.php b/src/Entity/NphOrder.php index 258d21fe9..bed62e816 100644 --- a/src/Entity/NphOrder.php +++ b/src/Entity/NphOrder.php @@ -19,6 +19,10 @@ class NphOrder public const TYPE_NAIL = 'nail'; public const TYPE_DLW = 'urineDlw'; public const TYPE_MODULE_3_SALIVA = 'saliva3'; + private const TYPE_DISPLAY_OVERRIDE = [ + '24urine' => '24 Hour Urine', + 'urineDlw' => 'Urine DLW', + ]; #[ORM\Id] #[ORM\GeneratedValue] @@ -376,4 +380,12 @@ public function getMetadataArray(): ?array } return $metadata; } + + public function getOrderTypeDisplayName(): string { + if (isset($this::TYPE_DISPLAY_OVERRIDE[$this->getOrderType()])) { + return $this::TYPE_DISPLAY_OVERRIDE[$this->getOrderType()]; + } else { + return ucfirst($this->getOrderType()); + } + } } diff --git a/src/Form/DlwType.php b/src/Form/DlwType.php index 45c6f9fa1..5e5e7e85b 100644 --- a/src/Form/DlwType.php +++ b/src/Form/DlwType.php @@ -42,19 +42,15 @@ public function buildForm(FormBuilderInterface $builder, array $options): void if ($value < 0 || $value === null) { $context->buildViolation('Participant weight required.') ->addViolation(); - return false; } if ($value > 907) { $context->buildViolation('Please verify the measurement is correct. Value should be less than 907 kg.') ->addViolation(); - return false; } if ($this->getNumDecimalPlaces($value) > 1) { $context->buildViolation('Please verify the measurement is correct. Value can be entered up to the tenths (0.1) place.') ->addViolation(); - return false; } - return true; }), 'scale' => 1, ]) diff --git a/templates/program/nph/order/partials/order-participant-details-barcode.html.twig b/templates/program/nph/order/partials/order-participant-details-barcode.html.twig index 2fe62d3a5..3b11a1b73 100644 --- a/templates/program/nph/order/partials/order-participant-details-barcode.html.twig +++ b/templates/program/nph/order/partials/order-participant-details-barcode.html.twig @@ -5,7 +5,7 @@
Module {{ order.module }} | Visit {{ order.visitType }} | {{ timePoints[order.timepoint] }} | {{ order - .orderType|capitalize }} + .getOrderTypeDisplayName() }}
diff --git a/templates/program/nph/participant/index.html.twig b/templates/program/nph/participant/index.html.twig index 1ce609056..217e954b3 100644 --- a/templates/program/nph/participant/index.html.twig +++ b/templates/program/nph/participant/index.html.twig @@ -133,7 +133,7 @@ Last Saved {{ dlwSummary[moduleNumber][VisitCode]|date('n/j/Y g:ia', app.user.timezone) }}
{% endif %} - {% elseif dlwDiet %} + {% elseif dlwDiet and participantDietStatus == constant('App\\Helper\\NphParticipant::DIET_STARTED') %}
From 684ca03010d24fd580cf957fc5e2ebb241c1ed34 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 31 Aug 2023 08:12:29 -0500 Subject: [PATCH 03/44] Validation Fixes --- src/Nph/Order/Samples/Module3.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Nph/Order/Samples/Module3.json b/src/Nph/Order/Samples/Module3.json index b960973c3..e5dd93b35 100644 --- a/src/Nph/Order/Samples/Module3.json +++ b/src/Nph/Order/Samples/Module3.json @@ -171,7 +171,7 @@ "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", - "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 4mL matrix aliquot tube barcode ID.", + "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 5mL matrix aliquot tube barcode ID.", "minVolume": 0, "maxVolume": 4, "warningMinVolume": 100, @@ -188,11 +188,11 @@ "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", - "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 2.5mL matrix aliquot tube barcode ID.", + "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 5mL matrix aliquot tube barcode ID.", "minVolume": 0, - "maxVolume": 4, + "maxVolume": 2.4, "warningMinVolume": 100, - "warningMaxVolume": 4000, + "warningMaxVolume": 2400, "addNew": false, "collectMetadata": true, "metadataFields": [ From 6dd404d8ef17126f0b78c481fba260774838233c Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 31 Aug 2023 09:27:55 -0500 Subject: [PATCH 04/44] Calculate total volume on page load, use input groups on glycerol volume. --- .../program/nph/order/sample-finalize.html.twig | 14 +++++++++----- web/assets/js/views/NphSampleFinalize.js | 4 ++++ 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index 5a40f3133..ee33a5623 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -16,17 +16,21 @@ - {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'style': 'width: 30%; float: left; top: 20px; position: relative'}}) }} - {{ aliquot['units'] }} +
+ {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control',}}) }} + {{ aliquot['units'] }} +
+ - {{ form_widget(form[aliquotCode~metadataField['identifier']], {'attr': {'style': 'width: 30%; float: right; position: relative; right: 20px; top: -5px'}}) }} - μl +
+ {{ form_widget(form[aliquotCode~metadataField['identifier']], {'attr': {'class': 'form-control'}}) }} + μl +
= Total Volume - # + # {{ aliquot['units'] }} diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index a83eff2ab..4ee396089 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -107,6 +107,10 @@ $(document).ready(function () { } disableEnableAliquotFields(); + calculateGlycerolVolume( + $("#nph_sample_finalize_SALIVAA2Volume_0"), + $("#nph_sample_finalize_SALIVAA2glycerolAdditiveVolume") + ); $(".aliquot-volume").trigger("keyup"); $(".sample-modify-checkbox").on("change", disableEnableAliquotFields); From 365831b1a99135d10d3d9564a1e2ab10bb743dd4 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 31 Aug 2023 09:29:37 -0500 Subject: [PATCH 05/44] Run php-cs-fixer --- src/Entity/NphOrder.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Entity/NphOrder.php b/src/Entity/NphOrder.php index bed62e816..165850da9 100644 --- a/src/Entity/NphOrder.php +++ b/src/Entity/NphOrder.php @@ -381,11 +381,11 @@ public function getMetadataArray(): ?array return $metadata; } - public function getOrderTypeDisplayName(): string { + public function getOrderTypeDisplayName(): string + { if (isset($this::TYPE_DISPLAY_OVERRIDE[$this->getOrderType()])) { return $this::TYPE_DISPLAY_OVERRIDE[$this->getOrderType()]; - } else { - return ucfirst($this->getOrderType()); } + return ucfirst($this->getOrderType()); } } From 6515a9022c5b3a542097bb95bd50e94296c1169a Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 5 Sep 2023 10:58:09 -0500 Subject: [PATCH 06/44] Added total volume constraint. --- src/Form/Nph/NphSampleFinalizeType.php | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index 85b945d64..f23d7e59c 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -132,6 +132,20 @@ public function buildForm(FormBuilderInterface $builder, array $options) ]); if (isset($aliquot['collectMetadata']) && $aliquot['collectMetadata']) { foreach ($aliquot['metadataFields'] as $metadataField) { + if ($metadataField['identifier'] === 'glycerolAdditiveVolume') { + $metadataConstraints = [ + new Constraints\Callback(function ($value, $context) use ($aliquotCode, $aliquot, $metadataField) { + $formData = $context->getRoot()->getData(); + $totalVolume = $formData["{$aliquotCode}Volume"][0] + ($formData[$aliquotCode . $metadataField['identifier']] / 1000); + if ($totalVolume > $aliquot['maxVolume']) { + $context->buildViolation("{$metadataField['label']} cannot be entered. This aliquot should contain a maximum of {$aliquot['maxVolume']} {$aliquot['units']}.")->addViolation(); + } + if ($totalVolume < $aliquot['minVolume']) { + $context->buildViolation("{$metadataField['label']} cannot be entered. This aliquot should contain a minimum of {$aliquot['minVolume']} {$aliquot['units']}.")->addViolation(); + } + }) + ]; + } $builder->add("{$aliquotCode}{$metadataField['identifier']}", $metadataField['entryType'], [ 'label' => $metadataField['label'], 'required' => false, @@ -140,10 +154,12 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'class' => $metadataField['class'] ?? '', ], 'data' => $formData[$aliquotCode . $metadataField['identifier']][0] ?? null, + 'constraints' => $metadataConstraints ?? [] ]); } } + $volumeConstraints = [ new Constraints\Callback(function ($value, $context) use ($aliquotCode, $aliquot) { $formData = $context->getRoot()->getData(); From 4c68cf56051ca9150db6dbf31b08e6897862d149 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 5 Sep 2023 11:02:34 -0500 Subject: [PATCH 07/44] Added form error. --- templates/program/nph/order/sample-finalize.html.twig | 1 + 1 file changed, 1 insertion(+) diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index ee33a5623..2f4206008 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -42,6 +42,7 @@ {{ form_errors(form[aliquotCode ~ 'Volume'][i]) }} + {{ form_errors(form[aliquotCode ~ 'glycerolAdditiveVolume']) }} {% endfor %} From bdf4f159e9ff085079e7ee6ce82d1270e46701c1 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 6 Sep 2023 12:59:09 -0500 Subject: [PATCH 08/44] Fix for checkboxes, save dlw finalization user. --- migrations/Version20230906173509.php | 35 +++++++++++++++++++ src/Controller/NphOrderController.php | 1 + src/Entity/NphDlw.php | 16 +++++++++ src/Service/Nph/NphOrderService.php | 6 ++-- templates/program/nph/order/collect.html.twig | 2 +- .../program/nph/order/dlw-collect.html.twig | 9 +++++ web/assets/js/views/NphSampleFinalize.js | 2 +- 7 files changed, 66 insertions(+), 5 deletions(-) create mode 100644 migrations/Version20230906173509.php diff --git a/migrations/Version20230906173509.php b/migrations/Version20230906173509.php new file mode 100644 index 000000000..7a30a0d18 --- /dev/null +++ b/migrations/Version20230906173509.php @@ -0,0 +1,35 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + $this->addSql('ALTER TABLE nph_dlw ADD user_id INT NOT NULL'); + $this->addSql('ALTER TABLE nph_dlw ADD CONSTRAINT FK_3F1C65B7A76ED395 FOREIGN KEY (user_id) REFERENCES users (id)'); + $this->addSql('CREATE INDEX IDX_3F1C65B7A76ED395 ON nph_dlw (user_id)'); + } + + public function down(Schema $schema): void + { + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + $this->addSql('ALTER TABLE nph_dlw DROP FOREIGN KEY FK_3F1C65B7A76ED395'); + $this->addSql('DROP INDEX IDX_3F1C65B7A76ED395 ON nph_dlw'); + $this->addSql('ALTER TABLE nph_dlw DROP user_id'); + } +} diff --git a/src/Controller/NphOrderController.php b/src/Controller/NphOrderController.php index 5433612a0..205f51b23 100644 --- a/src/Controller/NphOrderController.php +++ b/src/Controller/NphOrderController.php @@ -558,6 +558,7 @@ public function dlwSampleCollect( 'module' => $module, 'visit' => $visit, 'disabled' => $disabled, + 'dlwInfo' => $dlwObject, 'form' => $dlwForm->createView() ]); } diff --git a/src/Entity/NphDlw.php b/src/Entity/NphDlw.php index 66d13a048..d06fe5d1a 100644 --- a/src/Entity/NphDlw.php +++ b/src/Entity/NphDlw.php @@ -41,6 +41,10 @@ class NphDlw #[ORM\Column(nullable: true)] private ?int $ModifiedTimezoneId = null; + #[ORM\ManyToOne] + #[ORM\JoinColumn(nullable: false)] + private ?User $User = null; + public function getId(): int { return $this->id; @@ -153,4 +157,16 @@ public function setModifiedTimezoneId(?int $ModifiedTimezoneId): static return $this; } + + public function getUser(): ?User + { + return $this->User; + } + + public function setUser(?User $User): static + { + $this->User = $User; + + return $this; + } } diff --git a/src/Service/Nph/NphOrderService.php b/src/Service/Nph/NphOrderService.php index 908d47e8f..212b337dc 100644 --- a/src/Service/Nph/NphOrderService.php +++ b/src/Service/Nph/NphOrderService.php @@ -49,6 +49,8 @@ public function __construct( $this->siteService = $siteService; $this->loggerService = $loggerService; $this->rdrApiService = $rdrApiService; + $this->user = $this->em->getRepository(User::class)->find($this->userService->getUser()->getId()); + $this->site = $this->siteService->getSiteId(); } public function loadModules(string $module, string $visit, string $participantId, string $biobankId): void @@ -60,9 +62,6 @@ public function loadModules(string $module, string $visit, string $participantId $this->visit = $visit; $this->participantId = $participantId; $this->biobankId = $biobankId; - - $this->user = $this->em->getRepository(User::class)->find($this->userService->getUser()->getId()); - $this->site = $this->siteService->getSiteId(); } public function getVisitDiet(): string @@ -808,6 +807,7 @@ public function saveDlwCollection(NphDlw $formData, $participantId, $module, $vi $formData->setVisit($visit); $formData->setModifiedTimezoneId($this->getTimezoneid()); $formData->setModifiedTs(new DateTime()); + $formData->setUser($this->user); $this->em->persist($formData); $this->em->flush(); return $formData; diff --git a/templates/program/nph/order/collect.html.twig b/templates/program/nph/order/collect.html.twig index 3b03b9f84..f68a173ff 100644 --- a/templates/program/nph/order/collect.html.twig +++ b/templates/program/nph/order/collect.html.twig @@ -4,7 +4,7 @@ {% block body %} {% include 'program/nph/order/partials/order-header.html.twig' %}
- {{ timePoints[order.timepoint] }} {{ order.orderType|capitalize }} + {{ timePoints[order.timepoint] }} {{ order.orderTypeDisplayName }}
View Order Summary/Reprint Labels diff --git a/templates/program/nph/order/dlw-collect.html.twig b/templates/program/nph/order/dlw-collect.html.twig index 82e6fcef6..74ee9dc4c 100644 --- a/templates/program/nph/order/dlw-collect.html.twig +++ b/templates/program/nph/order/dlw-collect.html.twig @@ -2,6 +2,15 @@ {% block title %} DLW Collect - {% endblock %} {% block body %} - = - Total Volume - # + +
+ + mL +
+
- {{ aliquot['units'] }} {% if not sample.disabled and not sample.unlocked %} diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index 52a6388b9..ca9404184 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -103,7 +103,7 @@ $(document).ready(function () { let sampleVolume = $(sampleVolumeField).val() ? parseInt($(sampleVolumeField).val()) * 1000 : 0; let glycerolVolume = $(glycerolVolumeField).val() ? parseInt($(glycerolVolumeField).val()) : 0; let totalVolume = ((sampleVolume + glycerolVolume) / 1000).toFixed(2); - $("#totalVol").html(`${totalVolume} mL`); + $("#totalVol").val(`${totalVolume}`); } disableEnableAliquotFields(); From 2e9f3a5e7b3cfd55308c1752cbe3521a61aa9b33 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 6 Sep 2023 15:39:40 -0500 Subject: [PATCH 12/44] Removed flash, fixed showing finalized by unknown. --- src/Controller/NphOrderController.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Controller/NphOrderController.php b/src/Controller/NphOrderController.php index 205f51b23..a7b0f3e1f 100644 --- a/src/Controller/NphOrderController.php +++ b/src/Controller/NphOrderController.php @@ -543,9 +543,7 @@ public function dlwSampleCollect( $dlwForm->handleRequest($request); if ($dlwForm->isSubmitted()) { if ($dlwForm->isValid()) { - $nphOrderService->saveDlwCollection($dlwForm->getData(), $participantId, $module, $visit); - $timestamp = new \DateTime('now', new \DateTimeZone($this->getSecurityUser()->getTimezone())); - $this->addFlash('success', 'Saved by ' . $this->getSecurityUser()->getEmail() . ' on ' . $timestamp->format('m-d-Y h:i a')); + $dlwObject = $nphOrderService->saveDlwCollection($dlwForm->getData(), $participantId, $module, $visit); $disabled = true; } else { $disabled = false; From 431e971f62d6634211b52664fa141b8f7fe07c57 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 6 Sep 2023 15:53:44 -0500 Subject: [PATCH 13/44] Remove second units for glyercol. --- templates/program/nph/order/sample-finalize.html.twig | 1 - 1 file changed, 1 deletion(-) diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index 1029150f3..6681edba9 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -35,7 +35,6 @@
- {{ aliquot['units'] }} {% if not sample.disabled and not sample.unlocked %} {% endif %} From c01ea1c857b43565a8180e8ab265903121e84abc Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 8 Sep 2023 10:05:54 -0500 Subject: [PATCH 14/44] Color button, Form warning fix, Tube volumes. --- src/Nph/Order/Samples/Module3.json | 12 ++++++------ templates/program/nph/order/dlw-collect.html.twig | 2 +- .../program/nph/order/sample-finalize.html.twig | 7 ++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/Nph/Order/Samples/Module3.json b/src/Nph/Order/Samples/Module3.json index e5dd93b35..7874604f3 100644 --- a/src/Nph/Order/Samples/Module3.json +++ b/src/Nph/Order/Samples/Module3.json @@ -164,10 +164,10 @@ "aliquots": { "SALIVAA1": { "identifier": "SA1-U", - "container": "4mL Matrix tube (no glycerol)", - "description": "4mL Matrix tube", + "container": "5mL Matrix tube (no glycerol)", + "description": "5mL Matrix tube", "expectedAliquots": 1, - "expectedVolume": 2.4, + "expectedVolume": 4, "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", @@ -181,10 +181,10 @@ }, "SALIVAA2": { "identifier": "SA2-U", - "container": "2.5mL Matrix tube (w/glycerol)", - "description": "2.5mL Matrix tube", + "container": "5mL Matrix tube (w/glycerol)", + "description": "5mL Matrix tube", "expectedAliquots": 1, - "expectedVolume": 2, + "expectedVolume": 2.5, "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", diff --git a/templates/program/nph/order/dlw-collect.html.twig b/templates/program/nph/order/dlw-collect.html.twig index 74ee9dc4c..46dd24ca4 100644 --- a/templates/program/nph/order/dlw-collect.html.twig +++ b/templates/program/nph/order/dlw-collect.html.twig @@ -100,7 +100,7 @@ {{ form_rest(form) }}
{% if disabled %} - + {% else %} {% endif %} diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index 6681edba9..ac335e0b1 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -180,7 +180,12 @@ {% include 'program/nph/order/partials/sample-finalize-participant-details.html.twig' %} {% endif %}
- {{ form_start(sampleFinalizeForm, { attr: { class: 'warn-unsaved disable-enter prevent-resubmit'} }) }} + {% if isFormDisabled %} + {% set formClasses = 'disable-enter prevent-resumbit' %} + {% else %} + {% set formClasses = 'warn-unsaved disable-enter prevent-resubmit' %} + {% endif %} + {{ form_start(sampleFinalizeForm, { attr: { class: formClasses} }) }} {{ form_errors(sampleFinalizeForm) }}
From a9809da973055c830ce332a30df61615df60d0d2 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 7 Sep 2023 13:05:19 -0500 Subject: [PATCH 15/44] Module 3 fixes --- src/Entity/NphOrder.php | 12 ++++++++---- src/Form/DlwType.php | 10 ++++++++++ src/Nph/Order/Samples/Module3.json | 5 +++-- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/Entity/NphOrder.php b/src/Entity/NphOrder.php index 165850da9..99e9fa7f1 100644 --- a/src/Entity/NphOrder.php +++ b/src/Entity/NphOrder.php @@ -20,8 +20,12 @@ class NphOrder public const TYPE_DLW = 'urineDlw'; public const TYPE_MODULE_3_SALIVA = 'saliva3'; private const TYPE_DISPLAY_OVERRIDE = [ - '24urine' => '24 Hour Urine', - 'urineDlw' => 'Urine DLW', + 3 => [ + 'urine' => 'Spot Urine', + '24urine' => '24 Hour Urine', + 'urineDlw' => 'Urine DLW', + 'saliva3' => 'Saliva', + ], ]; #[ORM\Id] @@ -383,8 +387,8 @@ public function getMetadataArray(): ?array public function getOrderTypeDisplayName(): string { - if (isset($this::TYPE_DISPLAY_OVERRIDE[$this->getOrderType()])) { - return $this::TYPE_DISPLAY_OVERRIDE[$this->getOrderType()]; + if (isset($this::TYPE_DISPLAY_OVERRIDE[$this->getModule()][$this->getOrderType()])) { + return $this::TYPE_DISPLAY_OVERRIDE[$this->getModule()][$this->getOrderType()]; } return ucfirst($this->getOrderType()); } diff --git a/src/Form/DlwType.php b/src/Form/DlwType.php index 5e5e7e85b..625485c9b 100644 --- a/src/Form/DlwType.php +++ b/src/Form/DlwType.php @@ -10,6 +10,7 @@ use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\Callback; +use Symfony\Component\Validator\Constraints\GreaterThan; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Range; @@ -33,6 +34,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'label' => 'Actual Dose (g)*', 'required' => true, 'scale' => 1, + 'empty_data' => 0, + 'constraints' => new GreaterThan([ + 'value' => 0, + 'message' => 'Dose must be greater than 0.' + ]) ]) ->add('participantWeight', NumberType::class, [ 'required' => true, @@ -43,6 +49,10 @@ public function buildForm(FormBuilderInterface $builder, array $options): void $context->buildViolation('Participant weight required.') ->addViolation(); } + if ($value == 0) { + $context->buildViolation('Please verify the measurement is correct. Value should be greater than 0 kg.') + ->addViolation(); + } if ($value > 907) { $context->buildViolation('Please verify the measurement is correct. Value should be less than 907 kg.') ->addViolation(); diff --git a/src/Nph/Order/Samples/Module3.json b/src/Nph/Order/Samples/Module3.json index 7874604f3..9807ead67 100644 --- a/src/Nph/Order/Samples/Module3.json +++ b/src/Nph/Order/Samples/Module3.json @@ -117,6 +117,7 @@ "temperature": "Refrigerated", "specimen": "Urine", "type": "urine", + "typeDisplayName": "Spot Urine", "identifier": "UrineS", "aliquots": { "RU1U": { @@ -171,7 +172,7 @@ "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", - "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 5mL matrix aliquot tube barcode ID.", + "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 4mL matrix aliquot tube barcode ID.", "minVolume": 0, "maxVolume": 4, "warningMinVolume": 100, @@ -188,7 +189,7 @@ "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", - "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 5mL matrix aliquot tube barcode ID.", + "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 2.5mL matrix aliquot tube barcode ID.", "minVolume": 0, "maxVolume": 2.4, "warningMinVolume": 100, From f2e78b07aa977af5152039d690bd5f56b75f760c Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 8 Sep 2023 14:35:51 -0500 Subject: [PATCH 16/44] Fixed eraser alignment on sample finalize, added error class. --- templates/program/nph/order/dlw-collect.html.twig | 10 +++++----- templates/program/nph/order/sample-finalize.html.twig | 6 +++--- web/assets/css/nph.css | 6 ++++++ 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/templates/program/nph/order/dlw-collect.html.twig b/templates/program/nph/order/dlw-collect.html.twig index 46dd24ca4..a71203d70 100644 --- a/templates/program/nph/order/dlw-collect.html.twig +++ b/templates/program/nph/order/dlw-collect.html.twig @@ -62,7 +62,7 @@ {{ form_start(form, { attr: { class: 'disable-enter prevent-resubmit'} }) }} {{ form_errors(form) }}
-
+
{{ form_label(form['doseBatchId'])}}
NPHDLW @@ -70,7 +70,7 @@
{{ form_errors(form['doseBatchId'])}}
-
+
{{ form_label(form['participantWeight'])}} {{ form_widget(form['participantWeight'], {attr: {readonly: disabled}})}} {{ form_errors(form['participantWeight'])}} @@ -79,19 +79,19 @@

X 1.5 =

-
+
{{ form_label(form['calculatedDose']) }} {{ form_widget(form['calculatedDose'], {attr: {readonly: disabled}}) }} {{ form_errors(form['calculatedDose']) }}
-
+
{{ form_label(form['actualDose']) }} {{ form_widget(form['actualDose'], {attr: {readonly: disabled}}) }} {{ form_errors(form['actualDose']) }}
-
+
{{ form_label(form['doseAdministered']) }} {{ form_widget(form['doseAdministered'], {attr: {readonly: disabled}}) }} {{ form_errors(form['doseAdministered']) }} diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index ac335e0b1..c6cd48b90 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -29,14 +29,14 @@ -
+
mL
-
+ {% if not sample.disabled and not sample.unlocked %} - + {% endif %} diff --git a/web/assets/css/nph.css b/web/assets/css/nph.css index 38c2ba8ea..60a12c6a0 100644 --- a/web/assets/css/nph.css +++ b/web/assets/css/nph.css @@ -128,6 +128,12 @@ div.order-row { left: 33px; font-size: 22px } +.sample-metadata-eraser { + position: absolute; + bottom: 20px; + left: 33px; + font-size: 22px +} .aliquot-volume-units { position: absolute; bottom: 7px; From a1f58cee560f4d2e603d540d288fa7b340922b39 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 14 Sep 2023 09:40:40 -0500 Subject: [PATCH 17/44] Added code to allow multiple saliva collections. --- src/Entity/NphSample.php | 4 +- src/Form/Nph/NphSampleFinalizeType.php | 31 +++-- src/Nph/Order/Samples/Module3.json | 4 +- .../nph/order/sample-finalize.html.twig | 30 +++-- web/assets/css/nph.css | 1 - web/assets/js/views/NphSampleFinalize.js | 124 ++++++++++++------ 6 files changed, 128 insertions(+), 66 deletions(-) diff --git a/src/Entity/NphSample.php b/src/Entity/NphSample.php index 02d4bc0ff..d320d96a2 100644 --- a/src/Entity/NphSample.php +++ b/src/Entity/NphSample.php @@ -528,7 +528,9 @@ public function getRdrSampleObj(string $sampleIdentifier, string $description, a public function getRdrAliquotsSampleObj(array $aliquotsInfo): array { $aliquotObj = []; + $counter = []; foreach ($this->getNphAliquots() as $aliquot) { + $counter[$aliquot->getAliquotCode()] = isset($counter[$aliquot->getAliquotCode()]) ? $counter[$aliquot->getAliquotCode()] + 1 : 0; $collectedTs = $aliquot->getAliquotTs(); $collectedTs->setTimezone(new \DateTimeZone('UTC')); $aliquotsData = [ @@ -546,7 +548,7 @@ public function getRdrAliquotsSampleObj(array $aliquotsInfo): array ['units' => 'uL', 'volume' => $metadata[$aliquot->getAliquotCode() . 'glycerolAdditiveVolume'] ]; - $aliquotsData['volume'] += ($metadata[$aliquot->getAliquotCode() . 'glycerolAdditiveVolume'] / 1000); + $aliquotsData['volume'] += ($metadata[$aliquot->getAliquotCode() . 'glycerolAdditiveVolume'][$counter[$aliquot->getAliquotCode()]] / 1000); } if ($aliquot->getStatus()) { $aliquotsData['status'] = $aliquot->getStatus(); diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index f23d7e59c..589e460b1 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -135,26 +135,39 @@ public function buildForm(FormBuilderInterface $builder, array $options) if ($metadataField['identifier'] === 'glycerolAdditiveVolume') { $metadataConstraints = [ new Constraints\Callback(function ($value, $context) use ($aliquotCode, $aliquot, $metadataField) { + $key = intval($context->getObject()->getName()); $formData = $context->getRoot()->getData(); - $totalVolume = $formData["{$aliquotCode}Volume"][0] + ($formData[$aliquotCode . $metadataField['identifier']] / 1000); + $glycerolVolume = $formData[$aliquotCode . $metadataField['identifier']][$key]; + $totalVolume = $formData["{$aliquotCode}Volume"][$key] + ($glycerolVolume / 1000); if ($totalVolume > $aliquot['maxVolume']) { $context->buildViolation("{$metadataField['label']} cannot be entered. This aliquot should contain a maximum of {$aliquot['maxVolume']} {$aliquot['units']}.")->addViolation(); } if ($totalVolume < $aliquot['minVolume']) { $context->buildViolation("{$metadataField['label']} cannot be entered. This aliquot should contain a minimum of {$aliquot['minVolume']} {$aliquot['units']}.")->addViolation(); } + if ($glycerolVolume <= 0) { + $context->buildViolation("{$metadataField['label']} volume must be greater than 0")->addViolation(); + } + if ($glycerolVolume >= 0.1 && $glycerolVolume <= 0.4) { + $context->buildViolation('Glycerol Volume Please verify the unit of measurement is correct. (For reference 1mL = 1000uL)')->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); + } }) ]; } - $builder->add("{$aliquotCode}{$metadataField['identifier']}", $metadataField['entryType'], [ - 'label' => $metadataField['label'], - 'required' => false, - 'attr' => [ - 'placeholder' => $metadataField['placeholder'] ?? '', - 'class' => $metadataField['class'] ?? '', + $builder->add("{$aliquotCode}{$metadataField['identifier']}", Type\CollectionType::class, [ + 'entry_type' => Type\TextType::class, + 'entry_options' => [ + 'label' => $metadataField['label'], + 'required' => false, + 'attr' => [ + 'placeholder' => $metadataField['placeholder'] ?? '', + 'class' => $metadataField['class'] ?? '', + ], + 'constraints' => $metadataConstraints ?? [], ], - 'data' => $formData[$aliquotCode . $metadataField['identifier']][0] ?? null, - 'constraints' => $metadataConstraints ?? [] + 'allow_add' => true, + 'allow_delete' => true, + 'data' => $formData[$aliquotCode . $metadataField['identifier']] ?? [], ]); } } diff --git a/src/Nph/Order/Samples/Module3.json b/src/Nph/Order/Samples/Module3.json index 9807ead67..63f3402f8 100644 --- a/src/Nph/Order/Samples/Module3.json +++ b/src/Nph/Order/Samples/Module3.json @@ -185,7 +185,7 @@ "container": "5mL Matrix tube (w/glycerol)", "description": "5mL Matrix tube", "expectedAliquots": 1, - "expectedVolume": 2.5, + "expectedVolume": 2.4, "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", @@ -194,7 +194,7 @@ "maxVolume": 2.4, "warningMinVolume": 100, "warningMaxVolume": 2400, - "addNew": false, + "addNew": true, "collectMetadata": true, "metadataFields": [ { diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index c6cd48b90..94a26bb72 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -10,33 +10,32 @@ {% set colspan = 1 %} {% endif %} {% for metadataField in aliquot['metadataFields'] %} - +

{{ metadataField['label'] }}

(1ml = 1000uL) -
- {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control',}}) }} +
+ {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control aliquot-volume', 'data-warning-target': aliquotCode ~ '-warning-target'}}) }} {{ aliquot['units'] }}
+ -
+
{{ form_widget(form[aliquotCode~metadataField['identifier']], {'attr': {'class': 'form-control'}}) }} μl
- + -
- + = +
+ mL
- - - {% if not sample.disabled and not sample.unlocked %} - + {% if sample.unlocked %} + {% endif %} @@ -44,6 +43,9 @@ {{ form_errors(form[aliquotCode ~ 'Volume'][i]) }} {{ form_errors(form[aliquotCode ~ 'glycerolAdditiveVolume']) }} + {% endfor %} @@ -51,7 +53,7 @@ {% endmacro %} {% macro displayAliquotRow(aliquotCode, aliquot, sample, form, i, disabled, skipVolume = false) %} {% set aliquotId = form[aliquotCode][i].vars.data %} - + {{ form_widget(form[aliquotCode][i], { @@ -66,7 +68,7 @@ {% if not skipVolume %} {{ _self.displayVolumeTD(aliquotCode, aliquot, sample, form, i) }} {% elseif skipVolume and sample.unlocked %} - + {% endif %} {% if form['cancel_' ~ aliquotCode ~ '_' ~ aliquotId] is defined %} @@ -302,7 +304,7 @@ + Add Line + data-list-selector="#aliquots_fields_list_{{ aliquotCode }}" data-aliquot-code="{{ aliquotCode }}">+ Add Line
{% endif %} diff --git a/web/assets/css/nph.css b/web/assets/css/nph.css index 60a12c6a0..562d1f2d7 100644 --- a/web/assets/css/nph.css +++ b/web/assets/css/nph.css @@ -129,7 +129,6 @@ div.order-row { font-size: 22px } .sample-metadata-eraser { - position: absolute; bottom: 20px; left: 33px; font-size: 22px diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index ca9404184..4e5894e70 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -10,43 +10,11 @@ $(document).ready(function () { }); $(".add-aliquot-widget").click(function () { - let list = $($(this).attr("data-list-selector")); - let aliquotId = list.data("aliquot-id"); - let aliquotUnits = list.data("aliquot-units"); - let counter = list.data("widget-counter"); - - // Grab the prototype template and replace the "__name__" used in the id and name of the prototype - let newCodeWidget = list.data("code-prototype").replace(/__name__/g, counter); - let newTsWidget = list.data("ts-prototype").replace(/__name__/g, counter); - let newVolumeWidget = list.data("volume-prototype").replace(/__name__/g, counter); - - // Increment and update widget counter - counter++; - list.data("widget-counter", counter); - - let newElem = $(list.attr("data-widget-tags")).html( - "" + - newCodeWidget + - "" + - '' + - newTsWidget + - "" + - "" + - newVolumeWidget + - "" + - "" + - aliquotUnits + - '' - ); - - $(".aliquots-row-" + aliquotId) - .last() - .after(newElem); - - $(".order-ts").pmiDateTimePicker({ - maxDate: new Date().setHours(23, 59, 59, 999) - }); + if ($(this).data("aliquot-code") === "SALIVAA2") { + addGlycerolAliquotRow(this); + } else { + addNormalAliquotRow(this); + } }); $(document).on("click", ".delete-aliquot-widget", function () { @@ -57,6 +25,8 @@ $(document).ready(function () { $(this).closest("tr").find("input:not(:read-only)").val(""); }); + $(document).on("click"); + $(".aliquot-volume").keyup(function () { let inputValue = $(this).val(); let minValue = $(this).data("warning-min-volume"); @@ -65,8 +35,14 @@ $(document).ready(function () { calculateGlycerolVolume(this, $("#nph_sample_finalize_SALIVAA2glycerolAdditiveVolume")); } if (inputValue && inputValue >= minValue && inputValue <= maxValue) { + if ($(this).data("warning-target")) { + $("#" + $(this).data("warning-target")).show(); + } $(this).closest("tr").find(".aliquot-volume-warning").show(); } else { + if ($(this).data("warning-target")) { + $("#" + $(this).data("warning-target")).hide(); + } $(this).closest("tr").find(".aliquot-volume-warning").hide(); } }); @@ -100,12 +76,82 @@ $(document).ready(function () { }; function calculateGlycerolVolume(sampleVolumeField, glycerolVolumeField) { - let sampleVolume = $(sampleVolumeField).val() ? parseInt($(sampleVolumeField).val()) * 1000 : 0; - let glycerolVolume = $(glycerolVolumeField).val() ? parseInt($(glycerolVolumeField).val()) : 0; + let sampleVolume = $(sampleVolumeField).val() ? parseFloat($(sampleVolumeField).val()) * 1000 : 0; + let glycerolVolume = $(glycerolVolumeField).val() ? parseFloat($(glycerolVolumeField).val()) : 0; let totalVolume = ((sampleVolume + glycerolVolume) / 1000).toFixed(2); $("#totalVol").val(`${totalVolume}`); } + function addNormalAliquotRow(element) { + let list = $($(element).attr("data-list-selector")); + let aliquotId = list.data("aliquot-id"); + let aliquotUnits = list.data("aliquot-units"); + let counter = list.data("widget-counter"); + + // Grab the prototype template and replace the "__name__" used in the id and name of the prototype + let newCodeWidget = list.data("code-prototype").replace(/__name__/g, counter); + let newTsWidget = list.data("ts-prototype").replace(/__name__/g, counter); + let newVolumeWidget = list.data("volume-prototype").replace(/__name__/g, counter); + + // Increment and update widget counter + counter++; + list.data("widget-counter", counter); + + let newElem = $(list.attr("data-widget-tags")).html( + "" + + newCodeWidget + + "" + + '' + + newTsWidget + + "" + + "" + + newVolumeWidget + + "" + + "" + + aliquotUnits + + '' + ); + + $(".aliquots-row-" + aliquotId) + .last() + .after(newElem); + + $(".order-ts").pmiDateTimePicker({ + maxDate: new Date().setHours(23, 59, 59, 999) + }); + } + + function addGlycerolAliquotRow(element) { + let list = $($(element).attr("data-list-selector")); + let aliquotId = list.data("aliquot-id"); + let aliquotUnits = list.data("aliquot-units"); + let counter = list.data("widget-counter"); + let aliquotCode = $(element).data("aliquot-code"); + let rows = $(".duplicate-target-" + aliquotCode).clone(); + rows.each(function () { + let barcodeName = `nph_sample_finalize[SALIVAA2][${counter}]`; + let tsName = `nph_sample_finalize[SALIVAA2AliquotTs][${counter}]`; + let volumeName = `nph_sample_finalize[SALIVAA2Volume][${counter}]`; + let glycerolVolumeName = `nph_sample_finalize[SALIVAA2glycerolAdditiveVolume][${counter}]`; + $(this).removeClass("duplicate-target-" + aliquotCode); + $(this).find("[name='nph_sample_finalize[SALIVAA2][0]']").attr("name", barcodeName); + $(this).find("[name='nph_sample_finalize[SALIVAA2AliquotTs][0]']").attr("name", tsName); + $(this).find("[name='nph_sample_finalize[SALIVAA2Volume][0]']").attr("name", volumeName); + $(this) + .find("[name='nph_sample_finalize[SALIVAA2glycerolAdditiveVolume][0]']") + .attr("name", glycerolVolumeName); + $(this).find("input").val(""); + $(this).find("input:not(#totalVol)").attr("readonly", false); + }); + counter++; + list.data("widget-counter", counter); + $(element).closest("tr").before(rows); + $(".order-ts").pmiDateTimePicker({ + maxDate: new Date().setHours(23, 59, 59, 999) + }); + } + disableEnableAliquotFields(); calculateGlycerolVolume( $("#nph_sample_finalize_SALIVAA2Volume_0"), From 8e94e7388bb1bf7ac38c3d47873b0826947fd7b4 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 14 Sep 2023 09:47:52 -0500 Subject: [PATCH 18/44] set metadatafields data. --- src/Form/Nph/NphSampleFinalizeType.php | 6 +++++- templates/program/nph/order/sample-finalize.html.twig | 6 +++--- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index 589e460b1..a71b4452d 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -131,6 +131,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'data' => $tsData, ]); if (isset($aliquot['collectMetadata']) && $aliquot['collectMetadata']) { + $aliquotMetadataCount = 0; foreach ($aliquot['metadataFields'] as $metadataField) { if ($metadataField['identifier'] === 'glycerolAdditiveVolume') { $metadataConstraints = [ @@ -153,6 +154,8 @@ public function buildForm(FormBuilderInterface $builder, array $options) } }) ]; + $metadataValue[] = $formData["{$aliquotCode}GlycerolAdditiveVolume"][$aliquotMetadataCount] ?? null; + $aliquotMetadataCount++; } $builder->add("{$aliquotCode}{$metadataField['identifier']}", Type\CollectionType::class, [ 'entry_type' => Type\TextType::class, @@ -163,11 +166,12 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'placeholder' => $metadataField['placeholder'] ?? '', 'class' => $metadataField['class'] ?? '', ], + 'data' => $formData[$aliquotCode . $metadataField['identifier']][0] ?? null, 'constraints' => $metadataConstraints ?? [], ], 'allow_add' => true, 'allow_delete' => true, - 'data' => $formData[$aliquotCode . $metadataField['identifier']] ?? [], + 'data' => $metadataValue, ]); } } diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index 94a26bb72..7d7a09240 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -22,8 +22,8 @@
+ -
- {{ form_widget(form[aliquotCode~metadataField['identifier']], {'attr': {'class': 'form-control'}}) }} +
+ {{ form_widget(form[aliquotCode~metadataField['identifier']][i], {'attr': {'class': 'form-control'}}) }} μl
@@ -42,7 +42,7 @@ {{ form_errors(form[aliquotCode ~ 'Volume'][i]) }} - {{ form_errors(form[aliquotCode ~ 'glycerolAdditiveVolume']) }} + {{ form_errors(form[aliquotCode ~ 'glycerolAdditiveVolume'][i]) }} From 19d74fe51a0f4473266336b1a588921eae7f5168 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 14 Sep 2023 09:50:51 -0500 Subject: [PATCH 19/44] Fix for field not set --- src/Form/Nph/NphSampleFinalizeType.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index a71b4452d..c2aaec29d 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -131,7 +131,6 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'data' => $tsData, ]); if (isset($aliquot['collectMetadata']) && $aliquot['collectMetadata']) { - $aliquotMetadataCount = 0; foreach ($aliquot['metadataFields'] as $metadataField) { if ($metadataField['identifier'] === 'glycerolAdditiveVolume') { $metadataConstraints = [ @@ -154,8 +153,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) } }) ]; - $metadataValue[] = $formData["{$aliquotCode}GlycerolAdditiveVolume"][$aliquotMetadataCount] ?? null; - $aliquotMetadataCount++; + $metadataValue = $formData["{$aliquotCode}GlycerolAdditiveVolume"] ?? [null]; } $builder->add("{$aliquotCode}{$metadataField['identifier']}", Type\CollectionType::class, [ 'entry_type' => Type\TextType::class, From 108c4f249f4ee55ef6b5e2877fcf90bee26e3664 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 14 Sep 2023 10:02:54 -0500 Subject: [PATCH 20/44] Added default for metadataValue --- src/Form/Nph/NphSampleFinalizeType.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index c2aaec29d..7ce4d4454 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -154,6 +154,8 @@ public function buildForm(FormBuilderInterface $builder, array $options) }) ]; $metadataValue = $formData["{$aliquotCode}GlycerolAdditiveVolume"] ?? [null]; + } else { + $metadataValue = [null]; } $builder->add("{$aliquotCode}{$metadataField['identifier']}", Type\CollectionType::class, [ 'entry_type' => Type\TextType::class, From 1cd361250c12537c7384b1fe04a3beb2f12d7052 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 14 Sep 2023 10:06:34 -0500 Subject: [PATCH 21/44] Remove extra data variable. --- src/Form/Nph/NphSampleFinalizeType.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index 7ce4d4454..0890191f7 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -166,7 +166,6 @@ public function buildForm(FormBuilderInterface $builder, array $options) 'placeholder' => $metadataField['placeholder'] ?? '', 'class' => $metadataField['class'] ?? '', ], - 'data' => $formData[$aliquotCode . $metadataField['identifier']][0] ?? null, 'constraints' => $metadataConstraints ?? [], ], 'allow_add' => true, From ee937cb5035c4f5100e1d9f3a86d5daa7caad33a Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 14 Sep 2023 10:08:51 -0500 Subject: [PATCH 22/44] Remove useless code. --- web/assets/js/views/NphSampleFinalize.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index 4e5894e70..7d90d2f3f 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -25,8 +25,6 @@ $(document).ready(function () { $(this).closest("tr").find("input:not(:read-only)").val(""); }); - $(document).on("click"); - $(".aliquot-volume").keyup(function () { let inputValue = $(this).val(); let minValue = $(this).data("warning-min-volume"); From 80d59ac6e324ab6d5fe2cd99807857000b0f3bc9 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 15 Sep 2023 09:11:05 -0500 Subject: [PATCH 23/44] Updated javascript, fix for saving aliquot. --- src/Form/Nph/NphSampleFinalizeType.php | 12 ++++------ src/Nph/Order/Samples/Module3.json | 16 +++++++++---- src/Service/Nph/NphOrderService.php | 2 +- .../nph/order/sample-finalize.html.twig | 20 +++++++++++----- web/assets/js/views/NphSampleFinalize.js | 23 ++++++++++--------- 5 files changed, 43 insertions(+), 30 deletions(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index 0890191f7..5cad908af 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -139,21 +139,19 @@ public function buildForm(FormBuilderInterface $builder, array $options) $formData = $context->getRoot()->getData(); $glycerolVolume = $formData[$aliquotCode . $metadataField['identifier']][$key]; $totalVolume = $formData["{$aliquotCode}Volume"][$key] + ($glycerolVolume / 1000); - if ($totalVolume > $aliquot['maxVolume']) { - $context->buildViolation("{$metadataField['label']} cannot be entered. This aliquot should contain a maximum of {$aliquot['maxVolume']} {$aliquot['units']}.")->addViolation(); - } - if ($totalVolume < $aliquot['minVolume']) { - $context->buildViolation("{$metadataField['label']} cannot be entered. This aliquot should contain a minimum of {$aliquot['minVolume']} {$aliquot['units']}.")->addViolation(); + if ($totalVolume > $metadataField['warningMaxTotalVolume'] || $totalVolume < $metadataField['warningMinTotalVolume']) { + $context->buildViolation("Glycerol Volume Please verify the volume is correct this aliquot should contain {$metadataField['warningMaxVolume']} {$metadataField['units']} Only.") + ->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); } if ($glycerolVolume <= 0) { - $context->buildViolation("{$metadataField['label']} volume must be greater than 0")->addViolation(); + $context->buildViolation("Glycerol Volume Please verify the volume is correct. This aliquot should contain {$aliquot['minVolume']} {$aliquot['units']} Only.")->addViolation(); } if ($glycerolVolume >= 0.1 && $glycerolVolume <= 0.4) { $context->buildViolation('Glycerol Volume Please verify the unit of measurement is correct. (For reference 1mL = 1000uL)')->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); } }) ]; - $metadataValue = $formData["{$aliquotCode}GlycerolAdditiveVolume"] ?? [null]; + $metadataValue = $formData["{$aliquotCode}glycerolAdditiveVolume"] ?? [null]; } else { $metadataValue = [null]; } diff --git a/src/Nph/Order/Samples/Module3.json b/src/Nph/Order/Samples/Module3.json index 63f3402f8..89df7ccce 100644 --- a/src/Nph/Order/Samples/Module3.json +++ b/src/Nph/Order/Samples/Module3.json @@ -173,11 +173,11 @@ "barcodeLength" : 10, "barcodePrefix": "MC", "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 4mL matrix aliquot tube barcode ID.", - "minVolume": 0, + "minVolume": 0.1, "maxVolume": 4, "warningMinVolume": 100, "warningMaxVolume": 4000, - "addNew": false, + "addNew": true, "collectMetadata": false }, "SALIVAA2": { @@ -191,9 +191,9 @@ "barcodePrefix": "MC", "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 2.5mL matrix aliquot tube barcode ID.", "minVolume": 0, - "maxVolume": 2.4, - "warningMinVolume": 100, - "warningMaxVolume": 2400, + "maxVolume": 2, + "warningMinVolume": 0.1, + "warningMaxVolume": 2, "addNew": true, "collectMetadata": true, "metadataFields": [ @@ -203,6 +203,12 @@ "type": "number", "label": "Calculated Volume for Glycerol Additive Sample", "units": "μL", + "minVolume": 0, + "maxVolume": 2400, + "warningMinVolume": 0, + "warningMaxVolume": 400, + "warningMinTotalVolume": 0.1, + "warningMaxTotalVolume": 2.4, "entryType": "Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType", "required": true } diff --git a/src/Service/Nph/NphOrderService.php b/src/Service/Nph/NphOrderService.php index 307d2d016..999df3bee 100644 --- a/src/Service/Nph/NphOrderService.php +++ b/src/Service/Nph/NphOrderService.php @@ -1071,7 +1071,7 @@ private function saveNphAliquotFinalizedInfo(NphSample $sample, array $aliquots, } } if (!empty($formData["${aliquotCode}glycerolAdditiveVolume"])) { - $nphAliquot->setAliquotMetadata(array_merge($nphAliquot->getAliquotMetadata(), ["${aliquotCode}glycerolAdditiveVolume" => $formData["${aliquotCode}glycerolAdditiveVolume"]])); + $nphAliquot->setAliquotMetadata(array_merge($nphAliquot->getAliquotMetadata(), ["${aliquotCode}glycerolAdditiveVolume" => $formData["${aliquotCode}glycerolAdditiveVolume"][$key]])); } $this->em->persist($nphAliquot); $this->em->flush(); diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index 7d7a09240..3b5daf181 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -10,28 +10,30 @@ {% set colspan = 1 %} {% endif %} {% for metadataField in aliquot['metadataFields'] %} - +

{{ metadataField['label'] }}

(1ml = 1000uL)
- {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control aliquot-volume', 'data-warning-target': aliquotCode ~ '-warning-target'}}) }} + {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control aliquot-volume glycerol-volume sample', 'data-warning-target': aliquotCode ~ '-warning-target'}}) }} {{ aliquot['units'] }}
+
- {{ form_widget(form[aliquotCode~metadataField['identifier']][i], {'attr': {'class': 'form-control'}}) }} + {{ form_widget(form[aliquotCode~metadataField['identifier']][i], {'attr': {'class': 'form-control glycerol-volume aliquot-volume additive', + 'data-warning-target': aliquotCode ~ '-warning-target-glycerol', 'data-warning-max-volume': metadataField['warningMaxVolume'], 'data-warning-min-volume': metadataField['warningMinVolume']}}) }} μl
- + =
- + mL
{% if sample.unlocked %} @@ -44,7 +46,13 @@ {{ form_errors(form[aliquotCode ~ 'Volume'][i]) }} {{ form_errors(form[aliquotCode ~ 'glycerolAdditiveVolume'][i]) }} + + diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index 7d90d2f3f..3dd671925 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -9,7 +9,7 @@ $(document).ready(function () { $("form[name='nph_sample_finalize']").submit(); }); - $(".add-aliquot-widget").click(function () { + $(document).on("click", ".add-aliquot-widget", function () { if ($(this).data("aliquot-code") === "SALIVAA2") { addGlycerolAliquotRow(this); } else { @@ -25,13 +25,10 @@ $(document).ready(function () { $(this).closest("tr").find("input:not(:read-only)").val(""); }); - $(".aliquot-volume").keyup(function () { - let inputValue = $(this).val(); + $(document).on("keyup", ".aliquot-volume", function () { + let inputValue = parseFloat($(this).val()); let minValue = $(this).data("warning-min-volume"); let maxValue = $(this).data("warning-max-volume"); - if (this.id === "nph_sample_finalize_SALIVAA2Volume_0") { - calculateGlycerolVolume(this, $("#nph_sample_finalize_SALIVAA2glycerolAdditiveVolume")); - } if (inputValue && inputValue >= minValue && inputValue <= maxValue) { if ($(this).data("warning-target")) { $("#" + $(this).data("warning-target")).show(); @@ -45,8 +42,12 @@ $(document).ready(function () { } }); - $("#nph_sample_finalize_SALIVAA2glycerolAdditiveVolume").keyup(function () { - calculateGlycerolVolume($("#nph_sample_finalize_SALIVAA2Volume_0"), this); + $(document).on("keyup", ".glycerol-volume", function () { + calculateGlycerolVolume( + $(this).closest("tr").find(".sample"), + $(this).closest("tr").find(".additive"), + $(this).closest("tr").data("sample-index") + ); }); $(document).on("keyup", ".aliquot-barcode", function () { @@ -73,11 +74,11 @@ $(document).ready(function () { }); }; - function calculateGlycerolVolume(sampleVolumeField, glycerolVolumeField) { + function calculateGlycerolVolume(sampleVolumeField, glycerolVolumeField, index) { let sampleVolume = $(sampleVolumeField).val() ? parseFloat($(sampleVolumeField).val()) * 1000 : 0; let glycerolVolume = $(glycerolVolumeField).val() ? parseFloat($(glycerolVolumeField).val()) : 0; let totalVolume = ((sampleVolume + glycerolVolume) / 1000).toFixed(2); - $("#totalVol").val(`${totalVolume}`); + $(`#totalVol${index}`).val(`${totalVolume}`); } function addNormalAliquotRow(element) { @@ -140,7 +141,7 @@ $(document).ready(function () { .find("[name='nph_sample_finalize[SALIVAA2glycerolAdditiveVolume][0]']") .attr("name", glycerolVolumeName); $(this).find("input").val(""); - $(this).find("input:not(#totalVol)").attr("readonly", false); + $(this).find("input:not(.totalVol)").attr("readonly", false); }); counter++; list.data("widget-counter", counter); From 79cfd328c9f91588e9df9fcc35d2b986e7c33757 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 15 Sep 2023 10:03:45 -0500 Subject: [PATCH 24/44] Fix display error messages. --- templates/program/nph/order/sample-finalize.html.twig | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index 3b5daf181..c4ae71064 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -17,14 +17,14 @@
- {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control aliquot-volume glycerol-volume sample', 'data-warning-target': aliquotCode ~ '-warning-target'}}) }} + {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control aliquot-volume glycerol-volume sample', 'data-warning-target': aliquotCode ~ '-warning-target' ~ i}) }} {{ aliquot['units'] }}
+
{{ form_widget(form[aliquotCode~metadataField['identifier']][i], {'attr': {'class': 'form-control glycerol-volume aliquot-volume additive', - 'data-warning-target': aliquotCode ~ '-warning-target-glycerol', 'data-warning-max-volume': metadataField['warningMaxVolume'], 'data-warning-min-volume': metadataField['warningMinVolume']}}) }} + 'data-warning-target': aliquotCode ~ '-warning-target-glycerol' ~ i, 'data-warning-max-volume': metadataField['warningMaxVolume'], 'data-warning-min-volume': metadataField['warningMinVolume']}}) }} μl
@@ -33,7 +33,7 @@ =
+ data-warning-max-volume="{{ metadataField['warningMaxTotalVolume'] }}" data-warning-target="{{ aliquotCode }}-warning-target-total{{ i }}"> mL
{% if sample.unlocked %} From f87ee2fd0a6a0f71b992ff050fab3668a7be6031 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 15 Sep 2023 10:06:48 -0500 Subject: [PATCH 25/44] More javascript --- templates/program/nph/order/sample-finalize.html.twig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index c4ae71064..20580b708 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -17,7 +17,7 @@
- {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control aliquot-volume glycerol-volume sample', 'data-warning-target': aliquotCode ~ '-warning-target' ~ i}) }} + {{ form_widget(form[aliquotCode ~ 'Volume'][i], {'attr': {'class': 'form-control aliquot-volume glycerol-volume sample', 'data-warning-target': aliquotCode ~ '-warning-target' ~ i}}) }} {{ aliquot['units'] }}
+ @@ -45,13 +45,13 @@ {{ form_errors(form[aliquotCode ~ 'Volume'][i]) }} {{ form_errors(form[aliquotCode ~ 'glycerolAdditiveVolume'][i]) }} -
- {% if sample.unlocked %} + {% if not sample.disabled %} {% endif %} From b40126a7d33fbbe08b34eba473910af1713c572d Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 20 Sep 2023 09:48:46 -0500 Subject: [PATCH 32/44] Remove unused use statement. --- src/Form/Nph/NphSampleFinalizeType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index f96bb5da6..2d70341d1 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -134,7 +134,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) foreach ($aliquot['metadataFields'] as $metadataField) { if ($metadataField['identifier'] === 'glycerolAdditiveVolume') { $metadataConstraints = [ - new Constraints\Callback(function ($value, $context) use ($aliquotCode, $aliquot, $metadataField) { + new Constraints\Callback(function ($value, $context) use ($aliquotCode, $metadataField) { $key = intval($context->getObject()->getName()); $formData = $context->getRoot()->getData(); $glycerolVolume = $formData[$aliquotCode . $metadataField['identifier']][$key]; From 2cb8a56c607d66c4bd525fd4ac0c7a744a3917d6 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 20 Sep 2023 12:06:08 -0500 Subject: [PATCH 33/44] Fix javascript validations. --- src/Form/Nph/NphSampleFinalizeType.php | 2 -- src/Nph/Order/Samples/Module3.json | 7 ++++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index 2d70341d1..56c56d645 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -141,8 +141,6 @@ public function buildForm(FormBuilderInterface $builder, array $options) if (isset($formData[$aliquotCode][$key])) { if ($glycerolVolume == 0) { $context->buildViolation('Glycerol Volume Please verify the volume is correct. Volume should be greater than 0')->addViolation(); - } elseif ($glycerolVolume > $metadataField['warningMinVolume'] && $glycerolVolume <= $metadataField['warningMaxVolume']) { - $context->buildViolation('Glycerol Volume Please verify the unit of measurement is correct. (For reference 1mL = 1000uL)')->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); } elseif ($glycerolVolume > $metadataField['maxVolume']) { $context->buildViolation("Glycerol Volume Please verify the volume is correct. This aliquot should contain a maximum of {$metadataField['maxVolume']} {$metadataField['units']}.")->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); } diff --git a/src/Nph/Order/Samples/Module3.json b/src/Nph/Order/Samples/Module3.json index 2e71c43e4..c6634728e 100644 --- a/src/Nph/Order/Samples/Module3.json +++ b/src/Nph/Order/Samples/Module3.json @@ -192,8 +192,8 @@ "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 2.5mL matrix aliquot tube barcode ID.", "minVolume": 0, "maxVolume": 2, - "warningMinVolume": 0.1, - "warningMaxVolume": 0.4, + "warningMinVolume": 100, + "warningMaxVolume": 2000, "addNew": true, "collectMetadata": true, "metadataFields": [ @@ -205,10 +205,11 @@ "units": "μL", "minVolume": 0, "maxVolume": 400, - "warningMinVolume": 0, + "warningMinVolume": 0.1, "warningMaxVolume": 0.4, "warningMinTotalVolume": 100, "warningMaxTotalVolume": 2400, + "maxTotalVolume": 2.4, "entryType": "Symfony\\Component\\Form\\Extension\\Core\\Type\\TextType", "required": true } From 34663b546e9bfffb7253e83ec4d0a7b139415094 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 20 Sep 2023 12:06:28 -0500 Subject: [PATCH 34/44] Fixed javascript. Don't use rounded value for check. --- web/assets/js/views/NphSampleFinalize.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index e02209e7b..0f331a753 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -75,14 +75,16 @@ $(document).ready(function () { }; function calculateGlycerolVolume(sampleVolumeField, glycerolVolumeField, index) { + let totalVolumeField = $(`#totalVol${index}`); let sampleVolume = $(sampleVolumeField).val() ? parseFloat($(sampleVolumeField).val()) * 1000 : 0; let glycerolVolume = $(glycerolVolumeField).val() ? parseFloat($(glycerolVolumeField).val()) : 0; - let totalVolume = ((sampleVolume + glycerolVolume) / 1000).toFixed(2); - $(`#totalVol${index}`).val(`${totalVolume}`); + let totalVolume = sampleVolume + glycerolVolume; + let totalVolumeRounded = (totalVolume / 1000).toFixed(2); + totalVolumeField.val(`${totalVolumeRounded}`); $(`#totalVol${index}`).each(function () { if ( $(this).data("warning-max-volume") && - $(this).val() > $(this).data("warning-max-volume") && + totalVolume > $(this).data("warning-max-volume") && $(this).parent().parent().siblings().children().hasClass("has-error") && !$(this).parent().hasClass("has-error") ) { @@ -182,10 +184,6 @@ $(document).ready(function () { } disableEnableAliquotFields(); - calculateGlycerolVolume( - $("#nph_sample_finalize_SALIVAA2Volume_0"), - $("#nph_sample_finalize_SALIVAA2glycerolAdditiveVolume") - ); $(".aliquot-volume").trigger("keyup"); From 61fda7d622840ca7228a5b88c16d503426251347 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Wed, 20 Sep 2023 12:40:21 -0500 Subject: [PATCH 35/44] Don't worry about total volume validations. --- web/assets/js/views/NphSampleFinalize.js | 26 +++++------------------- 1 file changed, 5 insertions(+), 21 deletions(-) diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index 0f331a753..48541b8df 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -80,27 +80,11 @@ $(document).ready(function () { let glycerolVolume = $(glycerolVolumeField).val() ? parseFloat($(glycerolVolumeField).val()) : 0; let totalVolume = sampleVolume + glycerolVolume; let totalVolumeRounded = (totalVolume / 1000).toFixed(2); - totalVolumeField.val(`${totalVolumeRounded}`); - $(`#totalVol${index}`).each(function () { - if ( - $(this).data("warning-max-volume") && - totalVolume > $(this).data("warning-max-volume") && - $(this).parent().parent().siblings().children().hasClass("has-error") && - !$(this).parent().hasClass("has-error") - ) { - $(this).parent().addClass("has-error"); - $(this) - .parent() - .parent() - .parent() - .next() - .find("li") - .append( - `
  • Please verify the total volume is correct. This aliquot should contain a maximum of 2.4 mL.
  • ` - ); - $(this).trigger("keyup"); - } - }); + if (totalVolume > totalVolumeField.data("warning-max-volume")) { + totalVolumeField.val(""); + } else { + totalVolumeField.val(`${totalVolumeRounded}`); + } } function addNormalAliquotRow(element) { From 7b48749afcb79b312e2c8cbf369b7048d2598e27 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 21 Sep 2023 12:02:56 -0500 Subject: [PATCH 36/44] Updated barcode error messages. --- src/Nph/Order/Samples/Module3.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Nph/Order/Samples/Module3.json b/src/Nph/Order/Samples/Module3.json index c6634728e..7ee610437 100644 --- a/src/Nph/Order/Samples/Module3.json +++ b/src/Nph/Order/Samples/Module3.json @@ -172,7 +172,7 @@ "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", - "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 4mL matrix aliquot tube barcode ID.", + "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 5mL matrix aliquot tube barcode ID.", "minVolume": 0.1, "maxVolume": 4, "warningMinVolume": 0.1, @@ -189,7 +189,7 @@ "units": "mL", "barcodeLength" : 10, "barcodePrefix": "MC", - "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 2.5mL matrix aliquot tube barcode ID.", + "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 5mL matrix aliquot tube barcode ID.", "minVolume": 0, "maxVolume": 2, "warningMinVolume": 100, From 65326cec5560ec6b3a2c11b31958f0cf96d41514 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 21 Sep 2023 12:48:00 -0500 Subject: [PATCH 37/44] Allow volume error messages to have a prefix added. --- src/Form/Nph/NphSampleFinalizeType.php | 13 ++++++++++--- src/Nph/Order/Samples/Module3.json | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index 56c56d645..fbd5d6c25 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -140,9 +140,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) $glycerolVolume = $formData[$aliquotCode . $metadataField['identifier']][$key]; if (isset($formData[$aliquotCode][$key])) { if ($glycerolVolume == 0) { - $context->buildViolation('Glycerol Volume Please verify the volume is correct. Volume should be greater than 0')->addViolation(); + $context->buildViolation('Glycerol Volume: Please verify the volume is correct. Volume should be greater than 0')->addViolation(); } elseif ($glycerolVolume > $metadataField['maxVolume']) { - $context->buildViolation("Glycerol Volume Please verify the volume is correct. This aliquot should contain a maximum of {$metadataField['maxVolume']} {$metadataField['units']}.")->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); + $context->buildViolation("Glycerol Volume: Please verify the volume is correct. This aliquot should contain a maximum of {$metadataField['maxVolume']} {$metadataField['units']}.")->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); } } }) @@ -184,13 +184,20 @@ public function buildForm(FormBuilderInterface $builder, array $options) }) ]; if (isset($aliquot['minVolume'])) { + $errorMessage = 'Volume must be greater than 0'; + if (isset($aliquot['errorMessageVolumePrefix'])) { + $errorMessage = "{$aliquot['errorMessageVolumePrefix']} {$errorMessage}"; + } $volumeConstraints[] = new Constraints\GreaterThan([ 'value' => $aliquot['minVolume'], - 'message' => 'Volume must be greater than 0' + 'message' => $errorMessage ]); } if (isset($aliquot['maxVolume'])) { $errorMessage = "Please verify the volume is correct. This aliquot should contain a maximum of {$aliquot['maxVolume']} {$aliquot['units']}."; + if (isset($aliquot['errorMessageVolumePrefix'])) { + $errorMessage = "{$aliquot['errorMessageVolumePrefix']} {$errorMessage}"; + } $volumeConstraints[] = new Constraints\LessThanOrEqual([ 'value' => $aliquot['maxVolume'], 'message' => $errorMessage diff --git a/src/Nph/Order/Samples/Module3.json b/src/Nph/Order/Samples/Module3.json index 7ee610437..9e72a0c58 100644 --- a/src/Nph/Order/Samples/Module3.json +++ b/src/Nph/Order/Samples/Module3.json @@ -192,6 +192,7 @@ "barcodeErrorMessage": "Aliquot barcode ID invalid. Please enter a valid 5mL matrix aliquot tube barcode ID.", "minVolume": 0, "maxVolume": 2, + "errorMessageVolumePrefix": "Saliva Volume:", "warningMinVolume": 100, "warningMaxVolume": 2000, "addNew": true, From 59091a0c008fbe105cbc37dc740457bd3b3b6575 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Thu, 21 Sep 2023 13:48:44 -0500 Subject: [PATCH 38/44] Remove restore/remove checkboxes on add lines. --- web/assets/js/views/NphSampleFinalize.js | 1 + 1 file changed, 1 insertion(+) diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index 48541b8df..4981116c1 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -134,6 +134,7 @@ $(document).ready(function () { let counter = list.data("widget-counter"); let aliquotCode = $(element).data("aliquot-code"); let rows = $(".duplicate-target-" + aliquotId).clone(); + $(rows).find('input[type="checkbox"]').remove(); rows.each(function () { let barcodeName = `nph_sample_finalize[SALIVAA2][${counter}]`; let tsName = `nph_sample_finalize[SALIVAA2AliquotTs][${counter}]`; From da326d2cdd63036f374a4f117b75c5005a5ad459 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 22 Sep 2023 08:51:34 -0500 Subject: [PATCH 39/44] Change error message --- src/Form/Nph/NphSampleFinalizeType.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index fbd5d6c25..bea031a14 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -140,7 +140,7 @@ public function buildForm(FormBuilderInterface $builder, array $options) $glycerolVolume = $formData[$aliquotCode . $metadataField['identifier']][$key]; if (isset($formData[$aliquotCode][$key])) { if ($glycerolVolume == 0) { - $context->buildViolation('Glycerol Volume: Please verify the volume is correct. Volume should be greater than 0')->addViolation(); + $context->buildViolation('Glycerol Volume: Volume must be greater than 0')->addViolation(); } elseif ($glycerolVolume > $metadataField['maxVolume']) { $context->buildViolation("Glycerol Volume: Please verify the volume is correct. This aliquot should contain a maximum of {$metadataField['maxVolume']} {$metadataField['units']}.")->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); } From 8915fc6f8e793155c8ca1fa1b5cca497ad4d9fcd Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Fri, 22 Sep 2023 12:31:54 -0500 Subject: [PATCH 40/44] Changed volume is required error message to contain prefix, changed units --- src/Form/Nph/NphSampleFinalizeType.php | 14 ++++++++++++-- .../program/nph/order/sample-finalize.html.twig | 2 +- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/Form/Nph/NphSampleFinalizeType.php b/src/Form/Nph/NphSampleFinalizeType.php index bea031a14..d42c06dca 100644 --- a/src/Form/Nph/NphSampleFinalizeType.php +++ b/src/Form/Nph/NphSampleFinalizeType.php @@ -139,7 +139,9 @@ public function buildForm(FormBuilderInterface $builder, array $options) $formData = $context->getRoot()->getData(); $glycerolVolume = $formData[$aliquotCode . $metadataField['identifier']][$key]; if (isset($formData[$aliquotCode][$key])) { - if ($glycerolVolume == 0) { + if ($glycerolVolume === null) { + $context->buildViolation('Glycerol Volume: Volume is required')->addViolation(); + } elseif ($glycerolVolume === 0) { $context->buildViolation('Glycerol Volume: Volume must be greater than 0')->addViolation(); } elseif ($glycerolVolume > $metadataField['maxVolume']) { $context->buildViolation("Glycerol Volume: Please verify the volume is correct. This aliquot should contain a maximum of {$metadataField['maxVolume']} {$metadataField['units']}.")->atPath($aliquotCode . $metadataField['identifier'])->addViolation(); @@ -176,9 +178,17 @@ public function buildForm(FormBuilderInterface $builder, array $options) $key = intval($context->getObject()->getName()); if ($aliquot['expectedVolume'] && ($formData[$aliquotCode][$key] || $formData["{$aliquotCode}AliquotTs"][$key]) && $value === null) { - $context->buildViolation('Volume is required')->addViolation(); + $errorMessage = 'Volume is required'; + if (isset($aliquot['errorMessageVolumePrefix'])) { + $errorMessage = "{$aliquot['errorMessageVolumePrefix']} {$errorMessage}"; + } + $context->buildViolation($errorMessage)->addViolation(); } if ($aliquot['expectedVolume'] === null && !empty($value)) { + $errorMessage = 'Volume should not be entered'; + if (isset($aliquot['errorMessageVolumePrefix'])) { + $errorMessage = "{$aliquot['errorMessageVolumePrefix']} {$errorMessage}"; + } $context->buildViolation('Volume should not be entered')->addViolation(); } }) diff --git a/templates/program/nph/order/sample-finalize.html.twig b/templates/program/nph/order/sample-finalize.html.twig index 6f61073db..2a07c4c1f 100644 --- a/templates/program/nph/order/sample-finalize.html.twig +++ b/templates/program/nph/order/sample-finalize.html.twig @@ -30,7 +30,7 @@
    {{ form_widget(form[aliquotCode~metadataField['identifier']][i], {'attr': {'class': 'form-control glycerol-volume aliquot-volume additive', 'data-warning-target': aliquotCode ~ '-warning-target-glycerol' ~ i, 'data-warning-max-volume': metadataField['warningMaxVolume'], 'data-warning-min-volume': metadataField['warningMinVolume']}}) }} - μl + {{ metadataField['units'] }}
    From 5a930966a9a0805bd51843cf531cedbc6e494cd9 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 25 Sep 2023 14:20:39 -0500 Subject: [PATCH 41/44] Only send DLW Info if DLW Info exists. --- src/Service/Nph/NphOrderService.php | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/src/Service/Nph/NphOrderService.php b/src/Service/Nph/NphOrderService.php index 82aeaa3f3..cf9be4132 100644 --- a/src/Service/Nph/NphOrderService.php +++ b/src/Service/Nph/NphOrderService.php @@ -18,6 +18,7 @@ use DateTime; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\PersistentCollection; +use function PHPUnit\Framework\isNull; class NphOrderService { @@ -663,13 +664,15 @@ public function getRdrObject(NphOrder $order, NphSample $sample, string $type = $aliquotsInfo = $this->getAliquots($sample->getSampleCode()); if ($order->getModule() === '3' && $order->getOrderType() === $order::TYPE_DLW) { $dlwInfo = $this->em->getRepository(NphDlw::class)->findOneBy(['module' => $order->getModule(), 'visit' => $order->getVisitType(), 'NphParticipant' => $order->getParticipantId()]); - $obj->dlwDose = [ - 'batchid' => $dlwInfo->getDoseBatchId(), - 'participantweight' => $dlwInfo->getParticipantWeight(), - 'dose' => $dlwInfo->getActualDose(), - 'calculateddose' => ($dlwInfo->getParticipantWeight() * 1.5), - 'doseAdministered' => $dlwInfo->getDoseAdministered()->format('Y-m-d\TH:i:s\Z') - ]; + if (!is_null($dlwInfo) && !empty($dlwInfo)) { + $obj->dlwDose = [ + 'batchid' => $dlwInfo->getDoseBatchId(), + 'participantweight' => $dlwInfo->getParticipantWeight(), + 'dose' => $dlwInfo->getActualDose(), + 'calculateddose' => ($dlwInfo->getParticipantWeight() * 1.5), + 'doseAdministered' => $dlwInfo->getDoseAdministered()->format('Y-m-d\TH:i:s\Z') + ]; + } } if ($aliquotsInfo) { $obj->aliquots = $sample->getRdrAliquotsSampleObj($aliquotsInfo); From 1d6456ff86f9c5eb4633043645e3fb67858074d2 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 25 Sep 2023 14:22:03 -0500 Subject: [PATCH 42/44] Remove unused import. --- src/Service/Nph/NphOrderService.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Service/Nph/NphOrderService.php b/src/Service/Nph/NphOrderService.php index cf9be4132..0814a0eb4 100644 --- a/src/Service/Nph/NphOrderService.php +++ b/src/Service/Nph/NphOrderService.php @@ -18,7 +18,6 @@ use DateTime; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\PersistentCollection; -use function PHPUnit\Framework\isNull; class NphOrderService { From f6e7e76836cd60b519b0435f2e949c34d307434c Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Mon, 25 Sep 2023 14:31:00 -0500 Subject: [PATCH 43/44] Use truthy type conversion. --- src/Service/Nph/NphOrderService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service/Nph/NphOrderService.php b/src/Service/Nph/NphOrderService.php index 0814a0eb4..fd4c35e54 100644 --- a/src/Service/Nph/NphOrderService.php +++ b/src/Service/Nph/NphOrderService.php @@ -663,7 +663,7 @@ public function getRdrObject(NphOrder $order, NphSample $sample, string $type = $aliquotsInfo = $this->getAliquots($sample->getSampleCode()); if ($order->getModule() === '3' && $order->getOrderType() === $order::TYPE_DLW) { $dlwInfo = $this->em->getRepository(NphDlw::class)->findOneBy(['module' => $order->getModule(), 'visit' => $order->getVisitType(), 'NphParticipant' => $order->getParticipantId()]); - if (!is_null($dlwInfo) && !empty($dlwInfo)) { + if ($dlwInfo) { $obj->dlwDose = [ 'batchid' => $dlwInfo->getDoseBatchId(), 'participantweight' => $dlwInfo->getParticipantWeight(), From 6d94eca43d89c038ffa23e33d872da7c0ca40c44 Mon Sep 17 00:00:00 2001 From: Andrew Johnson Date: Tue, 26 Sep 2023 11:40:38 -0500 Subject: [PATCH 44/44] If salivaa2 aliquot clear previous row inputs. --- web/assets/js/views/NphSampleFinalize.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/web/assets/js/views/NphSampleFinalize.js b/web/assets/js/views/NphSampleFinalize.js index 4981116c1..1b3f31924 100644 --- a/web/assets/js/views/NphSampleFinalize.js +++ b/web/assets/js/views/NphSampleFinalize.js @@ -22,6 +22,9 @@ $(document).ready(function () { }); $(document).on("click", ".clear-aliquot-widget", function () { + if ($(this).closest("tr").attr("class") && $(this).closest("tr").attr("class").includes("SALIVAA2")) { + $(this).closest("tr").prev().find("input:not(:read-only)").val(""); + } $(this).closest("tr").find("input:not(:read-only)").val(""); });