Skip to content

Commit

Permalink
Add ProgressReportFilters.cumulativeSummary.scheduleStatus
Browse files Browse the repository at this point in the history
  • Loading branch information
CarsonF committed Oct 9, 2024
1 parent 396bcb4 commit 02e4b8e
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
} from '~/common';
import { EngagementFilters } from '../../engagement/dto';
import { PeriodicReportListInput } from '../../periodic-report/dto';
import { ProgressSummaryFilters } from '../../progress-summary/dto';
import { ProgressReportStatus } from './progress-report-status.enum';
import { ProgressReport } from './progress-report.entity';

Expand All @@ -21,6 +22,9 @@ export abstract class ProgressReportFilters extends PickType(
})
readonly status?: readonly ProgressReportStatus[];

@FilterField(() => ProgressSummaryFilters)
readonly cumulativeSummary?: ProgressSummaryFilters & {};

@FilterField(() => EngagementFilters)
readonly engagement?: EngagementFilters & {};
}
Expand Down
15 changes: 15 additions & 0 deletions src/components/progress-report/progress-report.repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@ import {
paginate,
requestingUser,
sortWith,
variable,
} from '~/core/database/query';
import { engagementFilters } from '../engagement/engagement.repository';
import { progressReportSorters } from '../periodic-report/periodic-report.repository';
import { SummaryPeriod } from '../progress-summary/dto';
import { progressSummaryFilters } from '../progress-summary/progress-summary.repository';
import {
ProgressReport,
ProgressReportFilters,
Expand Down Expand Up @@ -84,6 +87,18 @@ export const progressReportFilters = filter.define(
start: filter.dateTimeProp(),
end: filter.dateTimeProp(),
status: filter.stringListProp(),
cumulativeSummary: filter.sub(() => progressSummaryFilters)((sub) =>
sub
.optionalMatch([
node('outer'),
relation('out', '', 'summary', ACTIVE),
node('node', 'ProgressSummary', {
period: variable(`"${SummaryPeriod.Cumulative}"`),
}),
])
// needed in conjunction with `optionalMatch`
.with('outer, node'),
),
engagement: filter.sub(
() => engagementFilters,
'requestingUser',
Expand Down
1 change: 1 addition & 0 deletions src/components/progress-summary/dto/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './progress-summary.dto';
export * from './schedule-status.enum';
export * from './progress-summary-filters.dto';
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Field, InputType } from '@nestjs/graphql';
import { stripIndent } from 'common-tags';
import { ScheduleStatus } from './schedule-status.enum';

@InputType()
export abstract class ProgressSummaryFilters {
@Field(() => [ScheduleStatus], {
nullable: 'itemsAndList',
description: stripIndent`
Filter by schedule status.
- \`[X, Y]\` will allow summaries with either X or Y status.
- \`[null, X]\` will allow missing summaries or summaries with X status.
- \`[null]\` will filter to only missing summaries.
- \`null\` and \`[]\` will be ignored.
`,
})
readonly scheduleStatus?: ReadonlyArray<ScheduleStatus | null>;
}
40 changes: 38 additions & 2 deletions src/components/progress-summary/progress-summary.repository.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
import { Injectable } from '@nestjs/common';
import { mapValues } from '@seedcompany/common';
import { cleanJoin, isNotFalsy, mapValues, setOf } from '@seedcompany/common';
import { inArray, node, Query, relation } from 'cypher-query-builder';
import { ID } from '~/common';
import { CommonRepository } from '~/core/database';
import {
ACTIVE,
defineSorters,
filter,
listConcat,
merge,
SortCol,
} from '~/core/database/query';
import { WhereExp } from '~/core/database/query/where-and-list';
import { ProgressReport } from '../progress-report/dto';
import { FetchedSummaries, ProgressSummary, SummaryPeriod } from './dto';
import {
FetchedSummaries,
ProgressSummary,
ProgressSummaryFilters,
SummaryPeriod,
} from './dto';

@Injectable()
export class ProgressSummaryRepository extends CommonRepository {
Expand Down Expand Up @@ -95,3 +102,32 @@ export const progressSummarySorters = defineSorters(ProgressSummary, {
query.return<SortCol>('(node.actual - node.planned) as sortValue'),
).asRecord,
});

export const progressSummaryFilters = filter.define(
() => ProgressSummaryFilters,
{
scheduleStatus: ({ value, query }) => {
const status = setOf(value);
if (status.size === 0) {
return undefined;
}
if (status.size === 1 && status.has(null)) {
return query.where(new WhereExp('node IS NULL'));
}

const conditions = cleanJoin(' OR ', [
status.has(null) && `node IS NULL`,
status.has('Ahead') && `node.actual - node.planned > 0.1`,
status.has('Behind') && `node.actual - node.planned < -0.1`,
status.has('OnTime') &&
`node.actual - node.planned <= 0.1 and node.actual - node.planned >= -0.1`,
]);
const required = status.has(null) ? undefined : `node IS NOT NULL`;
const str = [required, conditions]
.filter(isNotFalsy)
.map((s) => `(${s})`)
.join(' AND ');
return str ? query.where(new WhereExp(str)) : query;
},
},
);
11 changes: 11 additions & 0 deletions src/core/database/query/where-and-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
WhereOp,
} from 'cypher-query-builder';
import { AnyConditions } from 'cypher-query-builder/dist/typings/clauses/where-utils';
import { exp, ExpressionInput } from './cypher-expression';

export class WhereAndList extends WhereOp {
constructor(public conditions: AnyConditions[]) {
Expand All @@ -24,3 +25,13 @@ export class WhereAndList extends WhereOp {
return braces ? `(${string})` : string;
}
}

export class WhereExp extends WhereOp {
constructor(public exp: ExpressionInput) {
super();
}

evaluate() {
return exp(this.exp);
}
}

0 comments on commit 02e4b8e

Please sign in to comment.