diff --git a/api/config_sample.php b/api/config_sample.php index e89e01bec..7bcbfb406 100644 --- a/api/config_sample.php +++ b/api/config_sample.php @@ -266,6 +266,7 @@ $use_shipping_service = null; $use_shipping_service_nde = False; $use_shipping_service_incoming_shipments = null; + $use_shipping_service_incoming_shipments_nde = False; $use_shipping_service_redirect = null; $use_shipping_service_redirect_incoming_shipments = null; $shipping_service_api_user = null; diff --git a/api/index.php b/api/index.php index f4116e816..96e785b5c 100644 --- a/api/index.php +++ b/api/index.php @@ -72,7 +72,7 @@ function setupApplication($mode): Slim $visit_persist_storage_dir_segment, $dhl_enable, $scale_grid, $scale_grid_end_date, $preset_proposal, $timezone, $valid_components, $enabled_container_types, $synchweb_version, $redirects, $shipping_service_app_url, $use_shipping_service_redirect, $use_shipping_service_redirect_incoming_shipments, - $use_shipping_service_nde, + $use_shipping_service_nde, $use_shipping_service_incoming_shipments_nde, $dials_rest_url_rings, $closed_proposal_link, $ccp4_cloud_upload_url, $only_staff_can_assign, $industrial_prop_codes, $upstream_reprocessing_pipelines, $downstream_reprocessing_pipelines, $prop_codes_data_deleted, $container_types_with_parents, $bl_capacity; @@ -103,6 +103,7 @@ function setupApplication($mode): Slim 'shipping_service_app_url' => $use_shipping_service_redirect ? $shipping_service_app_url : null, 'shipping_service_app_url_incoming' => $use_shipping_service_redirect_incoming_shipments ? $shipping_service_app_url : null, 'use_shipping_service_nde' => $use_shipping_service_nde, + 'use_shipping_service_incoming_shipments_nde' => $use_shipping_service_incoming_shipments_nde, 'dials_rest_url_rings' => $dials_rest_url_rings, 'closed_proposal_link' => $closed_proposal_link, 'ccp4_cloud_upload_url' => $ccp4_cloud_upload_url, diff --git a/api/src/Page/Shipment.php b/api/src/Page/Shipment.php index 63141cef8..00d42d596 100644 --- a/api/src/Page/Shipment.php +++ b/api/src/Page/Shipment.php @@ -1098,19 +1098,23 @@ function _dispatch_dewar_shipment_request($dewar) return $dewar['EXTERNALSHIPPINGIDFROMSYNCHROTRON']; } - $dewars = [$dewar]; - $proposal = $dewar['PROPOSAL']; - $session_number = $dewar['VIS']; - $external_id = (int) $dewar['DEWARID']; - $shipping_id = (int) $dewar['SHIPPINGID']; - $token = Utils::generateRandomMd5(); - $this->db->pq( - "UPDATE dewar SET extra = JSON_SET(IFNULL(extra, '{}'), '$.token', :1 ) WHERE dewarid=:2", - array($token, $external_id) - ); + if (!is_null($dewar['EXTERNALSHIPPINGIDTOSYNCHROTRON']) && !is_null($dewar['TOKEN']) && $dewar['DCOUNT'] == 1) { + $external_shipping_id = $dewar['EXTERNALSHIPPINGIDTOSYNCHROTRON']; + } else { + $dewars = [$dewar]; + $proposal = $dewar['PROPOSAL']; + $session_number = $dewar['VIS']; + $external_id = (int) $dewar['DEWARID']; + $shipping_id = (int) $dewar['SHIPPINGID']; + $token = Utils::generateRandomMd5(); + $this->db->pq( + "UPDATE dewar SET extra = JSON_SET(IFNULL(extra, '{}'), '$.token', :1 ) WHERE dewarid=:2", + array($token, $external_id) + ); - $callback_url = "/api/shipment/dewars/confirmdispatch/did/{$external_id}/token/{$token}"; - $external_shipping_id = $this->_create_dewars_shipment_request($dewars, $proposal, $session_number, $external_id, $shipping_id, $callback_url); + $callback_url = "/api/shipment/dewars/confirmdispatch/did/{$external_id}/token/{$token}"; + $external_shipping_id = $this->_create_dewars_shipment_request($dewars, $proposal, $session_number, $external_id, $shipping_id, $callback_url); + } $this->db->pq( "UPDATE dewar SET externalShippingIdFromSynchrotron=:1 WHERE dewarid=:2", @@ -1214,7 +1218,9 @@ function _dispatch_dewar() $dew = $this->db->pq( "SELECT d.dewarid, d.barcode, d.storagelocation, d.dewarstatus, d.externalShippingIdFromSynchrotron, + s.externalshippingidtosynchrotron, json_unquote(json_extract(d.extra, '$.token')) as token, s.shippingid, p.proposalcode, CONCAT(p.proposalcode, p.proposalnumber) as proposal, + (SELECT COUNT(*) FROM dewar d2 WHERE d2.shippingid = s.shippingid) as dcount, count(distinct c.containerId) as num_pucks, count(b.blsampleId) as num_samples, ifnull(bls.visit_number, 0) as vis, IF(d.facilitycode, d.facilitycode, d.code) as name, dr.manufacturerserialnumber @@ -3544,7 +3550,7 @@ function _create_awb() { global $dhl_service, $dhl_service_eu, $dhl_acc, $dhl_acc_import, $facility_courier_countries, $facility_courier_countries_nde, $use_shipping_service_incoming_shipments, - $use_shipping_service_redirect_incoming_shipments; + $use_shipping_service_incoming_shipments_nde, $use_shipping_service_redirect_incoming_shipments; if (!$this->has_arg('prop')) $this->_error('No proposal specified'); if (!$this->has_arg('sid')) @@ -3591,8 +3597,10 @@ function _create_awb() } if ( - Utils::getValueOrDefault($use_shipping_service_incoming_shipments) - && in_array($this->arg('COUNTRY'), $facility_courier_countries) + ((Utils::getValueOrDefault($use_shipping_service_incoming_shipments) + && in_array($this->arg('COUNTRY'), $facility_courier_countries)) + || (Utils::getValueOrDefault($use_shipping_service_incoming_shipments_nde) + && in_array($this->arg('COUNTRY'), $facility_courier_countries_nde))) && Utils::getValueOrDefault($use_shipping_service_redirect_incoming_shipments) ) { if ($ship['EXTERNALSHIPPINGIDTOSYNCHROTRON']) { diff --git a/client/src/js/modules/shipment/views/createawb.js b/client/src/js/modules/shipment/views/createawb.js index 9d5373bb9..9f11ba4a9 100644 --- a/client/src/js/modules/shipment/views/createawb.js +++ b/client/src/js/modules/shipment/views/createawb.js @@ -520,7 +520,8 @@ define(['backbone', if ( ss_url && (Number(self.terms.get('ACCEPTED')) === 1) // terms.ACCEPTED could be undefined, 1, or "1" - && app.options.get("facility_courier_countries").includes(country) + && (app.options.get("facility_courier_countries").includes(country) || + app.options.get("facility_courier_countries_nde").includes(country)) ) { self.shipment.fetch().done((shipment) => { const external_id = shipment.EXTERNALSHIPPINGIDTOSYNCHROTRON; diff --git a/client/src/js/modules/shipment/views/shipment.js b/client/src/js/modules/shipment/views/shipment.js index 394e03907..2f4ba05be 100644 --- a/client/src/js/modules/shipment/views/shipment.js +++ b/client/src/js/modules/shipment/views/shipment.js @@ -225,7 +225,12 @@ define(['marionette', const sendingId = this.model.get('SENDINGLABCONTACTID') if (!sendingId || !this.contacts || !this.contacts.length) return const contact = this.contacts.findWhere({ LABCONTACTID: sendingId }) - if (contact) this.model.set('COUNTRY', contact.get('COUNTRY')) + if (contact) { + const country = contact.get('COUNTRY') + this.model.set('COUNTRY', country) + const fac_country_nde = app.options.get('facility_courier_countries_nde') + this.nde = country && fac_country_nde.includes(country) + } }, showButtons: function() { @@ -246,6 +251,7 @@ define(['marionette', const safetylevel = this.model.get('SAFETYLEVEL') const externalid = this.model.get('EXTERNALSHIPPINGIDTOSYNCHROTRON') const shippingid = this.model.get('SHIPPINGID') + const dcount = this.model.get('DCOUNT') if (!courier || (app.options.get('dhl_enable') && courier.toLowerCase().trim() == 'dhl')) { if (label == '1') { this.ui.booking.html(' Print Air Waybill') @@ -253,11 +259,17 @@ define(['marionette', if (!pickup) { this.ui.booking.append(' Rebook Pickup') } - } else if ((country && !fac_country.includes(country)) || safetylevel == "Red") { - this.ui.booking.html(' Create Air Waybill - Disabled') } else if (externalid && ss_url) { const link = ss_url+'/shipment-requests/'+externalid+'/incoming' this.ui.booking.html(' Manage Shipment Booking') + } else if (safetylevel && safetylevel == "Red") { + this.ui.booking.html(' Create Air Waybill - Disabled') + } else if (this.nde && (this.industrial_visit || dcount > 1 || !this.ss_nde_incoming)) { + this.ui.booking.html(' Create Air Waybill - Disabled') + } else if (this.nde) { + this.ui.booking.html(' Request DHL Air Waybill') + } else if (country && !fac_country.includes(country)) { + this.ui.booking.html(' Create Air Waybill - Disabled') } else { this.ui.booking.html(' Create DHL Air Waybill') } @@ -272,23 +284,26 @@ define(['marionette', const safetylevel = this.model.get('SAFETYLEVEL') const country = this.model.get('COUNTRY') const courier = this.model.get('DELIVERYAGENT_AGENTNAME') - const fac_country_nde = app.options.get('facility_courier_countries_nde') - const fac_country_link = app.options.get('facility_courier_countries_link') const fac_country = app.options.get('facility_courier_countries') const ss_url = app.options.get("shipping_service_app_url_incoming") const externalid = this.model.get('EXTERNALSHIPPINGIDTOSYNCHROTRON') + const dcount = this.model.get('DCOUNT') if (label == '1') { this.ui.dhlmessage.html('

You can print your Air Waybill by clicking "Print Air Waybill" below.

') + } else if (externalid && ss_url) { + this.ui.dhlmessage.html('

You can now manage your shipment with DHL using "Manage Shipment Booking" below.

') } else if (safetylevel && safetylevel == "Red") { this.ui.dhlmessage.html('

Shipping of red samples is not available through this application.

') - } else if (country && fac_country_nde.includes(country) ) { - this.ui.dhlmessage.html('

International shipping is not available through this application. If you're arranging your own shipping (e.g. industrial users), enter your tracking numbers below after booking and include printed return labels in the dewar case. European academic users, please see here.

') + } else if (this.nde && (this.industrial_visit || !this.ss_nde_incoming)) { + this.ui.dhlmessage.html('

International shipping is not available through this application. If you're arranging your own shipping, enter your tracking numbers below after booking and include printed return labels in the dewar case.

') + } else if (this.nde && dcount > 1) { + this.ui.dhlmessage.html('

International shipping is not available where there is more than one dewar in the shipment

') + } else if (this.nde) { + this.ui.dhlmessage.html('

You can now request your shipment with DHL using "Request Air Waybill" below.

') } else if (country && !fac_country.includes(country) ) { this.ui.dhlmessage.html('

International shipping is not available through this application. If you're arranging your own shipping, enter your tracking numbers below after booking and include printed return labels in the dewar case.

') } else if (courier && courier.toLowerCase().trim() != 'dhl') { this.ui.dhlmessage.html('

Shipping through this application is only available using DHL.

') - } else if (externalid && ss_url) { - this.ui.dhlmessage.html('

You can now manage your shipment with DHL using "Manage Shipment Booking" below.

') } else { this.ui.dhlmessage.html('

You can now book your shipment with DHL using "Create Air Waybill" below.

') } @@ -324,7 +339,12 @@ define(['marionette', this.$el.find(".remoteform").show() } } - if (dynamic === 'Ready' || (app.proposal && app.proposal.get('ACTIVE') != '1')) { + + if ( + dynamic === 'Ready' || + (app.proposal && app.proposal.get('ACTIVE') != '1') || + (this.termsaccepted && this.nde && this.ss_nde_incoming) + ) { this.ui.add_dewar.hide() } else { this.ui.add_dewar.show() @@ -393,22 +413,21 @@ define(['marionette', this.edit.create("ONSITEUSERS", 'text', { placeholder: 'No' }); this.edit.create("MULTIAXISGONIOMETRY", 'select', { data: {'Yes': 'Yes', 'No': 'No'}}) - this.updateGUI() + this.termsaccepted = this.model.get('TERMSACCEPTED') == 1 + this.ss_nde_incoming = app.options.get('use_shipping_service_incoming_shipments_nde') + this.listenTo(this.model, "change", this.updateGUI) - - var self = this this.contacts = new LabContacts(null, { state: { pageSize: 9999 } }) - this.contacts.fetch().done(function() { - console.log(self.contacts, self.contacts.kv()) - self.edit.create('SENDINGLABCONTACTID', 'select', { data: self.contacts.kv() }) - self.edit.create('RETURNLABCONTACTID', 'select', { data: self.contacts.kv() }) + this.contacts.fetch().done(() => { + this.edit.create('SENDINGLABCONTACTID', 'select', { data: this.contacts.kv() }) + this.edit.create('RETURNLABCONTACTID', 'select', { data: this.contacts.kv() }) + this.updateGUI() }) const externalid = this.model.get('EXTERNALSHIPPINGIDTOSYNCHROTRON') - const termsaccepted = this.model.get('TERMSACCEPTED') == 1 const ss_url = app.options.get("shipping_service_app_url_incoming") - if (ss_url && (externalid || termsaccepted)) { + if (ss_url && (externalid || this.termsaccepted)) { this.ui.courierfields.hide() } }, diff --git a/client/src/js/modules/shipment/views/shipmentadd.js b/client/src/js/modules/shipment/views/shipmentadd.js index 9c0d36894..2b31396cf 100644 --- a/client/src/js/modules/shipment/views/shipmentadd.js +++ b/client/src/js/modules/shipment/views/shipmentadd.js @@ -130,6 +130,12 @@ define(['marionette', 'views/form', this.model.set({ TERMSACCEPTED: 1 }) this.ui.accountnumber.val('') this.ui.couriername.val('') + const lc = this.contacts.findWhere({ LABCONTACTID: this.ui.lcout.val() }) + const nde = app.options.get('facility_courier_countries_nde').indexOf(lc.get('COUNTRY')) > -1 + const ss_nde_incoming = app.options.get('use_shipping_service_incoming_shipments_nde') + if (nde && ss_nde_incoming) { + this.setMaxDewarsPerShipment() + } }, addLC: function(e) { @@ -326,9 +332,12 @@ define(['marionette', 'views/form', const industrial_visit = industrial_codes.includes(app.prop.slice(0,2)) const lc = this.contacts.findWhere({ LABCONTACTID: this.ui.lcout.val() }) - const countryOk = app.options.get('facility_courier_countries').indexOf(lc.get('COUNTRY')) > -1 || app.options.get('facility_courier_countries_nde').indexOf(lc.get('COUNTRY')) > -1 + const domestic = app.options.get('facility_courier_countries').indexOf(lc.get('COUNTRY')) > -1 + const nde = app.options.get('facility_courier_countries_nde').indexOf(lc.get('COUNTRY')) > -1 + const countryOk = domestic || nde const usingFacilityAccount = this.model.get('TERMSACCEPTED') === 1 + const ss_nde_incoming = app.options.get('use_shipping_service_incoming_shipments_nde') if (countryOk && !industrial_visit && !usingFacilityAccount) { this.ui.facc.show() @@ -341,6 +350,22 @@ define(['marionette', 'views/form', this.ui.accmsg.text('') this.model.set({ TERMSACCEPTED: 0 }) } + + if (nde && ss_nde_incoming && usingFacilityAccount) { + this.setMaxDewarsPerShipment() + } else { + this.ui.dewars.prop('disabled', false) + } + + }, + + setMaxDewarsPerShipment: function() { + if (this.ui.dewars.val() > 1) { + this.ui.dewars.val(1) + this.updateFCodes() + app.alert({ message: 'For international shipping we are limited to 1 dewar per shipment'}) + } + this.ui.dewars.prop('disabled', true) }, diff --git a/client/src/js/templates/shipment/shipmentadd.html b/client/src/js/templates/shipment/shipmentadd.html index e0fac3873..2d8d7f27d 100644 --- a/client/src/js/templates/shipment/shipmentadd.html +++ b/client/src/js/templates/shipment/shipmentadd.html @@ -22,7 +22,7 @@

Add New Shipment

- +