@chevre/domain
Version:
Chevre Domain Library for Node.js
173 lines (155 loc) • 6.85 kB
text/typescript
// tslint:disable:no-console
import * as fs from 'fs';
import * as moment from 'moment-timezone';
import * as mongoose from 'mongoose';
import { chevre } from '../../../../lib/index';
const PROJECT_ID = String(process.env.PROJECT_ID);
// const SCREEN_CODE = '10';
// const MOVIE_THEATER_CODE = '118';
const SCREEN_CODE = '130';
// const SCREEN_CODE = '211';
const MOVIE_THEATER_CODE = '020';
const AGGREGATE_PERIOD_IN_MONTHS = 12;
// tslint:disable-next-line:max-func-body-length
async function main() {
await mongoose.connect(<string>process.env.MONGOLAB_URI, { autoIndex: false });
const aggregateOrderRepo = await chevre.repository.AggregateOrder.createInstance(mongoose.connection);
const seatRepo = await chevre.repository.place.Seat.createInstance(mongoose.connection);
const orderRepo = await chevre.repository.Order.createInstance(mongoose.connection);
const royalCustomers = await aggregateOrderRepo.searchRoyalCustomers({
limit: 300,
project: { id: PROJECT_ID },
aggregateOrder: { orderCount: { $gte: 12 } }
});
// tslint:disable-next-line:no-null-keyword
console.dir(royalCustomers, { depth: null });
console.log(royalCustomers.length, 'royalCustomers found');
const customerEmails = royalCustomers.map(({ identifier }) => identifier);
const seats = <Pick<chevre.factory.place.seat.IPlace, 'branchCode'>[]>await seatRepo.searchSeats({
// limit: 50,
$projection: {
additionalProperty: 0,
'containedInPlace.typeOf': 0,
'containedInPlace.name': 0,
'containedInPlace.containedInPlace': 0,
name: 0, typeOf: 0
},
project: { id: { $eq: PROJECT_ID } },
containedInPlace: {
containedInPlace: {
branchCode: { $eq: SCREEN_CODE },
containedInPlace: { branchCode: { $eq: MOVIE_THEATER_CODE } }
}
}
});
// tslint:disable-next-line:no-null-keyword
// console.dir(seats, { depth: null });
console.log(seats.length, 'seats found');
const orderDateGte: Date = moment()
.add(-AGGREGATE_PERIOD_IN_MONTHS, 'months')
.toDate();
const orderDateLte: Date = moment()
.toDate();
let maxSumGraceTime: number = 0;
let maxRepeatRate: number = 0;
const seatsWithAggregateOrder: {
branchCode: string;
aggregateOrder: {
emailCount: number;
orderCount: number;
repeatRate: number;
avgGraceTime?: number;
sumGraceTime: number;
avgGraceTimeInHours?: number;
sumGraceTimeInHours: number;
};
score?: number;
}[] = [];
let i = 1;
for (const { branchCode } of seats) {
i += 1;
const startTime = process.hrtime();
const aggregateResult = await orderRepo.aggregateOrderOfSeat({
project: { id: { $eq: PROJECT_ID } },
orderDate: { $gte: orderDateGte, $lte: orderDateLte },
acceptedOffers: {
itemOffered: {
reservationFor: {
location: { branchCode: SCREEN_CODE },
superEvent: { location: { branchCode: MOVIE_THEATER_CODE } }
},
reservedTicket: { ticketedSeat: { seatNumber: branchCode } }
}
},
customer: { email: { $in: customerEmails } }
});
console.log('aggregateOrder:result', aggregateResult, orderDateGte, orderDateLte, i);
const diff = process.hrtime(startTime);
console.log(`aggregateOrderOfSeat took ${diff[0]} seconds and ${diff[1]} nanoseconds.`);
const emailCount = (typeof aggregateResult.aggregation.emailCount === 'number')
? aggregateResult.aggregation.emailCount
: 0;
const repeatRate = (aggregateResult.aggregation.orderCount > 0)
// tslint:disable-next-line:no-magic-numbers
? (aggregateResult.aggregation.orderCount - emailCount) * 100 / aggregateResult.aggregation.orderCount
: 0;
const sumGraceTime = (typeof aggregateResult.aggregation.sumGraceTime === 'number')
? aggregateResult.aggregation.sumGraceTime
: 0;
const avgGraceTimeInHours = (typeof aggregateResult.aggregation.sumGraceTime === 'number')
? Math.floor(
moment.duration(Math.floor(aggregateResult.aggregation.sumGraceTime / aggregateResult.aggregation.orderCount), 'milliseconds')
.asHours()
)
: 0;
const sumGraceTimeInHours = (typeof aggregateResult.aggregation.sumGraceTime === 'number')
? Math.floor(moment.duration(aggregateResult.aggregation.sumGraceTime, 'milliseconds')
.asHours())
: 0;
maxSumGraceTime = Math.max(sumGraceTime, maxSumGraceTime);
maxRepeatRate = Math.max(repeatRate, maxRepeatRate);
seatsWithAggregateOrder.push({
branchCode,
aggregateOrder: {
...aggregateResult.aggregation,
emailCount,
repeatRate,
avgGraceTimeInHours,
sumGraceTimeInHours,
sumGraceTime
}
});
}
const seatsJson = seatsWithAggregateOrder.map((seat, key) => {
// tslint:disable-next-line:no-magic-numbers
const score = Math.floor(seat.aggregateOrder.sumGraceTime * 100 / maxSumGraceTime);
console.log('aggregateOrder:result', seat.branchCode, key);
return {
branchCode: seat.branchCode,
score
};
});
const scoresByEmailJson = seatsWithAggregateOrder.map((seat, key) => {
// tslint:disable-next-line:no-magic-numbers
const score = Math.floor(seat.aggregateOrder.repeatRate * 100 / maxRepeatRate);
console.log('aggregateOrder:result', seat.branchCode, seat.aggregateOrder.emailCount, key);
return {
branchCode: seat.branchCode,
score
// repeatRate: seat.aggregateOrder.repeatRate,
// emailCount: seat.aggregateOrder.emailCount,
// orderCount: seat.aggregateOrder.orderCount
};
});
console.log('maxSumGraceTime:', maxSumGraceTime);
console.log('maxRepeatRate:', maxRepeatRate);
// tslint:disable-next-line:non-literal-fs-path no-null-keyword
fs.writeFileSync(`${__dirname}/seatScoresByGraceTime.json`, JSON.stringify(seatsJson, null, ' '));
// tslint:disable-next-line:non-literal-fs-path no-null-keyword
fs.writeFileSync(`${__dirname}/seatScoresByEmail.json`, JSON.stringify(scoresByEmailJson, null, ' '));
}
main()
.then(() => {
console.log('success!');
})
.catch(console.error);