From c55652d906a04e45becda0790583d70c8e0e6c6f Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Thu, 16 Nov 2023 13:10:37 +0000 Subject: [PATCH 01/14] LIMS-1113: Redirect to shipping-service on dispatch --- .../emails/html/dewar-dispatch-lite.html | 30 ++++++ api/index.php | 5 +- api/src/Page/Shipment.php | 92 ++++++++++++++-- api/src/Shipment/ShippingService.php | 10 ++ .../js/modules/shipment/models/dispatch.js | 5 +- .../src/js/modules/shipment/views/dispatch.js | 16 +++ .../src/js/templates/shipment/dispatch.html | 101 +++++++++--------- 7 files changed, 197 insertions(+), 62 deletions(-) create mode 100644 api/assets/emails/html/dewar-dispatch-lite.html diff --git a/api/assets/emails/html/dewar-dispatch-lite.html b/api/assets/emails/html/dewar-dispatch-lite.html new file mode 100644 index 000000000..ad3b16b2b --- /dev/null +++ b/api/assets/emails/html/dewar-dispatch-lite.html @@ -0,0 +1,30 @@ +

Dewar ready to leave diamond

+ +
+ Goods Handling, please arrange dispatch of the following Dewar. +
+ + + + + + + + + + + + + + + + + + + + + + + + +
Proposal
Air Waybill
Dewar Facility Code
Dewar Barcode
Current Location
diff --git a/api/index.php b/api/index.php index 45435ea84..e6a0e450e 100644 --- a/api/index.php +++ b/api/index.php @@ -70,7 +70,7 @@ function setupApplication($mode): Slim global $motd, $authentication_type, $cas_url, $cas_sso, $sso_url, $package_description, $facility_courier_countries, $facility_courier_countries_nde, $dhl_enable, $dhl_link, $scale_grid, $scale_grid_end_date, $preset_proposal, $timezone, - $valid_components, $enabled_container_types, $ifsummary; + $valid_components, $enabled_container_types, $ifsummary, $shipping_service_app_url, $use_shipping_service_redirect; $app->contentType('application/json'); $options = $app->container['options']; $app->response()->body(json_encode(array( @@ -90,7 +90,8 @@ function setupApplication($mode): Slim 'timezone' => $timezone, 'valid_components' => $valid_components, 'enabled_container_types' => $enabled_container_types, - 'ifsummary' => $ifsummary + 'ifsummary' => $ifsummary, + 'shipping_service_app_url' => $use_shipping_service_redirect ? $shipping_service_app_url : null, ))); }); return $app; diff --git a/api/src/Page/Shipment.php b/api/src/Page/Shipment.php index 73b47f61f..c56c59043 100644 --- a/api/src/Page/Shipment.php +++ b/api/src/Page/Shipment.php @@ -924,6 +924,54 @@ function _transfer_dewar() $this->_output(1); } + function _dispatch_dewar_shipment_request($dewar) + { + if (is_null($dewar['EXTERNALSHIPPINGIDFROMSYNCHROTRON'])) { + $server_port = ($_SERVER['SERVER_PORT']==='443') ? '' : ":{$_SERVER['SERVER_PORT']}"; + $shipment_request_info = array( + "proposal" => $dewar['PROPOSAL'], + "external_id" => (int) $dewar['DEWARID'], + "origin_url" => "https://{$_SERVER['SERVER_NAME']}{$server_port}/shipments/sid/{$dewar['SHIPPINGID']}", + "packages" => [ + [ + "external_id" => (int) $dewar['DEWARID'], + "shippable_item_type" => "CRYOGENIC_DRY_SHIPPER_CASE", + "line_items" => [ + [ + "shippable_item_type" => "CRYOGENIC_DRY_SHIPPER", + "quantity" => 1 + ], + [ + "shippable_item_type"=> "UNI_PUCK", + "quantity" => (int) $dewar['NUM_PUCKS'] + ], + [ + "shippable_item_type" => "SHELVED_UNI_PUCK_SHIPPING_CANE", + "quantity" => 1 + ], + [ + "shippable_item_type" => "SPINE_SAMPLE_HOLDER", + "quantity" => (int) $dewar['NUM_SAMPLES'] + ] + ] + ] + ] + ); + try { + $response = $this->shipping_service->create_shipment_request($shipment_request_info); + $external_shipping_id = $response['shipmentRequestId']; + $this->db->pq( + "UPDATE dewar SET externalShippingIdFromSynchrotron=:1 WHERE dewarid=:2", + array($external_shipping_id, $dewar['DEWARID']) + ); + return $external_shipping_id; + } catch (Exception $e) { + throw new Exception("Error returned from shipping service: " . $e . "\nShipment data: " . json_encode($shipment_data)); + } + } + return $dewar['EXTERNALSHIPPINGIDFROMSYNCHROTRON']; + } + function _dispatch_dewar_in_shipping_service($dispatch_info, $dewar) { global $facility_company; @@ -1000,6 +1048,8 @@ function _dispatch_dewar() global $dispatch_email_intl; global $use_shipping_service; global $shipping_service_links_in_emails; + global $use_shipping_service_redirect; + global $shipping_service_app_url; // Variable to store where the dewar is (Synchrotron or eBIC building) // Could map this to dewar storage locations in ISPyB to make more generic...? $dispatch_from_location = 'Synchrotron'; @@ -1014,10 +1064,12 @@ function _dispatch_dewar() } $dew = $this->db->pq( - "SELECT d.dewarid, d.barcode, d.storagelocation, d.dewarstatus, s.shippingid, CONCAT(p.proposalcode, p.proposalnumber) as proposal + "SELECT d.dewarid, d.barcode, d.storagelocation, d.dewarstatus, d.externalShippingIdFromSynchrotron, s.shippingid, CONCAT(p.proposalcode, p.proposalnumber) as proposal, count(distinct c.containerId) as num_pucks, count(b.blsampleId) as num_samples FROM dewar d INNER JOIN shipping s ON s.shippingid = d.shippingid INNER JOIN proposal p ON p.proposalid = s.proposalid + INNER JOIN container c on c.dewarid = d.dewarid + LEFT JOIN BLSample b on b.containerId = c.containerId WHERE d.dewarid=:1 and p.proposalid=:2", array($this->arg('DEWARID'), $this->proposalid) ); @@ -1032,7 +1084,7 @@ function _dispatch_dewar() // If no location specified (i.e. deleted), then read from dewar transport history. // If no dewar transport history fall back to dewar location // We still update history based on provided location to record action from user - $dewar_location = $this->has_arg('LOCATION)') ? $this->arg('LOCATION') : ""; + $dewar_location = $this->has_arg('LOCATION') ? $this->arg('LOCATION') : ""; if (empty($dewar_location)) { // What was the last history entry for this dewar? @@ -1080,21 +1132,40 @@ function _dispatch_dewar() if (Utils::getValueOrDefault($use_shipping_service) && in_array($country, $facility_courier_countries)) { if ($terms_accepted) { - try { - $shipment_id = $this->_dispatch_dewar_in_shipping_service($data, $dew); + if (Utils::getValueOrDefault($use_shipping_service_redirect)) { + try { + $shipment_id = $this->_dispatch_dewar_shipment_request($dew); + } catch (Exception $e) { + $this->_error($e); + } + if (Utils::getValueOrDefault($shipping_service_links_in_emails)) { + $data['AWBURL'] = "{$shipping_service_app_url}/shipment_requests/{$shipment_id}/outgoing"; + } + } else { + try { + $shipment_id = $this->_dispatch_dewar_in_shipping_service($data, $dew); + } catch (Exception $e) { + error_log($e); + $data['AWBURL'] = ""; + } if (Utils::getValueOrDefault($shipping_service_links_in_emails)) { $data['AWBURL'] = $this->shipping_service->get_awb_pdf_url($shipment_id); } - } catch (Exception $e) { - error_log($e); - $data['AWBURL'] = ""; } } } # Prepare e-mail response for dispatch request - $subject_line = '*** Dispatch requested for Dewar ' . $dew['BARCODE'] . ' from ' . $dispatch_from_location . ' - Pickup Date: ' . $this->args['DELIVERYAGENT_SHIPPINGDATE'] . ' ***'; - $email = new Email('dewar-dispatch', $subject_line); + $use_dispatch_lite_template = ( + Utils::getValueOrDefault($use_shipping_service) + && in_array($country, $facility_courier_countries) + && $terms_accepted + && Utils::getValueOrDefault($use_shipping_service_redirect) + ); + $subject_pickup_date = $use_dispatch_lite_template ? '' : ' - Pickup Date: ' . $this->args['DELIVERYAGENT_SHIPPINGDATE']; + $subject_line = '*** Dispatch requested for Dewar ' . $dew['BARCODE'] . ' from ' . $dispatch_from_location . $subject_pickup_date . ' ***'; + $email_template = $use_dispatch_lite_template ? 'dewar-dispatch-lite' : 'dewar-dispatch'; + $email = new Email($email_template, $subject_line); // If a local contact is given, try to find their email address // First try LDAP, if unsuccessful look at the ISPyB person record for a matching staff user @@ -1120,6 +1191,7 @@ function _dispatch_dewar() $data['LOCALCONTACT'] = $local_contact; if (!array_key_exists('LCEMAIL', $data)) $data['LCEMAIL'] = ''; + $data['BARCODE'] = $dew['BARCODE']; $email->data = $data; if ($country != $facility_country && !is_null($dispatch_email_intl)) { @@ -1343,7 +1415,7 @@ function _get_dewars() $order = $cols[$this->arg('sort_by')] . ' ' . $dir; } - $dewars = $this->db->paginate("SELECT CONCAT(p.proposalcode, p.proposalnumber) as prop, CONCAT(p.proposalcode, p.proposalnumber, '-', se.visit_number) as firstexperiment, r.labcontactid, se.beamlineoperator as localcontact, se.beamlinename, TO_CHAR(se.startdate, 'HH24:MI DD-MM-YYYY') as firstexperimentst, d.firstexperimentid, s.shippingid, s.shippingname, d.facilitycode, count(c.containerid) as ccount, (case when se.visit_number > 0 then (CONCAT(p.proposalcode, p.proposalnumber, '-', se.visit_number)) else '' end) as exp, d.code, d.barcode, d.storagelocation, d.dewarstatus, d.dewarid, d.trackingnumbertosynchrotron, d.trackingnumberfromsynchrotron, s.deliveryagent_agentname, d.weight, d.deliveryagent_barcode, GROUP_CONCAT(c.code SEPARATOR ', ') as containers, s.sendinglabcontactid, s.returnlabcontactid, pe.givenname, pe.familyname + $dewars = $this->db->paginate("SELECT CONCAT(p.proposalcode, p.proposalnumber) as prop, CONCAT(p.proposalcode, p.proposalnumber, '-', se.visit_number) as firstexperiment, r.labcontactid, se.beamlineoperator as localcontact, se.beamlinename, TO_CHAR(se.startdate, 'HH24:MI DD-MM-YYYY') as firstexperimentst, d.firstexperimentid, s.shippingid, s.shippingname, d.facilitycode, count(c.containerid) as ccount, (case when se.visit_number > 0 then (CONCAT(p.proposalcode, p.proposalnumber, '-', se.visit_number)) else '' end) as exp, d.code, d.barcode, d.storagelocation, d.dewarstatus, d.dewarid, d.trackingnumbertosynchrotron, d.trackingnumberfromsynchrotron, d.externalShippingIdFromSynchrotron, s.deliveryagent_agentname, d.weight, d.deliveryagent_barcode, GROUP_CONCAT(c.code SEPARATOR ', ') as containers, s.sendinglabcontactid, s.returnlabcontactid, pe.givenname, pe.familyname FROM dewar d LEFT OUTER JOIN container c ON c.dewarid = d.dewarid INNER JOIN shipping s ON d.shippingid = s.shippingid diff --git a/api/src/Shipment/ShippingService.php b/api/src/Shipment/ShippingService.php index 647fba717..a43e90363 100644 --- a/api/src/Shipment/ShippingService.php +++ b/api/src/Shipment/ShippingService.php @@ -151,4 +151,14 @@ function get_awb_pdf_url($shipment_id) { return $this->shipping_app_url . '/shipments/' . $shipment_id . '/awb'; } + + function create_shipment_request($shipment_request_data) + { + return $this->_send_request( + $this->shipping_api_url . '/shipment_requests/', + "POST", + $shipment_request_data, + 201 + ); + } } diff --git a/client/src/js/modules/shipment/models/dispatch.js b/client/src/js/modules/shipment/models/dispatch.js index bd4652cc0..36baa84dc 100644 --- a/client/src/js/modules/shipment/models/dispatch.js +++ b/client/src/js/modules/shipment/models/dispatch.js @@ -16,7 +16,9 @@ define(['backbone'], function(Backbone) { }, VISIT: { - required: true, + required: function() { + return this.visitRequired + }, pattern: 'visit', }, @@ -108,6 +110,7 @@ define(['backbone'], function(Backbone) { courierDetailsRequired: false, // We want to set this default to false unless 'DELIVERYAGENT_AGENTCODE' has a value in the shipment model postCodeRequired: false, + visitRequired: true, }) }) diff --git a/client/src/js/modules/shipment/views/dispatch.js b/client/src/js/modules/shipment/views/dispatch.js index cf74fb433..c8304ce5f 100644 --- a/client/src/js/modules/shipment/views/dispatch.js +++ b/client/src/js/modules/shipment/views/dispatch.js @@ -84,6 +84,7 @@ define(['marionette', 'views/form', accountNumber: 'input[NAME=DELIVERYAGENT_AGENTCODE]', courier: 'input[name=DELIVERYAGENT_AGENTNAME]', courierDetails: '.courierDetails', + dispatchDetails: '.dispatchDetails', facilityCourier: '.facilityCourier', awbNumber: 'input[name=AWBNUMBER]', useAnotherCourierAccount: 'input[name=USE_ANOTHER_COURIER_ACCOUNT]', @@ -112,6 +113,14 @@ define(['marionette', 'views/form', success: function() { app.trigger('shipment:show', this.getOption('dewar').get('SHIPPINGID')) + if (app.options.get("shipping_service_app_url") && (this.terms.get('ACCEPTED') == 1)) { // terms.ACCPETED could be undefined, 1, or "1" + this.getOption('dewar').fetch().done((dewar) => { + const external_id = dewar.EXTERNALSHIPPINGIDFROMSYNCHROTRON; + window.location.assign( + `https://${app.options.get("shipping_service_app_url")}/shipment-requests/${external_id}/outgoing` + ) + }) + } }, failure: function() { @@ -120,6 +129,7 @@ define(['marionette', 'views/form', onRender: function() { this.date('input[name=DELIVERYAGENT_SHIPPINGDATE]') + this.$el.hide() var d = new Date() var today = (d.getDate() < 10 ? '0'+d.getDate() : d.getDate()) + '-' + (d.getMonth() < 9 ? '0'+(d.getMonth()+1) : d.getMonth()+1) + '-' + d.getFullYear() @@ -150,6 +160,8 @@ define(['marionette', 'views/form', this.populateCountries() this.stripPostCode() this.formatAddress() + this.$el.show() + this.getOption('dewar').fetch().done((foo)=>{console.log(foo);}) }, populateCountries: function() { @@ -266,6 +278,10 @@ define(['marionette', 'views/form', this.ui.courierDetails.hide() this.ui.facilityCourier.show() this.model.courierDetailsRequired = false + if (app.options.get("shipping_service_app_url")){ + this.model.visitRequired = false + this.ui.dispatchDetails.hide() + } }, checkPostCodeRequired: function() { diff --git a/client/src/js/templates/shipment/dispatch.html b/client/src/js/templates/shipment/dispatch.html index b21cc8eec..d5dc8291a 100644 --- a/client/src/js/templates/shipment/dispatch.html +++ b/client/src/js/templates/shipment/dispatch.html @@ -23,6 +23,56 @@

Request Dewar Dispatch

<%-DEWAR.FACILITYCODE%> <% } %> + + +
  • + Courier Details + + Use Facility Account +
  • + + <% if (SHIPPING.TERMSACCEPTED == 0) { %> + +
  • + + +
  • + +
  • + + +
  • + + <% if (SHIPPING.DELIVERYAGENT_AGENTNAME && SHIPPING.DELIVERYAGENT_AGENTCODE) { %> +
  • + + +
  • + <% } %> + +
  • + + +
  • + + <% } %> + +
  • + + This dewar will be returned using the facility's courier account +
  • + + + - + - From d73eaad15afa6407fb3d56390adb788f08e5c6db Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Fri, 17 Nov 2023 10:41:49 +0000 Subject: [PATCH 02/14] LIMS-1113: Fix typos in shipping service URLs --- api/src/Page/Shipment.php | 2 +- client/src/js/modules/shipment/views/dispatch.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/api/src/Page/Shipment.php b/api/src/Page/Shipment.php index c56c59043..bc6b543a2 100644 --- a/api/src/Page/Shipment.php +++ b/api/src/Page/Shipment.php @@ -1139,7 +1139,7 @@ function _dispatch_dewar() $this->_error($e); } if (Utils::getValueOrDefault($shipping_service_links_in_emails)) { - $data['AWBURL'] = "{$shipping_service_app_url}/shipment_requests/{$shipment_id}/outgoing"; + $data['AWBURL'] = "{$shipping_service_app_url}/shipment-requests/{$shipment_id}/outgoing"; } } else { try { diff --git a/client/src/js/modules/shipment/views/dispatch.js b/client/src/js/modules/shipment/views/dispatch.js index c8304ce5f..95283f19a 100644 --- a/client/src/js/modules/shipment/views/dispatch.js +++ b/client/src/js/modules/shipment/views/dispatch.js @@ -117,7 +117,7 @@ define(['marionette', 'views/form', this.getOption('dewar').fetch().done((dewar) => { const external_id = dewar.EXTERNALSHIPPINGIDFROMSYNCHROTRON; window.location.assign( - `https://${app.options.get("shipping_service_app_url")}/shipment-requests/${external_id}/outgoing` + `${app.options.get("shipping_service_app_url")}/shipment-requests/${external_id}/outgoing` ) }) } From 1a0061f06b12ccdf1977a79bfe10409086a86415 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Mon, 20 Nov 2023 11:49:09 +0000 Subject: [PATCH 03/14] LIMS-1113: Change text on submit button if redirecting --- client/src/js/modules/shipment/views/dispatch.js | 4 +++- client/src/js/templates/shipment/dispatch.html | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/client/src/js/modules/shipment/views/dispatch.js b/client/src/js/modules/shipment/views/dispatch.js index 95283f19a..d2d1a7dd7 100644 --- a/client/src/js/modules/shipment/views/dispatch.js +++ b/client/src/js/modules/shipment/views/dispatch.js @@ -80,6 +80,8 @@ define(['marionette', 'views/form', ph: 'input[name=PHONENUMBER]', lab: 'input[name=LABNAME]', + submit: 'button[name=submit]', + facc: 'a.facc', accountNumber: 'input[NAME=DELIVERYAGENT_AGENTCODE]', courier: 'input[name=DELIVERYAGENT_AGENTNAME]', @@ -161,7 +163,6 @@ define(['marionette', 'views/form', this.stripPostCode() this.formatAddress() this.$el.show() - this.getOption('dewar').fetch().done((foo)=>{console.log(foo);}) }, populateCountries: function() { @@ -281,6 +282,7 @@ define(['marionette', 'views/form', if (app.options.get("shipping_service_app_url")){ this.model.visitRequired = false this.ui.dispatchDetails.hide() + this.ui.submit.text("Proceed") } }, diff --git a/client/src/js/templates/shipment/dispatch.html b/client/src/js/templates/shipment/dispatch.html index d5dc8291a..3765dbe56 100644 --- a/client/src/js/templates/shipment/dispatch.html +++ b/client/src/js/templates/shipment/dispatch.html @@ -185,7 +185,7 @@

    Request Dewar Dispatch

    - + From 13b2cb8110bd46d4694bb6b044363a134de12873 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Mon, 20 Nov 2023 16:39:36 +0000 Subject: [PATCH 04/14] LIMS-1113: Fix shipment request requests for Dewars with no pucks/samples --- api/src/Page/Shipment.php | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/api/src/Page/Shipment.php b/api/src/Page/Shipment.php index bc6b543a2..77517101f 100644 --- a/api/src/Page/Shipment.php +++ b/api/src/Page/Shipment.php @@ -941,22 +941,32 @@ function _dispatch_dewar_shipment_request($dewar) "shippable_item_type" => "CRYOGENIC_DRY_SHIPPER", "quantity" => 1 ], - [ - "shippable_item_type"=> "UNI_PUCK", - "quantity" => (int) $dewar['NUM_PUCKS'] - ], [ "shippable_item_type" => "SHELVED_UNI_PUCK_SHIPPING_CANE", "quantity" => 1 ], - [ - "shippable_item_type" => "SPINE_SAMPLE_HOLDER", - "quantity" => (int) $dewar['NUM_SAMPLES'] - ] ] ] ] ); + if ((int) $dewar['NUM_PUCKS'] > 0) { + array_push( + $shipment_request_info["packages"][0]["line_items"], + [ + "shippable_item_type"=> "UNI_PUCK", + "quantity" => (int) $dewar['NUM_PUCKS'] + ] + ); + } + if ((int) $dewar['NUM_SAMPLES'] > 0) { + array_push( + $shipment_request_info["packages"][0]["line_items"], + [ + "shippable_item_type"=> "SPINE_SAMPLE_HOLDER", + "quantity" => (int) $dewar['NUM_SAMPLES'] + ] + ); + } try { $response = $this->shipping_service->create_shipment_request($shipment_request_info); $external_shipping_id = $response['shipmentRequestId']; @@ -1068,7 +1078,7 @@ function _dispatch_dewar() FROM dewar d INNER JOIN shipping s ON s.shippingid = d.shippingid INNER JOIN proposal p ON p.proposalid = s.proposalid - INNER JOIN container c on c.dewarid = d.dewarid + LEFT JOIN container c on c.dewarid = d.dewarid LEFT JOIN BLSample b on b.containerId = c.containerId WHERE d.dewarid=:1 and p.proposalid=:2", array($this->arg('DEWARID'), $this->proposalid) From 2ba736c74649b97b760b2d74c1eb6d4554f5b485 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Tue, 21 Nov 2023 10:44:11 +0000 Subject: [PATCH 05/14] LIMS-1113: Don't redirect for international shipments --- client/src/js/modules/shipment/views/dispatch.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/src/js/modules/shipment/views/dispatch.js b/client/src/js/modules/shipment/views/dispatch.js index d2d1a7dd7..0e4c23760 100644 --- a/client/src/js/modules/shipment/views/dispatch.js +++ b/client/src/js/modules/shipment/views/dispatch.js @@ -279,7 +279,10 @@ define(['marionette', 'views/form', this.ui.courierDetails.hide() this.ui.facilityCourier.show() this.model.courierDetailsRequired = false - if (app.options.get("shipping_service_app_url")){ + if ( + app.options.get("shipping_service_app_url") + && app.options.get("facility_courier_countries").includes(this.ui.country.val()) + ){ this.model.visitRequired = false this.ui.dispatchDetails.hide() this.ui.submit.text("Proceed") From f1ed639874063fe0675018277dd848cfc258f029 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Tue, 21 Nov 2023 11:30:08 +0000 Subject: [PATCH 06/14] LIMS-1113: Tweak logic for international shipments --- client/src/js/modules/shipment/views/dispatch.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/js/modules/shipment/views/dispatch.js b/client/src/js/modules/shipment/views/dispatch.js index 0e4c23760..3b3c18546 100644 --- a/client/src/js/modules/shipment/views/dispatch.js +++ b/client/src/js/modules/shipment/views/dispatch.js @@ -281,7 +281,7 @@ define(['marionette', 'views/form', this.model.courierDetailsRequired = false if ( app.options.get("shipping_service_app_url") - && app.options.get("facility_courier_countries").includes(this.ui.country.val()) + && app.options.get("facility_courier_countries").includes(this.labContactCountry) ){ this.model.visitRequired = false this.ui.dispatchDetails.hide() From 3b7d8c0badf876f802d790e40816615fd3076794 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Wed, 22 Nov 2023 15:44:00 +0000 Subject: [PATCH 07/14] LIMS-1113: Propagate shipping service error codes to client --- api/src/Page/Shipment.php | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/api/src/Page/Shipment.php b/api/src/Page/Shipment.php index 77517101f..0ca8d5fdb 100644 --- a/api/src/Page/Shipment.php +++ b/api/src/Page/Shipment.php @@ -967,17 +967,13 @@ function _dispatch_dewar_shipment_request($dewar) ] ); } - try { - $response = $this->shipping_service->create_shipment_request($shipment_request_info); - $external_shipping_id = $response['shipmentRequestId']; - $this->db->pq( - "UPDATE dewar SET externalShippingIdFromSynchrotron=:1 WHERE dewarid=:2", - array($external_shipping_id, $dewar['DEWARID']) - ); - return $external_shipping_id; - } catch (Exception $e) { - throw new Exception("Error returned from shipping service: " . $e . "\nShipment data: " . json_encode($shipment_data)); - } + $response = $this->shipping_service->create_shipment_request($shipment_request_info); + $external_shipping_id = $response['shipmentRequestId']; + $this->db->pq( + "UPDATE dewar SET externalShippingIdFromSynchrotron=:1 WHERE dewarid=:2", + array($external_shipping_id, $dewar['DEWARID']) + ); + return $external_shipping_id; } return $dewar['EXTERNALSHIPPINGIDFROMSYNCHROTRON']; } @@ -1146,7 +1142,9 @@ function _dispatch_dewar() try { $shipment_id = $this->_dispatch_dewar_shipment_request($dew); } catch (Exception $e) { - $this->_error($e); + error_log("Error returned from shipping service: " . $e . "\nShipment data: " . json_encode($shipment_data)); + $error_response = json_decode($e->getMessage()); + $this->_error($error_response->content->detail, $error_response->status); } if (Utils::getValueOrDefault($shipping_service_links_in_emails)) { $data['AWBURL'] = "{$shipping_service_app_url}/shipment-requests/{$shipment_id}/outgoing"; @@ -1180,12 +1178,12 @@ function _dispatch_dewar() // If a local contact is given, try to find their email address // First try LDAP, if unsuccessful look at the ISPyB person record for a matching staff user $local_contact = $this->has_arg('LOCALCONTACT') ? $this->args['LOCALCONTACT'] : ''; - if ($local_contact) { - $this->args['LCEMAIL'] = $this->_get_email_fn($local_contact); - if (!$this->args['LCEMAIL']) { - $this->args['LCEMAIL'] = $this->_get_ispyb_email_fn($local_contact); - } - } + // if ($local_contact) { + // $this->args['LCEMAIL'] = $this->_get_email_fn($local_contact); + // if (!$this->args['LCEMAIL']) { + // $this->args['LCEMAIL'] = $this->_get_ispyb_email_fn($local_contact); + // } + // } if (!array_key_exists('FACILITYCODE', $data)) $data['FACILITYCODE'] = ''; From 2fbc0cefbf4357bd0fe45a097de340ce6d814c32 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Wed, 22 Nov 2023 16:46:38 +0000 Subject: [PATCH 08/14] LIMS-1113: Link to shipping service from shipping page --- client/src/js/templates/shipment/dewarlistrow.html | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/client/src/js/templates/shipment/dewarlistrow.html b/client/src/js/templates/shipment/dewarlistrow.html index 47f737029..1be50e6e2 100644 --- a/client/src/js/templates/shipment/dewarlistrow.html +++ b/client/src/js/templates/shipment/dewarlistrow.html @@ -15,7 +15,12 @@ Add Container <% if (STORAGELOCATION != 'stores-out') { %> - Dispatch Dewar + <% if (app.options.get("shipping_service_app_url") && EXTERNALSHIPPINGIDFROMSYNCHROTRON) { %> + <% const link = `${app.options.get("shipping_service_app_url")}/shipment-requests/${EXTERNALSHIPPINGIDFROMSYNCHROTRON}/outgoing` %> + Dispatch Dewar + <% } else { %> + Dispatch Dewar + <% } %> Transfer Dewar <% } %> From d1e756b7fa316a37b4dc2174390339eb7264269d Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Thu, 23 Nov 2023 13:17:04 +0000 Subject: [PATCH 09/14] LIMS-1113: Restore commented code --- api/src/Page/Shipment.php | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/api/src/Page/Shipment.php b/api/src/Page/Shipment.php index 0ca8d5fdb..03218dc01 100644 --- a/api/src/Page/Shipment.php +++ b/api/src/Page/Shipment.php @@ -1178,12 +1178,12 @@ function _dispatch_dewar() // If a local contact is given, try to find their email address // First try LDAP, if unsuccessful look at the ISPyB person record for a matching staff user $local_contact = $this->has_arg('LOCALCONTACT') ? $this->args['LOCALCONTACT'] : ''; - // if ($local_contact) { - // $this->args['LCEMAIL'] = $this->_get_email_fn($local_contact); - // if (!$this->args['LCEMAIL']) { - // $this->args['LCEMAIL'] = $this->_get_ispyb_email_fn($local_contact); - // } - // } + if ($local_contact) { + $this->args['LCEMAIL'] = $this->_get_email_fn($local_contact); + if (!$this->args['LCEMAIL']) { + $this->args['LCEMAIL'] = $this->_get_ispyb_email_fn($local_contact); + } + } if (!array_key_exists('FACILITYCODE', $data)) $data['FACILITYCODE'] = ''; From b7e0713b017bc2fe19ce34da75c02ec8fe2c047b Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Tue, 28 Nov 2023 15:13:54 +0000 Subject: [PATCH 10/14] LIMS-1113: Include Dewar data in dispatch error log --- api/src/Page/Shipment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/src/Page/Shipment.php b/api/src/Page/Shipment.php index 03218dc01..ad4c51008 100644 --- a/api/src/Page/Shipment.php +++ b/api/src/Page/Shipment.php @@ -1142,7 +1142,7 @@ function _dispatch_dewar() try { $shipment_id = $this->_dispatch_dewar_shipment_request($dew); } catch (Exception $e) { - error_log("Error returned from shipping service: " . $e . "\nShipment data: " . json_encode($shipment_data)); + error_log("Error returned from shipping service: " . $e . "\nDewar data: " . json_encode($dew)); $error_response = json_decode($e->getMessage()); $this->_error($error_response->content->detail, $error_response->status); } From f02855db3c0334427118d06d73b0ba1e4f689a85 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Mon, 4 Dec 2023 15:50:51 +0000 Subject: [PATCH 11/14] LIMS-1113: Apply GdF suggestions --- api/src/Page/Shipment.php | 90 +++++++++---------- .../src/js/modules/shipment/views/dispatch.js | 2 +- 2 files changed, 46 insertions(+), 46 deletions(-) diff --git a/api/src/Page/Shipment.php b/api/src/Page/Shipment.php index b30545139..459e4bdc6 100644 --- a/api/src/Page/Shipment.php +++ b/api/src/Page/Shipment.php @@ -926,56 +926,56 @@ function _transfer_dewar() function _dispatch_dewar_shipment_request($dewar) { - if (is_null($dewar['EXTERNALSHIPPINGIDFROMSYNCHROTRON'])) { - $server_port = ($_SERVER['SERVER_PORT']==='443') ? '' : ":{$_SERVER['SERVER_PORT']}"; - $shipment_request_info = array( - "proposal" => $dewar['PROPOSAL'], - "external_id" => (int) $dewar['DEWARID'], - "origin_url" => "https://{$_SERVER['SERVER_NAME']}{$server_port}/shipments/sid/{$dewar['SHIPPINGID']}", - "packages" => [ - [ - "external_id" => (int) $dewar['DEWARID'], - "shippable_item_type" => "CRYOGENIC_DRY_SHIPPER_CASE", - "line_items" => [ - [ - "shippable_item_type" => "CRYOGENIC_DRY_SHIPPER", - "quantity" => 1 - ], - [ - "shippable_item_type" => "SHELVED_UNI_PUCK_SHIPPING_CANE", - "quantity" => 1 - ], - ] + if (!is_null($dewar['EXTERNALSHIPPINGIDFROMSYNCHROTRON'])) { + return $dewar['EXTERNALSHIPPINGIDFROMSYNCHROTRON']; + } + $server_port = ($_SERVER['SERVER_PORT']==='443') ? '' : ":{$_SERVER['SERVER_PORT']}"; + $shipment_request_info = array( + "proposal" => $dewar['PROPOSAL'], + "external_id" => (int) $dewar['DEWARID'], + "origin_url" => "https://{$_SERVER['SERVER_NAME']}{$server_port}/shipments/sid/{$dewar['SHIPPINGID']}", + "packages" => [ + [ + "external_id" => (int) $dewar['DEWARID'], + "shippable_item_type" => "CRYOGENIC_DRY_SHIPPER_CASE", + "line_items" => [ + [ + "shippable_item_type" => "CRYOGENIC_DRY_SHIPPER", + "quantity" => 1 + ], + [ + "shippable_item_type" => "SHELVED_UNI_PUCK_SHIPPING_CANE", + "quantity" => 1 + ], ] ] + ] + ); + if ((int) $dewar['NUM_PUCKS'] > 0) { + array_push( + $shipment_request_info["packages"][0]["line_items"], + [ + "shippable_item_type"=> "UNI_PUCK", + "quantity" => (int) $dewar['NUM_PUCKS'] + ] ); - if ((int) $dewar['NUM_PUCKS'] > 0) { - array_push( - $shipment_request_info["packages"][0]["line_items"], - [ - "shippable_item_type"=> "UNI_PUCK", - "quantity" => (int) $dewar['NUM_PUCKS'] - ] - ); - } - if ((int) $dewar['NUM_SAMPLES'] > 0) { - array_push( - $shipment_request_info["packages"][0]["line_items"], - [ - "shippable_item_type"=> "SPINE_SAMPLE_HOLDER", - "quantity" => (int) $dewar['NUM_SAMPLES'] - ] - ); - } - $response = $this->shipping_service->create_shipment_request($shipment_request_info); - $external_shipping_id = $response['shipmentRequestId']; - $this->db->pq( - "UPDATE dewar SET externalShippingIdFromSynchrotron=:1 WHERE dewarid=:2", - array($external_shipping_id, $dewar['DEWARID']) + } + if ((int) $dewar['NUM_SAMPLES'] > 0) { + array_push( + $shipment_request_info["packages"][0]["line_items"], + [ + "shippable_item_type"=> "SPINE_SAMPLE_HOLDER", + "quantity" => (int) $dewar['NUM_SAMPLES'] + ] ); - return $external_shipping_id; } - return $dewar['EXTERNALSHIPPINGIDFROMSYNCHROTRON']; + $response = $this->shipping_service->create_shipment_request($shipment_request_info); + $external_shipping_id = $response['shipmentRequestId']; + $this->db->pq( + "UPDATE dewar SET externalShippingIdFromSynchrotron=:1 WHERE dewarid=:2", + array($external_shipping_id, $dewar['DEWARID']) + ); + return $external_shipping_id; } function _dispatch_dewar_in_shipping_service($dispatch_info, $dewar) diff --git a/client/src/js/modules/shipment/views/dispatch.js b/client/src/js/modules/shipment/views/dispatch.js index 3b3c18546..c6ef56dbf 100644 --- a/client/src/js/modules/shipment/views/dispatch.js +++ b/client/src/js/modules/shipment/views/dispatch.js @@ -115,7 +115,7 @@ define(['marionette', 'views/form', success: function() { app.trigger('shipment:show', this.getOption('dewar').get('SHIPPINGID')) - if (app.options.get("shipping_service_app_url") && (this.terms.get('ACCEPTED') == 1)) { // terms.ACCPETED could be undefined, 1, or "1" + if (app.options.get("shipping_service_app_url") && (Number(this.terms.get('ACCEPTED')) === 1)) { // terms.ACCPETED could be undefined, 1, or "1" this.getOption('dewar').fetch().done((dewar) => { const external_id = dewar.EXTERNALSHIPPINGIDFROMSYNCHROTRON; window.location.assign( From 88e293f7805d024b5e5ea1666ad9ad743356964d Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Thu, 7 Dec 2023 10:50:33 +0000 Subject: [PATCH 12/14] LIMS-1113: Update config_sample.php --- api/config_sample.php | 1 + 1 file changed, 1 insertion(+) diff --git a/api/config_sample.php b/api/config_sample.php index 1267f8fe3..69bf049d7 100644 --- a/api/config_sample.php +++ b/api/config_sample.php @@ -264,6 +264,7 @@ # Shipping service details $use_shipping_service = null; $use_shipping_service_incoming_shipments = null; + $use_shipping_service_redirect = null; $shipping_service_api_url = null; $shipping_service_api_user = null; $shipping_service_api_password = null; From e1fd023b2da0b617a99c122136a16c9489ba2161 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Mon, 11 Dec 2023 11:14:49 +0000 Subject: [PATCH 13/14] LIMS-1113: Limit redirects to supported countries --- client/src/js/modules/shipment/views/dispatch.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/client/src/js/modules/shipment/views/dispatch.js b/client/src/js/modules/shipment/views/dispatch.js index c6ef56dbf..d235505bc 100644 --- a/client/src/js/modules/shipment/views/dispatch.js +++ b/client/src/js/modules/shipment/views/dispatch.js @@ -115,7 +115,11 @@ define(['marionette', 'views/form', success: function() { app.trigger('shipment:show', this.getOption('dewar').get('SHIPPINGID')) - if (app.options.get("shipping_service_app_url") && (Number(this.terms.get('ACCEPTED')) === 1)) { // terms.ACCPETED could be undefined, 1, or "1" + if ( + app.options.get("shipping_service_app_url") + && (Number(this.terms.get('ACCEPTED')) === 1) // terms.ACCPETED could be undefined, 1, or "1" + && app.options.get("facility_courier_countries").includes(this.labContactCountry) + ) { this.getOption('dewar').fetch().done((dewar) => { const external_id = dewar.EXTERNALSHIPPINGIDFROMSYNCHROTRON; window.location.assign( From 40f737b5026fe1d605419ce1956313c293e56887 Mon Sep 17 00:00:00 2001 From: Matthew Pritchard Date: Fri, 26 Jan 2024 15:06:19 +0000 Subject: [PATCH 14/14] LIMS-1113: Add supported country dropdown to dispatch from --- .../src/js/modules/shipment/views/dispatch.js | 45 +++++++++++++++++-- .../src/js/templates/shipment/dispatch.html | 18 +++++--- 2 files changed, 54 insertions(+), 9 deletions(-) diff --git a/client/src/js/modules/shipment/views/dispatch.js b/client/src/js/modules/shipment/views/dispatch.js index d235505bc..977a5f746 100644 --- a/client/src/js/modules/shipment/views/dispatch.js +++ b/client/src/js/modules/shipment/views/dispatch.js @@ -60,7 +60,8 @@ define(['marionette', 'views/form', 'click @ui.facc': 'showTerms', 'blur @ui.postCode': 'stripPostCode', 'blur @ui.addr': 'formatAddress', - 'change @ui.country': 'checkPostCodeRequired' + 'change @ui.country': 'checkPostCodeRequired', + 'change @ui.dispatchCountry': 'showDispatchForm' }, ui: { @@ -90,10 +91,14 @@ define(['marionette', 'views/form', facilityCourier: '.facilityCourier', awbNumber: 'input[name=AWBNUMBER]', useAnotherCourierAccount: 'input[name=USE_ANOTHER_COURIER_ACCOUNT]', - dispatchState: '.dispatch-state' + dispatchState: '.dispatch-state', + + dispatchCountry: 'select[name=DISPATCHCOUNTRY]', + courierSection: '.courierSection' }, labContactCountry : null, + dispatchCountry: null, templateHelpers: function() { return { @@ -118,7 +123,7 @@ define(['marionette', 'views/form', if ( app.options.get("shipping_service_app_url") && (Number(this.terms.get('ACCEPTED')) === 1) // terms.ACCPETED could be undefined, 1, or "1" - && app.options.get("facility_courier_countries").includes(this.labContactCountry) + && app.options.get("facility_courier_countries").includes(this.dispatchCountry) ) { this.getOption('dewar').fetch().done((dewar) => { const external_id = dewar.EXTERNALSHIPPINGIDFROMSYNCHROTRON; @@ -163,10 +168,20 @@ define(['marionette', 'views/form', doOnRender: function() { this.ui.exp.html(this.visits.opts()).val(this.model.get('VISIT')) this.updateLC() + this.populateDispatchCountries() this.populateCountries() this.stripPostCode() this.formatAddress() this.$el.show() + this.hideDispatchForm(); + }, + + populateDispatchCountries: function () { + const dispatchCountryOptions = [...app.options.get("facility_courier_countries"), 'Other'] + .map((country) => ``) + .join(""); + this.ui.dispatchCountry.html(dispatchCountryOptions); + this.ui.dispatchCountry.val(''); }, populateCountries: function() { @@ -257,6 +272,28 @@ define(['marionette', 'views/form', } }, + hideDispatchForm: function () { + this.ui.courierSection.hide(); + this.ui.dispatchDetails.hide(); + this.ui.submit.hide(); + }, + + showDispatchForm: function() { + this.dispatchCountry = this.ui.dispatchCountry.val() + this.ui.courierSection.show(); + this.ui.dispatchDetails.show(); + this.ui.submit.show(); + if ( + this.terms.get("ACCEPTED") + && app.options.get("shipping_service_app_url") + && app.options.get("facility_courier_countries").includes(this.dispatchCountry) + ){ + this.model.visitRequired = false + this.ui.dispatchDetails.hide() + this.ui.submit.text("Proceed") + } + }, + showTerms: function() { var terms = new TCDialog({ model: this.terms }) this.listenTo(terms, 'terms:accepted', this.termsAccepted, this) @@ -285,7 +322,7 @@ define(['marionette', 'views/form', this.model.courierDetailsRequired = false if ( app.options.get("shipping_service_app_url") - && app.options.get("facility_courier_countries").includes(this.labContactCountry) + && app.options.get("facility_courier_countries").includes(this.ui.dispatchCountry.val()) ){ this.model.visitRequired = false this.ui.dispatchDetails.hide() diff --git a/client/src/js/templates/shipment/dispatch.html b/client/src/js/templates/shipment/dispatch.html index 3765dbe56..d8e4cd634 100644 --- a/client/src/js/templates/shipment/dispatch.html +++ b/client/src/js/templates/shipment/dispatch.html @@ -24,6 +24,19 @@

    Request Dewar Dispatch

    <% } %> +
  • + + +
  • +
  • + + +
  • + + +
    • Courier Details @@ -119,11 +132,6 @@

      Request Dewar Dispatch

    • -
    • - - -
    • -