Skip to content

Commit cea9d24

Browse files
authored
feat(growers): filter growers by deviceIdentifier (#598)
1 parent 46730b6 commit cea9d24

4 files changed

Lines changed: 85 additions & 19 deletions

File tree

src/controllers/planter.controller.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,10 @@ import { Planter, Trees } from '../models';
2020
import { TreesFilter } from './trees.controller';
2121
import { PlanterRepository, TreesRepository } from '../repositories';
2222

23-
// Extend the LoopBack filter types for the Planter model to include organizationId
24-
type PlanterWhere = (Where<Planter> & { organizationId?: number }) | undefined;
23+
// Extend the LoopBack filter types for the Planter model to include organizationId and deviceIdentifier
24+
type PlanterWhere =
25+
| (Where<Planter> & { deviceIdentifier?: string; organizationId?: number })
26+
| undefined;
2527
export type PlanterFilter = Filter<Planter> & { where: PlanterWhere };
2628

2729
export class PlanterController {
@@ -44,6 +46,8 @@ export class PlanterController {
4446
@param.query.object('where', getWhereSchemaFor(Planter))
4547
where?: PlanterWhere,
4648
): Promise<Count> {
49+
const deviceIdentifier = where?.deviceIdentifier;
50+
4751
// Replace organizationId with full entity tree and planter
4852
if (where) {
4953
const { organizationId, ...whereWithoutOrganizationId } = where;
@@ -54,7 +58,7 @@ export class PlanterController {
5458
}
5559
// console.log('get /planter/count where -->', where);
5660

57-
return await this.planterRepository.countWithOrg(where);
61+
return await this.planterRepository.countWithOrg(where, deviceIdentifier);
5862
}
5963

6064
@get('/planter', {
@@ -73,6 +77,8 @@ export class PlanterController {
7377
@param.query.object('filter', getFilterSchemaFor(Planter))
7478
filter?: PlanterFilter,
7579
): Promise<Planter[]> {
80+
const deviceIdentifier = filter?.where?.deviceIdentifier;
81+
7682
// Replace organizationId with full entity tree and planter
7783
if (filter?.where) {
7884
const { organizationId, ...whereWithoutOrganizationId } = filter.where;
@@ -82,7 +88,7 @@ export class PlanterController {
8288
);
8389
}
8490

85-
return await this.planterRepository.findWithOrg(filter);
91+
return await this.planterRepository.findWithOrg(filter, deviceIdentifier);
8692
}
8793

8894
@get('/planter/{id}', {

src/controllers/planterRegistration.controller.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,13 @@ export class PlanterRegistrationController {
3333

3434
const sql = `SELECT * FROM planter_registrations
3535
LEFT JOIN (
36-
SELECT region.name AS country, region.geom FROM region, region_type
37-
WHERE region_type.type='country' AND region.type_id=region_type.id
38-
) AS region ON ST_DWithin(region.geom, planter_registrations.geom, 0.01)`;
36+
SELECT
37+
region.name AS country,
38+
region.geom FROM region, region_type
39+
WHERE region_type.type='country'
40+
AND region.type_id=region_type.id
41+
) AS region
42+
ON ST_DWithin(region.geom, planter_registrations.geom, 0.01)`;
3943

4044
const params = {
4145
filter,

src/models/planter.model.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
import { Entity, model, property } from '@loopback/repository';
1+
import { Entity, model, property, hasMany } from '@loopback/repository';
2+
import { PlanterRegistration } from './planterRegistration.model';
23

34
/* eslint-disable @typescript-eslint/no-empty-interface */
45

@@ -183,6 +184,9 @@ export class Planter extends Entity {
183184
})
184185
imageRotation?: Number;
185186

187+
@hasMany(() => PlanterRegistration, { keyTo: 'planterId' })
188+
planterRegs: PlanterRegistration[];
189+
186190
// Define well-known properties here
187191

188192
// Indexer property to allow additional data

src/repositories/planter.repository.ts

Lines changed: 63 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
import {
22
DefaultCrudRepository,
3+
repository,
4+
HasManyRepositoryFactory,
35
Filter,
6+
Options,
47
Where,
58
Count,
69
} from '@loopback/repository';
7-
import { Planter, PlanterRelations } from '../models';
10+
import { Planter, PlanterRelations, PlanterRegistration } from '../models';
811
import { TreetrackerDataSource } from '../datasources';
9-
import { inject } from '@loopback/core';
12+
import { inject, Getter } from '@loopback/core';
13+
import { PlanterRegistrationRepository } from './planterRegistration.repository';
1014
import expect from 'expect-runtime';
1115
import { buildFilterQuery } from '../js/buildFilterQuery';
1216
import { utils } from '../js/utils';
@@ -16,10 +20,24 @@ export class PlanterRepository extends DefaultCrudRepository<
1620
typeof Planter.prototype.id,
1721
PlanterRelations
1822
> {
23+
public readonly planterRegs: HasManyRepositoryFactory<
24+
PlanterRegistration,
25+
typeof Planter.prototype.id
26+
>;
1927
constructor(
2028
@inject('datasources.treetracker') dataSource: TreetrackerDataSource,
29+
@repository.getter('PlanterRegistrationRepository')
30+
protected planterRegistrationRepositoryGetter: Getter<PlanterRegistrationRepository>,
2131
) {
2232
super(Planter, dataSource);
33+
this.planterRegs = this.createHasManyRepositoryFactoryFor(
34+
'planterRegs',
35+
planterRegistrationRepositoryGetter,
36+
);
37+
this.registerInclusionResolver(
38+
'planterRegs',
39+
this.planterRegs.inclusionResolver,
40+
);
2341
}
2442

2543
async getEntityIdsByOrganizationId(
@@ -91,12 +109,27 @@ export class PlanterRepository extends DefaultCrudRepository<
91109
};
92110
}
93111

112+
getPlanterRegistrationJoinClause(deviceIdentifier: string): string {
113+
if (deviceIdentifier === null) {
114+
return `LEFT JOIN planter_registrations
115+
ON planter.id=planter_registrations.planter_id
116+
WHERE (planter_registrations.device_identifier ISNULL)
117+
GROUP BY planter.id`;
118+
}
119+
return `JOIN planter_registrations
120+
ON planter.id=planter_registrations.planter_id
121+
WHERE (planter_registrations.device_identifier='${deviceIdentifier}')
122+
GROUP BY planter.id`;
123+
}
124+
94125
// loopback .find() wasn't applying the org filters
95126
async findWithOrg(
96127
filter?: Filter<Planter>,
128+
deviceIdentifier?: string,
129+
options?: Options,
97130
): Promise<(Planter & PlanterRelations)[]> {
98-
if (!filter) {
99-
return await this.find(filter);
131+
if (!filter || deviceIdentifier === null) {
132+
return await this.find(filter, options);
100133
}
101134

102135
try {
@@ -106,7 +139,14 @@ export class PlanterRepository extends DefaultCrudRepository<
106139
filter,
107140
);
108141

109-
const selectStmt = `SELECT ${columnNames} FROM planter `;
142+
let selectStmt;
143+
if (deviceIdentifier) {
144+
selectStmt = `SELECT planter.* FROM planter ${this.getPlanterRegistrationJoinClause(
145+
deviceIdentifier,
146+
)}`;
147+
} else {
148+
selectStmt = `SELECT ${columnNames} FROM planter`;
149+
}
110150

111151
const params = {
112152
filter,
@@ -115,25 +155,37 @@ export class PlanterRepository extends DefaultCrudRepository<
115155
};
116156

117157
const query = buildFilterQuery(selectStmt, params);
158+
// console.log('query ---------', query);
118159

119-
const result = await this.execute(query.sql, query.params);
160+
const result = await this.execute(query.sql, query.params, options);
120161
return <Planter[]>result.map((planter) => utils.convertCamel(planter));
121162
} else {
122163
throw 'Connector not defined';
123164
}
124165
} catch (e) {
125166
console.log(e);
126-
return await this.find(filter);
167+
return await this.find(filter, options);
127168
}
128169
}
129170

130-
async countWithOrg(where?: Where<Planter>): Promise<Count> {
131-
if (!where) {
132-
return await this.count(where);
171+
async countWithOrg(
172+
where?: Where<Planter>,
173+
deviceIdentifier?: string,
174+
options?: Options,
175+
): Promise<Count> {
176+
if (!where || deviceIdentifier === null) {
177+
return await this.count(where, options);
133178
}
134179

135180
try {
136-
const selectStmt = `SELECT COUNT(*) FROM planter `;
181+
let selectStmt;
182+
if (deviceIdentifier) {
183+
selectStmt = `SELECT COUNT(*) FROM planter ${this.getPlanterRegistrationJoinClause(
184+
deviceIdentifier,
185+
)}`;
186+
} else {
187+
selectStmt = `SELECT COUNT(*) FROM planter`;
188+
}
137189

138190
const params = {
139191
filter: { where },

0 commit comments

Comments
 (0)