UNPKG

@chevre/domain

Version:

Chevre Domain Library for Node.js

173 lines (155 loc) • 6.85 kB
// 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);