@things-factory/integration-accounting 9.0.0-beta.27 → 9.0.0-beta.29
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/controllers/accounting-api/decorators.d.ts +1 -0
- package/dist-server/controllers/accounting-api/decorators.js +33 -0
- package/dist-server/controllers/accounting-api/decorators.js.map +1 -0
- package/dist-server/controllers/accounting-api/index.d.ts +25 -0
- package/dist-server/controllers/accounting-api/index.js +124 -0
- package/dist-server/controllers/accounting-api/index.js.map +1 -0
- package/dist-server/controllers/index.d.ts +2 -0
- package/dist-server/controllers/index.js +6 -0
- package/dist-server/controllers/index.js.map +1 -0
- package/dist-server/controllers/xero/apis/contact/get-contact.d.ts +19 -0
- package/dist-server/controllers/xero/apis/contact/get-contact.js +32 -0
- package/dist-server/controllers/xero/apis/contact/get-contact.js.map +1 -0
- package/dist-server/controllers/xero/apis/contact/get-contacts.d.ts +8 -0
- package/dist-server/controllers/xero/apis/contact/get-contacts.js +18 -0
- package/dist-server/controllers/xero/apis/contact/get-contacts.js.map +1 -0
- package/dist-server/controllers/xero/apis/contact/index.d.ts +2 -0
- package/dist-server/controllers/xero/apis/contact/index.js +6 -0
- package/dist-server/controllers/xero/apis/contact/index.js.map +1 -0
- package/dist-server/controllers/xero/apis/index.d.ts +4 -0
- package/dist-server/controllers/xero/apis/index.js +8 -0
- package/dist-server/controllers/xero/apis/index.js.map +1 -0
- package/dist-server/controllers/xero/apis/invoice/create-invoice.d.ts +6 -0
- package/dist-server/controllers/xero/apis/invoice/create-invoice.js +16 -0
- package/dist-server/controllers/xero/apis/invoice/create-invoice.js.map +1 -0
- package/dist-server/controllers/xero/apis/invoice/get-invoice.d.ts +10 -0
- package/dist-server/controllers/xero/apis/invoice/get-invoice.js +18 -0
- package/dist-server/controllers/xero/apis/invoice/get-invoice.js.map +1 -0
- package/dist-server/controllers/xero/apis/invoice/get-invoices.d.ts +10 -0
- package/dist-server/controllers/xero/apis/invoice/get-invoices.js +59 -0
- package/dist-server/controllers/xero/apis/invoice/get-invoices.js.map +1 -0
- package/dist-server/controllers/xero/apis/invoice/index.d.ts +4 -0
- package/dist-server/controllers/xero/apis/invoice/index.js +8 -0
- package/dist-server/controllers/xero/apis/invoice/index.js.map +1 -0
- package/dist-server/controllers/xero/apis/invoice/update-invoice.d.ts +6 -0
- package/dist-server/controllers/xero/apis/invoice/update-invoice.js +16 -0
- package/dist-server/controllers/xero/apis/invoice/update-invoice.js.map +1 -0
- package/dist-server/controllers/xero/apis/item/create-item.d.ts +16 -0
- package/dist-server/controllers/xero/apis/item/create-item.js +32 -0
- package/dist-server/controllers/xero/apis/item/create-item.js.map +1 -0
- package/dist-server/controllers/xero/apis/item/delete-item.d.ts +11 -0
- package/dist-server/controllers/xero/apis/item/delete-item.js +21 -0
- package/dist-server/controllers/xero/apis/item/delete-item.js.map +1 -0
- package/dist-server/controllers/xero/apis/item/get-item.d.ts +10 -0
- package/dist-server/controllers/xero/apis/item/get-item.js +34 -0
- package/dist-server/controllers/xero/apis/item/get-item.js.map +1 -0
- package/dist-server/controllers/xero/apis/item/get-items.d.ts +8 -0
- package/dist-server/controllers/xero/apis/item/get-items.js +32 -0
- package/dist-server/controllers/xero/apis/item/get-items.js.map +1 -0
- package/dist-server/controllers/xero/apis/item/index.d.ts +6 -0
- package/dist-server/controllers/xero/apis/item/index.js +10 -0
- package/dist-server/controllers/xero/apis/item/index.js.map +1 -0
- package/dist-server/controllers/xero/apis/item/update-item.d.ts +14 -0
- package/dist-server/controllers/xero/apis/item/update-item.js +30 -0
- package/dist-server/controllers/xero/apis/item/update-item.js.map +1 -0
- package/dist-server/controllers/xero/apis/item/update-items.d.ts +10 -0
- package/dist-server/controllers/xero/apis/item/update-items.js +36 -0
- package/dist-server/controllers/xero/apis/item/update-items.js.map +1 -0
- package/dist-server/controllers/xero/apis/purchase-order/get-purchase-orders.d.ts +8 -0
- package/dist-server/controllers/xero/apis/purchase-order/get-purchase-orders.js +56 -0
- package/dist-server/controllers/xero/apis/purchase-order/get-purchase-orders.js.map +1 -0
- package/dist-server/controllers/xero/apis/purchase-order/index.d.ts +1 -0
- package/dist-server/controllers/xero/apis/purchase-order/index.js +5 -0
- package/dist-server/controllers/xero/apis/purchase-order/index.js.map +1 -0
- package/dist-server/controllers/xero/index.d.ts +1 -0
- package/dist-server/controllers/xero/index.js +9 -0
- package/dist-server/controllers/xero/index.js.map +1 -0
- package/dist-server/controllers/xero/platform-action.d.ts +6 -0
- package/dist-server/controllers/xero/platform-action.js +49 -0
- package/dist-server/controllers/xero/platform-action.js.map +1 -0
- package/dist-server/controllers/xero/xero.d.ts +18 -0
- package/dist-server/controllers/xero/xero.js +155 -0
- package/dist-server/controllers/xero/xero.js.map +1 -0
- package/dist-server/engine/connector/accounting-connector.d.ts +8 -0
- package/dist-server/engine/connector/accounting-connector.js +28 -0
- package/dist-server/engine/connector/accounting-connector.js.map +1 -0
- package/dist-server/engine/connector/index.d.ts +1 -0
- package/dist-server/engine/connector/index.js +4 -0
- package/dist-server/engine/connector/index.js.map +1 -0
- package/dist-server/engine/index.d.ts +2 -0
- package/dist-server/engine/index.js +5 -0
- package/dist-server/engine/index.js.map +1 -0
- package/dist-server/engine/task/accounting-api.d.ts +1 -0
- package/dist-server/engine/task/accounting-api.js +54 -0
- package/dist-server/engine/task/accounting-api.js.map +1 -0
- package/dist-server/engine/task/index.d.ts +1 -0
- package/dist-server/engine/task/index.js +4 -0
- package/dist-server/engine/task/index.js.map +1 -0
- package/dist-server/entities/account.d.ts +23 -0
- package/dist-server/entities/account.js +113 -0
- package/dist-server/entities/account.js.map +1 -0
- package/dist-server/entities/index.d.ts +3 -0
- package/dist-server/entities/index.js +7 -0
- package/dist-server/entities/index.js.map +1 -0
- package/dist-server/graphql/index.d.ts +6 -0
- package/dist-server/graphql/index.js +11 -0
- package/dist-server/graphql/index.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/account.d.ts +6 -0
- package/dist-server/graphql/resolvers/accounting/account.js +15 -0
- package/dist-server/graphql/resolvers/accounting/account.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/accounts.d.ts +8 -0
- package/dist-server/graphql/resolvers/accounting/accounts.js +14 -0
- package/dist-server/graphql/resolvers/accounting/accounts.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/create-account.d.ts +5 -0
- package/dist-server/graphql/resolvers/accounting/create-account.js +13 -0
- package/dist-server/graphql/resolvers/accounting/create-account.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/delete-account.d.ts +5 -0
- package/dist-server/graphql/resolvers/accounting/delete-account.js +16 -0
- package/dist-server/graphql/resolvers/accounting/delete-account.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/delete-accounts.d.ts +5 -0
- package/dist-server/graphql/resolvers/accounting/delete-accounts.js +20 -0
- package/dist-server/graphql/resolvers/accounting/delete-accounts.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/index.d.ts +25 -0
- package/dist-server/graphql/resolvers/accounting/index.js +15 -0
- package/dist-server/graphql/resolvers/accounting/index.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/update-account.d.ts +6 -0
- package/dist-server/graphql/resolvers/accounting/update-account.js +15 -0
- package/dist-server/graphql/resolvers/accounting/update-account.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/update-multiple-accounts.d.ts +5 -0
- package/dist-server/graphql/resolvers/accounting/update-multiple-accounts.js +30 -0
- package/dist-server/graphql/resolvers/accounting/update-multiple-accounts.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/xero/deactivate-xero-account.d.ts +5 -0
- package/dist-server/graphql/resolvers/accounting/xero/deactivate-xero-account.js +51 -0
- package/dist-server/graphql/resolvers/accounting/xero/deactivate-xero-account.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/xero/get-xero-auth-url.d.ts +6 -0
- package/dist-server/graphql/resolvers/accounting/xero/get-xero-auth-url.js +31 -0
- package/dist-server/graphql/resolvers/accounting/xero/get-xero-auth-url.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/xero/index.d.ts +13 -0
- package/dist-server/graphql/resolvers/accounting/xero/index.js +9 -0
- package/dist-server/graphql/resolvers/accounting/xero/index.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting/xero/refresh-xero-access-token.d.ts +5 -0
- package/dist-server/graphql/resolvers/accounting/xero/refresh-xero-access-token.js +51 -0
- package/dist-server/graphql/resolvers/accounting/xero/refresh-xero-access-token.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-invoice.d.ts +20 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-invoice.js +32 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-invoice.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-item.d.ts +24 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-item.js +36 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-item.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-purchase-order.d.ts +6 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-purchase-order.js +16 -0
- package/dist-server/graphql/resolvers/accounting-api/accounting-purchase-order.js.map +1 -0
- package/dist-server/graphql/resolvers/accounting-api/index.d.ts +44 -0
- package/dist-server/graphql/resolvers/accounting-api/index.js +9 -0
- package/dist-server/graphql/resolvers/accounting-api/index.js.map +1 -0
- package/dist-server/graphql/resolvers/index.d.ts +25 -0
- package/dist-server/graphql/resolvers/index.js +8 -0
- package/dist-server/graphql/resolvers/index.js.map +1 -0
- package/dist-server/graphql/types/accounting/account-list.d.ts +1 -0
- package/dist-server/graphql/types/accounting/account-list.js +12 -0
- package/dist-server/graphql/types/accounting/account-list.js.map +1 -0
- package/dist-server/graphql/types/accounting/account-patch.d.ts +1 -0
- package/dist-server/graphql/types/accounting/account-patch.js +18 -0
- package/dist-server/graphql/types/accounting/account-patch.js.map +1 -0
- package/dist-server/graphql/types/accounting/account.d.ts +1 -0
- package/dist-server/graphql/types/accounting/account.js +29 -0
- package/dist-server/graphql/types/accounting/account.js.map +1 -0
- package/dist-server/graphql/types/accounting/index.d.ts +3 -0
- package/dist-server/graphql/types/accounting/index.js +45 -0
- package/dist-server/graphql/types/accounting/index.js.map +1 -0
- package/dist-server/graphql/types/accounting/new-account.d.ts +1 -0
- package/dist-server/graphql/types/accounting/new-account.js +16 -0
- package/dist-server/graphql/types/accounting/new-account.js.map +1 -0
- package/dist-server/graphql/types/accounting-api/invoice.d.ts +3 -0
- package/dist-server/graphql/types/accounting-api/invoice.js +63 -0
- package/dist-server/graphql/types/accounting-api/invoice.js.map +1 -0
- package/dist-server/graphql/types/accounting-api/item.d.ts +3 -0
- package/dist-server/graphql/types/accounting-api/item.js +63 -0
- package/dist-server/graphql/types/accounting-api/item.js.map +1 -0
- package/dist-server/graphql/types/accounting-api/purchase-order.d.ts +2 -0
- package/dist-server/graphql/types/accounting-api/purchase-order.js +34 -0
- package/dist-server/graphql/types/accounting-api/purchase-order.js.map +1 -0
- package/dist-server/graphql/types/index.d.ts +3 -0
- package/dist-server/graphql/types/index.js +12 -0
- package/dist-server/graphql/types/index.js.map +1 -0
- package/dist-server/index.d.ts +6 -0
- package/dist-server/index.js +11 -0
- package/dist-server/index.js.map +1 -0
- package/dist-server/migrations/index.d.ts +1 -0
- package/dist-server/migrations/index.js +12 -0
- package/dist-server/migrations/index.js.map +1 -0
- package/dist-server/routers/xero-private-router.d.ts +1 -0
- package/dist-server/routers/xero-private-router.js +17 -0
- package/dist-server/routers/xero-private-router.js.map +1 -0
- package/dist-server/routers/xero-router.d.ts +1 -0
- package/dist-server/routers/xero-router.js +109 -0
- package/dist-server/routers/xero-router.js.map +1 -0
- package/dist-server/routes.d.ts +1 -0
- package/dist-server/routes.js +11 -0
- package/dist-server/routes.js.map +1 -0
- package/dist-server/tsconfig.tsbuildinfo +1 -0
- package/package.json +13 -13
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.deleteItem = deleteItem;
|
|
4
|
+
function deleteItem() {
|
|
5
|
+
return {
|
|
6
|
+
method: 'put',
|
|
7
|
+
path: '/Items/{itemId}',
|
|
8
|
+
denormalize(req) {
|
|
9
|
+
return {
|
|
10
|
+
resource: {
|
|
11
|
+
itemId: req.itemId
|
|
12
|
+
},
|
|
13
|
+
payload: Object.assign({}, req)
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
normalize(res) {
|
|
17
|
+
return res;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=delete-item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete-item.js","sourceRoot":"","sources":["../../../../../server/controllers/xero/apis/item/delete-item.ts"],"names":[],"mappings":";;AAAA,gCAkBC;AAlBD,SAAgB,UAAU;IACxB,OAAO;QACL,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,iBAAiB;QACvB,WAAW,CAAC,GAAG;YACb,OAAO;gBACL,QAAQ,EAAE;oBACR,MAAM,EAAE,GAAG,CAAC,MAAM;iBACnB;gBACD,OAAO,oBACF,GAAG,CACP;aACF,CAAA;QACH,CAAC;QACD,SAAS,CAAC,GAAG;YACX,OAAO,GAAG,CAAA;QACZ,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["export function deleteItem() {\n return {\n method: 'put',\n path: '/Items/{itemId}',\n denormalize(req) {\n return {\n resource: {\n itemId: req.itemId\n },\n payload: {\n ...req\n }\n }\n },\n normalize(res) {\n return res\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getItem = getItem;
|
|
4
|
+
function getItem() {
|
|
5
|
+
return {
|
|
6
|
+
method: 'get',
|
|
7
|
+
path: '/Items/{Code}',
|
|
8
|
+
denormalize(req) {
|
|
9
|
+
return {
|
|
10
|
+
resource: {
|
|
11
|
+
Code: req.itemCode
|
|
12
|
+
}
|
|
13
|
+
};
|
|
14
|
+
},
|
|
15
|
+
normalize(res) {
|
|
16
|
+
var { Items } = res;
|
|
17
|
+
let results = [];
|
|
18
|
+
results = Items.map(item => {
|
|
19
|
+
var { Code: sku, Description: description, PurchaseDetails, Name: name, IsTrackedAsInventory: isTrackedAsInventory, InventoryAssetAccountCode: inventoryAccountCode } = item;
|
|
20
|
+
var { AccountCode: cogsAccountCode } = PurchaseDetails;
|
|
21
|
+
return {
|
|
22
|
+
sku,
|
|
23
|
+
description,
|
|
24
|
+
name,
|
|
25
|
+
isTrackedAsInventory,
|
|
26
|
+
inventoryAccountCode,
|
|
27
|
+
cogsAccountCode
|
|
28
|
+
};
|
|
29
|
+
});
|
|
30
|
+
return results[0];
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=get-item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-item.js","sourceRoot":"","sources":["../../../../../server/controllers/xero/apis/item/get-item.ts"],"names":[],"mappings":";;AAAA,0BAwCC;AAxCD,SAAgB,OAAO;IACrB,OAAO;QACL,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,eAAe;QACrB,WAAW,CAAC,GAAG;YACb,OAAO;gBACL,QAAQ,EAAE;oBACR,IAAI,EAAE,GAAG,CAAC,QAAQ;iBACnB;aACF,CAAA;QACH,CAAC;QACD,SAAS,CAAC,GAAG;YACX,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,CAAA;YAEnB,IAAI,OAAO,GAAU,EAAE,CAAA;YAEvB,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBACzB,IAAI,EACF,IAAI,EAAE,GAAG,EACT,WAAW,EAAE,WAAW,EACxB,eAAe,EACf,IAAI,EAAE,IAAI,EACV,oBAAoB,EAAE,oBAAoB,EAC1C,yBAAyB,EAAE,oBAAoB,EAChD,GAAG,IAAI,CAAA;gBACR,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,eAAe,CAAA;gBAEtD,OAAO;oBACL,GAAG;oBACH,WAAW;oBACX,IAAI;oBACJ,oBAAoB;oBACpB,oBAAoB;oBACpB,eAAe;iBAChB,CAAA;YACH,CAAC,CAAC,CAAA;YAEF,OAAO,OAAO,CAAC,CAAC,CAAC,CAAA;QACnB,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["export function getItem() {\n return {\n method: 'get',\n path: '/Items/{Code}',\n denormalize(req) {\n return {\n resource: {\n Code: req.itemCode\n }\n }\n },\n normalize(res) {\n var { Items } = res\n\n let results: any[] = []\n\n results = Items.map(item => {\n var {\n Code: sku,\n Description: description,\n PurchaseDetails,\n Name: name,\n IsTrackedAsInventory: isTrackedAsInventory,\n InventoryAssetAccountCode: inventoryAccountCode\n } = item\n var { AccountCode: cogsAccountCode } = PurchaseDetails\n\n return {\n sku,\n description,\n name,\n isTrackedAsInventory,\n inventoryAccountCode,\n cogsAccountCode\n }\n })\n\n return results[0]\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getItems = getItems;
|
|
4
|
+
function getItems() {
|
|
5
|
+
return {
|
|
6
|
+
method: 'get',
|
|
7
|
+
path: '/Items',
|
|
8
|
+
denormalize(req) {
|
|
9
|
+
return {
|
|
10
|
+
payload: Object.assign({}, req)
|
|
11
|
+
};
|
|
12
|
+
},
|
|
13
|
+
normalize(res) {
|
|
14
|
+
var { Items } = res;
|
|
15
|
+
let results = [];
|
|
16
|
+
results = Items.map(item => {
|
|
17
|
+
var { Code: sku, Description: description, PurchaseDetails, Name: name, IsTrackedAsInventory: isTrackedAsInventory, InventoryAssetAccountCode: inventoryAccountCode } = item;
|
|
18
|
+
var { AccountCode: cogsAccountCode } = PurchaseDetails;
|
|
19
|
+
return {
|
|
20
|
+
sku,
|
|
21
|
+
description,
|
|
22
|
+
name,
|
|
23
|
+
isTrackedAsInventory,
|
|
24
|
+
inventoryAccountCode,
|
|
25
|
+
cogsAccountCode
|
|
26
|
+
};
|
|
27
|
+
});
|
|
28
|
+
return results;
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=get-items.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-items.js","sourceRoot":"","sources":["../../../../../server/controllers/xero/apis/item/get-items.ts"],"names":[],"mappings":";;AAAA,4BAwCC;AAxCD,SAAgB,QAAQ;IACtB,OAAO;QACL,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,QAAQ;QACd,WAAW,CAAC,GAAG;YACb,OAAO;gBACL,OAAO,oBACF,GAAG,CACP;aACF,CAAA;QACH,CAAC;QACD,SAAS,CAAC,GAAG;YACX,IAAI,EAAE,KAAK,EAAE,GAAG,GAAG,CAAA;YAEnB,IAAI,OAAO,GAAU,EAAE,CAAA;YAEvB,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBACzB,IAAI,EACF,IAAI,EAAE,GAAG,EACT,WAAW,EAAE,WAAW,EACxB,eAAe,EACf,IAAI,EAAE,IAAI,EACV,oBAAoB,EAAE,oBAAoB,EAC1C,yBAAyB,EAAE,oBAAoB,EAChD,GAAG,IAAI,CAAA;gBACR,IAAI,EAAE,WAAW,EAAE,eAAe,EAAE,GAAG,eAAe,CAAA;gBAEtD,OAAO;oBACL,GAAG;oBACH,WAAW;oBACX,IAAI;oBACJ,oBAAoB;oBACpB,oBAAoB;oBACpB,eAAe;iBAChB,CAAA;YACH,CAAC,CAAC,CAAA;YAEF,OAAO,OAAO,CAAA;QAChB,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["export function getItems() {\n return {\n method: 'get',\n path: '/Items',\n denormalize(req) {\n return {\n payload: {\n ...req\n }\n }\n },\n normalize(res) {\n var { Items } = res\n\n let results: any[] = []\n\n results = Items.map(item => {\n var {\n Code: sku,\n Description: description,\n PurchaseDetails,\n Name: name,\n IsTrackedAsInventory: isTrackedAsInventory,\n InventoryAssetAccountCode: inventoryAccountCode\n } = item\n var { AccountCode: cogsAccountCode } = PurchaseDetails\n\n return {\n sku,\n description,\n name,\n isTrackedAsInventory,\n inventoryAccountCode,\n cogsAccountCode\n }\n })\n\n return results\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./get-item"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./get-items"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./create-item"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./update-item"), exports);
|
|
8
|
+
tslib_1.__exportStar(require("./update-items"), exports);
|
|
9
|
+
tslib_1.__exportStar(require("./delete-item"), exports);
|
|
10
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../server/controllers/xero/apis/item/index.ts"],"names":[],"mappings":";;;AAAA,qDAA0B;AAC1B,sDAA2B;AAC3B,wDAA6B;AAC7B,wDAA6B;AAC7B,yDAA8B;AAC9B,wDAA6B","sourcesContent":["export * from './get-item'\nexport * from './get-items'\nexport * from './create-item'\nexport * from './update-item'\nexport * from './update-items'\nexport * from './delete-item'\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare function updateItem(): {
|
|
2
|
+
method: string;
|
|
3
|
+
path: string;
|
|
4
|
+
denormalize(req: any): {
|
|
5
|
+
Code: any;
|
|
6
|
+
Description: any;
|
|
7
|
+
Name: any;
|
|
8
|
+
PurchaseDetails: Object;
|
|
9
|
+
IsSold: Boolean;
|
|
10
|
+
IsPurchased: Boolean;
|
|
11
|
+
InventoryAssetAccountCode: any;
|
|
12
|
+
};
|
|
13
|
+
normalize(res: any): any;
|
|
14
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateItem = updateItem;
|
|
4
|
+
function updateItem() {
|
|
5
|
+
return {
|
|
6
|
+
method: 'post',
|
|
7
|
+
path: '/Items',
|
|
8
|
+
denormalize(req) {
|
|
9
|
+
var { sku: Code, name: Name, description: Description, inventoryAccountCode: InventoryAssetAccountCode, cogsAccountCode: COGSAccountCode } = req;
|
|
10
|
+
let IsSold = true;
|
|
11
|
+
let IsPurchased = true;
|
|
12
|
+
var PurchaseDetails = {
|
|
13
|
+
COGSAccountCode
|
|
14
|
+
};
|
|
15
|
+
return {
|
|
16
|
+
Code,
|
|
17
|
+
Description,
|
|
18
|
+
Name,
|
|
19
|
+
PurchaseDetails,
|
|
20
|
+
IsSold,
|
|
21
|
+
IsPurchased,
|
|
22
|
+
InventoryAssetAccountCode
|
|
23
|
+
};
|
|
24
|
+
},
|
|
25
|
+
normalize(res) {
|
|
26
|
+
return res;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=update-item.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-item.js","sourceRoot":"","sources":["../../../../../server/controllers/xero/apis/item/update-item.ts"],"names":[],"mappings":";;AAAA,gCAkCC;AAlCD,SAAgB,UAAU;IACxB,OAAO;QACL,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,QAAQ;QACd,WAAW,CAAC,GAAG;YACb,IAAI,EACF,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,WAAW,EACxB,oBAAoB,EAAE,yBAAyB,EAC/C,eAAe,EAAE,eAAe,EACjC,GAAG,GAAG,CAAA;YAEP,IAAI,MAAM,GAAY,IAAI,CAAA;YAC1B,IAAI,WAAW,GAAY,IAAI,CAAA;YAE/B,IAAI,eAAe,GAAW;gBAC5B,eAAe;aAChB,CAAA;YAED,OAAO;gBACL,IAAI;gBACJ,WAAW;gBACX,IAAI;gBACJ,eAAe;gBACf,MAAM;gBACN,WAAW;gBACX,yBAAyB;aAC1B,CAAA;QACH,CAAC;QACD,SAAS,CAAC,GAAG;YACX,OAAO,GAAG,CAAA;QACZ,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["export function updateItem() {\n return {\n method: 'post',\n path: '/Items',\n denormalize(req) {\n var {\n sku: Code,\n name: Name,\n description: Description,\n inventoryAccountCode: InventoryAssetAccountCode,\n cogsAccountCode: COGSAccountCode\n } = req\n\n let IsSold: Boolean = true\n let IsPurchased: Boolean = true\n\n var PurchaseDetails: Object = {\n COGSAccountCode\n }\n\n return {\n Code,\n Description,\n Name,\n PurchaseDetails,\n IsSold,\n IsPurchased,\n InventoryAssetAccountCode\n }\n },\n normalize(res) {\n return res\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateItems = updateItems;
|
|
4
|
+
function updateItems() {
|
|
5
|
+
return {
|
|
6
|
+
method: 'post',
|
|
7
|
+
path: '/Items',
|
|
8
|
+
denormalize(req) {
|
|
9
|
+
let { products } = req;
|
|
10
|
+
const Items = products.map(item => {
|
|
11
|
+
var { sku: Code, name: Name, description: Description, inventoryAccountCode: InventoryAssetAccountCode, cogsAccountCode: COGSAccountCode } = item;
|
|
12
|
+
let IsPurchased = true;
|
|
13
|
+
var PurchaseDetails = {
|
|
14
|
+
COGSAccountCode
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
Code,
|
|
18
|
+
Description,
|
|
19
|
+
Name,
|
|
20
|
+
PurchaseDetails,
|
|
21
|
+
IsPurchased,
|
|
22
|
+
InventoryAssetAccountCode
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
return {
|
|
26
|
+
payload: {
|
|
27
|
+
Items
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
},
|
|
31
|
+
normalize(res) {
|
|
32
|
+
return res;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=update-items.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update-items.js","sourceRoot":"","sources":["../../../../../server/controllers/xero/apis/item/update-items.ts"],"names":[],"mappings":";;AAAA,kCA0CC;AA1CD,SAAgB,WAAW;IACzB,OAAO;QACL,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,QAAQ;QACd,WAAW,CAAC,GAAG;YACb,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;YAEtB,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;gBAChC,IAAI,EACF,GAAG,EAAE,IAAI,EACT,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,WAAW,EACxB,oBAAoB,EAAE,yBAAyB,EAC/C,eAAe,EAAE,eAAe,EACjC,GAAG,IAAI,CAAA;gBAER,IAAI,WAAW,GAAY,IAAI,CAAA;gBAE/B,IAAI,eAAe,GAAW;oBAC5B,eAAe;iBAChB,CAAA;gBAED,OAAO;oBACL,IAAI;oBACJ,WAAW;oBACX,IAAI;oBACJ,eAAe;oBACf,WAAW;oBACX,yBAAyB;iBAC1B,CAAA;YACH,CAAC,CAAC,CAAA;YAEF,OAAO;gBACL,OAAO,EAAE;oBACP,KAAK;iBACN;aACF,CAAA;QACH,CAAC;QACD,SAAS,CAAC,GAAG;YACX,OAAO,GAAG,CAAA;QACZ,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["export function updateItems() {\n return {\n method: 'post',\n path: '/Items',\n denormalize(req) {\n let { products } = req\n\n const Items = products.map(item => {\n var {\n sku: Code,\n name: Name,\n description: Description,\n inventoryAccountCode: InventoryAssetAccountCode,\n cogsAccountCode: COGSAccountCode\n } = item\n\n let IsPurchased: Boolean = true\n\n var PurchaseDetails: Object = {\n COGSAccountCode\n }\n\n return {\n Code,\n Description,\n Name,\n PurchaseDetails,\n IsPurchased,\n InventoryAssetAccountCode\n }\n })\n\n return {\n payload: {\n Items\n }\n }\n },\n normalize(res) {\n return res\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getPurchaseOrders = getPurchaseOrders;
|
|
4
|
+
function getPurchaseOrders() {
|
|
5
|
+
return {
|
|
6
|
+
method: 'get',
|
|
7
|
+
path: '/PurchaseOrders',
|
|
8
|
+
denormalize(req) {
|
|
9
|
+
return {
|
|
10
|
+
payload: Object.assign({}, req)
|
|
11
|
+
};
|
|
12
|
+
},
|
|
13
|
+
normalize(res) {
|
|
14
|
+
const { PurchaseOrders } = res;
|
|
15
|
+
let results = PurchaseOrders.map(purchaseOrder => {
|
|
16
|
+
const { PurchaseOrderNumber: refNo, Reference: refNo2, DeliveryDateString, LineItems } = purchaseOrder;
|
|
17
|
+
const etaDate = DeliveryDateString !== undefined ? String(DeliveryDateString.split('T')[0]) : 'undefined';
|
|
18
|
+
let products = LineItems.map(lineItem => {
|
|
19
|
+
return {
|
|
20
|
+
product: { sku: lineItem.ItemCode },
|
|
21
|
+
batchId: refNo,
|
|
22
|
+
packQty: lineItem.Quantity,
|
|
23
|
+
unitPrice: lineItem.UnitAmount
|
|
24
|
+
};
|
|
25
|
+
}).reduce((newItem, item) => {
|
|
26
|
+
var foundItem = newItem.find(newItem => newItem.batchId === item.batchId && newItem.product.sku === item.product.sku);
|
|
27
|
+
if (!foundItem) {
|
|
28
|
+
newItem.push(Object.assign({}, item));
|
|
29
|
+
return newItem;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
return newItem.map(ni => {
|
|
33
|
+
if (ni.batchId === item.batchId && ni.product.sku === item.product.sku) {
|
|
34
|
+
return Object.assign(Object.assign({}, ni), { packQty: ni.packQty + item.packQty });
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
return ni;
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
}, []);
|
|
42
|
+
return {
|
|
43
|
+
refNo,
|
|
44
|
+
refNo2,
|
|
45
|
+
etaDate,
|
|
46
|
+
ownTransport: true,
|
|
47
|
+
importCargo: false,
|
|
48
|
+
container: false,
|
|
49
|
+
orderProducts: products
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
return results;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=get-purchase-orders.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-purchase-orders.js","sourceRoot":"","sources":["../../../../../server/controllers/xero/apis/purchase-order/get-purchase-orders.ts"],"names":[],"mappings":";;AAAA,8CA4DC;AA5DD,SAAgB,iBAAiB;IAC/B,OAAO;QACL,MAAM,EAAE,KAAK;QACb,IAAI,EAAE,iBAAiB;QACvB,WAAW,CAAC,GAAG;YACb,OAAO;gBACL,OAAO,oBACF,GAAG,CACP;aACF,CAAA;QACH,CAAC;QACD,SAAS,CAAC,GAAG;YACX,MAAM,EAAE,cAAc,EAAE,GAAG,GAAG,CAAA;YAE9B,IAAI,OAAO,GAAU,cAAc,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE;gBACtD,MAAM,EAAE,mBAAmB,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,kBAAkB,EAAE,SAAS,EAAE,GAAG,aAAa,CAAA;gBACtG,MAAM,OAAO,GAAQ,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,kBAAkB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAA;gBAE9G,IAAI,QAAQ,GAAU,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;oBAC7C,OAAO;wBACL,OAAO,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,QAAQ,EAAE;wBACnC,OAAO,EAAE,KAAK;wBACd,OAAO,EAAE,QAAQ,CAAC,QAAQ;wBAC1B,SAAS,EAAE,QAAQ,CAAC,UAAU;qBAC/B,CAAA;gBACH,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE;oBAC1B,IAAI,SAAS,GAAG,OAAO,CAAC,IAAI,CAC1B,OAAO,CAAC,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,CACxF,CAAA;oBACD,IAAI,CAAC,SAAS,EAAE,CAAC;wBACf,OAAO,CAAC,IAAI,mBAAM,IAAI,EAAG,CAAA;wBACzB,OAAO,OAAO,CAAA;oBAChB,CAAC;yBAAM,CAAC;wBACN,OAAO,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;4BACtB,IAAI,EAAE,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,GAAG,KAAK,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;gCACvE,uCACK,EAAE,KACL,OAAO,EAAE,EAAE,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IACnC;4BACH,CAAC;iCAAM,CAAC;gCACN,OAAO,EAAE,CAAA;4BACX,CAAC;wBACH,CAAC,CAAC,CAAA;oBACJ,CAAC;gBACH,CAAC,EAAE,EAAE,CAAC,CAAA;gBAEN,OAAO;oBACL,KAAK;oBACL,MAAM;oBACN,OAAO;oBACP,YAAY,EAAE,IAAI;oBAClB,WAAW,EAAE,KAAK;oBAClB,SAAS,EAAE,KAAK;oBAChB,aAAa,EAAE,QAAQ;iBACxB,CAAA;YACH,CAAC,CAAC,CAAA;YAEF,OAAO,OAAO,CAAA;QAChB,CAAC;KACF,CAAA;AACH,CAAC","sourcesContent":["export function getPurchaseOrders() {\n return {\n method: 'get',\n path: '/PurchaseOrders',\n denormalize(req) {\n return {\n payload: {\n ...req\n }\n }\n },\n normalize(res) {\n const { PurchaseOrders } = res\n\n let results: any[] = PurchaseOrders.map(purchaseOrder => {\n const { PurchaseOrderNumber: refNo, Reference: refNo2, DeliveryDateString, LineItems } = purchaseOrder\n const etaDate: any = DeliveryDateString !== undefined ? String(DeliveryDateString.split('T')[0]) : 'undefined'\n\n let products: any[] = LineItems.map(lineItem => {\n return {\n product: { sku: lineItem.ItemCode },\n batchId: refNo,\n packQty: lineItem.Quantity,\n unitPrice: lineItem.UnitAmount\n }\n }).reduce((newItem, item) => {\n var foundItem = newItem.find(\n newItem => newItem.batchId === item.batchId && newItem.product.sku === item.product.sku\n )\n if (!foundItem) {\n newItem.push({ ...item })\n return newItem\n } else {\n return newItem.map(ni => {\n if (ni.batchId === item.batchId && ni.product.sku === item.product.sku) {\n return {\n ...ni,\n packQty: ni.packQty + item.packQty\n }\n } else {\n return ni\n }\n })\n }\n }, [])\n\n return {\n refNo,\n refNo2,\n etaDate,\n ownTransport: true,\n importCargo: false,\n container: false,\n orderProducts: products\n }\n })\n\n return results\n }\n }\n}\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './get-purchase-orders';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../server/controllers/xero/apis/purchase-order/index.ts"],"names":[],"mappings":";;;AAAA,gEAAqC","sourcesContent":["export * from './get-purchase-orders'\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './xero';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const tslib_1 = require("tslib");
|
|
4
|
+
tslib_1.__exportStar(require("./xero"), exports);
|
|
5
|
+
const accounting_api_1 = require("../accounting-api");
|
|
6
|
+
const platform_action_1 = require("./platform-action");
|
|
7
|
+
const APIS = tslib_1.__importStar(require("./apis"));
|
|
8
|
+
accounting_api_1.AccountingAPI.registerPlatform('xero', platform_action_1.action, APIS);
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../server/controllers/xero/index.ts"],"names":[],"mappings":";;;AAAA,iDAAsB;AAEtB,sDAAiD;AACjD,uDAA0C;AAE1C,qDAA8B;AAE9B,8BAAa,CAAC,gBAAgB,CAAC,MAAM,EAAE,wBAAM,EAAE,IAAI,CAAC,CAAA","sourcesContent":["export * from './xero'\n\nimport { AccountingAPI } from '../accounting-api'\nimport { action } from './platform-action'\n\nimport * as APIS from './apis'\n\nAccountingAPI.registerPlatform('xero', action, APIS)\n"]}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.action = void 0;
|
|
4
|
+
const env_1 = require("@things-factory/env");
|
|
5
|
+
const xero_1 = require("./xero");
|
|
6
|
+
const xeroConfig = env_1.config.get('accountingIntegrationXero', {});
|
|
7
|
+
const { apiKey, apiSecret, callback } = xeroConfig;
|
|
8
|
+
function substitute(path, obj) {
|
|
9
|
+
var props = [];
|
|
10
|
+
var re = /{([^}]+)}/g;
|
|
11
|
+
var text;
|
|
12
|
+
while ((text = re.exec(path))) {
|
|
13
|
+
props.push(text[1]);
|
|
14
|
+
}
|
|
15
|
+
var result = path;
|
|
16
|
+
props.forEach(prop => {
|
|
17
|
+
let value = obj[prop.trim()];
|
|
18
|
+
result = result.replace(`{${prop}}`, value === undefined ? '' : value);
|
|
19
|
+
});
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
async function _action({ accounting, method = 'get', path, request }) {
|
|
23
|
+
const client = new xero_1.Xero({
|
|
24
|
+
apiKey,
|
|
25
|
+
apiSecret,
|
|
26
|
+
accessToken: accounting.accessToken,
|
|
27
|
+
tenantId: accounting.accountId,
|
|
28
|
+
callback
|
|
29
|
+
});
|
|
30
|
+
const { resource = {}, payload = {} } = request;
|
|
31
|
+
path = substitute(path, resource);
|
|
32
|
+
return await client[method](path, payload);
|
|
33
|
+
}
|
|
34
|
+
const action = async ({ accounting, method = 'get', path, request }) => {
|
|
35
|
+
try {
|
|
36
|
+
return await _action({ accounting, method, path, request });
|
|
37
|
+
}
|
|
38
|
+
catch (ex) {
|
|
39
|
+
if (ex.status === 401) {
|
|
40
|
+
var refreshedAccounting = await xero_1.Xero.refreshAccessToken(apiKey, apiSecret, accounting);
|
|
41
|
+
return await _action({ accounting: refreshedAccounting, method, path, request });
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
env_1.logger.error(`Xero: action: ${ex}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
exports.action = action;
|
|
49
|
+
//# sourceMappingURL=platform-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"platform-action.js","sourceRoot":"","sources":["../../../server/controllers/xero/platform-action.ts"],"names":[],"mappings":";;;AAAA,6CAAoD;AAEpD,iCAA6B;AAE7B,MAAM,UAAU,GAAG,YAAM,CAAC,GAAG,CAAC,2BAA2B,EAAE,EAAE,CAAC,CAAA;AAC9D,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAA;AAElD,SAAS,UAAU,CAAC,IAAI,EAAE,GAAG;IAC3B,IAAI,KAAK,GAAG,EAAE,CAAA;IACd,IAAI,EAAE,GAAG,YAAY,CAAA;IACrB,IAAI,IAAI,CAAA;IAER,OAAO,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;QAC9B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAA;IACrB,CAAC;IAED,IAAI,MAAM,GAAG,IAAI,CAAA;IACjB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;QACnB,IAAI,KAAK,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAA;QAC5B,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,GAAG,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;IACxE,CAAC,CAAC,CAAA;IAEF,OAAO,MAAM,CAAA;AACf,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;IAClE,MAAM,MAAM,GAAG,IAAI,WAAI,CAAC;QACtB,MAAM;QACN,SAAS;QACT,WAAW,EAAE,UAAU,CAAC,WAAW;QACnC,QAAQ,EAAE,UAAU,CAAC,SAAS;QAC9B,QAAQ;KACT,CAAC,CAAA;IAEF,MAAM,EAAE,QAAQ,GAAG,EAAE,EAAE,OAAO,GAAG,EAAE,EAAE,GAAG,OAAO,CAAA;IAE/C,IAAI,GAAG,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;IAEjC,OAAO,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,OAAO,CAAC,CAAA;AAC5C,CAAC;AAEM,MAAM,MAAM,GAAG,KAAK,EAAE,EAAE,UAAU,EAAE,MAAM,GAAG,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;IAC5E,IAAI,CAAC;QACH,OAAO,MAAM,OAAO,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;IAC7D,CAAC;IAAC,OAAO,EAAE,EAAE,CAAC;QACZ,IAAI,EAAE,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YACtB,IAAI,mBAAmB,GAAG,MAAM,WAAI,CAAC,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,CAAC,CAAA;YACtF,OAAO,MAAM,OAAO,CAAC,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;QAClF,CAAC;aAAM,CAAC;YACN,YAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE,EAAE,CAAC,CAAA;QACrC,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAXY,QAAA,MAAM,UAWlB","sourcesContent":["import { config, logger } from '@things-factory/env'\n\nimport { Xero } from './xero'\n\nconst xeroConfig = config.get('accountingIntegrationXero', {})\nconst { apiKey, apiSecret, callback } = xeroConfig\n\nfunction substitute(path, obj) {\n var props = []\n var re = /{([^}]+)}/g\n var text\n\n while ((text = re.exec(path))) {\n props.push(text[1])\n }\n\n var result = path\n props.forEach(prop => {\n let value = obj[prop.trim()]\n result = result.replace(`{${prop}}`, value === undefined ? '' : value)\n })\n\n return result\n}\n\nasync function _action({ accounting, method = 'get', path, request }) {\n const client = new Xero({\n apiKey,\n apiSecret,\n accessToken: accounting.accessToken,\n tenantId: accounting.accountId,\n callback\n })\n\n const { resource = {}, payload = {} } = request\n\n path = substitute(path, resource)\n\n return await client[method](path, payload)\n}\n\nexport const action = async ({ accounting, method = 'get', path, request }) => {\n try {\n return await _action({ accounting, method, path, request })\n } catch (ex) {\n if (ex.status === 401) {\n var refreshedAccounting = await Xero.refreshAccessToken(apiKey, apiSecret, accounting)\n return await _action({ accounting: refreshedAccounting, method, path, request })\n } else {\n logger.error(`Xero: action: ${ex}`)\n }\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type XeroConfig = {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
apiSecret: string;
|
|
4
|
+
accessToken?: string;
|
|
5
|
+
tenantId?: string;
|
|
6
|
+
callback?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare class Xero {
|
|
9
|
+
private config;
|
|
10
|
+
constructor(config: XeroConfig);
|
|
11
|
+
buildAuthURL(nonce: any): string;
|
|
12
|
+
get(path: string, data: any): Promise<any>;
|
|
13
|
+
post(path: string, data?: any): Promise<any>;
|
|
14
|
+
put(path: string, data?: any): Promise<any>;
|
|
15
|
+
delete(path: string, data?: any): Promise<any>;
|
|
16
|
+
private convertStatusCode;
|
|
17
|
+
static refreshAccessToken(apiKey: any, apiSecret: any, account: any): Promise<any>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Xero = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const node_fetch_1 = tslib_1.__importDefault(require("node-fetch"));
|
|
6
|
+
const shell_1 = require("@things-factory/shell");
|
|
7
|
+
const utils_1 = require("@things-factory/utils");
|
|
8
|
+
const account_1 = require("../../entities/account");
|
|
9
|
+
const ENDPOINT = 'https://api.xero.com/api.xro/2.0';
|
|
10
|
+
const debug = require('debug')('things-factory:integration-accounting:xero');
|
|
11
|
+
class Xero {
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = Object.assign({}, config);
|
|
14
|
+
}
|
|
15
|
+
buildAuthURL(nonce) {
|
|
16
|
+
const scopes = 'offline_access openid profile email accounting.transactions accounting.settings accounting.contacts';
|
|
17
|
+
const { apiKey, callback: redirectUrl } = this.config;
|
|
18
|
+
return `https://login.xero.com/identity/connect/authorize?response_type=code&client_id=${apiKey}&scope=${scopes}&redirect_uri=${redirectUrl}&state=${nonce}`;
|
|
19
|
+
}
|
|
20
|
+
async get(path, data) {
|
|
21
|
+
const { accessToken, tenantId } = this.config;
|
|
22
|
+
const qs = Object.entries(data)
|
|
23
|
+
.map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)
|
|
24
|
+
.join('&');
|
|
25
|
+
const endpoint = `${ENDPOINT}${path}${qs ? '?' + qs : ''}`;
|
|
26
|
+
debug('endpoint', endpoint);
|
|
27
|
+
const response = await (0, node_fetch_1.default)(endpoint, {
|
|
28
|
+
method: 'get',
|
|
29
|
+
headers: {
|
|
30
|
+
accept: 'application/json',
|
|
31
|
+
'Content-Type': 'application/json',
|
|
32
|
+
Authorization: `Bearer ${accessToken}`,
|
|
33
|
+
'xero-tenant-id': tenantId
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
if (!response.ok) {
|
|
37
|
+
throw response;
|
|
38
|
+
}
|
|
39
|
+
let result = await response.json();
|
|
40
|
+
debug('response result', result);
|
|
41
|
+
result = this.convertStatusCode(result);
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
async post(path, data = {}) {
|
|
45
|
+
const { accessToken, tenantId } = this.config;
|
|
46
|
+
debug('data', data);
|
|
47
|
+
const jsondata = JSON.stringify(data);
|
|
48
|
+
const endpoint = `${ENDPOINT}${path}`;
|
|
49
|
+
debug('endpoint', endpoint);
|
|
50
|
+
const response = await (0, node_fetch_1.default)(endpoint, {
|
|
51
|
+
method: 'post',
|
|
52
|
+
headers: {
|
|
53
|
+
accept: 'application/json',
|
|
54
|
+
'Content-Type': 'application/json',
|
|
55
|
+
Authorization: `Bearer ${accessToken}`,
|
|
56
|
+
'xero-tenant-id': tenantId
|
|
57
|
+
},
|
|
58
|
+
body: jsondata
|
|
59
|
+
});
|
|
60
|
+
if (!response.ok) {
|
|
61
|
+
throw response;
|
|
62
|
+
}
|
|
63
|
+
let result = await response.json();
|
|
64
|
+
debug('response result', result);
|
|
65
|
+
result = this.convertStatusCode(result);
|
|
66
|
+
return result;
|
|
67
|
+
}
|
|
68
|
+
async put(path, data = {}) {
|
|
69
|
+
const { accessToken, tenantId } = this.config;
|
|
70
|
+
debug('data', data);
|
|
71
|
+
const jsondata = JSON.stringify(data);
|
|
72
|
+
const endpoint = `${ENDPOINT}${path}`;
|
|
73
|
+
debug('endpoint', endpoint);
|
|
74
|
+
const response = await (0, node_fetch_1.default)(endpoint, {
|
|
75
|
+
method: 'put',
|
|
76
|
+
headers: {
|
|
77
|
+
accept: 'application/json',
|
|
78
|
+
'Content-Type': 'application/json',
|
|
79
|
+
Authorization: `Bearer ${accessToken}`,
|
|
80
|
+
'xero-tenant-id': tenantId
|
|
81
|
+
},
|
|
82
|
+
body: jsondata
|
|
83
|
+
});
|
|
84
|
+
if (!response.ok) {
|
|
85
|
+
throw response;
|
|
86
|
+
}
|
|
87
|
+
let result = await response.json();
|
|
88
|
+
debug('response result', result);
|
|
89
|
+
result = this.convertStatusCode(result);
|
|
90
|
+
return result;
|
|
91
|
+
}
|
|
92
|
+
async delete(path, data = {}) {
|
|
93
|
+
const { accessToken, tenantId } = this.config;
|
|
94
|
+
debug('data', data);
|
|
95
|
+
const jsondata = JSON.stringify(data);
|
|
96
|
+
const endpoint = `${ENDPOINT}${path}`;
|
|
97
|
+
debug('endpoint', endpoint);
|
|
98
|
+
const response = await (0, node_fetch_1.default)(endpoint, {
|
|
99
|
+
method: 'delete',
|
|
100
|
+
headers: {
|
|
101
|
+
accept: 'application/json',
|
|
102
|
+
'Content-Type': 'application/json',
|
|
103
|
+
Authorization: `Bearer ${accessToken}`,
|
|
104
|
+
'xero-tenant-id': tenantId
|
|
105
|
+
},
|
|
106
|
+
body: jsondata
|
|
107
|
+
});
|
|
108
|
+
if (!response.ok) {
|
|
109
|
+
throw response;
|
|
110
|
+
}
|
|
111
|
+
let result = await response.json();
|
|
112
|
+
debug('response result', result);
|
|
113
|
+
result = this.convertStatusCode(result);
|
|
114
|
+
return result;
|
|
115
|
+
}
|
|
116
|
+
convertStatusCode(result) {
|
|
117
|
+
result.ok = result.Status.toLowerCase() === 'ok';
|
|
118
|
+
return result;
|
|
119
|
+
}
|
|
120
|
+
static async refreshAccessToken(apiKey, apiSecret, account) {
|
|
121
|
+
const refreshRequestData = {
|
|
122
|
+
grant_type: 'refresh_token',
|
|
123
|
+
refresh_token: account.refreshToken
|
|
124
|
+
};
|
|
125
|
+
const refreshResponse = await (0, node_fetch_1.default)(`https://identity.xero.com/connect/token`, {
|
|
126
|
+
method: 'post',
|
|
127
|
+
headers: {
|
|
128
|
+
Authorization: `Basic ${Buffer.from(apiKey + ':' + apiSecret).toString('base64')}`,
|
|
129
|
+
'Content-Type': 'application/x-www-form-urlencoded'
|
|
130
|
+
},
|
|
131
|
+
body: Object.entries(refreshRequestData)
|
|
132
|
+
.map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))
|
|
133
|
+
.join('&')
|
|
134
|
+
});
|
|
135
|
+
if (!refreshResponse.ok) {
|
|
136
|
+
throw new Error(`get account information failed: ${await refreshResponse.text()}`);
|
|
137
|
+
}
|
|
138
|
+
const body = await refreshResponse.json();
|
|
139
|
+
const { access_token /* token used to call the API */, id_token /* token containing user identity details (only returned if OpenID Connect scopes are requested) */, expires_in /* amount of seconds until the access token expires */, token_type: tokenType /* must be Bearer */, refresh_token
|
|
140
|
+
/* token used to refresh the access token once it has expired (only returned if the offline_access scope is requested).
|
|
141
|
+
*/
|
|
142
|
+
} = body;
|
|
143
|
+
const { exp } = (0, utils_1.parseJwt)(access_token);
|
|
144
|
+
var patch = {
|
|
145
|
+
accessToken: access_token,
|
|
146
|
+
refreshToken: refresh_token,
|
|
147
|
+
tokenType,
|
|
148
|
+
expiresIn: new Date(exp * 1000)
|
|
149
|
+
};
|
|
150
|
+
const repository = (0, shell_1.getRepository)(account_1.Account);
|
|
151
|
+
return await repository.save(Object.assign(Object.assign({}, account), patch));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
exports.Xero = Xero;
|
|
155
|
+
//# sourceMappingURL=xero.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"xero.js","sourceRoot":"","sources":["../../../server/controllers/xero/xero.ts"],"names":[],"mappings":"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","sourcesContent":["import fetch from 'node-fetch'\n\nimport { getRepository } from '@things-factory/shell'\nimport { parseJwt } from '@things-factory/utils'\n\nimport { Account } from '../../entities/account'\n\nconst ENDPOINT = 'https://api.xero.com/api.xro/2.0'\nconst debug = require('debug')('things-factory:integration-accounting:xero')\n\nexport type XeroConfig = {\n apiKey: string\n apiSecret: string\n accessToken?: string\n tenantId?: string\n callback?: string\n}\n\nexport class Xero {\n private config: XeroConfig\n\n constructor(config: XeroConfig) {\n this.config = {\n ...config\n }\n }\n\n buildAuthURL(nonce) {\n const scopes = 'offline_access openid profile email accounting.transactions accounting.settings accounting.contacts'\n const { apiKey, callback: redirectUrl } = this.config\n\n return `https://login.xero.com/identity/connect/authorize?response_type=code&client_id=${apiKey}&scope=${scopes}&redirect_uri=${redirectUrl}&state=${nonce}`\n }\n\n async get(path: string, data: any) {\n const { accessToken, tenantId } = this.config\n\n const qs = Object.entries(data)\n .map(([k, v]) => `${k}=${encodeURIComponent(String(v))}`)\n .join('&')\n\n const endpoint = `${ENDPOINT}${path}${qs ? '?' + qs : ''}`\n debug('endpoint', endpoint)\n\n const response = await fetch(endpoint, {\n method: 'get',\n headers: {\n accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n 'xero-tenant-id': tenantId\n }\n })\n\n if (!response.ok) {\n throw response\n }\n\n let result = await response.json()\n debug('response result', result)\n result = this.convertStatusCode(result)\n\n return result\n }\n\n async post(path: string, data: any = {}) {\n const { accessToken, tenantId } = this.config\n\n debug('data', data)\n\n const jsondata = JSON.stringify(data)\n\n const endpoint = `${ENDPOINT}${path}`\n debug('endpoint', endpoint)\n\n const response = await fetch(endpoint, {\n method: 'post',\n headers: {\n accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n 'xero-tenant-id': tenantId\n },\n body: jsondata\n })\n\n if (!response.ok) {\n throw response\n }\n\n let result = await response.json()\n debug('response result', result)\n result = this.convertStatusCode(result)\n\n return result\n }\n\n async put(path: string, data: any = {}) {\n const { accessToken, tenantId } = this.config\n\n debug('data', data)\n\n const jsondata = JSON.stringify(data)\n\n const endpoint = `${ENDPOINT}${path}`\n debug('endpoint', endpoint)\n\n const response = await fetch(endpoint, {\n method: 'put',\n headers: {\n accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n 'xero-tenant-id': tenantId\n },\n body: jsondata\n })\n\n if (!response.ok) {\n throw response\n }\n\n let result = await response.json()\n debug('response result', result)\n result = this.convertStatusCode(result)\n\n return result\n }\n\n async delete(path: string, data: any = {}) {\n const { accessToken, tenantId } = this.config\n\n debug('data', data)\n\n const jsondata = JSON.stringify(data)\n\n const endpoint = `${ENDPOINT}${path}`\n debug('endpoint', endpoint)\n\n const response = await fetch(endpoint, {\n method: 'delete',\n headers: {\n accept: 'application/json',\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${accessToken}`,\n 'xero-tenant-id': tenantId\n },\n body: jsondata\n })\n\n if (!response.ok) {\n throw response\n }\n\n let result = await response.json()\n debug('response result', result)\n result = this.convertStatusCode(result)\n\n return result\n }\n\n private convertStatusCode(result: Record<string, any>): Record<string, any> {\n result.ok = result.Status.toLowerCase() === 'ok'\n return result\n }\n\n public static async refreshAccessToken(apiKey, apiSecret, account) {\n const refreshRequestData = {\n grant_type: 'refresh_token',\n refresh_token: account.refreshToken\n }\n\n const refreshResponse = await fetch(`https://identity.xero.com/connect/token`, {\n method: 'post',\n headers: {\n Authorization: `Basic ${Buffer.from(apiKey + ':' + apiSecret).toString('base64')}`,\n 'Content-Type': 'application/x-www-form-urlencoded'\n },\n body: Object.entries(refreshRequestData)\n .map(([key, value]) => encodeURIComponent(key) + '=' + encodeURIComponent(value))\n .join('&')\n })\n\n if (!refreshResponse.ok) {\n throw new Error(`get account information failed: ${await refreshResponse.text()}`)\n }\n\n const body = await refreshResponse.json()\n const {\n access_token /* token used to call the API */,\n id_token /* token containing user identity details (only returned if OpenID Connect scopes are requested) */,\n expires_in /* amount of seconds until the access token expires */,\n token_type: tokenType /* must be Bearer */,\n refresh_token\n /* token used to refresh the access token once it has expired (only returned if the offline_access scope is requested).\n */\n } = body\n\n const { exp } = parseJwt(access_token)\n\n var patch = {\n accessToken: access_token,\n refreshToken: refresh_token,\n tokenType,\n expiresIn: new Date(exp * 1000)\n }\n\n const repository = getRepository(Account)\n\n return await repository.save({\n ...account,\n ...patch\n })\n }\n}\n"]}
|