Skip to content

Commit aec73d2

Browse files
authored
Merge pre-release/2025-R3.1 into master (#946)
* LIMS-1447: Don't allow shipping of red samples (#929) * LIMS-1664: Improvements to registered dewar and container pages (#927) * LIMS-1636: Make LDAP server ID field configurable (#934) * LIMS-1699: Show confirmation dialog if a user creates a plate that is not full (#924) * LIMS-1713: Allow sm beamlines to use mx Create Container page (#932) * LIMS-1770: Fix download of attachments on saxs and xpdf beamlines (#944)
1 parent 2e7a75d commit aec73d2

File tree

19 files changed

+270
-81
lines changed

19 files changed

+270
-81
lines changed

api/config_sample.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@
4040
# CAS CA Cert (for SSO)
4141
$cacert = '/etc/certs/ca-bundle.crt';
4242

43+
# Field to get user ID from in LDAP
44+
$ldap_id_field = "cn";
4345
# ldap server, used for lookup and authentication (if using, set to null if not)
4446
# Update the ldap(s) prefix, hostname and search settings as required
4547
$ldap_server = 'ldaps://ldap.example.com';

api/src/Page.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -758,7 +758,9 @@ function bcr()
758758
*/
759759
function _get_name($fedid)
760760
{
761-
$src = $this->_ldap_search('uid=' . $fedid);
761+
global $ldap_id_field;
762+
763+
$src = $this->_ldap_search($ldap_id_field . '=' . $fedid);
762764
return array_key_exists($fedid, $src) ? $src[$fedid] : '';
763765
}
764766

@@ -770,7 +772,9 @@ function _get_name($fedid)
770772
*/
771773
function _get_email($fedid)
772774
{
773-
$src = $this->_ldap_search('uid=' . $fedid, True);
775+
global $ldap_id_field;
776+
777+
$src = $this->_ldap_search($ldap_id_field . '=' . $fedid, True);
774778
return array_key_exists($fedid, $src) ? $src[$fedid] : $fedid;
775779
}
776780

@@ -853,12 +857,12 @@ function _get_ispyb_email_fn($name)
853857
* Search LDAP for name or email
854858
*
855859
* @param boolean $email Search for an email adddress if true, search for name if false
856-
* @param string $search ldap query, typically uid=fedid or name search
860+
* @param string $search ldap query, typically cn=fedid or name search
857861
* @return array Returns array of results, either fedid=>emailAddresses or fedid=>"givenname sn" from ldap records
858862
*/
859863
function _ldap_search($search, $email = False)
860864
{
861-
global $ldap_server, $ldap_search;
865+
global $ldap_server, $ldap_search, $ldap_id_field;
862866

863867
$ret = array();
864868
if (is_null($ldap_server)) {
@@ -881,7 +885,7 @@ function _ldap_search($search, $email = False)
881885
{
882886
// Strictly speaking we could set anything as the key here, since only the first record is used in e.g. _get_email_fn
883887
// But as the logic maps fedid=>email, use similar keys here
884-
$fedid = $info[$i]['uid'][0];
888+
$fedid = $info[$i][$ldap_id_field][0];
885889
if ($email)
886890
{
887891
$ret[$fedid] = array_key_exists('mail', $info[$i]) ? $info[$i]['mail'][0] : '';

api/src/Page/Proposal.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class Proposal extends Page
5858
'BEAMLINESETUPID' => '\d+',
5959
'BEAMCALENDARID' => '\d+',
6060
'VISITNUMBER' => '\d+',
61+
'RISKRATING' => '\w+',
6162

6263
// visit has person
6364
'SHPKEY' => '\d+\-\d+',
@@ -406,6 +407,16 @@ function _get_visits($visit = null, $output = true)
406407
$where .= " AND s.scheduled=1";
407408
}
408409

410+
if ($this->has_arg('RISKRATING')) {
411+
if ($this->arg('RISKRATING') == 'high') {
412+
$where .= " AND s.riskrating = 'high'";
413+
} else if ($this->arg('RISKRATING') == 'medium') {
414+
$where .= " AND s.riskrating in ('high', 'medium')";
415+
} else if ($this->arg('RISKRATING') == 'low') {
416+
$where .= " AND s.riskrating in ('high', 'medium', 'low')";
417+
}
418+
}
419+
409420
if ($visit) {
410421
$where .= " AND CONCAT(p.proposalcode, p.proposalnumber, '-', s.visit_number) LIKE :" . (sizeof($args) + 1);
411422
array_push($args, $visit);

api/src/Page/Shipment.php

Lines changed: 35 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -218,7 +218,7 @@ class Shipment extends Page
218218
// TODO: Need to have a separate method for handling queueing and unqueueing of containers
219219
array('/containers/queue(/:cid)', 'patch', '_queue_container'),
220220
array('/containers/queue(/:cid)', 'get', '_queue_container'),
221-
array('/containers/barcode/:BARCODE', 'get', '_check_container'),
221+
array('/containers/barcode/(:BARCODE)', 'get', '_check_container'),
222222

223223

224224
array('/containers/registry(/:CONTAINERREGISTRYID)', 'get', '_container_registry'),
@@ -649,7 +649,15 @@ function _dewar_registry()
649649

650650
if ($this->has_arg('s')) {
651651
$st = sizeof($args) + 1;
652-
$where .= " AND (lower(r.facilitycode) LIKE lower(CONCAT(CONCAT('%', :" . ($st) . "), '%')) OR lower(CONCAT(p.proposalcode,p.proposalnumber)) LIKE lower(CONCAT(CONCAT('%',:" . ($st + 1) . "), '%')))";
652+
$where .= " AND (r.dewarregistryid IN (
653+
SELECT DISTINCT r2.dewarregistryid
654+
FROM dewarregistry r2
655+
LEFT JOIN dewarregistry_has_proposal rhp2 ON rhp2.dewarregistryid = r2.dewarregistryid
656+
LEFT JOIN Proposal p2 ON p2.proposalid = rhp2.proposalid
657+
WHERE r2.facilitycode LIKE CONCAT('%',:" . $st . ",'%')
658+
OR CONCAT(p2.proposalcode, p2.proposalnumber) LIKE CONCAT('%',:" . ($st + 1) . ",'%')
659+
)
660+
)";
653661
array_push($args, $this->arg('s'), $this->arg('s'));
654662
}
655663

@@ -2060,16 +2068,20 @@ function _accept_terms()
20602068
# Check if a barcode exists
20612069
function _check_container()
20622070
{
2063-
$cont = $this->db->pq("SELECT CONCAT(p.proposalcode, p.proposalnumber) as prop, c.barcode
2064-
FROM container c
2065-
INNER JOIN dewar d ON d.dewarid = c.dewarid
2066-
INNER JOIN shipping s ON s.shippingid = d.shippingid
2067-
INNER JOIN proposal p ON p.proposalid = s.proposalid
2068-
WHERE c.barcode=:1", array($this->arg('BARCODE')));
2071+
if ($this->has_arg('BARCODE')) {
2072+
$cont = $this->db->pq("SELECT CONCAT(p.proposalcode, p.proposalnumber) as prop, c.barcode
2073+
FROM container c
2074+
INNER JOIN dewar d ON d.dewarid = c.dewarid
2075+
INNER JOIN shipping s ON s.shippingid = d.shippingid
2076+
INNER JOIN proposal p ON p.proposalid = s.proposalid
2077+
WHERE c.barcode=:1", array($this->arg('BARCODE')));
20692078

2070-
if (!sizeof($cont))
2071-
$this->_error('Barcode not used');
2072-
$this->_output($cont[0]);
2079+
if (!sizeof($cont)) {
2080+
$this->_output('Barcode not used');
2081+
} else {
2082+
$this->_output($cont[0]);
2083+
}
2084+
}
20732085
}
20742086

20752087
function _get_all_containers()
@@ -2731,10 +2743,17 @@ function _container_registry()
27312743

27322744
if ($this->has_arg('s')) {
27332745
$st = sizeof($args) + 1;
2734-
$where .= " AND (lower(r.barcode) LIKE lower(CONCAT(CONCAT('%',:" . $st . "), '%')) OR lower(r.comments) LIKE lower(CONCAT(CONCAT('%',:" . ($st + 1) . "), '%')) OR lower(CONCAT(p.proposalcode,p.proposalnumber)) LIKE lower(CONCAT(CONCAT('%',:" . ($st + 2) . "), '%')))";
2735-
array_push($args, $this->arg('s'));
2736-
array_push($args, $this->arg('s'));
2737-
array_push($args, $this->arg('s'));
2746+
$where .= " AND (r.containerregistryid IN (
2747+
SELECT DISTINCT r2.containerregistryid
2748+
FROM containerregistry r2
2749+
LEFT JOIN containerregistry_has_proposal rhp2 ON rhp2.containerregistryid = r2.containerregistryid
2750+
LEFT JOIN proposal p2 ON p2.proposalid = rhp2.proposalid
2751+
WHERE r2.barcode LIKE CONCAT('%',:" . $st . ",'%')
2752+
OR r2.comments LIKE CONCAT('%',:" . ($st + 1) . ",'%')
2753+
OR CONCAT(p2.proposalcode, p2.proposalnumber) LIKE CONCAT('%',:" . ($st + 2) . ",'%')
2754+
)
2755+
)";
2756+
array_push($args, $this->arg('s'), $this->arg('s'), $this->arg('s'));
27382757
}
27392758

27402759
if ($this->has_arg('t')) {
@@ -2743,7 +2762,7 @@ function _container_registry()
27432762
}
27442763

27452764

2746-
$tot = $this->db->pq("SELECT count(r.containerregistryid) as tot
2765+
$tot = $this->db->pq("SELECT count(DISTINCT r.containerregistryid) as tot
27472766
FROM containerregistry r
27482767
LEFT OUTER JOIN containerregistry_has_proposal rhp on rhp.containerregistryid = r.containerregistryid
27492768
LEFT OUTER JOIN proposal p ON p.proposalid = rhp.proposalid

client/src/js/modules/shipment/components/container-add-wrapper.vue

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export default {
101101
if (!this.mview) {
102102
const newAddContainers = {
103103
mx: 'mx-container-add',
104+
sm: 'mx-container-add',
104105
}
105106
106107
this.componentType = newAddContainers[this.proposalType]
@@ -120,4 +121,4 @@ export default {
120121
}
121122
122123
}
123-
</script>
124+
</script>

client/src/js/modules/shipment/components/container-map.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ export const ContainerListMap = {
1616
// We assign null to the view property because we want to use new components
1717
export const ContainerViewMap = {
1818
mx: { title: 'Container', view: null },
19+
sm: { title: 'Container', view: null },
1920
xpdf: { title: 'Container', view: XpdfContainerView },
2021
default:{ title: 'Container', view: ContainerView }
2122
}
@@ -29,6 +30,8 @@ export const ContainerPlateViewMap = {
2930
export const ContainerAddMap = {
3031
xpdf: { title: 'Container', view: XpdfContainerAddView },
3132
default:{ title: 'Container', view: ContainerAddView },
33+
sm: { title: 'Container', view: null },
3234
mx: { title: 'Container', view: null }
35+
3336
}
3437

client/src/js/modules/shipment/components/container-view-wrapper.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ export default {
101101
if (!this.mview) {
102102
const newViewContainers = {
103103
mx: 'mx-container-view',
104+
sm: 'mx-container-view',
104105
}
105106
106107
this.componentType = newViewContainers[this.proposalType]

client/src/js/modules/shipment/views/containerregistry.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,7 @@ define(['marionette',
111111

112112
if (app.staff) {
113113
this.listenTo(this.collection, 'backgrid:selected', this.selectModel, this)
114+
this.collection.each(this.bindModelEvents, this)
114115

115116
this.proposals = new Proposals()
116117
this.listenTo(this.proposals, 'backgrid:selected', this.selectModel, this)
@@ -138,7 +139,11 @@ define(['marionette',
138139
})
139140
}
140141
},
141-
142+
143+
bindModelEvents: function(model) {
144+
this.listenTo(model, 'backgrid:selected', this.selectModel)
145+
},
146+
142147
addToCollection: function(m) {
143148
this.collection.add(m)
144149
this.addProposalsToModel(m)
@@ -156,7 +161,16 @@ define(['marionette',
156161
props.push(p.get('PROPOSAL'))
157162
m.set('PROPOSALS', props.join(','))
158163
// This will be called multiple times for many proposals. Might be a cleaner method..?
159-
app.alert({message: 'Added registered container ' + m.get('BARCODE') + ' to proposal(s) ' + props, notify: true})
164+
app.message({message: 'Added registered container ' + m.get('BARCODE') + ' to proposal ' + p.get('PROPOSAL'), notify: true})
165+
},
166+
error: function(model, response, options) {
167+
var errorMsg
168+
try {
169+
errorMsg = response.responseJSON.message
170+
} catch (e) {
171+
errorMsg = 'An unknown error occurred.'
172+
}
173+
app.alert({message: 'Failed to add ' + m.get('BARCODE') + ' to proposal ' + p.get('PROPOSAL') + ': ' + errorMsg, notify: true})
160174
}
161175
})
162176
}, this)

client/src/js/modules/shipment/views/createawb.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ define(['backbone',
112112
terms: '.terms',
113113
termsq: '.terms-quote',
114114
country: '.COUNTRY',
115+
green: '.green',
116+
red: '.red',
115117

116118
createAWBForm: '.createAWBForm',
117119
},
@@ -350,6 +352,11 @@ define(['backbone',
350352
this.qt.show(this.qtable)
351353

352354
$.when.apply($, this.ready).done(this.doOnRender.bind(this))
355+
356+
if (this.shipment.get('SAFETYLEVEL') == 'Red') {
357+
this.ui.green.hide()
358+
this.ui.red.show()
359+
}
353360
},
354361

355362
doOnRender: function() {

client/src/js/modules/shipment/views/dewarregistry.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ define(['marionette', 'backgrid',
161161

162162
if (app.staff) {
163163
this.listenTo(this.collection, 'backgrid:selected', this.selectModel, this)
164+
this.collection.each(this.bindModelEvents, this)
164165

165166
this.proposals = new Proposals()
166167
this.listenTo(this.proposals, 'backgrid:selected', this.selectModel, this)
@@ -189,7 +190,11 @@ define(['marionette', 'backgrid',
189190
})
190191
}
191192
},
192-
193+
194+
bindModelEvents: function(model) {
195+
this.listenTo(model, 'backgrid:selected', this.selectModel)
196+
},
197+
193198
addToCollection: function(m) {
194199
this.collection.add(m)
195200
this.addProposalsToModel(m)
@@ -207,7 +212,16 @@ define(['marionette', 'backgrid',
207212
m.set('PROPOSALS', props.join(','))
208213
if (!m.get('PROP')) m.set('PROP', p.get('PROPOSAL'))
209214
// This will be called multiple times for many proposals. Might be a cleaner method..?
210-
app.message({message: 'Added registered dewar ' + m.get('FACILITYCODE') + ' to proposal(s) ' + props, notify: true})
215+
app.message({message: 'Added registered dewar ' + m.get('FACILITYCODE') + ' to proposal ' + p.get('PROPOSAL'), notify: true})
216+
},
217+
error: function(model, response, options) {
218+
var errorMsg
219+
try {
220+
errorMsg = response.responseJSON.message
221+
} catch (e) {
222+
errorMsg = 'An unknown error occurred.'
223+
}
224+
app.alert({message: 'Failed to add ' + m.get('FACILITYCODE') + ' to proposal ' + p.get('PROPOSAL') + ': ' + errorMsg, notify: true})
211225
}
212226
})
213227
}, this)

0 commit comments

Comments
 (0)