offers changes and select status

This commit is contained in:
ntr committed 2022-09-10 17:47:18 +10:00
1 parent bbc3fe6b48
commit 5f853696ab
10 files changed
+80 -9

No files matched your search

+2 -1
View File
@@ -67,12 +67,13 @@ model Offer {
status String status String
item Decimal @db.Money item Decimal @db.Money
// markup Decimal @db.Money
shipping Decimal @db.Money shipping Decimal @db.Money
total Decimal @db.Money total Decimal @db.Money
comparison Decimal @db.Money comparison Decimal @db.Money
listingId Int listingId Int
listing Listing @relation(fields: [listingId], references: [id], onDelete: Restrict) listing Listing @relation(fields: [listingId], references: [id])
userId String @db.Uuid userId String @db.Uuid
user User @relation(fields: [userId], references: [id], onDelete: Cascade) user User @relation(fields: [userId], references: [id], onDelete: Cascade)
+1
View File
@@ -27,6 +27,7 @@ export default function createEvents(log: Log, pg: Pg, discogs, offers) {
await setTimeout(60 * 1000); await setTimeout(60 * 1000);
return populateListings(want); return populateListings(want);
} }
throw e;
} }
} }
+2 -1
View File
@@ -10,8 +10,9 @@ import { Pg } from './pg';
export enum Status { export enum Status {
Pending = 'pending', Pending = 'pending',
Accepted = 'accepted', Accepted = 'accepted',
Declined = 'declined',
Ordered = 'ordered', Ordered = 'ordered',
Delivered = 'delivered', Complete = 'complete',
} }
export default function createOffers(log: Log, pg: Pg) { export default function createOffers(log: Log, pg: Pg) {
+43 -4
View File
@@ -2,7 +2,7 @@ import bcrypt from 'bcrypt';
import type Log from 'bunyan'; import type Log from 'bunyan';
import type { PrismaClient, Want, User, Listing, Offer, Prisma } from '@prisma/client'; import type { PrismaClient, Want, User, Listing, Offer, Prisma } from '@prisma/client';
import * as Bluebird from 'bluebird'; import * as Bluebird from 'bluebird';
import omit from 'lodash/omit'; import _ from 'lodash';
import { Status } from './offers'; import { Status } from './offers';
@@ -123,17 +123,56 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
}); });
} }
async function listingRmUnlisted(want: Want, ids: DiscogsListing[]) { async function listingRmUnlisted(want: Want, currentListingIds: DiscogsListing[]) {
return prisma.$transaction(async (prisma) => {
log.debug({ currentListingIds });
const openOfferStatuses = [Status.Pending, Status.Accepted];
// can't delete a listing with an open offer
// so delete those offers first
const { count: offersRemoved } = await prisma.offer.deleteMany({
where: {
wantId: want.id,
listingId: {
notIn: currentListingIds,
},
status: {
in: openOfferStatuses,
},
}
});
if (offersRemoved > 0) log.info({ offersRemoved }, 'open offers removed');
// now we have to filter listingIds with confirmed offers
// and get their listingIds to filter out
const confirmedListingIds = (await prisma.offer.findMany({
where: {
wantId: want.id,
status: {
notIn: openOfferStatuses,
}
},
select: {
listingId: true,
}
})).map(r => r.listingId);
const removalIds = _.without(currentListingIds, ...confirmedListingIds);
// finally we delete listings that aren't related
// to a historical offer
const { count } = await prisma.listing.deleteMany({ const { count } = await prisma.listing.deleteMany({
where: { where: {
wantId: want.id, wantId: want.id,
id: { id: {
notIn: ids, notIn: currentListingIds,
} }
} }
}); });
return count; return count;
});
} }
async function listingUpsert(listing, want) { async function listingUpsert(listing, want) {
@@ -214,7 +253,7 @@ export default function createPg(log: Log, prisma: PrismaClient): Pg {
listingId: offer.listingId, listingId: offer.listingId,
}, },
create: offer, create: offer,
update: omit(offer, ['status']), update: _.omit(offer, ['status']),
})) }))
); );
} }
+4
View File
@@ -2,6 +2,10 @@ import { route } from 'preact-router';
import http from './http'; import http from './http';
const actions = store => ({ const actions = store => ({
setWs: function setWs(state, ws) {
return { ws };
},
setUser: function setUser(state, user) { setUser: function setUser(state, user) {
return { user }; return { user };
}, },
+2 -1
View File
@@ -26,11 +26,12 @@ async function init() {
if (error) return route('/login'); if (error) return route('/login');
route('/bundles'); route('/bundles');
store.setState({ user }); store.setState({ user });
store.setState({ ws });
} }
init(); init();
const App = () =>{ const App = () => {
return ( return (
<Provider store={store}> <Provider store={store}>
<main id="app"> <main id="app">
+7
View File
@@ -96,6 +96,13 @@ const actions = {
id, id,
}); });
}, },
postOfferStatus: async function postOfferStatus(id, status) {
return api.post('/acp/offer/status', {
id,
status,
});
},
}; };
export default actions; export default actions;
+17 -2
View File
@@ -1,12 +1,22 @@
import { h } from 'preact'; import { h } from 'preact';
import { useState, useEffect } from 'preact/hooks'; import { useState, useEffect } from 'preact/hooks';
import { connect } from 'unistore/preact'
import http from './../http'; import http from './../http';
import AcpOffer from './../components/acp.offer'; import AcpOffer from './../components/acp.offer';
function Item(item) { import { Status } from './../../../api/src/offers';
function ItemEl({ item, ws }) {
console.log(item); console.log(item);
console.log(ws);
const statuses = Object.entries(Status).map(([label, value]) => (
<option value={value}>{label}</option>
));
function onChange(e) {
console.log(item.id, e.target.value);
}
return ( return (
<div key={item.id}> <div key={item.id}>
@@ -15,10 +25,15 @@ function Item(item) {
</a> </a>
<h5 class='alt-text'>{item.total}</h5> <h5 class='alt-text'>{item.total}</h5>
<h5>{item.status}</h5> <h5>{item.status}</h5>
<select onChange={onChange}>
{statuses}
</select>
</div> </div>
); );
} }
const Item = connect(['ws'], {}, ItemEl);
function SellerGroup(group) { function SellerGroup(group) {
return ( return (
<div class="bundle"> <div class="bundle">
@@ -29,7 +44,7 @@ function SellerGroup(group) {
</section> </section>
<div class='items'> <div class='items'>
{group.offers.map(Item)} {group.offers.map(i => <Item item={i} />)}
</div> </div>
</div> </div>
) )
+1
View File
@@ -5,5 +5,6 @@ export default function createStore() {
bundles: [], bundles: [],
offers: [], offers: [],
user: null, user: null,
ws: null,
}); });
}; };
+1
View File
@@ -31,6 +31,7 @@ services:
- '8080:8080' # fwd the hmr websocket - '8080:8080' # fwd the hmr websocket
volumes: volumes:
- "./client:/opt/mcrates/client" - "./client:/opt/mcrates/client"
- "./api:/opt/mcrates/api"
nginx: nginx:
image: nginx:latest image: nginx:latest