simplify and automate offer creation
This commit is contained in:
1 parent
7ea2c37116
commit
a43d4f32e4
10 files changed
+97
-67
No files matched your search
+2
-1
@@ -28,7 +28,8 @@ async function start() {
|
||||
events,
|
||||
} = createServices(log);
|
||||
|
||||
events.emit(Events.StartupSync);
|
||||
// events.emit(Events.StartupSync);
|
||||
events.emit(Events.ListingsUpdated);
|
||||
|
||||
await api.listen();
|
||||
}
|
||||
|
||||
@@ -81,6 +81,7 @@ model Offer {
|
||||
want Want @relation(fields: [wantId], references: [id], onDelete: Cascade, onUpdate: Cascade)
|
||||
|
||||
// only one offer per want for a user
|
||||
@@unique([userId, wantId])
|
||||
// @@unique([userId, wantId])
|
||||
@@unique([listingId])
|
||||
@@map("offers")
|
||||
}
|
||||
+1
-41
@@ -37,46 +37,6 @@ export default function createApi(log: Log, pg: Pg, discogs, offers, events) {
|
||||
|
||||
const router = koaRouter();
|
||||
|
||||
interface ListingData extends Listing {
|
||||
data: any,
|
||||
want: { user: User },
|
||||
};
|
||||
|
||||
async function getBundles() {
|
||||
const bundles = await pg.bundleCandidates();
|
||||
|
||||
return bundles.map((b: ListingData[]) => {
|
||||
const total = b.reduce((acc, l) => acc + l.data.price.value, 0);
|
||||
const items = b.map(l => ({
|
||||
id: l.data.id,
|
||||
description: l.data.release.description,
|
||||
originalPrice: l.data.original_price.value,
|
||||
originalCurrency: l.data.original_price.curr_abbr,
|
||||
price: l.data.price.value,
|
||||
currency: l.data.price.currency,
|
||||
condition: l.data.condition,
|
||||
uri: l.data.uri,
|
||||
user: l.want.user,
|
||||
}));
|
||||
|
||||
const shipping = b[0]?.data.seller.shipping;
|
||||
|
||||
const bundle = {
|
||||
username: b[0]?.data.seller.username,
|
||||
seller: b[0]?.data.seller.id,
|
||||
shipsFrom: b[0]?.data.ships_from,
|
||||
total,
|
||||
currency: b[0]?.data.price.currency,
|
||||
shipping: '...',
|
||||
items,
|
||||
mentionsAustralia: shipping.toLowerCase().includes('australia'),
|
||||
mentionsWorldwide: shipping.toLowerCase().includes('world'),
|
||||
}
|
||||
|
||||
return bundle;
|
||||
});
|
||||
}
|
||||
|
||||
function listen() {
|
||||
return new Promise((resolve, reject) => {
|
||||
app.on('error', err => {
|
||||
@@ -105,7 +65,7 @@ export default function createApi(log: Log, pg: Pg, discogs, offers, events) {
|
||||
});
|
||||
|
||||
router.get('/acp/bundles', async function bundlesGet(ctx, next) {
|
||||
const bundles = await getBundles();
|
||||
const bundles = await offers.bundles();
|
||||
ctx.response.body = bundles;
|
||||
})
|
||||
|
||||
|
||||
+28
-1
@@ -11,9 +11,10 @@ import routerAuth from './routers/router.auth';
|
||||
export enum Events {
|
||||
WantsAdded = 'WantsAdded',
|
||||
StartupSync = 'StartupSync',
|
||||
ListingsUpdated = 'ListingsUpdated',
|
||||
}
|
||||
|
||||
export default function createEvents(log: Log, pg: Pg, discogs) {
|
||||
export default function createEvents(log: Log, pg: Pg, discogs, offers) {
|
||||
const events = new EventEmitter({ captureRejections: true });
|
||||
|
||||
events.on('error', function eventError(e) {
|
||||
@@ -50,5 +51,31 @@ export default function createEvents(log: Log, pg: Pg, discogs) {
|
||||
});
|
||||
|
||||
|
||||
events.on(Events.ListingsUpdated, async function listingsUpdated() {
|
||||
const bundles = await offers.bundles();
|
||||
log.info({ event: Events.ListingsUpdated, bundles: bundles.length });
|
||||
|
||||
// const bundle = {
|
||||
// username: b[0]?.data.seller.username,
|
||||
// seller: b[0]?.data.seller.id,
|
||||
// shipsFrom: b[0]?.data.ships_from,
|
||||
// total,
|
||||
// currency: b[0]?.data.price.currency,
|
||||
// shipping: '...',
|
||||
// items,
|
||||
// mentionsAustralia: shipping.toLowerCase().includes('australia'),
|
||||
// mentionsWorldwide: shipping.toLowerCase().includes('world'),
|
||||
// }
|
||||
|
||||
for (const bundle of bundles) {
|
||||
log.info({ seller: bundle.seller, items: bundle.items.length }, 'generating offers...');
|
||||
const listingIds = bundle.items.map(i => i.id);
|
||||
const updatedOffers = await offers.generate(listingIds, 100, 30)
|
||||
log.info({ offers: updatedOffers.length }, 'offers set');
|
||||
}
|
||||
|
||||
log.info('offers up to date');
|
||||
});
|
||||
|
||||
return events;
|
||||
}
|
||||
+46
-2
@@ -19,9 +19,11 @@ export default function createOffers(log: Log, pg: Pg) {
|
||||
log.info('generateOffers', { listingIds, bulkShipping, baseShipping });
|
||||
const listings = await pg.listingByIds(listingIds);
|
||||
|
||||
log.info({ listings }, 'creating offers for listings')
|
||||
// log.info({ listings }, 'creating offers for listings')
|
||||
|
||||
const shipping = bulkShipping / listings.length;
|
||||
const shipping = 10 + Math.random(); // yolt
|
||||
|
||||
// const shipping = bulkShipping / listings.length;
|
||||
// how to deal with users who don't want all items in a bundle...
|
||||
|
||||
const offers = listings.map(l => ({
|
||||
@@ -60,8 +62,50 @@ export default function createOffers(log: Log, pg: Pg) {
|
||||
return pg.offerSetStatus(offer.id, Status.Accepted);
|
||||
}
|
||||
|
||||
async function bundles() {
|
||||
const bundles = await pg.bundleCandidates();
|
||||
|
||||
interface ListingData extends Listing {
|
||||
data: any,
|
||||
want: { user: User },
|
||||
};
|
||||
|
||||
return bundles.map((b: ListingData[]) => {
|
||||
const total = b.reduce((acc, l) => acc + l.data.price.value, 0);
|
||||
const items = b.map(l => ({
|
||||
id: l.data.id,
|
||||
description: l.data.release.description,
|
||||
originalPrice: l.data.original_price.value,
|
||||
originalCurrency: l.data.original_price.curr_abbr,
|
||||
price: l.data.price.value,
|
||||
currency: l.data.price.currency,
|
||||
condition: l.data.condition,
|
||||
uri: l.data.uri,
|
||||
user: l.want.user,
|
||||
}));
|
||||
|
||||
const shipping = b[0]?.data.seller.shipping;
|
||||
|
||||
const bundle = {
|
||||
username: b[0]?.data.seller.username,
|
||||
seller: b[0]?.data.seller.id,
|
||||
shipsFrom: b[0]?.data.ships_from,
|
||||
total,
|
||||
currency: b[0]?.data.price.currency,
|
||||
shipping: '...',
|
||||
items,
|
||||
mentionsAustralia: shipping.toLowerCase().includes('australia'),
|
||||
mentionsWorldwide: shipping.toLowerCase().includes('world'),
|
||||
}
|
||||
|
||||
return bundle;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
generate,
|
||||
accept,
|
||||
bundles,
|
||||
};
|
||||
}
|
||||
+6
-6
@@ -2,6 +2,7 @@ import bcrypt from 'bcrypt';
|
||||
import type Log from 'bunyan';
|
||||
import type { PrismaClient, Want, User, Listing, Offer, Prisma } from '@prisma/client';
|
||||
import * as Bluebird from 'bluebird';
|
||||
import omit from 'lodash/omit';
|
||||
|
||||
import { Status } from './offers';
|
||||
|
||||
@@ -54,7 +55,7 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
|
||||
want: true,
|
||||
},
|
||||
orderBy: {
|
||||
status: 'desc',
|
||||
total: 'asc',
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -184,6 +185,8 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
|
||||
seller, count(distinct("wantId")), array_agg(id) as listings
|
||||
from
|
||||
listings
|
||||
where
|
||||
seller not in (3709203)
|
||||
group by
|
||||
seller
|
||||
order by
|
||||
@@ -208,13 +211,10 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
|
||||
return await prisma.$transaction(
|
||||
offers.map(offer => prisma.offer.upsert({
|
||||
where: {
|
||||
userId_wantId: {
|
||||
userId: offer.userId,
|
||||
wantId: offer.wantId,
|
||||
},
|
||||
listingId: offer.listingId,
|
||||
},
|
||||
create: offer,
|
||||
update: offer
|
||||
update: omit(offer, ['status']),
|
||||
}))
|
||||
);
|
||||
}
|
||||
|
||||
+1
-1
@@ -11,8 +11,8 @@ export default function creates(log) {
|
||||
const prisma = new PrismaClient();
|
||||
const pg = createPg(log, prisma);
|
||||
const discogs = createDiscogs(log, pg);
|
||||
const events = createEvents(log, pg, discogs);
|
||||
const offers = createOffers(log, pg);
|
||||
const events = createEvents(log, pg, discogs, offers);
|
||||
const api = createApi(log, pg, discogs, offers, events);
|
||||
|
||||
return {
|
||||
|
||||
Reference in new issue
Block a user