Skip to content

Commit

Permalink
Merge Pre-release/2023-R3.4 into Master (#656)
Browse files Browse the repository at this point in the history
* LIMS_817: Update shipping service requests

* LIMS-817: Add  param to dispatch function

* LIMS-832: Book incoming shipments with the shipping service

* LIMS-832: Fix array string conversion error

* LIMS-832: Label address input with 'max 3 lines'

* Format address & post code in dispatch form

* LIMS-832: Trim post code & email for shipping service

* [LIMS-116] Fix: Summary page revamp, make css local  (#639)

* updating .gitignore

* adding frontend files and building backend

* adding front end files and router files

* create sidebar, filter options added, routes added

* add routing to page,search bar and column selector

* adding pagination continutation

* adding csv, all columns, rest of filters

* added descending and ascending

* sidebar dropdown&changed data structure&hide row

* cleaning up fixing jump bug

* refactored backend mapped data

* added expanding row

* refactored favourites

* refactored orderby filter

* cleaned up code, added comments

* added all params to watcher

* added summary db connection

* add routes to summary

* add backend changes summarypage

* changes to expandable sidebar, cleaning up fronte

* clean up, add functions to get data

* front end changes, group concat backend

* remove summarypage code

* fix pagination, timeout

* delete old summary file

* changed pagination in summary.php

* changed backend to not include tot

* fix refined cell c column

* added ifsets to avoid undefined offset error

* delete offset for output

* change order of operands

* change filters, fix operands

* fix csv button

* changed prop to propid

* format beamlinename

* change al,be,gamma

* add selected columns summary

* additional changes for selected columns

* add multiple selections change expandable sidebar

* redo  routing, keep alive summary

* fixes, change routing, results display, orderby

* fixes to selected columns

* format page to allow for customisation

* area for potential formatting and fix to querypara

* changes to regex, combobox multiple,  and fomat

* column select fix, resize pill fix, format inputs

* Update api/src/Database/DatabaseConnectionFactory.php

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/sp/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/saxs/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/pow/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/mx/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/em/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/app/components/combo-box.vue

Co-authored-by: Guilherme Francisco <[email protected]>

* Update api/src/Database/DatabaseFactory.php

Co-authored-by: John Holt <[email protected]>

* Update api/src/TemplateParser.php

Co-authored-by: Guilherme Francisco <[email protected]>

* Code review changes: database conns, code tidy

* add get started button

* Change styling to be local rather than global

---------

Co-authored-by: Guilherme Francisco <[email protected]>
Co-authored-by: John Holt <[email protected]>

* [LIMS-116] Fix: Summary page revamp, delete css global (#640)

* updating .gitignore

* adding frontend files and building backend

* adding front end files and router files

* create sidebar, filter options added, routes added

* add routing to page,search bar and column selector

* adding pagination continutation

* adding csv, all columns, rest of filters

* added descending and ascending

* sidebar dropdown&changed data structure&hide row

* cleaning up fixing jump bug

* refactored backend mapped data

* added expanding row

* refactored favourites

* refactored orderby filter

* cleaned up code, added comments

* added all params to watcher

* added summary db connection

* add routes to summary

* add backend changes summarypage

* changes to expandable sidebar, cleaning up fronte

* clean up, add functions to get data

* front end changes, group concat backend

* remove summarypage code

* fix pagination, timeout

* delete old summary file

* changed pagination in summary.php

* changed backend to not include tot

* fix refined cell c column

* added ifsets to avoid undefined offset error

* delete offset for output

* change order of operands

* change filters, fix operands

* fix csv button

* changed prop to propid

* format beamlinename

* change al,be,gamma

* add selected columns summary

* additional changes for selected columns

* add multiple selections change expandable sidebar

* redo  routing, keep alive summary

* fixes, change routing, results display, orderby

* fixes to selected columns

* format page to allow for customisation

* area for potential formatting and fix to querypara

* changes to regex, combobox multiple,  and fomat

* column select fix, resize pill fix, format inputs

* Update api/src/Database/DatabaseConnectionFactory.php

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/sp/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/saxs/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/pow/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/mx/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/modules/types/em/menu.js

Co-authored-by: Guilherme Francisco <[email protected]>

* Update client/src/js/app/components/combo-box.vue

Co-authored-by: Guilherme Francisco <[email protected]>

* Update api/src/Database/DatabaseFactory.php

Co-authored-by: John Holt <[email protected]>

* Update api/src/TemplateParser.php

Co-authored-by: Guilherme Francisco <[email protected]>

* Code review changes: database conns, code tidy

* add get started button

* Change styling to be local rather than global

* delete summary css globals

---------

Co-authored-by: Guilherme Francisco <[email protected]>
Co-authored-by: John Holt <[email protected]>

* Update api/src/Page/Shipment.php

* Update to use fns in 7.3 and improve errors

* Use constants

* Fix failing tests

* LIMS-892: Dont allow UDC samples with no screening method and no reqd resolution (#629)

Co-authored-by: Mark Williams <[email protected]>

* User shipping service if using facility account number

* LIMS-932: Send proposal when creating shipments in shipping service (#646)

* LIMS-932: Send proposal when creating shipments in shipping service

* Use proposal from db query rather than args

---------

Co-authored-by: John Holt <[email protected]>

---------

Co-authored-by: Matthew Pritchard <[email protected]>
Co-authored-by: Guilherme Francisco <[email protected]>
Co-authored-by: John Holt <[email protected]>
Co-authored-by: John Holt <[email protected]>
Co-authored-by: Mark W <[email protected]>
Co-authored-by: Mark Williams <[email protected]>
Co-authored-by: Matthew Pritchard <[email protected]>
  • Loading branch information
8 people authored Aug 29, 2023
1 parent d0df7be commit 89d82b6
Show file tree
Hide file tree
Showing 10 changed files with 139 additions and 46 deletions.
1 change: 1 addition & 0 deletions api/config_sample.php
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@

# Shipping service details
$use_shipping_service = null;
$use_shipping_service_incoming_shipments = null;
$shipping_service_url = null;
$shipping_service_links_in_emails = null;

Expand Down
11 changes: 6 additions & 5 deletions api/src/Database/DatabaseFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,25 +22,26 @@ function __construct($databaseConnectionFactory)

public function get($databaseType = null)
{
global $dbtype;

if ( $databaseType == null) {
// Global variable is named $dbtype in config.php.
global $dbtype;
$databaseType = $dbtype;
}

if (!$databaseType) {
error_log('Database type variable, dbtype, is not specified in config.php - defaulting to MySql.');
$database_type = 'MySQL';
$databaseType = 'MySQL';
}

// Determine fully-qualified class name of database class corresponding to $database_type.
if (key_exists(strtolower($databaseType), $this->database_types)) {
$dbType = $this->database_types[strtolower($databaseType)];
$selectedDBConfig = $this->database_types[strtolower($databaseType)];

$full_class_name = 'SynchWeb\\Database\\Type\\' . $dbType["dbClassName"];;
$full_class_name = 'SynchWeb\\Database\\Type\\' . $selectedDBConfig["dbClassName"];

if (class_exists($full_class_name)) {
$conn = $this->databaseConnectionFactory->get($dbType["dataConnectionName"]);
$conn = $this->databaseConnectionFactory->get($selectedDBConfig["dataConnectionName"]);
return new $full_class_name($conn);
}
else {
Expand Down
112 changes: 89 additions & 23 deletions api/src/Page/Shipment.php
Original file line number Diff line number Diff line change
Expand Up @@ -951,7 +951,9 @@ function _dispatch_dewar_in_shipping_service($dispatch_info, $dewar)
"shipper_contact_email" => $facility_email,
"internal_contact_name" => $this->has_arg('LOCALCONTACT') ? $this->args['LOCALCONTACT'] : null,
"shipment_reference" => $dispatch_info['VISIT'],
"external_id" => (int) $dispatch_info['DEWARID']
"external_id" => (int) $dispatch_info['DEWARID'],
"journey_type" => ShippingService::JOURNEY_FROM_FACILITY,
"packages" => array(array("external_id" => (int) $dispatch_info['DEWARID']))
);

# Split up address. Necessary as address is a single field in ispyb
Expand All @@ -968,15 +970,16 @@ function _dispatch_dewar_in_shipping_service($dispatch_info, $dewar)

try {
if ($create === true) {
$shipment_data["proposal"] = $dewar["PROPOSAL"];
$response = $this->shipping_service->create_shipment($shipment_data);
} else {
$this->shipping_service->update_shipment($dispatch_info['DEWARID'], $shipment_data);
$response = $this->shipping_service->get_shipment($dispatch_info['DEWARID']);
$this->shipping_service->update_shipment($dispatch_info['DEWARID'], $shipment_data, ShippingService::JOURNEY_FROM_FACILITY);
$response = $this->shipping_service->get_shipment($dispatch_info['DEWARID'], ShippingService::JOURNEY_FROM_FACILITY);
}
$shipment_id = $response['shipmentId'];
$this->shipping_service->dispatch_shipment($shipment_id);
$this->shipping_service->dispatch_shipment($shipment_id, false);
} catch (Exception $e) {
throw new Exception("Error returned from shipping service: " . $e . "\nShipment data: " . $shipment_data);
throw new Exception("Error returned from shipping service: " . $e . "\nShipment data: " . json_encode($shipment_data));
}

return $shipment_id;
Expand Down Expand Up @@ -1004,7 +1007,7 @@ function _dispatch_dewar()
}

$dew = $this->db->pq(
"SELECT d.dewarid, d.barcode, d.storagelocation, d.dewarstatus, s.shippingid
"SELECT d.dewarid, d.barcode, d.storagelocation, d.dewarstatus, s.shippingid, CONCAT(p.proposalcode, p.proposalnumber) as proposal
FROM dewar d
INNER JOIN shipping s ON s.shippingid = d.shippingid
INNER JOIN proposal p ON p.proposalid = s.proposalid
Expand Down Expand Up @@ -2646,9 +2649,66 @@ function _get_default_dewar()
}


function _book_shipment_in_shipping_service($user, $shipment, $dewars, $journey_type) {
$address_lines = explode(PHP_EOL, rtrim($user["address"]));
$contact = array(
"company_name" => $user["company"],
"address_line1" => isset($address_lines[0]) ? $address_lines[0] : null,
"address_line2" => isset($address_lines[1]) ? $address_lines[1] : null,
"address_line3" => isset($address_lines[2]) ? $address_lines[2] : null,
"city" => $user["city"],
"country" => $user["country"],
"post_code" => rtrim($user["postcode"]),
"contact_name" => $user["name"],
"contact_phone_number" => $user["phone"],
"contact_email" => rtrim($user["email"])
);
$shipment_data = array(
"shipment_reference" => $shipment["PROP"],
"external_id" => $shipment['SHIPPINGID'],
"packages" => array_map(
function($dewar) {return array("external_id" => $dewar["DEWARID"]);},
$dewars
)
);

// Create or update shipment in shipping service
try {
$response = $this->shipping_service->get_shipment($shipment['SHIPPINGID'], $journey_type);
$user_shipment_role = $this->has_arg('RETURN') ? "consignee" : "shipper";
$relabelled_contact = array_combine(
array_map(function($key) use ($user_shipment_role) {return $user_shipment_role."_".$key;},
array_keys($contact)),
$contact);
$shipment_update_data = array_merge($response, $shipment_data, $relabelled_contact);
$this->shipping_service->update_shipment($shipment["SHIPPINGID"], $shipment_update_data, ShippingService::JOURNEY_TO_FACILITY);
} catch (\Exception $e) {
$shipment_data["proposal"] = $shipment["PROP"];
$shipment_data["contact"] = $contact;
$response = $this->shipping_service->create_shipment_by_journey_type($shipment_data, $journey_type);
}

// Dispatch shipment in shipping service
$shipmentId = $response["shipmentId"];
$dispatch_details = $this->shipping_service->dispatch_shipment($shipmentId, false);

$awb_pieces = array_map(
function($package, $index) {return array("piecenumber" => $index+1, "licenseplate" => $package["tracking_number"]);},
$dispatch_details["packages"],
array_keys($dispatch_details["packages"])
);

return array(
"awb" => $dispatch_details["tracking_number"],
"label" => $dispatch_details["air_waybill"],
"pieces" => $awb_pieces
);
}


function _create_awb()
{
global $dhl_service, $dhl_service_eu, $dhl_acc, $dhl_acc_import, $facility_courier_countries, $facility_courier_countries_nde;
global $dhl_service, $dhl_service_eu, $dhl_acc, $dhl_acc_import, $facility_courier_countries, $facility_courier_countries_nde, $use_shipping_service_incoming_shipments;

if (!$this->has_arg('prop'))
$this->_error('No proposal specified');
Expand Down Expand Up @@ -2764,22 +2824,28 @@ function _create_awb()
$awb = null;
if (!$ship['DELIVERYAGENT_FLIGHTCODE']) {
try {
$awb = $this->dhl->create_awb(array(
'payee' => $payee,
'accountnumber' => $accno,
'shipperid' => $ship['PROP'],
'service' => $product,
'date' => $ship['DELIVERYAGENT_SHIPPINGDATE'],
'declaredvalue' => $this->arg('DECLAREDVALUE'),
'description' => $this->arg('DESCRIPTION'),

'sender' => $this->has_arg('RETURN') ? $facility : $user,
'receiver' => $this->has_arg('RETURN') ? $user : $facility,

'pieces' => $pieces,
'notification' => implode(';', $emails),
'message' => $facility_company . ': Shipment booked from ISPyB for ' . $ship['PROP'] . ' ' . $ship['SHIPPINGNAME'] . ' containing ' . implode(',', $names)
));
if (Utils::getValueOrDefault($use_shipping_service_incoming_shipments) && $accno === $dhl_acc) {
$journey_type = $this->has_arg('RETURN') ? ShippingService::JOURNEY_FROM_FACILITY : ShippingService::JOURNEY_TO_FACILITY;
$awb = $this->_book_shipment_in_shipping_service($user, $ship, $dewars, $journey_type);
} else {
error_log("Not using shipping service for: {$ship['SHIPPINGID']}");
$awb = $this->dhl->create_awb(array(
'payee' => $payee,
'accountnumber' => $accno,
'shipperid' => $ship['PROP'],
'service' => $product,
'date' => $ship['DELIVERYAGENT_SHIPPINGDATE'],
'declaredvalue' => $this->arg('DECLAREDVALUE'),
'description' => $this->arg('DESCRIPTION'),

'sender' => $this->has_arg('RETURN') ? $facility : $user,
'receiver' => $this->has_arg('RETURN') ? $user : $facility,

'pieces' => $pieces,
'notification' => implode(';', $emails),
'message' => $facility_company . ': Shipment booked from ISPyB for ' . $ship['PROP'] . ' ' . $ship['SHIPPINGNAME'] . ' containing ' . implode(',', $names)
));
}

$this->db->pq("UPDATE shipping
SET deliveryagent_flightcode=:1, deliveryagent_flightcodetimestamp=CURRENT_TIMESTAMP, deliveryagent_label=:2, deliveryagent_productcode=:3, deliveryagent_flightcodepersonid=:4, shippingstatus='awb created', deliveryagent_agentname='DHL'
Expand Down
28 changes: 21 additions & 7 deletions api/src/Shipment/ShippingService.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class ShippingService
{
private $shipping_api_url;
private $headers;
public const JOURNEY_TO_FACILITY = "TO_FACILITY";
public const JOURNEY_FROM_FACILITY = "FROM_FACILITY";

function __construct()
{
Expand Down Expand Up @@ -77,34 +79,46 @@ function create_shipment($shipment_data)
}


function get_shipment($external_id)
function create_shipment_by_journey_type($shipment_data, $journey_type)
{
return $this->_send_request(
$this->shipping_api_url . '/shipments/external_id/' . $external_id,
$this->shipping_api_url . '/shipments/' . $journey_type,
"POST",
$shipment_data,
201
);
}


function get_shipment($external_id, $journey_type)
{
return $this->_send_request(
$this->shipping_api_url . '/shipments/external_id/' . $external_id . '?journey_type=' . $journey_type,
"GET",
null,
200
);
}


function update_shipment($external_id, $shipment_data)
function update_shipment($external_id, $shipment_data, $journey_type)
{
return $this->_send_request(
$this->shipping_api_url . '/shipments/external_id/' . $external_id,
$this->shipping_api_url . '/shipments/external_id/' . $external_id . '?journey_type=' . $journey_type,
"PUT",
$shipment_data,
204
);
}


function dispatch_shipment($shipment_id)
function dispatch_shipment($shipment_id, $pickup_requested)
{
$pickup_requested_str = ($pickup_requested) ? "true" : "false";
return $this->_send_request(
$this->shipping_api_url . '/shipments/' . $shipment_id . '/dispatch',
$this->shipping_api_url . '/shipments/' . $shipment_id . '/dispatch?pickup_requested=' . $pickup_requested_str,
"POST",
array(),
null,
201
);
}
Expand Down
2 changes: 1 addition & 1 deletion api/tests/Database/DatabaseFactoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function testErrorIsLoggedForDatabaseTypeClassThatDoesNotExist(): void
{
global $dbtype;
$dbtype = "obscure-db2";
$this->dbFactory->database_types[$dbtype] = $dbtype;
$this->dbFactory->database_types[$dbtype] = ["dbClassName" =>$dbtype, "dataConnectionName" => 'MySQL'];

$log = $this->getFunctionMock(__NAMESPACE__, "error_log");
$log->expects($this->once())->with("Database class 'SynchWeb\Database\Type\obscure-db2' does not exist.");
Expand Down
23 changes: 16 additions & 7 deletions client/src/js/modules/shipment/views/createawb.js
Original file line number Diff line number Diff line change
Expand Up @@ -314,11 +314,19 @@ define(['backbone',
},

checkAvailability: function() {
if (this.shipment.get('DELIVERYAGENT_AGENTNAME').toLowerCase() != 'dhl' && (
!(app.options.get('facility_courier_countries').indexOf(this.lc.get('COUNTRY')) > -1) &&
!(app.options.get('facility_courier_countries_nde').indexOf(this.lc.get('COUNTRY')) > -1)
))
app.message({ title: 'Service Not Available', message: 'This service is only available for shipments from '+app.options.get('facility_courier_countries').concat(app.options.get('facility_courier_countries_nde')).join(',')+', or for user with DHL accounts. Please either update your labcontact or the shipment courier'})
const agent_name = this.shipment.get('DELIVERYAGENT_AGENTNAME')
const facility_courier_countries = app.options.get('facility_courier_countries')
const facility_courier_countries_nde = app.options.get('facility_courier_countries_nde')
if ((agent_name==null || agent_name.toLowerCase() != 'dhl') && (
!(facility_courier_countries.indexOf(this.lc.get('COUNTRY')) > -1) &&
!(facility_courier_countries_nde.indexOf(this.lc.get('COUNTRY')) > -1)
)) {
const valid_countries = facility_courier_countries.concat(facility_courier_countries_nde).join(', ')
app.message({
title: 'Service Not Available',
message: 'This service is only available for shipments from ' + valid_countries +
', or for user with DHL accounts. Please either update your labcontact or the shipment courier'})
}
},

populateLC: function() {
Expand Down Expand Up @@ -435,7 +443,7 @@ define(['backbone',
PRODUCTCODE: prod,
},
success: function(resp) {
app.alert({ message: 'Air Waybill Successfully Created'})
app.message({ message: 'Air Waybill Successfully Created'})
setTimeout(function() {
app.trigger('shipment:show', self.shipment.get('SHIPPINGID'))
}, 1000)
Expand All @@ -452,7 +460,8 @@ define(['backbone',
console.error("Error parsing response: ", err)
}
}
app.alert({ message: json.message })
app.alert({ message: json.message, persist:true })
app.alert({ message: json.message})
self.ui.submit.prop('disabled', false)
self.$el.removeClass('loading')
}
Expand Down
2 changes: 2 additions & 0 deletions client/src/js/modules/shipment/views/dispatch.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,8 @@ define(['marionette', 'views/form',
this.ui.exp.html(this.visits.opts()).val(this.model.get('VISIT'))
this.updateLC()
this.populateCountries()
this.stripPostCode()
this.formatAddress()
},

populateCountries: function() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@
<extended-validation-provider
:ref="`sample_${sampleIndex}_required_resolution`"
class-names="tw-px-2 tw-w-24"
:rules="sample['PROTEINID'] > -1 ? `required_if:sample ${sampleIndex + 1} screening method,none|positive_decimal:6` : ''"
:rules="sample['PROTEINID'] > -1 && queueForUDC ? `required_if:sample ${sampleIndex + 1} screening method,none,|positive_decimal:6` : ''"
:name="`Sample ${sampleIndex + 1} Required Resolution`"
:vid="`sample ${sampleIndex + 1} required resolution`"
>
Expand Down
2 changes: 1 addition & 1 deletion client/src/js/templates/contact/contactview.html
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ <h1>View Home Lab Contact</h1>
</li>

<li class="clearfix">
<span class="label">Street Address <br />(excluding post code, city)</span>
<span class="label">Street Address <br />(Max 3 lines, excluding post code, city)</span>
<div class="ADDRESS text editable tw-block"><%-ADDRESS%></div>
</li>

Expand Down
2 changes: 1 addition & 1 deletion client/src/js/templates/shipment/createawb.html
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ <h2>Laboratory Details</h2>
</li>

<li class="clearfix">
<span class="label">Laboratory Address <br /><span class="small">(excluding post code)</span></span>
<span class="label">Laboratory Address <br /><span class="small">(Max 3 lines, excluding post code, city)</span></span>
<div class="ADDRESS text"></div>
</li>

Expand Down

0 comments on commit 89d82b6

Please sign in to comment.