@@ -23,6 +23,7 @@ import { ProposalDataSource } from '../ProposalDataSource';
2323import { TagDataSource } from '../TagDataSource' ;
2424import { WorkflowDataSource } from '../WorkflowDataSource' ;
2525import {
26+ InstrumentFilterInput ,
2627 ProposalsFilter ,
2728 QuestionFilterInput ,
2829} from './../../resolvers/queries/ProposalsQuery' ;
@@ -94,6 +95,29 @@ export async function calculateReferenceNumber(
9495 return prefix + paddedSequence ;
9596}
9697
98+ /**
99+ * Resolves instrument IDs from an InstrumentFilterInput.
100+ * Supports both `instrumentIds` and `instrumentId`(deprecated).
101+ */
102+ export function resolveInstrumentIds (
103+ instrumentFilter ?: InstrumentFilterInput
104+ ) : number [ ] | undefined {
105+ if ( ! instrumentFilter ) {
106+ return undefined ;
107+ }
108+ if (
109+ instrumentFilter . instrumentIds &&
110+ instrumentFilter . instrumentIds . length > 0
111+ ) {
112+ return instrumentFilter . instrumentIds ;
113+ }
114+ if ( instrumentFilter . instrumentId ) {
115+ return [ instrumentFilter . instrumentId ] ;
116+ }
117+
118+ return undefined ;
119+ }
120+
97121@injectable ( )
98122export default class PostgresProposalDataSource implements ProposalDataSource {
99123 constructor (
@@ -312,6 +336,32 @@ export default class PostgresProposalDataSource implements ProposalDataSource {
312336 } ) ;
313337 }
314338
339+ async getRequestedTime (
340+ proposalPk : number ,
341+ instrumentId : number
342+ ) : Promise < number > {
343+ //Non-nullable, time is either requested for the instrument or it is zero.
344+ const result = await database ( 'proposals as p' )
345+ . sum ( {
346+ total_time_requested : database . raw (
347+ "(a.answer->'value'->>'timeRequested')::numeric"
348+ ) ,
349+ } )
350+ . innerJoin ( 'questionaries as q2' , 'q2.questionary_id' , 'p.questionary_id' )
351+ . innerJoin ( 'answers as a' , 'a.questionary_id' , 'q2.questionary_id' )
352+ . innerJoin ( 'questions as q' , 'q.question_id' , 'a.question_id' )
353+ . where ( 'p.proposal_pk' , proposalPk )
354+ . where ( 'q.data_type' , 'INSTRUMENT_PICKER' )
355+ . whereRaw ( "a.answer->'value'->>'instrumentId' = ?" , [
356+ instrumentId . toString ( ) ,
357+ ] )
358+ . first ( ) ;
359+
360+ return result ?. total_time_requested
361+ ? Number ( result . total_time_requested )
362+ : 0 ;
363+ }
364+
315365 async create (
316366 proposer_id : number ,
317367 call_id : number ,
@@ -471,11 +521,20 @@ export default class PostgresProposalDataSource implements ProposalDataSource {
471521
472522 if ( filter ?. instrumentFilter ?. showMultiInstrumentProposals ) {
473523 query . whereRaw ( 'jsonb_array_length(instruments) > 1' ) ;
474- } else if ( filter ?. instrumentFilter ?. instrumentId ) {
475- query . whereRaw (
476- 'jsonb_path_exists(instruments, \'$[*].id \\? (@.type() == "number" && @ == :instrumentId:)\')' ,
477- { instrumentId : filter . instrumentFilter . instrumentId }
524+ } else {
525+ const effectiveInstrumentIds = resolveInstrumentIds (
526+ filter ?. instrumentFilter
478527 ) ;
528+ if ( effectiveInstrumentIds && effectiveInstrumentIds . length > 0 ) {
529+ query . where ( function ( ) {
530+ effectiveInstrumentIds . forEach ( ( id ) => {
531+ this . orWhereRaw (
532+ 'jsonb_path_exists(instruments, \'$[*].id \\? (@.type() == "number" && @ == :instrumentId:)\')' ,
533+ { instrumentId : id }
534+ ) ;
535+ } ) ;
536+ } ) ;
537+ }
479538 }
480539
481540 if ( filter ?. proposalStatusId ) {
@@ -629,16 +688,19 @@ export default class PostgresProposalDataSource implements ProposalDataSource {
629688 ) ;
630689 }
631690
632- if ( filter ?. instrumentFilter ?. instrumentId ) {
691+ const effectiveInstrumentIds = resolveInstrumentIds (
692+ filter ?. instrumentFilter
693+ ) ;
694+ if ( effectiveInstrumentIds && effectiveInstrumentIds . length > 0 ) {
633695 query
634696 . leftJoin (
635697 'instrument_has_proposals' ,
636698 'instrument_has_proposals.proposal_pk' ,
637699 'proposals.proposal_pk'
638700 )
639- . where (
701+ . whereIn (
640702 'instrument_has_proposals.instrument_id' ,
641- filter . instrumentFilter . instrumentId
703+ effectiveInstrumentIds
642704 ) ;
643705 }
644706
@@ -788,12 +850,21 @@ export default class PostgresProposalDataSource implements ProposalDataSource {
788850
789851 if ( filter ?. instrumentFilter ?. showMultiInstrumentProposals ) {
790852 query . whereRaw ( 'jsonb_array_length(instruments) > 1' ) ;
791- } else if ( filter ?. instrumentFilter ?. instrumentId ) {
792- // NOTE: Using jsonpath we check the jsonb (instruments) field if it contains object with id equal to filter.instrumentId
793- query . whereRaw (
794- 'jsonb_path_exists(instruments, \'$[*].id \\? (@.type() == "number" && @ == :instrumentId:)\')' ,
795- { instrumentId : filter . instrumentFilter ?. instrumentId }
853+ } else {
854+ const effectiveInstrumentIds = resolveInstrumentIds (
855+ filter ?. instrumentFilter
796856 ) ;
857+ if ( effectiveInstrumentIds && effectiveInstrumentIds . length > 0 ) {
858+ // NOTE: Using jsonpath we check the jsonb (instruments) field if it contains object with id equal to filter.instrumentId
859+ query . where ( function ( ) {
860+ effectiveInstrumentIds . forEach ( ( id ) => {
861+ this . orWhereRaw (
862+ 'jsonb_path_exists(instruments, \'$[*].id \\? (@.type() == "number" && @ == :instrumentId:)\')' ,
863+ { instrumentId : id }
864+ ) ;
865+ } ) ;
866+ } ) ;
867+ }
797868 }
798869
799870 if ( filter ?. proposalStatusId ) {
@@ -1117,14 +1188,15 @@ export default class PostgresProposalDataSource implements ProposalDataSource {
11171188 'ins.instrument_id'
11181189 )
11191190 . modify ( ( query ) => {
1120- const instrumentId = filter ?. instrumentFilter ?. instrumentId ;
1191+ const effectiveInstrumentIds = resolveInstrumentIds (
1192+ filter ?. instrumentFilter
1193+ ) ;
11211194
1122- if ( instrumentId && ! isNaN ( instrumentId ) ) {
1195+ if ( effectiveInstrumentIds && effectiveInstrumentIds . length > 0 ) {
11231196 query . join ( 'instrument_has_proposals as ihp' , function ( ) {
1124- this . on ( 'ihp.proposal_pk' , '=' , 'proposals.proposal_pk' ) . andOnVal (
1197+ this . on ( 'ihp.proposal_pk' , '=' , 'proposals.proposal_pk' ) . andOnIn (
11251198 'ihp.instrument_id' ,
1126- '=' ,
1127- instrumentId
1199+ effectiveInstrumentIds
11281200 ) ;
11291201 } ) ;
11301202 }
0 commit comments