From e0f629d54d03b9ca97abb5eff374e3fbd8d236e0 Mon Sep 17 00:00:00 2001 From: Niklas Fondberg Date: Thu, 8 Apr 2021 13:20:43 +0200 Subject: [PATCH] Added orderrows --- package.json | 1 + queries.graphql | 66 +++++++++++ src/config.ts | 2 +- src/datasources/order-api.ts | 187 +++++++++++++++++-------------- src/datasources/order-types.ts | 88 +++++++++++++++ src/resolvers/index.ts | 3 +- src/resolvers/orders-resolver.ts | 8 +- src/schema.ts | 29 +++++ 8 files changed, 295 insertions(+), 89 deletions(-) create mode 100644 src/datasources/order-types.ts diff --git a/package.json b/package.json index 0278500..75ede10 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "pg": "^8.5.1", "pg-hstore": "^2.3.3", "prettier": "^2.2.1", + "stringcase": "^4.3.1", "ts-node": "^9.1.1", "typescript": "^4.2.3", "validator": "^13.5.2" diff --git a/queries.graphql b/queries.graphql index 989d8a0..0360b9b 100644 --- a/queries.graphql +++ b/queries.graphql @@ -18,3 +18,69 @@ } } } + +{ + order(id: 588274) { + id + rows { + id + } + billingInformation { + email + phone + address { + id + firstname + lastname + recipientName + companyname + address1 + address2 + countryCode + city + zipcode + stateCountyOrRegion + } + } + deliveryInformation { + email + phone + address { + id + firstname + lastname + recipientName + companyname + address1 + address2 + countryCode + city + zipcode + stateCountyOrRegion + } + } + } +} + +{ + order(id: 588274) { + id + rows { + id + insertedDate + orderId + productId + productGroup + artNo + path + name + price + designerId + commissionAmount + status + pwintyImageId + frameColor + pwintySku + } + } +} diff --git a/src/config.ts b/src/config.ts index e4aedd2..5957894 100644 --- a/src/config.ts +++ b/src/config.ts @@ -1,6 +1,6 @@ export const dbConfig = { client: 'pg', - connection: 'postgresql://fondberg:@docker.for.mac.localhost/photowall', + connection: process.env.DATABASE_URL, pool: { min: 1, max: 10, diff --git a/src/datasources/order-api.ts b/src/datasources/order-api.ts index 9db300d..71935ad 100644 --- a/src/datasources/order-api.ts +++ b/src/datasources/order-api.ts @@ -1,70 +1,9 @@ import { SQLDataSource } from 'datasource-sql'; +import { camelcase } from 'stringcase'; +import { Address, ContactInformation, Order, OrderRow } from './order-types'; import { Maybe } from './types'; const MINUTE = 60; - -interface Address { - id: number; - firstname: string; -} - -interface ContactInformation { - email: string; - phone: string; - addressId: number; -} - -interface Order { - id: number; - inserted: Date; - paid: boolean; - confirmed: boolean; - delivered: boolean; - newsletter: boolean; - creditInvoice: boolean; - canceled: boolean; - reminder: boolean; - deliveredDate: Date; - countryCode: string; - language: string; - deliveryCountryCode: string; - deliveryMethod: string; - deliveryPrice: string; - deliveryVat: number; - customerType: string; - paymentType: string; - attention: string; - currency: string; - exchangeRate: number; - exchangeRateEur: number; - invoiceId: string; - contractCustomerId: number | null; - vatNumber: string; - comment: string; - cancelsOrderId: number; - cancelledByOrderId: number; - orderlogId: number; - resellerStore: string; - orderSum: number; - klarnaOrderId: string; - pwintyId: number; - email: string; - phone: string; - deliveryEmail: string; - deliveryPhone: string; - customerFirstname: string; - customerLastname: string; - customerEmail: string; - customerCellphone: string; - flyerIds: string; - market: string; - locale: string; - billingInformation: ContactInformation; - deliveryInformation: ContactInformation; - billingAddressId: number; - deliveryAddressId: number; -} - export class OrderAPI extends SQLDataSource { constructor(config) { super(config); @@ -77,32 +16,18 @@ export class OrderAPI extends SQLDataSource { .where('id', addressId) .first() .cache(MINUTE); - console.log('HERE', row); + return row ? { - id: row.id, + ...row, + /* Change this later to camelCase but also need to change in Pwinty lambda */ firstname: row.firstName, + lastname: row.lastName, + companyname: row.companyName, + recipientName: `${row.firstName} ${row.lastName}`.trim(), + stateCountyOrRegion: row.state ? row.state : null, } : null; - /** - * address = cls() - address.id = row["id"] - address.firstname = row["first_name"] - address.lastname = row["last_name"] - address.companyname = row["company_name"] - address.address1 = row["address1"] - address.address2 = row["address2"] - address.countryCode = row["country_code"] - address.city = row["city"] - address.zipcode = row["zipcode"] - address.stateCountyOrRegion = row["state"] - - return address - - def resolve_recipientName(self, info): - if self.firstname or self.lastname: - return "{} {}".format(self.firstname, self.lastname).strip() - */ } getBillingInformation(row): ContactInformation { @@ -121,7 +46,7 @@ export class OrderAPI extends SQLDataSource { }; } - async getOrders() { + async getOrders(): Promise> { return await this.knex .select('*') .from('orders') @@ -142,6 +67,96 @@ export class OrderAPI extends SQLDataSource { .from('orders') .where('id', id) .first() - .cache(MINUTE); + .cache(MINUTE) + .then((row) => { + row.billingInformation = this.getBillingInformation(row); + row.deliveryInformation = this.getDeliveryInformation(row); + return row; + }); + } + + async getOrderRows(orderId: number): Promise> { + // const fields = await this.knex.select('*').from('order-row_fields'); + const fieldsRes = await this.knex + .raw('SELECT * from "order-row_fields"') + .then((data) => data.rows); + + const fields = fieldsRes.reduce((obj, item) => { + obj[item.fieldid] = item.name; + return obj; + }, {}); + + const rows = await this.knex + .raw('SELECT * FROM "order-rows" WHERE orderid = ?', orderId) + .then((data) => data.rows); + + let orderRows = []; + for (let i = 0; i < rows.length; i++) { + const rowId = rows[i].rowid; + const details = await this.knex + .raw('SELECT * FROM "order-rows_details" WHERE rowid = ?', rowId) + .then((data) => data.rows); + + // Skip empty order rows + if (!details.length) { + continue; + } + const orderRow = details.reduce((obj, item) => { + obj[camelcase(fields[item.fieldid])] = item.value; + obj['insertedDate'] = item.inserted; + return obj; + }, {}); + + if ('group' in orderRow) { + orderRow['productGroup'] = orderRow['group']; + } + + orderRow['id'] = rowId; + orderRow['orderId'] = orderId; + orderRows.push(orderRow); + } + return orderRows; } } + +/** +{ + printId: '73963', + inserted: 2021-02-04T10:11:41.093Z, + productId: '54192', + group: 'photo-wallpaper', + type: 'scaling', + artNo: 'e50075', + path: 'flora-hysterica-4', + name: 'Flora Hysterica 4', + price: '587.092480', + width: '640', + height: '260', + x: '0.000000', + y: '0.135133', + weight: '1', + designer: 'martin-bergstrom', + designerId: '201', + commission: '0', + commissionResale: '0', + status: 'print', + process: 'true', + vat: '1.210000', + commissionAmount: '0.000000', + framed: '0', + mirrored: '0', + edge: '0', + imageprocessed: 'true', + imageprocessingrejected: 'false', + resolution: '150', + imagedonotprint: 'false', + material: 'premium-wallpaper', + discountType: '%', + discountValue: '25', + measureUnit: 'cm', + displayWidth: '640', + displayHeight: '260', + designerPath: 'martin-bergstrom' + }, + + */ diff --git a/src/datasources/order-types.ts b/src/datasources/order-types.ts new file mode 100644 index 0000000..5a94ec5 --- /dev/null +++ b/src/datasources/order-types.ts @@ -0,0 +1,88 @@ +export interface Address { + id: number; + firstname: string; + lastname: string; + recipientName: string; + companyname: string; + address1: string; + address2: string; + countryCode: string; + city: string; + zipcode: string; + stateCountyOrRegion: string; +} + +export interface ContactInformation { + email: string; + phone: string; + addressId: number; +} + +export interface Order { + id: number; + inserted: Date; + paid: boolean; + confirmed: boolean; + delivered: boolean; + newsletter: boolean; + creditInvoice: boolean; + canceled: boolean; + reminder: boolean; + deliveredDate: Date; + countryCode: string; + language: string; + deliveryCountryCode: string; + deliveryMethod: string; + deliveryPrice: string; + deliveryVat: number; + customerType: string; + paymentType: string; + attention: string; + currency: string; + exchangeRate: number; + exchangeRateEur: number; + invoiceId: string; + contractCustomerId: number | null; + vatNumber: string; + comment: string; + cancelsOrderId: number; + cancelledByOrderId: number; + orderlogId: number; + resellerStore: string; + orderSum: number; + klarnaOrderId: string; + pwintyId: number; + email: string; + phone: string; + deliveryEmail: string; + deliveryPhone: string; + customerFirstname: string; + customerLastname: string; + customerEmail: string; + customerCellphone: string; + flyerIds: string; + market: string; + locale: string; + billingInformation: ContactInformation; + deliveryInformation: ContactInformation; + billingAddressId: number; + deliveryAddressId: number; +} + +export interface OrderRow { + id: number; + insertedDate: Date; + orderId: number; + productId: number; + productGroup: string; + artNo: string; + path: string; + name: string; + price: number; + designerId: string; + commissionAmount: string; + status: string; + pwintyImageId: number; + frameColor: string; + pwintySku: string; +} diff --git a/src/resolvers/index.ts b/src/resolvers/index.ts index 1d1843b..91143bd 100644 --- a/src/resolvers/index.ts +++ b/src/resolvers/index.ts @@ -1,4 +1,4 @@ -import orders, { ContactInformation } from './orders-resolver'; +import orders, { ContactInformation, Order } from './orders-resolver'; import products from './products-resolver'; import { DateTimeScalar } from './datetime-type'; @@ -6,6 +6,7 @@ const resolvers = { Query: { ...orders, ...products }, DateTime: DateTimeScalar, ContactInformation, + Order, }; export default resolvers; diff --git a/src/resolvers/orders-resolver.ts b/src/resolvers/orders-resolver.ts index 9dee12c..3e76c26 100644 --- a/src/resolvers/orders-resolver.ts +++ b/src/resolvers/orders-resolver.ts @@ -7,6 +7,12 @@ export const ContactInformation: IResolverObject = { }, }; +export const Order: IResolverObject = { + async rows({ id }, args, { dataSources }) { + return dataSources.orderApi.getOrderRows(id); + }, +}; + async function getOrders(_, __, { dataSources }) { return dataSources.orderApi.getOrders(); } @@ -17,7 +23,7 @@ async function getOrder(_, { id }, { dataSources }) { const orders = { orders: getOrders, - order: () => getOrder, + order: getOrder, }; export default orders; diff --git a/src/schema.ts b/src/schema.ts index bb3e594..218f1ce 100644 --- a/src/schema.ts +++ b/src/schema.ts @@ -12,6 +12,15 @@ const typeDefs = gql` type Address { id: ID! firstname: String + lastname: String + recipientName: String + companyname: String + address1: String + address2: String + countryCode: String + city: String + zipcode: String + stateCountyOrRegion: String } type ContactInformation { @@ -69,6 +78,26 @@ const typeDefs = gql` deliveryInformation: ContactInformation billingAddressId: Int deliveryAddressId: Int + rows: [OrderRow] + } + + type OrderRow { + id: ID! + order: Order + insertedDate: DateTime + orderId: Int + productId: Int + productGroup: String + artNo: String + path: String + name: String + price: Float + designerId: String + commissionAmount: String + status: String + pwintyImageId: Int + frameColor: String + pwintySku: String } type Product {