Skip to content

Commit 2008454

Browse files
authored
Merge pre-release/2025-R4.2 into master (#986)
* LIMS-1844: Update archiving messages for 'il' proposals (#977) * LIMS-1807: Leave 'Mark Dispensing' button active until cancelled (#967) * LIMS-1799: Checks for safety level should be case insensitive (#955) * LIMS-1786: Add Dewars column to Shipments page (#958) * LIMS-1426: Allow setting of pipeline when ranking samples (#950) * LIMS-1783: Add parent container dropdown for gridboxes (#965) * LIMS-1903: Fix display of shipping labels (#984)
1 parent 0580ece commit 2008454

File tree

20 files changed

+243
-71
lines changed

20 files changed

+243
-71
lines changed

api/config_sample.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@
124124
# List of enabled container types, all if empty
125125
$enabled_container_types = array();
126126

127+
# Show parent container field for these types
128+
$container_types_with_parents = array();
129+
127130
# Zocalo message broker credentials - Set to empty string to disable
128131
$rabbitmq_zocalo_host = 'rabbitmq.server.ac.uk';
129132
$rabbitmq_zocalo_port = 5672;
@@ -313,6 +316,9 @@
313316
# Industrial proposals are not allowed to use the facility shipping account
314317
$industrial_prop_codes = array('sw', 'in', 'ic');
315318

319+
# Proposal codes where data is deleted, not archived
320+
$prop_codes_data_deleted = array('in');
321+
316322
# This maps beamlinename in blsession to a proposal type
317323
# - Internal maps a beamline to an api "type", there are currently:
318324
# mx, gen, em

api/index.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ function setupApplication($mode): Slim
7373
$valid_components, $enabled_container_types, $synchweb_version, $redirects,
7474
$shipping_service_app_url, $use_shipping_service_redirect, $use_shipping_service_redirect_incoming_shipments,
7575
$dials_rest_url_rings, $closed_proposal_link, $ccp4_cloud_upload_url,
76-
$only_staff_can_assign, $industrial_prop_codes;
76+
$only_staff_can_assign, $industrial_prop_codes, $prop_codes_data_deleted, $container_types_with_parents;
7777
$app->contentType('application/json');
7878
$options = $app->container['options'];
7979
$app->response()->body(json_encode(array(
@@ -103,7 +103,9 @@ function setupApplication($mode): Slim
103103
'ccp4_cloud_upload_url' => $ccp4_cloud_upload_url,
104104
'redirects' => $redirects,
105105
'only_staff_can_assign' => $only_staff_can_assign,
106-
'industrial_prop_codes' => $industrial_prop_codes
106+
'container_types_with_parents' => $container_types_with_parents,
107+
'industrial_prop_codes' => $industrial_prop_codes,
108+
'prop_codes_data_deleted' => $prop_codes_data_deleted ?? array(),
107109
)));
108110
});
109111
return $app;

api/src/Page/PDF.php

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,14 +119,27 @@ function _shipment_label()
119119
if (!$this->has_arg('sid'))
120120
$this->_error('No shipment specified', 'No shipment id was specified');
121121

122-
$ship = $this->db->pq("SELECT s.safetylevel, CONCAT(p.proposalcode, p.proposalnumber) as prop, s.shippingid, s.shippingname, pe.givenname, pe.familyname, pe.phonenumber,pe.faxnumber, l.name as labname, l.address, l.city, l.postcode, l.country, pe2.givenname as givenname2, pe2.familyname as familyname2, pe2.phonenumber as phonenumber2, pe2.faxnumber as faxnumber2, l2.name as labname2, l2.address as address2, l2.city as city2, l2.postcode as postcode2, l2.country as country2, c2.courieraccount, c2.billingreference, c2.defaultcourriercompany
122+
$ship = $this->db->pq("SELECT s.safetylevel, CONCAT(p.proposalcode, p.proposalnumber) as prop, s.shippingid, s.shippingname,
123+
pe.givenname, pe.familyname, pe.phonenumber, pe.faxnumber, l.name as labname, l.address, l.city, l.postcode, l.country,
124+
IFNULL(pe2.givenname, pe.givenname) as givenname2,
125+
IFNULL(pe2.familyname, pe.familyname) as familyname2,
126+
IFNULL(pe2.phonenumber, pe.phonenumber) as phonenumber2,
127+
IFNULL(pe2.faxnumber, pe.faxnumber) as faxnumber2,
128+
IFNULL(l2.name, l.name) as labname2,
129+
IFNULL(l2.address, l.address) as address2,
130+
IFNULL(l2.city, l.city) as city2,
131+
IFNULL(l2.postcode, l.postcode) as postcode2,
132+
IFNULL(l2.country, l.country) as country2,
133+
IFNULL(c2.courieraccount, c.courieraccount) as courieraccount,
134+
IFNULL(c2.billingreference, c.billingreference) as billingreference,
135+
IFNULL(c2.defaultcourriercompany, c.defaultcourriercompany) as defaultcourriercompany
123136
FROM shipping s
124137
INNER JOIN labcontact c ON s.sendinglabcontactid = c.labcontactid
125138
INNER JOIN person pe ON c.personid = pe.personid
126139
INNER JOIN laboratory l ON l.laboratoryid = pe.laboratoryid
127-
INNER JOIN labcontact c2 ON s.returnlabcontactid = c2.labcontactid
128-
INNER JOIN person pe2 ON c2.personid = pe2.personid
129-
INNER JOIN laboratory l2 ON l2.laboratoryid = pe2.laboratoryid
140+
LEFT OUTER JOIN labcontact c2 ON s.returnlabcontactid = c2.labcontactid
141+
LEFT OUTER JOIN person pe2 ON c2.personid = pe2.personid
142+
LEFT OUTER JOIN laboratory l2 ON l2.laboratoryid = pe2.laboratoryid
130143
INNER JOIN proposal p ON p.proposalid = s.proposalid
131144
WHERE s.shippingid=:1", array($this->arg('sid')));
132145

api/src/Page/Sample.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ class Sample extends Page
4343
'capillaryPhase' => '',
4444
'json' => '',
4545
'dcp' => '\d',
46+
'pipeline' => '\w+',
4647

4748
'collected_during' => '\w+\d+-\d+',
4849

@@ -1181,7 +1182,11 @@ function _samples()
11811182
$join WHERE $where", $args);
11821183
$tot = intval($tot[0]['TOT']);
11831184

1184-
1185+
# Get stats only for a specific processing pipeline
1186+
if ($this->has_arg('pipeline')) {
1187+
$where .= ' AND (app.processingprograms is null OR app.processingpipelineid is null OR app.processingpipelineid=:' . (sizeof($args) + 1) . ')';
1188+
array_push($args, $this->arg('pipeline'));
1189+
}
11851190

11861191
$start = 0;
11871192
$pp = $this->has_arg('per_page') ? $this->arg('per_page') : 15;

api/src/Page/Shipment.php

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,8 @@ class Shipment extends Page
132132
'SOURCE' => '[\w\-]+',
133133

134134
'CONTAINERREGISTRYID' => '\d+',
135+
'PARENTCONTAINERID' => '\d*',
136+
'PARENTCONTAINERLOCATION' => '\d*',
135137
'PROPOSALID' => '\d+',
136138
't' => '\w+',
137139

@@ -2387,6 +2389,7 @@ function _get_all_containers()
23872389
count(distinct ci.containerinspectionid) as inspections,
23882390
c.scheduleid, c.screenid, c.ownerid, c.imagerid, c.bltimestamp, c.samplechangerlocation, c.beamlinelocation, c.containertype, c.capacity, c.barcode,
23892391
c.containerstatus, c.containerid, c.code as name, c.requestedreturn, c.requestedimagerid, c.comments, c.experimenttype, c.storagetemperature,
2392+
c.parentcontainerid, c.parentcontainerlocation, pc.code as parentcontainer,
23902393
sc.name as screen,
23912394
i.temperature, i.name as imager,
23922395
CONCAT(p.proposalcode, p.proposalnumber) as prop, CONCAT(p.proposalcode, p.proposalnumber, '-', ses.visit_number) as visit, ses.beamlinename,
@@ -2416,6 +2419,7 @@ function _get_all_containers()
24162419
LEFT OUTER JOIN containerqueue cq2 ON cq2.containerid = c.containerid AND cq2.completedtimestamp IS NOT NULL
24172420
LEFT OUTER JOIN containerregistry reg ON reg.containerregistryid = c.containerregistryid
24182421
LEFT OUTER JOIN blsession ses ON c.sessionid = ses.sessionid
2422+
LEFT OUTER JOIN container pc ON c.parentcontainerid = pc.containerid
24192423
24202424
$join
24212425
WHERE $where
@@ -2541,11 +2545,12 @@ function _update_container()
25412545
if (!sizeof($chkc))
25422546
$this->_error('No such container');
25432547

2544-
$fields = array('NAME' => 'CODE', 'REQUESTEDRETURN' => 'REQUESTEDRETURN', 'REQUESTEDIMAGERID' => 'REQUESTEDIMAGERID', 'COMMENTS' => 'COMMENTS', 'BARCODE' => 'BARCODE', 'CONTAINERTYPE' => 'CONTAINERTYPE', 'EXPERIMENTTYPE' => 'EXPERIMENTTYPE', 'STORAGETEMPERATURE' => 'STORAGETEMPERATURE', 'CONTAINERREGISTRYID' => 'CONTAINERREGISTRYID', 'PROCESSINGPIPELINEID' => 'PRIORITYPIPELINEID', 'OWNERID' => 'OWNERID');
2548+
$fields = array('NAME' => 'CODE', 'REQUESTEDRETURN' => 'REQUESTEDRETURN', 'REQUESTEDIMAGERID' => 'REQUESTEDIMAGERID', 'COMMENTS' => 'COMMENTS', 'BARCODE' => 'BARCODE', 'CONTAINERTYPE' => 'CONTAINERTYPE', 'EXPERIMENTTYPE' => 'EXPERIMENTTYPE', 'STORAGETEMPERATURE' => 'STORAGETEMPERATURE', 'CONTAINERREGISTRYID' => 'CONTAINERREGISTRYID', 'PROCESSINGPIPELINEID' => 'PRIORITYPIPELINEID', 'OWNERID' => 'OWNERID', 'PARENTCONTAINERID' => 'PARENTCONTAINERID', 'PARENTCONTAINERLOCATION' => 'PARENTCONTAINERLOCATION');
25452549
foreach ($fields as $k => $f) {
25462550
if ($this->has_arg($k)) {
2547-
$this->db->pq("UPDATE container SET $f=:1 WHERE containerid=:2", array($this->arg($k), $this->arg('cid')));
2548-
$this->_output(array($k => $this->arg($k)));
2551+
$val = $this->arg($k) != '' ? $this->arg($k) : null;
2552+
$this->db->pq("UPDATE container SET $f=:1 WHERE containerid=:2", array($val, $this->arg('cid')));
2553+
$this->_output(array($k => $val));
25492554
}
25502555
}
25512556

@@ -2581,15 +2586,17 @@ function _add_container()
25812586
$tem = $this->has_arg('STORAGETEMPERATURE') ? $this->arg('STORAGETEMPERATURE') : null;
25822587

25832588
$crid = $this->has_arg('CONTAINERREGISTRYID') ? $this->arg('CONTAINERREGISTRYID') : null;
2589+
$pcid = $this->has_arg('PARENTCONTAINERID') ? $this->arg('PARENTCONTAINERID') : null;
2590+
$pcl = $this->has_arg('PARENTCONTAINERLOCATION') ? $this->arg('PARENTCONTAINERLOCATION') : null;
25842591

25852592
$pipeline = $this->has_arg('PROCESSINGPIPELINEID') ? $this->arg('PROCESSINGPIPELINEID') : null;
25862593
$source = $this->has_arg('SOURCE') ? $this->arg('SOURCE') : null;
25872594

25882595
try {
25892596
$this->db->pq(
2590-
"INSERT INTO container (containerid,dewarid,code,bltimestamp,capacity,containertype,scheduleid,screenid,ownerid,requestedimagerid,comments,barcode,experimenttype,storagetemperature,containerregistryid,prioritypipelineid,source)
2591-
VALUES (s_container.nextval,:1,:2,CURRENT_TIMESTAMP,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,IFNULL(:15,CURRENT_USER)) RETURNING containerid INTO :id",
2592-
array($this->arg('DEWARID'), $this->arg('NAME'), $cap, $this->arg('CONTAINERTYPE'), $sch, $scr, $own, $rid, $com, $bar, $ext, $tem, $crid, $pipeline, $source)
2597+
"INSERT INTO container (containerid,dewarid,code,bltimestamp,capacity,containertype,scheduleid,screenid,ownerid,requestedimagerid,comments,barcode,experimenttype,storagetemperature,containerregistryid,parentcontainerid,parentcontainerlocation,prioritypipelineid,source)
2598+
VALUES (s_container.nextval,:1,:2,CURRENT_TIMESTAMP,:3,:4,:5,:6,:7,:8,:9,:10,:11,:12,:13,:14,:15,:16,IFNULL(:17,CURRENT_USER)) RETURNING containerid INTO :id",
2599+
array($this->arg('DEWARID'), $this->arg('NAME'), $cap, $this->arg('CONTAINERTYPE'), $sch, $scr, $own, $rid, $com, $bar, $ext, $tem, $crid, $pcid, $pcl, $pipeline, $source)
25932600
);
25942601

25952602
$cid = $this->db->id();

client/src/js/app/components/base-input-text.vue

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ https://eslint.vuejs.org/rules/no-v-html.html
5959
</span>
6060
</span>
6161
<button
62-
v-if="inline && editable"
62+
v-if="inline && editable && !errorMessage"
6363
class="button tw-px-2 tw-py-1"
6464
@mousedown="onSave"
6565
>
@@ -132,6 +132,11 @@ export default {
132132
type: Boolean,
133133
default: false
134134
},
135+
// Force validation on input, even to an inline field
136+
validateOnInput: {
137+
type: Boolean,
138+
default: false
139+
},
135140
// If using the input within a table, set quiet mode to suppress error messages
136141
// Keeps the styling around input fields
137142
quiet: {
@@ -190,7 +195,7 @@ export default {
190195
updateValue(event) {
191196
// If we are in inline editing mode, only update model on save
192197
// If not them update value via input event
193-
if (!this.inline) this.$emit("input", event.target.value);
198+
if (!this.inline || this.validateOnInput) this.$emit("input", event.target.value);
194199
},
195200
onBlur() {
196201
// If in inline edit mode cancel edit

client/src/js/modules/dc/datacollections.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ function(Marionette, Pages, DCListView,
114114
IS_DCG: !(!this.getOption('params').dcg),
115115
IS_PJ: !(!this.getOption('params').pjid),
116116
IS_STAFF: app.staff,
117+
IS_ARCHIVED: app.options.get('prop_codes_data_deleted').some(code => app.prop.includes(code)) ? "deleted" : "archived",
117118
}
118119
},
119120

client/src/js/modules/dc/dclist.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ function(Marionette,
5050
return {
5151
IS_VISIT: is_vis,
5252
VIS_LINK: vl,
53-
APIURL: app.apiurl
53+
APIURL: app.apiurl,
54+
IS_ARCHIVED: app.options.get('prop_codes_data_deleted').some(code => app.prop.includes(code)) ? "deleted" : "archived",
5455
}
5556
},
5657
visit: vl,
@@ -107,4 +108,4 @@ function(Marionette,
107108
})
108109

109110

110-
})
111+
})

client/src/js/modules/imaging/views/imageviewer.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,6 @@ define(['marionette',
201201
editDispensing: function(x, y) {
202202
var s = new Sample({ BLSAMPLEID: this.model.get('BLSAMPLEID') })
203203
s.set({ X: x, Y: y })
204-
this.trigger('finishdispensing')
205204
this.subsamples.fetch()
206205
},
207206

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

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ define(['marionette',
3737
'modules/imaging/collections/autoscoreschemas',
3838
'modules/imaging/collections/autoscores',
3939
'collections/users',
40+
'collections/processingpipelines',
4041

4142
'utils/editable',
4243
'views/table',
@@ -74,7 +75,7 @@ define(['marionette',
7475
AutoScoreSchemas, AutoScores,
7576

7677
Users,
77-
78+
ProcessingPipelines,
7879
Editable, TableView, table, XHRImage, utils,
7980
template, templateimage){
8081

@@ -261,6 +262,7 @@ define(['marionette',
261262

262263
sampleStatusCurrent: 'input[id=sample_status_current]',
263264
param: 'select[name=param]',
265+
pipeline: 'select[name=pipeline]',
264266
rank: 'input[name=rank]',
265267

266268
sampleStatusAuto: 'input[id=sample_status_auto]',
@@ -295,6 +297,7 @@ define(['marionette',
295297

296298
'click @ui.rank': 'setRankStatus',
297299
'change @ui.param': 'setParamValue',
300+
'change @ui.pipeline': 'setPipeline',
298301

299302
'click @ui.sampleStatusAuto': 'setSampleStatusShown',
300303
'change @ui.class': 'setAutoStatus',
@@ -335,6 +338,11 @@ define(['marionette',
335338
this.setRankStatus()
336339
},
337340

341+
setPipeline: function() {
342+
this.samples.queryParams.pipeline = this.ui.pipeline.val()
343+
this.samples.fetch({ data: {'sort_by': 'POSITION' } })
344+
},
345+
338346
setRankStatus: function() {
339347
if (this.ui.rank.is(':checked')) {
340348
this.ui.sampleStatusData.prop('checked', true)
@@ -548,7 +556,7 @@ define(['marionette',
548556
} else {
549557
this.ui.addis.addClass('button-highlight')
550558
this.image.setAddDispensing(true)
551-
this.ui.addis.find('span').text('Cancel')
559+
this.ui.addis.find('span').text('Finish')
552560
this.ui.addis.find('i').removeClass('fa-plus').addClass('fa-times')
553561
if (this.subsamples.length && this.subsamples.findWhere({ BLSAMPLEID: this.getSample() }).get('DISPENSEX')) {
554562
this.ui.deldis.show()
@@ -684,12 +692,20 @@ define(['marionette',
684692
// Assumption all plates are for vmxi, so login => users only
685693
this.users.queryParams.login = 1
686694

695+
this.processing_pipelines = new ProcessingPipelines()
696+
this.processing_pipelines.queryParams.category = 'processing'
697+
this.processing_pipelines.fetch().done(this.updatePipelines.bind(this))
698+
687699
this.touchstartX = 0;
688700
this.touchstartY = 0;
689701

690702
Backbone.Validation.bind(this)
691703
},
692704

705+
updatePipelines: function() {
706+
this.ui.pipeline.html('<option value="">All pipelines</option>'+this.processing_pipelines.opts())
707+
},
708+
693709
updateSchemas: function() {
694710
if (this.autoscoreschemas.length === 1) {
695711
this.ui.schemaspan.html(this.autoscoreschemas.at(0).get('SCHEMANAME'))
@@ -960,7 +976,6 @@ define(['marionette',
960976
this.listenTo(this.image, 'image:prev', this.prevImage, this)
961977
this.listenTo(this.image, 'image:first', this.firstImage, this)
962978
this.listenTo(this.image, 'image:last', this.lastImage, this)
963-
this.listenTo(this.image, 'finishdispensing', this.setAddDispensing, this)
964979

965980
if (this.getOption('params').iid) this.ui.ins.val(this.getOption('params').iid)
966981
this.selectInspection()

0 commit comments

Comments
 (0)