@things-factory/integration-sellercraft 4.1.27 → 4.1.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-server/constants/index.js +1 -0
- package/dist-server/constants/index.js.map +1 -1
- package/dist-server/constants/order-status-mapping.js +10 -0
- package/dist-server/constants/order-status-mapping.js.map +1 -0
- package/dist-server/controllers/index.js +2 -0
- package/dist-server/controllers/index.js.map +1 -1
- package/dist-server/controllers/sellercraft/apis/fetch-order-document.js +2 -2
- package/dist-server/controllers/sellercraft/apis/fetch-order-document.js.map +1 -1
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.js +7 -5
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.js.map +1 -1
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.js +17 -14
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.js.map +1 -1
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.js +23 -37
- package/dist-server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.js.map +1 -1
- package/dist-server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.js +1 -1
- package/dist-server/routers/sellercraft-router.js +25 -9
- package/dist-server/routers/sellercraft-router.js.map +1 -1
- package/dist-server/service/index.js +5 -1
- package/dist-server/service/index.js.map +1 -1
- package/dist-server/service/marketplace-channel/index.js +9 -0
- package/dist-server/service/marketplace-channel/index.js.map +1 -0
- package/dist-server/service/marketplace-channel/marketplace-channel-order-mutation.js +142 -0
- package/dist-server/service/marketplace-channel/marketplace-channel-order-mutation.js.map +1 -0
- package/dist-server/service/marketplace-channel/marketplace-channel-product-mutation.js +138 -0
- package/dist-server/service/marketplace-channel/marketplace-channel-product-mutation.js.map +1 -0
- package/dist-server/service/marketplace-channel/marketplace-channel.js +83 -0
- package/dist-server/service/marketplace-channel/marketplace-channel.js.map +1 -0
- package/dist-server/service/sellercraft/sellercraft.js +1 -1
- package/package.json +15 -15
- package/server/constants/index.ts +2 -1
- package/server/constants/order-status-mapping.ts +6 -0
- package/server/controllers/index.ts +2 -0
- package/server/controllers/sellercraft/apis/fetch-order-document.ts +2 -2
- package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-categories.ts +7 -5
- package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-order.ts +18 -14
- package/server/controllers/sellercraft-channel-integration/apis/ingest-channel-product.ts +23 -43
- package/server/controllers/sellercraft-channel-integration/sellercraft-channel-integration.ts +1 -1
- package/server/routers/sellercraft-router.ts +41 -11
- package/server/service/index.ts +6 -1
- package/server/service/marketplace-channel/index.ts +6 -0
- package/server/service/marketplace-channel/marketplace-channel-order-mutation.ts +182 -0
- package/server/service/marketplace-channel/marketplace-channel-product-mutation.ts +167 -0
- package/server/service/marketplace-channel/marketplace-channel.ts +64 -0
- package/server/service/sellercraft/sellercraft.ts +1 -1
package/server/service/index.ts
CHANGED
@@ -3,10 +3,12 @@ export * from './sellercraft/sellercraft'
|
|
3
3
|
|
4
4
|
/* IMPORT ENTITIES AND RESOLVERS */
|
5
5
|
import { entities as SellercraftEntities, resolvers as SellercraftResolvers } from './sellercraft'
|
6
|
+
import { entities as MarketplaceChannelEntities, resolvers as MarketplaceSellercraftResolvers } from './marketplace-channel'
|
6
7
|
|
7
8
|
export const entities = [
|
8
9
|
/* ENTITIES */
|
9
10
|
...SellercraftEntities,
|
11
|
+
...MarketplaceChannelEntities
|
10
12
|
]
|
11
13
|
|
12
14
|
|
@@ -14,5 +16,8 @@ export const schema = {
|
|
14
16
|
resolverClasses: [
|
15
17
|
/* RESOLVER CLASSES */
|
16
18
|
...SellercraftResolvers,
|
17
|
-
|
19
|
+
...MarketplaceSellercraftResolvers
|
20
|
+
]
|
18
21
|
}
|
22
|
+
|
23
|
+
export { MarketplaceSellercraftResolvers }
|
@@ -0,0 +1,6 @@
|
|
1
|
+
import { MarketplaceChannel } from './marketplace-channel'
|
2
|
+
import { MarketplaceChannelOrderMutation } from './marketplace-channel-order-mutation'
|
3
|
+
import { MarketplaceChannelProductMutation } from './marketplace-channel-product-mutation'
|
4
|
+
|
5
|
+
export const entities = [MarketplaceChannel]
|
6
|
+
export const resolvers = [MarketplaceChannelOrderMutation, MarketplaceChannelProductMutation]
|
@@ -0,0 +1,182 @@
|
|
1
|
+
import { Arg, Ctx, Mutation, Resolver } from 'type-graphql'
|
2
|
+
import { getRepository } from 'typeorm'
|
3
|
+
|
4
|
+
import { MarketplaceChannel } from './marketplace-channel'
|
5
|
+
|
6
|
+
import { config } from '@things-factory/env'
|
7
|
+
import { StoreAPI } from '@things-factory/integration-marketplace'
|
8
|
+
import { SellercraftChannelIntegrationAPI } from '../../controllers/sellercraft-channel-integration-api'
|
9
|
+
|
10
|
+
@Resolver()
|
11
|
+
export class MarketplaceChannelOrderMutation {
|
12
|
+
@Mutation(returns => Boolean)
|
13
|
+
async syncAllMarketplaceChannelOrders(
|
14
|
+
@Arg('fromDate') fromDate: string,
|
15
|
+
@Arg('toDate') toDate: string,
|
16
|
+
@Ctx() context: any
|
17
|
+
): Promise<boolean> {
|
18
|
+
const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
|
19
|
+
const { tokenCraftApiKey: apiKey, getShopsTokenCraftUrl } = sellercraftChannelIntegrationConfig
|
20
|
+
|
21
|
+
const channels: MarketplaceChannel[] = await getRepository(MarketplaceChannel).find()
|
22
|
+
|
23
|
+
for (var i = 0; i < channels.length; i++) {
|
24
|
+
var channelsFullPath = getShopsTokenCraftUrl + '?channel_id=' + channels[i].channelId
|
25
|
+
const channelResponse: any = await fetch(channelsFullPath, {
|
26
|
+
method: 'get',
|
27
|
+
headers: {
|
28
|
+
'Content-Type': 'application/json',
|
29
|
+
'x-api-key': apiKey
|
30
|
+
}
|
31
|
+
})
|
32
|
+
|
33
|
+
if (!channelResponse.ok) {
|
34
|
+
throw new Error(channelResponse)
|
35
|
+
}
|
36
|
+
var shopsResponse = await channelResponse.json()
|
37
|
+
var shops = shopsResponse.shops
|
38
|
+
|
39
|
+
for (var j = 0; j < shops.length; j++) {
|
40
|
+
var store = {
|
41
|
+
accessKey: shops[j].credential.consumer_key,
|
42
|
+
accessSecret: shops[j].credential.consumer_secret,
|
43
|
+
storeURL: shops[j].credential.store_url,
|
44
|
+
platform: channels[i].name
|
45
|
+
}
|
46
|
+
|
47
|
+
// let countryCode = shops[j].country_code
|
48
|
+
// let channelCode = shops[j].org_prefix
|
49
|
+
let organisationId = shops[j].credential.account_id
|
50
|
+
let channelShopId = shops[j].credential.channel_shop_id
|
51
|
+
|
52
|
+
const orderReq = {
|
53
|
+
fromDate: fromDate,
|
54
|
+
toDate: toDate
|
55
|
+
}
|
56
|
+
const orderResult = await StoreAPI.getStoreOrders(store, orderReq)
|
57
|
+
|
58
|
+
var sellercraftStore = { ...store, platform: 'sellercraftChannelIntegration' }
|
59
|
+
|
60
|
+
let mappedOrderResult = orderResult.results.map(order => {
|
61
|
+
let {
|
62
|
+
firstName: custFirstName,
|
63
|
+
lastName: custLastName,
|
64
|
+
orderCreatedAt: createdAt,
|
65
|
+
orderUpdatedAt: updatedAt,
|
66
|
+
orderNo: id,
|
67
|
+
status
|
68
|
+
} = order
|
69
|
+
|
70
|
+
let {
|
71
|
+
first_name: billFirstName,
|
72
|
+
last_name: billLastName,
|
73
|
+
address_1: billAddress1,
|
74
|
+
address_2: billAddress2,
|
75
|
+
address_3: billAddress3,
|
76
|
+
address_4: billAddress4,
|
77
|
+
address_5: billAddress5,
|
78
|
+
city: billCity,
|
79
|
+
postcode: billPostalCode,
|
80
|
+
country: billCountry,
|
81
|
+
phone: billPhone1,
|
82
|
+
phone_2: billPhone2
|
83
|
+
} = order.billing
|
84
|
+
|
85
|
+
let {
|
86
|
+
first_name: shipFirstName,
|
87
|
+
last_name: shipLastName,
|
88
|
+
address_1: shipAddress1,
|
89
|
+
address_2: shipAddress2,
|
90
|
+
address_3: shipAddress3,
|
91
|
+
address_4: shipAddress4,
|
92
|
+
address_5: shipAddress5,
|
93
|
+
city: shipCity,
|
94
|
+
postcode: shipPostalCode,
|
95
|
+
country: shipCountry,
|
96
|
+
phone: shipPhone1,
|
97
|
+
phone_2: shipPhone2
|
98
|
+
} = order.shipping
|
99
|
+
|
100
|
+
let orderItems = order.orderItems.map(item => {
|
101
|
+
let {
|
102
|
+
name: id,
|
103
|
+
variationId: variationId,
|
104
|
+
slaExpiresAt,
|
105
|
+
total,
|
106
|
+
totalTax,
|
107
|
+
subtotal,
|
108
|
+
subtotalTax
|
109
|
+
} = item
|
110
|
+
|
111
|
+
return {
|
112
|
+
id,
|
113
|
+
variationId,
|
114
|
+
currency: order.orderShipping.collectionCurrency,
|
115
|
+
createdAt: order.orderCreatedAt,
|
116
|
+
updatedAt: order.orderUpdatedAt,
|
117
|
+
charges: [
|
118
|
+
{
|
119
|
+
name: 'PRICE_NORMAL_SELLING',
|
120
|
+
grossAmount: total,
|
121
|
+
nettAmount: subtotal
|
122
|
+
},
|
123
|
+
{
|
124
|
+
name: 'TAXES',
|
125
|
+
grossAmount: totalTax,
|
126
|
+
nettAmount: subtotalTax
|
127
|
+
}
|
128
|
+
],
|
129
|
+
slaExpiresAt
|
130
|
+
}
|
131
|
+
})
|
132
|
+
|
133
|
+
return {
|
134
|
+
custFirstName,
|
135
|
+
custLastName,
|
136
|
+
createdAt,
|
137
|
+
updatedAt,
|
138
|
+
id,
|
139
|
+
billFirstName,
|
140
|
+
billLastName,
|
141
|
+
billAddress1,
|
142
|
+
billAddress2,
|
143
|
+
billAddress3,
|
144
|
+
billAddress4,
|
145
|
+
billAddress5,
|
146
|
+
billCity,
|
147
|
+
billPostalCode,
|
148
|
+
billCountry,
|
149
|
+
billPhone1,
|
150
|
+
billPhone2,
|
151
|
+
shipFirstName,
|
152
|
+
shipLastName,
|
153
|
+
shipAddress1,
|
154
|
+
shipAddress2,
|
155
|
+
shipAddress3,
|
156
|
+
shipAddress4,
|
157
|
+
shipAddress5,
|
158
|
+
shipCity,
|
159
|
+
shipPostalCode,
|
160
|
+
shipCountry,
|
161
|
+
shipPhone1,
|
162
|
+
shipPhone2,
|
163
|
+
orderItems,
|
164
|
+
channelShopId,
|
165
|
+
organisationId,
|
166
|
+
status
|
167
|
+
}
|
168
|
+
|
169
|
+
})
|
170
|
+
|
171
|
+
if (mappedOrderResult.length > 0) {
|
172
|
+
const ingestOrder = await SellercraftChannelIntegrationAPI.ingestChannelOrder(
|
173
|
+
sellercraftStore,
|
174
|
+
{ orders: mappedOrderResult }
|
175
|
+
)
|
176
|
+
}
|
177
|
+
}
|
178
|
+
|
179
|
+
return true
|
180
|
+
}
|
181
|
+
}
|
182
|
+
}
|
@@ -0,0 +1,167 @@
|
|
1
|
+
import { Ctx, Mutation, Resolver } from 'type-graphql'
|
2
|
+
import { getRepository } from 'typeorm'
|
3
|
+
|
4
|
+
import { MarketplaceChannel } from './marketplace-channel'
|
5
|
+
|
6
|
+
import { config } from '@things-factory/env'
|
7
|
+
import { StoreAPI } from '@things-factory/integration-marketplace'
|
8
|
+
import { SellercraftChannelIntegrationAPI } from '../../controllers/sellercraft-channel-integration-api'
|
9
|
+
|
10
|
+
@Resolver()
|
11
|
+
export class MarketplaceChannelProductMutation {
|
12
|
+
@Mutation(returns => Boolean)
|
13
|
+
async syncAllMarketplaceChannelProducts(
|
14
|
+
@Ctx() context: any
|
15
|
+
): Promise<boolean> {
|
16
|
+
const sellercraftChannelIntegrationConfig = config.get('sellercraftChannelIntegrationConfig', {})
|
17
|
+
const { tokenCraftApiKey: apiKey, getShopsTokenCraftUrl } = sellercraftChannelIntegrationConfig
|
18
|
+
|
19
|
+
const channels: MarketplaceChannel[] = await getRepository(MarketplaceChannel).find()
|
20
|
+
|
21
|
+
for (var i = 0; i < channels.length; i++) {
|
22
|
+
var channelsFullPath = getShopsTokenCraftUrl + '?channel_id=' + channels[i].channelId
|
23
|
+
const channelResponse: any = await fetch(channelsFullPath, {
|
24
|
+
method: 'get',
|
25
|
+
headers: {
|
26
|
+
'Content-Type': 'application/json',
|
27
|
+
'x-api-key': apiKey
|
28
|
+
}
|
29
|
+
})
|
30
|
+
|
31
|
+
if (!channelResponse.ok) {
|
32
|
+
throw new Error(channelResponse)
|
33
|
+
}
|
34
|
+
var shopsResponse = await channelResponse.json()
|
35
|
+
var shops = shopsResponse.shops
|
36
|
+
|
37
|
+
for (var j = 0; j < shops.length; j++) {
|
38
|
+
var store = {
|
39
|
+
accessKey: shops[j].credential.consumer_key,
|
40
|
+
accessSecret: shops[j].credential.consumer_secret,
|
41
|
+
storeURL: shops[j].credential.store_url,
|
42
|
+
platform: channels[i].name
|
43
|
+
}
|
44
|
+
|
45
|
+
let countryCode = shops[j].country_code
|
46
|
+
let channelCode = shops[j].org_prefix
|
47
|
+
let organisationId = shops[j].credential.account_id
|
48
|
+
let channelShopId = shops[j].credential.channel_shop_id
|
49
|
+
|
50
|
+
var sellercraftStore = { ...store, platform: 'sellercraftChannelIntegration' }
|
51
|
+
|
52
|
+
const productResult = await StoreAPI.getStoreProducts(store, {})
|
53
|
+
|
54
|
+
const categoryResult = await StoreAPI.getStoreProductCategories(store, {})
|
55
|
+
|
56
|
+
let mappedProducts = productResult.results.map((item) => {
|
57
|
+
let {
|
58
|
+
categoryId,
|
59
|
+
itemId: productId,
|
60
|
+
name,
|
61
|
+
brand,
|
62
|
+
isVerified,
|
63
|
+
images,
|
64
|
+
attributes,
|
65
|
+
variations
|
66
|
+
} = item
|
67
|
+
|
68
|
+
variations = variations.map(variation => {
|
69
|
+
let {
|
70
|
+
variationSku,
|
71
|
+
variationId,
|
72
|
+
name,
|
73
|
+
isEnabled: isEnabled,
|
74
|
+
isEnabled: isSellable,
|
75
|
+
attributes,
|
76
|
+
stockLocked,
|
77
|
+
qty: stockReported,
|
78
|
+
costPrice: fullPrice,
|
79
|
+
sellPrice: priceDiscounted,
|
80
|
+
length,
|
81
|
+
width,
|
82
|
+
height,
|
83
|
+
weight
|
84
|
+
} = variation
|
85
|
+
|
86
|
+
return {
|
87
|
+
variationSku,
|
88
|
+
variationId,
|
89
|
+
name,
|
90
|
+
isEnabled,
|
91
|
+
isSellable,
|
92
|
+
attributes,
|
93
|
+
stockLocked,
|
94
|
+
stockReported,
|
95
|
+
fullPrice,
|
96
|
+
priceDiscounted,
|
97
|
+
inventoryProducts: [{
|
98
|
+
qty: stockReported,
|
99
|
+
name: `${name} - ${variationSku}`,
|
100
|
+
sku: variationSku,
|
101
|
+
productVersions: [{
|
102
|
+
label: 'Default',
|
103
|
+
packageLengthMM: length,
|
104
|
+
packageWidthMM: width,
|
105
|
+
packageHeightMM: height,
|
106
|
+
packageWeightGram: weight,
|
107
|
+
qty: 1
|
108
|
+
}]
|
109
|
+
}]
|
110
|
+
}
|
111
|
+
})
|
112
|
+
|
113
|
+
images = images.map(image => {
|
114
|
+
return {
|
115
|
+
url: image
|
116
|
+
}
|
117
|
+
})
|
118
|
+
|
119
|
+
return {
|
120
|
+
organisationId,
|
121
|
+
channelShopId: channelShopId,
|
122
|
+
channelCode: channels[i].channelCode,
|
123
|
+
channelCountry: shops[j].country_code,
|
124
|
+
categoryId,
|
125
|
+
productId,
|
126
|
+
name,
|
127
|
+
brand,
|
128
|
+
isVerified,
|
129
|
+
images,
|
130
|
+
attributes,
|
131
|
+
variations
|
132
|
+
}
|
133
|
+
})
|
134
|
+
|
135
|
+
let mappedCategories = categoryResult.results.map((category) => {
|
136
|
+
let {
|
137
|
+
id: categoryId,
|
138
|
+
name: categoryName,
|
139
|
+
parent,
|
140
|
+
isActive
|
141
|
+
} = category
|
142
|
+
|
143
|
+
return {
|
144
|
+
categoryId,
|
145
|
+
categoryName,
|
146
|
+
parent,
|
147
|
+
isLeaf: parent == 0 ? false : true,
|
148
|
+
isActive: isActive || true,
|
149
|
+
channelCode,
|
150
|
+
countryCode
|
151
|
+
}
|
152
|
+
})
|
153
|
+
|
154
|
+
mappedCategories.map((category) => {
|
155
|
+
category.childrenCategories = mappedCategories.filter(e => e.parent == category.categoryId )
|
156
|
+
})
|
157
|
+
|
158
|
+
const ingestCategory = await SellercraftChannelIntegrationAPI.ingestChannelCategories(sellercraftStore, { categories: mappedCategories})
|
159
|
+
|
160
|
+
const ingestProduct = await SellercraftChannelIntegrationAPI.ingestChannelProduct(sellercraftStore, { products: mappedProducts })
|
161
|
+
|
162
|
+
}
|
163
|
+
|
164
|
+
return true
|
165
|
+
}
|
166
|
+
}
|
167
|
+
}
|
@@ -0,0 +1,64 @@
|
|
1
|
+
import { Field, ID, ObjectType } from 'type-graphql'
|
2
|
+
import {
|
3
|
+
Column,
|
4
|
+
CreateDateColumn,
|
5
|
+
Entity,
|
6
|
+
Index,
|
7
|
+
ManyToOne,
|
8
|
+
PrimaryGeneratedColumn,
|
9
|
+
RelationId,
|
10
|
+
UpdateDateColumn
|
11
|
+
} from 'typeorm'
|
12
|
+
|
13
|
+
import { User } from '@things-factory/auth-base'
|
14
|
+
import { Domain } from '@things-factory/shell'
|
15
|
+
|
16
|
+
@Entity()
|
17
|
+
@Index('ix_marketplace_channel_0 ', (marketplaceChannel: MarketplaceChannel) => [marketplaceChannel.domain, marketplaceChannel.name], { unique: true })
|
18
|
+
@ObjectType({ description: 'Entity for Marketplace Channel' })
|
19
|
+
export class MarketplaceChannel {
|
20
|
+
@PrimaryGeneratedColumn('uuid')
|
21
|
+
@Field(type => ID)
|
22
|
+
readonly id: string
|
23
|
+
|
24
|
+
@ManyToOne(type => Domain)
|
25
|
+
@Field({ nullable: true })
|
26
|
+
domain?: Domain
|
27
|
+
|
28
|
+
@RelationId((marketplaceChannel: MarketplaceChannel) => marketplaceChannel.domain)
|
29
|
+
domainId?: string
|
30
|
+
|
31
|
+
@Column()
|
32
|
+
@Field()
|
33
|
+
name: string
|
34
|
+
|
35
|
+
@Column()
|
36
|
+
@Field()
|
37
|
+
channelCode: string
|
38
|
+
|
39
|
+
@Column()
|
40
|
+
@Field()
|
41
|
+
channelId: string
|
42
|
+
|
43
|
+
@CreateDateColumn()
|
44
|
+
@Field({ nullable: true })
|
45
|
+
createdAt?: Date
|
46
|
+
|
47
|
+
@UpdateDateColumn()
|
48
|
+
@Field({ nullable: true })
|
49
|
+
updatedAt?: Date
|
50
|
+
|
51
|
+
@ManyToOne(type => User, { nullable: true })
|
52
|
+
@Field({ nullable: true })
|
53
|
+
creator?: User
|
54
|
+
|
55
|
+
@RelationId((marketplaceChannel: MarketplaceChannel) => marketplaceChannel.creator)
|
56
|
+
creatorId?: string
|
57
|
+
|
58
|
+
@ManyToOne(type => User, { nullable: true })
|
59
|
+
@Field({ nullable: true })
|
60
|
+
updater?: User
|
61
|
+
|
62
|
+
@RelationId((marketplaceChannel: MarketplaceChannel) => marketplaceChannel.updater)
|
63
|
+
updaterId?: string
|
64
|
+
}
|