Add product
This commit is contained in:
@@ -65,8 +65,18 @@
|
|||||||
{
|
{
|
||||||
order(id: 588274) {
|
order(id: 588274) {
|
||||||
id
|
id
|
||||||
|
marketObject {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
vat
|
||||||
|
currency
|
||||||
|
priceAdjustment
|
||||||
|
}
|
||||||
rows {
|
rows {
|
||||||
id
|
id
|
||||||
|
order {
|
||||||
|
id
|
||||||
|
}
|
||||||
insertedDate
|
insertedDate
|
||||||
orderId
|
orderId
|
||||||
productId
|
productId
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
import { SQLDataSource } from 'datasource-sql';
|
import { SQLDataSource } from 'datasource-sql';
|
||||||
import { camelcase } from 'stringcase';
|
import { camelcase } from 'stringcase';
|
||||||
import { Address, ContactInformation, Order, OrderRow } from './order-types';
|
import {
|
||||||
|
Address,
|
||||||
|
ContactInformation,
|
||||||
|
Market,
|
||||||
|
Order,
|
||||||
|
OrderRow,
|
||||||
|
} from './order-types';
|
||||||
import { Maybe } from './types';
|
import { Maybe } from './types';
|
||||||
|
|
||||||
const MINUTE = 60;
|
const MINUTE = 60;
|
||||||
@@ -9,6 +15,24 @@ export class OrderAPI extends SQLDataSource {
|
|||||||
super(config);
|
super(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getMarketById(id: number): Promise<Market> {
|
||||||
|
return await this.knex
|
||||||
|
.select('*')
|
||||||
|
.from('markets')
|
||||||
|
.where('id', id)
|
||||||
|
.first()
|
||||||
|
.cache(MINUTE);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getMarketByName(name: string): Promise<Market> {
|
||||||
|
return await this.knex
|
||||||
|
.select('*')
|
||||||
|
.from('markets')
|
||||||
|
.where('name', name)
|
||||||
|
.first()
|
||||||
|
.cache(MINUTE);
|
||||||
|
}
|
||||||
|
|
||||||
async getAddress(addressId: number): Promise<Maybe<Address>> {
|
async getAddress(addressId: number): Promise<Maybe<Address>> {
|
||||||
const row = await this.knex
|
const row = await this.knex
|
||||||
.select('*')
|
.select('*')
|
||||||
@@ -103,7 +127,6 @@ export class OrderAPI extends SQLDataSource {
|
|||||||
}
|
}
|
||||||
const orderRow = details.reduce((obj, item) => {
|
const orderRow = details.reduce((obj, item) => {
|
||||||
obj[camelcase(fields[item.fieldid])] = item.value;
|
obj[camelcase(fields[item.fieldid])] = item.value;
|
||||||
obj['insertedDate'] = item.inserted;
|
|
||||||
return obj;
|
return obj;
|
||||||
}, {});
|
}, {});
|
||||||
|
|
||||||
@@ -120,6 +143,7 @@ export class OrderAPI extends SQLDataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* row
|
||||||
{
|
{
|
||||||
printId: '73963',
|
printId: '73963',
|
||||||
inserted: 2021-02-04T10:11:41.093Z,
|
inserted: 2021-02-04T10:11:41.093Z,
|
||||||
|
|||||||
@@ -1,3 +1,11 @@
|
|||||||
|
export interface Market {
|
||||||
|
id: number;
|
||||||
|
name: string;
|
||||||
|
vat: number;
|
||||||
|
currency: string;
|
||||||
|
priceAdjustment: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Address {
|
export interface Address {
|
||||||
id: number;
|
id: number;
|
||||||
firstname: string;
|
firstname: string;
|
||||||
@@ -71,7 +79,7 @@ export interface Order {
|
|||||||
|
|
||||||
export interface OrderRow {
|
export interface OrderRow {
|
||||||
id: number;
|
id: number;
|
||||||
insertedDate: Date;
|
inserted: Date;
|
||||||
orderId: number;
|
orderId: number;
|
||||||
productId: number;
|
productId: number;
|
||||||
productGroup: string;
|
productGroup: string;
|
||||||
|
|||||||
@@ -39,21 +39,29 @@ export class ProductAPI extends SQLDataSource {
|
|||||||
limit: Maybe<number>,
|
limit: Maybe<number>,
|
||||||
visible: Maybe<boolean>,
|
visible: Maybe<boolean>,
|
||||||
browsable: Maybe<boolean>,
|
browsable: Maybe<boolean>,
|
||||||
): Promise<Product> {
|
): Promise<Array<Product>> {
|
||||||
// console.log(limit, browsable, visible);
|
|
||||||
limit = limit ?? 100;
|
limit = limit ?? 100;
|
||||||
const query = sql.products(limit, visible, browsable);
|
const query = sql.products(limit, visible, browsable);
|
||||||
|
|
||||||
const data = await this.knex.raw(query).then((data) =>
|
return await this.knex.raw(query).then((data) =>
|
||||||
data.rows.map((row) => {
|
data.rows.map((row) => {
|
||||||
row.blacklisting = this.getBlacklisting(row);
|
row.blacklisting = this.getBlacklisting(row);
|
||||||
row.printProducts = this.getPrintProducts(row);
|
row.printProducts = this.getPrintProducts(row);
|
||||||
return row;
|
return row;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// console.log(JSON.stringify(data, null, 2));
|
async getProduct(id: number): Promise<Maybe<Product>> {
|
||||||
|
const query = sql.product(id);
|
||||||
|
|
||||||
return data;
|
const res = await this.knex.raw(query).then((data) =>
|
||||||
|
data.rows.map((row) => {
|
||||||
|
row.blacklisting = this.getBlacklisting(row);
|
||||||
|
row.printProducts = this.getPrintProducts(row);
|
||||||
|
return row;
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
return res.find(Boolean);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,14 +2,9 @@ import { Maybe } from '../types';
|
|||||||
|
|
||||||
// Get syntax highlighting with vscode by installing "Comment tagged templates2
|
// Get syntax highlighting with vscode by installing "Comment tagged templates2
|
||||||
|
|
||||||
export function products(
|
const baseQuery = /* sql */ `
|
||||||
limit: number = 100,
|
|
||||||
visible: Maybe<boolean>,
|
|
||||||
browsable: Maybe<boolean>,
|
|
||||||
) {
|
|
||||||
const query = /* sql */ `
|
|
||||||
|
|
||||||
SELECT products.productid as id,
|
SELECT products.productid as id,
|
||||||
products.path,
|
products.path,
|
||||||
products.visible,
|
products.visible,
|
||||||
products.browsable,
|
products.browsable,
|
||||||
@@ -50,6 +45,16 @@ export function products(
|
|||||||
) FROM product_blacklist WHERE product_blacklist.product_id = products.productid
|
) FROM product_blacklist WHERE product_blacklist.product_id = products.productid
|
||||||
) AS blacklisting
|
) AS blacklisting
|
||||||
FROM "product-products" products
|
FROM "product-products" products
|
||||||
|
`;
|
||||||
|
|
||||||
|
export function products(
|
||||||
|
limit: number = 100,
|
||||||
|
visible: Maybe<boolean>,
|
||||||
|
browsable: Maybe<boolean>,
|
||||||
|
) {
|
||||||
|
return (
|
||||||
|
baseQuery +
|
||||||
|
/* sql */ `
|
||||||
${
|
${
|
||||||
visible != null
|
visible != null
|
||||||
? /* sql */ `
|
? /* sql */ `
|
||||||
@@ -58,7 +63,15 @@ export function products(
|
|||||||
: ``
|
: ``
|
||||||
}
|
}
|
||||||
LIMIT ${limit}
|
LIMIT ${limit}
|
||||||
`;
|
`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return query;
|
export function product(id: number) {
|
||||||
|
return (
|
||||||
|
baseQuery +
|
||||||
|
/* sql */ `
|
||||||
|
WHERE products.productid = ${id}
|
||||||
|
`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import knexStringcase from 'knex-stringcase';
|
|||||||
import { dbConfig } from './config';
|
import { dbConfig } from './config';
|
||||||
import { typeDefs } from './schema';
|
import { typeDefs } from './schema';
|
||||||
import resolvers from './resolvers';
|
import resolvers from './resolvers';
|
||||||
|
|
||||||
import { OrderAPI } from './datasources/order-api';
|
import { OrderAPI } from './datasources/order-api';
|
||||||
import { ProductAPI } from './datasources/product-api';
|
import { ProductAPI } from './datasources/product-api';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { GraphQLScalarType } from 'graphql';
|
import { GraphQLScalarType } from 'graphql';
|
||||||
import { Kind } from 'graphql/language';
|
import { Kind } from 'graphql/language';
|
||||||
|
|
||||||
|
// possible switch to https://github.com/Urigo/graphql-scalars
|
||||||
export const DateTimeScalar = new GraphQLScalarType({
|
export const DateTimeScalar = new GraphQLScalarType({
|
||||||
name: 'DateTime',
|
name: 'DateTime',
|
||||||
description: 'Date custom scalar type',
|
description: 'Date custom scalar type',
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import orders, { ContactInformation, Order } from './orders-resolver';
|
import { orderQueryTypeDefs, orderTypeDefs } from './orders-resolver';
|
||||||
import products from './products-resolver';
|
import { productQueryTypeDefs, productTypeDefs } from './products-resolver';
|
||||||
import { DateTimeScalar } from './datetime-type';
|
import { DateTimeScalar } from './datetime-type';
|
||||||
|
|
||||||
const resolvers = {
|
const resolvers = {
|
||||||
Query: { ...orders, ...products },
|
Query: { ...orderQueryTypeDefs, ...productQueryTypeDefs },
|
||||||
DateTime: DateTimeScalar,
|
DateTime: DateTimeScalar,
|
||||||
ContactInformation,
|
...orderTypeDefs,
|
||||||
Order,
|
...productTypeDefs,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default resolvers;
|
export default resolvers;
|
||||||
|
|||||||
@@ -1,16 +1,25 @@
|
|||||||
import { IResolverObject } from 'graphql-tools';
|
import { IResolverObject } from 'graphql-tools';
|
||||||
|
|
||||||
export const ContactInformation: IResolverObject = {
|
const ContactInformation: IResolverObject = {
|
||||||
// (parent, args, ctx, info)
|
// (parent, args, ctx, info)
|
||||||
async address({ addressId }, args, { dataSources }) {
|
async address({ addressId }, args, { dataSources }) {
|
||||||
return dataSources.orderApi.getAddress(addressId);
|
return dataSources.orderApi.getAddress(addressId);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export const Order: IResolverObject = {
|
const Order: IResolverObject = {
|
||||||
async rows({ id }, args, { dataSources }) {
|
async rows({ id }, args, { dataSources }) {
|
||||||
return dataSources.orderApi.getOrderRows(id);
|
return dataSources.orderApi.getOrderRows(id);
|
||||||
},
|
},
|
||||||
|
async marketObject({ market }, args, { dataSources }) {
|
||||||
|
return dataSources.orderApi.getMarketByName(market);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const OrderRow: IResolverObject = {
|
||||||
|
async order(parent, args, { dataSources }) {
|
||||||
|
return dataSources.orderApi.getOrder(parent.orderId);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
async function getOrders(_, __, { dataSources }) {
|
async function getOrders(_, __, { dataSources }) {
|
||||||
@@ -21,9 +30,13 @@ async function getOrder(_, { id }, { dataSources }) {
|
|||||||
return dataSources.orderApi.getOrder(id);
|
return dataSources.orderApi.getOrder(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const orders = {
|
export const orderTypeDefs = {
|
||||||
|
ContactInformation,
|
||||||
|
Order,
|
||||||
|
OrderRow,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const orderQueryTypeDefs = {
|
||||||
orders: getOrders,
|
orders: getOrders,
|
||||||
order: getOrder,
|
order: getOrder,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default orders;
|
|
||||||
|
|||||||
@@ -1,7 +1,25 @@
|
|||||||
// (parent, args, ctx, info)
|
// (parent, args, ctx, info)
|
||||||
const products = {
|
import { IResolverObject } from 'graphql-tools';
|
||||||
products: (_, { limit, visible, browsable }, { dataSources }) =>
|
|
||||||
dataSources.productApi.getProducts(limit, visible, browsable),
|
const ProductBlacklist: IResolverObject = {
|
||||||
|
async market(parent, args, { dataSources }) {
|
||||||
|
return dataSources.orderApi.getMarketById(parent.marketId);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default products;
|
async function getProducts(_, { limit, visible, browsable }, { dataSources }) {
|
||||||
|
return dataSources.productApi.getProducts(limit, visible, browsable);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getProduct(_, { id }, { dataSources }) {
|
||||||
|
return dataSources.productApi.getProduct(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
export const productTypeDefs = {
|
||||||
|
ProductBlacklist,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const productQueryTypeDefs = {
|
||||||
|
products: getProducts,
|
||||||
|
product: getProduct,
|
||||||
|
};
|
||||||
|
|||||||
+21
-102
@@ -7,6 +7,15 @@ const typeDefs = gql`
|
|||||||
orders: [Order]
|
orders: [Order]
|
||||||
order(id: ID!): Order
|
order(id: ID!): Order
|
||||||
products(limit: Int, visible: Boolean, browsable: Boolean): [Product]
|
products(limit: Int, visible: Boolean, browsable: Boolean): [Product]
|
||||||
|
product(id: Int!): Product
|
||||||
|
}
|
||||||
|
|
||||||
|
type Market {
|
||||||
|
id: ID!
|
||||||
|
name: String
|
||||||
|
vat: Float
|
||||||
|
currency: String
|
||||||
|
priceAdjustment: Float
|
||||||
}
|
}
|
||||||
|
|
||||||
type Address {
|
type Address {
|
||||||
@@ -79,12 +88,13 @@ const typeDefs = gql`
|
|||||||
billingAddressId: Int
|
billingAddressId: Int
|
||||||
deliveryAddressId: Int
|
deliveryAddressId: Int
|
||||||
rows: [OrderRow]
|
rows: [OrderRow]
|
||||||
|
marketObject: Market
|
||||||
}
|
}
|
||||||
|
|
||||||
type OrderRow {
|
type OrderRow {
|
||||||
id: ID!
|
id: ID!
|
||||||
order: Order
|
order: Order
|
||||||
insertedDate: DateTime
|
inserted: DateTime
|
||||||
orderId: Int
|
orderId: Int
|
||||||
productId: Int
|
productId: Int
|
||||||
productGroup: String
|
productGroup: String
|
||||||
@@ -100,6 +110,11 @@ const typeDefs = gql`
|
|||||||
pwintySku: String
|
pwintySku: String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type Category {
|
||||||
|
id: ID!
|
||||||
|
name: String
|
||||||
|
}
|
||||||
|
|
||||||
type Product {
|
type Product {
|
||||||
id: ID!
|
id: ID!
|
||||||
path: String!
|
path: String!
|
||||||
@@ -126,6 +141,7 @@ const typeDefs = gql`
|
|||||||
groupId: Int!
|
groupId: Int!
|
||||||
group: ProductGroup!
|
group: ProductGroup!
|
||||||
marketId: Int!
|
marketId: Int!
|
||||||
|
market: Market!
|
||||||
inserted: DateTime!
|
inserted: DateTime!
|
||||||
updated: DateTime!
|
updated: DateTime!
|
||||||
}
|
}
|
||||||
@@ -141,38 +157,13 @@ const typeDefs = gql`
|
|||||||
|
|
||||||
export { typeDefs };
|
export { typeDefs };
|
||||||
/**
|
/**
|
||||||
schema {
|
|
||||||
query: Query
|
|
||||||
}
|
|
||||||
|
|
||||||
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 Category {
|
type Category {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String
|
name: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type ContactInformation {
|
|
||||||
email: String
|
|
||||||
phone: String
|
|
||||||
address: Address
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar Date
|
|
||||||
|
|
||||||
scalar DateTime
|
|
||||||
|
|
||||||
type Designer {
|
type Designer {
|
||||||
id: ID!
|
id: ID!
|
||||||
@@ -180,98 +171,26 @@ type Designer {
|
|||||||
orderRows(fromDate: Date, toDate: Date): [OrderRow]
|
orderRows(fromDate: Date, toDate: Date): [OrderRow]
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Group {
|
|
||||||
PHOTO_WALLPAPER
|
|
||||||
CANVAS
|
|
||||||
WALLPAPER
|
|
||||||
DO_IT_YOURSELF_FRAME
|
|
||||||
DESIGNER_WALLPAPER
|
|
||||||
POSTER
|
|
||||||
FRAMED_PRINT
|
|
||||||
}
|
|
||||||
|
|
||||||
scalar JSONString
|
|
||||||
|
|
||||||
type Market {
|
|
||||||
id: ID!
|
|
||||||
name: String
|
|
||||||
}
|
|
||||||
|
|
||||||
type Order {
|
|
||||||
id: ID!
|
|
||||||
insertedDate: DateTime!
|
|
||||||
paid: Boolean!
|
|
||||||
confirmed: Boolean!
|
|
||||||
delivered: Boolean!
|
|
||||||
canceled: Boolean!
|
|
||||||
countryCode: String!
|
|
||||||
locale: String!
|
|
||||||
market: String!
|
|
||||||
currency: String
|
|
||||||
contractCustomerId: Int
|
|
||||||
exchangeRateEUR: Float
|
|
||||||
language: String
|
|
||||||
pwintyId: Int
|
|
||||||
email: String
|
|
||||||
phone: String
|
|
||||||
rows: [OrderRow]
|
|
||||||
billingInformation: ContactInformation
|
|
||||||
deliveryInformation: ContactInformation
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
json: JSONString
|
|
||||||
}
|
|
||||||
|
|
||||||
type PrintProduct {
|
type PrintProduct {
|
||||||
id: ID!
|
|
||||||
group: Group!
|
|
||||||
insertedDate: DateTime!
|
insertedDate: DateTime!
|
||||||
updatedDate: DateTime
|
updatedDate: DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
type Product {
|
type Product {
|
||||||
id: ID!
|
|
||||||
path: String!
|
|
||||||
visible: Boolean
|
|
||||||
browsable: Boolean
|
|
||||||
insertedDate: DateTime!
|
|
||||||
updatedDate: DateTime!
|
|
||||||
categories: [Category]
|
categories: [Category]
|
||||||
designer: Designer
|
designer: Designer
|
||||||
printProducts: [PrintProduct]
|
insertedDate: DateTime!
|
||||||
blacklisting: [ProductBlacklist]
|
updatedDate: DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductBlacklist {
|
type ProductBlacklist {
|
||||||
id: ID!
|
|
||||||
group: Group!
|
|
||||||
marketId: String!
|
|
||||||
insertedDate: DateTime!
|
|
||||||
updatedDate: DateTime!
|
|
||||||
market: Market
|
market: Market
|
||||||
|
insertedDate: DateTime!
|
||||||
|
updatedDate: DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query {
|
type Query {
|
||||||
products(limit: Int, visible: Boolean, browsable: Boolean): [Product]
|
|
||||||
product(id: Int!): Product
|
product(id: Int!): Product
|
||||||
order(id: Int!): Order
|
|
||||||
designer(id: Int!): Designer
|
designer(id: Int!): Designer
|
||||||
designers: [Designer]
|
designers: [Designer]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user