What the app template looks like:
{
"AllowVersions": true,
"PersonalizationNotLoaded": false,
"HasOrphans": false,
"Layout": {
"name": "App",
"guid": "2dcd1674-5e34-4d98-b493-c75747027376",
"caption": "ExportAllTheThings",
"viewType": "Apps",
"pageType": "Responsive",
"components": [
{
"parentId": null,
"id": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"sourceTypeId": "metafx-panel-card",
"model": {
"guid": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"title": "Downloads",
"id": "metafx-panel-card-42b8f",
"bodyComponents": [
{
"id": "5609002a-b234-4242-8c7c-3e7ef3500ece",
"sourceTypeId": "metafx-div",
"model": {
"guid": "5609002a-b234-4242-8c7c-3e7ef3500ece",
"id": "rowTemplate",
"labelText": "PluginName"
},
"parentId": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"components": [
{
"id": "987433d4-9110-4151-9a3f-b65285a227c6",
"sourceTypeId": "metafx-col",
"model": {
"guid": "987433d4-9110-4151-9a3f-b65285a227c6",
"flexBasis": "25%",
"id": "lcTemplate",
"orientation": "horizontal"
},
"parentId": "5609002a-b234-4242-8c7c-3e7ef3500ece",
"components": [
{
"id": "0529688d-9a5c-4dbc-97b2-c41466c616db",
"sourceTypeId": "erp-button",
"model": {
"guid": "0529688d-9a5c-4dbc-97b2-c41466c616db",
"labelText": "Download",
"id": "btnDownload"
},
"parentId": "987433d4-9110-4151-9a3f-b65285a227c6",
"components": []
}
]
},
{
"id": "78a17344-9a59-4d21-9556-3efd40dfc0b3",
"sourceTypeId": "metafx-col",
"model": {
"guid": "78a17344-9a59-4d21-9556-3efd40dfc0b3",
"flexBasis": "75%",
"id": "rcTemplate"
},
"parentId": "5609002a-b234-4242-8c7c-3e7ef3500ece",
"components": [
{
"id": "73014d32-0641-4a20-a31b-c0c733a955c8",
"sourceTypeId": "erp-text-box",
"model": {
"guid": "73014d32-0641-4a20-a31b-c0c733a955c8",
"labelText": "Sample Plugin Description",
"id": "txtPluginDesc",
"personalizable": false,
"customizable": false,
"disabled": true,
"width": 1000
},
"parentId": "78a17344-9a59-4d21-9556-3efd40dfc0b3",
"components": []
}
]
}
]
}
]
},
"layoutData": {
"flexLayout": true,
"hostId": "App"
}
}
],
"navigation": {
"dataSetId": "",
"pageCaption": "",
"tabId": "",
"enable": false,
"parentPage": "",
"epBinding": "",
"epBindingLevel": 0,
"epBindingPeerOrder": 0
},
"width": 1440
},
"Events": [
{
"trigger": {
"hook": "onClick",
"type": "Control",
"target": "btnDownload"
},
"actions": [
{
"type": "file-transfer-erp",
"param": {
"specialFolder": 5,
"transferType": "download",
"company": "MS67964",
"serverPath": "EATT://TemplatePath",
"clientPath": "Wut"
}
}
],
"id": "btnDownload_onClick",
"customizable": true,
"disable": false
}
],
"ToolBar": [],
"DataViews": [],
"Rules": [],
"References": null,
"Pages": [],
"Properties": null,
"Wasm": null,
"IsLayerDisabled": false,
"ConfiguratorInfo": null,
"ApplicationStrings": null,
"ServerErrorCode": null,
"ServerErrors": null,
"Orphans": []
}
What the app looks like after processing:
{
"AllowVersions": true,
"PersonalizationNotLoaded": false,
"HasOrphans": false,
"Layout": {
"name": "App",
"guid": "2dcd1674-5e34-4d98-b493-c75747027376",
"caption": "ExportAllTheThings",
"viewType": "Apps",
"pageType": "Responsive",
"components": [
{
"parentId": null,
"id": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"sourceTypeId": "metafx-panel-card",
"model": {
"guid": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"title": "Downloads",
"id": "metafx-panel-card-42b8f",
"bodyComponents": [
{
"id": "d52bc555-7fa5-4f2e-a489-1ce407541918",
"sourceTypeId": "metafx-div",
"model": {
"guid": "d52bc555-7fa5-4f2e-a489-1ce407541918",
"id": "rowExportAllCustomBAQs",
"labelText": "ExportAllCustomBAQs"
},
"parentId": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"components": [
{
"id": "8831fa29-6c81-4fd0-a31a-3cc55c024951",
"sourceTypeId": "metafx-col",
"model": {
"guid": "8831fa29-6c81-4fd0-a31a-3cc55c024951",
"flexBasis": "25%",
"id": "lcExportAllCustomBAQs",
"orientation": "horizontal"
},
"parentId": "d52bc555-7fa5-4f2e-a489-1ce407541918",
"components": [
{
"id": "f1fe3052-e11f-450f-84c2-3157fba6df96",
"sourceTypeId": "erp-button",
"model": {
"guid": "f1fe3052-e11f-450f-84c2-3157fba6df96",
"labelText": "Download",
"id": "btnExportAllCustomBAQs"
},
"parentId": "f1fe3052-e11f-450f-84c2-3157fba6df96",
"components": []
}
]
},
{
"id": "e46e0b25-ff15-4b7e-9ebd-fd03e9b52686",
"sourceTypeId": "metafx-col",
"model": {
"guid": "e46e0b25-ff15-4b7e-9ebd-fd03e9b52686",
"flexBasis": "75%",
"id": "rcExportAllCustomBAQs"
},
"parentId": "d52bc555-7fa5-4f2e-a489-1ce407541918",
"components": [
{
"id": "6a6d8e35-3ada-41ae-a3be-ddd47c97c93e",
"sourceTypeId": "erp-text-box",
"model": {
"guid": "6a6d8e35-3ada-41ae-a3be-ddd47c97c93e",
"labelText": "This plugin downloads all custom BAQs.",
"id": "txtExportAllCustomBAQsDescription",
"personalizable": false,
"customizable": false,
"disabled": true,
"width": 1000
},
"parentId": "6a6d8e35-3ada-41ae-a3be-ddd47c97c93e",
"components": []
}
]
}
]
},
{
"id": "367530f3-8706-4f37-a61d-70b8b478f76d",
"sourceTypeId": "metafx-div",
"model": {
"guid": "367530f3-8706-4f37-a61d-70b8b478f76d",
"id": "rowExportAllFunctionLibraries",
"labelText": "ExportAllFunctionLibraries"
},
"parentId": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"components": [
{
"id": "6d2b6cd6-6d2f-4efc-b6a6-94e85105565d",
"sourceTypeId": "metafx-col",
"model": {
"guid": "6d2b6cd6-6d2f-4efc-b6a6-94e85105565d",
"flexBasis": "25%",
"id": "lcExportAllFunctionLibraries",
"orientation": "horizontal"
},
"parentId": "367530f3-8706-4f37-a61d-70b8b478f76d",
"components": [
{
"id": "8383ab8d-91af-48de-89b4-4286c4aa4018",
"sourceTypeId": "erp-button",
"model": {
"guid": "8383ab8d-91af-48de-89b4-4286c4aa4018",
"labelText": "Download",
"id": "btnExportAllFunctionLibraries"
},
"parentId": "8383ab8d-91af-48de-89b4-4286c4aa4018",
"components": []
}
]
},
{
"id": "7cfcf13f-3a9d-4291-8e10-e048fa757f1e",
"sourceTypeId": "metafx-col",
"model": {
"guid": "7cfcf13f-3a9d-4291-8e10-e048fa757f1e",
"flexBasis": "75%",
"id": "rcExportAllFunctionLibraries"
},
"parentId": "367530f3-8706-4f37-a61d-70b8b478f76d",
"components": [
{
"id": "2c4ed096-c8b6-4d9b-8220-bd293270e38a",
"sourceTypeId": "erp-text-box",
"model": {
"guid": "2c4ed096-c8b6-4d9b-8220-bd293270e38a",
"labelText": "This plugin downloads all Function Libraries.",
"id": "txtExportAllFunctionLibrariesDescription",
"personalizable": false,
"customizable": false,
"disabled": true,
"width": 1000
},
"parentId": "2c4ed096-c8b6-4d9b-8220-bd293270e38a",
"components": []
}
]
}
]
},
{
"id": "3f32cbc8-d3c0-45a4-9226-db58d9ab11fe",
"sourceTypeId": "metafx-div",
"model": {
"guid": "3f32cbc8-d3c0-45a4-9226-db58d9ab11fe",
"id": "rowExportAllUDCodes",
"labelText": "ExportAllUDCodes"
},
"parentId": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"components": [
{
"id": "c4a6e44a-2968-4051-98b9-1a47f83cbd71",
"sourceTypeId": "metafx-col",
"model": {
"guid": "c4a6e44a-2968-4051-98b9-1a47f83cbd71",
"flexBasis": "25%",
"id": "lcExportAllUDCodes",
"orientation": "horizontal"
},
"parentId": "3f32cbc8-d3c0-45a4-9226-db58d9ab11fe",
"components": [
{
"id": "c4386dc7-dcb4-46bf-b1e9-bb5fec53c42b",
"sourceTypeId": "erp-button",
"model": {
"guid": "c4386dc7-dcb4-46bf-b1e9-bb5fec53c42b",
"labelText": "Download",
"id": "btnExportAllUDCodes"
},
"parentId": "c4386dc7-dcb4-46bf-b1e9-bb5fec53c42b",
"components": []
}
]
},
{
"id": "94e283ed-bc24-4d1a-aeec-2c6b21910cd0",
"sourceTypeId": "metafx-col",
"model": {
"guid": "94e283ed-bc24-4d1a-aeec-2c6b21910cd0",
"flexBasis": "75%",
"id": "rcExportAllUDCodes"
},
"parentId": "3f32cbc8-d3c0-45a4-9226-db58d9ab11fe",
"components": [
{
"id": "5f9bd722-3530-4047-b957-c3e7ae89b05a",
"sourceTypeId": "erp-text-box",
"model": {
"guid": "5f9bd722-3530-4047-b957-c3e7ae89b05a",
"labelText": "This plugin exports all UD Codes. (User Codes)",
"id": "txtExportAllUDCodesDescription",
"personalizable": false,
"customizable": false,
"disabled": true,
"width": 1000
},
"parentId": "5f9bd722-3530-4047-b957-c3e7ae89b05a",
"components": []
}
]
}
]
},
{
"id": "583cbebc-45a2-4df7-b57a-36e824f0748e",
"sourceTypeId": "metafx-div",
"model": {
"guid": "583cbebc-45a2-4df7-b57a-36e824f0748e",
"id": "rowExportDataDirectivesByTable",
"labelText": "ExportDataDirectivesByTable"
},
"parentId": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"components": [
{
"id": "8a02fad0-1d8c-4651-a89a-2697fea1bb25",
"sourceTypeId": "metafx-col",
"model": {
"guid": "8a02fad0-1d8c-4651-a89a-2697fea1bb25",
"flexBasis": "25%",
"id": "lcExportDataDirectivesByTable",
"orientation": "horizontal"
},
"parentId": "583cbebc-45a2-4df7-b57a-36e824f0748e",
"components": [
{
"id": "db6f90b1-b5b1-4c95-b0b7-0975530c983d",
"sourceTypeId": "erp-button",
"model": {
"guid": "db6f90b1-b5b1-4c95-b0b7-0975530c983d",
"labelText": "Download",
"id": "btnExportDataDirectivesByTable"
},
"parentId": "db6f90b1-b5b1-4c95-b0b7-0975530c983d",
"components": []
}
]
},
{
"id": "be8821d8-6e1f-4f09-a7a5-5a16eba47eb0",
"sourceTypeId": "metafx-col",
"model": {
"guid": "be8821d8-6e1f-4f09-a7a5-5a16eba47eb0",
"flexBasis": "75%",
"id": "rcExportDataDirectivesByTable"
},
"parentId": "583cbebc-45a2-4df7-b57a-36e824f0748e",
"components": [
{
"id": "b410145c-45d3-4ea4-8585-1fb0f1015049",
"sourceTypeId": "erp-text-box",
"model": {
"guid": "b410145c-45d3-4ea4-8585-1fb0f1015049",
"labelText": "This plugin downloads all Data Directives by \"Table\".",
"id": "txtExportDataDirectivesByTableDescription",
"personalizable": false,
"customizable": false,
"disabled": true,
"width": 1000
},
"parentId": "b410145c-45d3-4ea4-8585-1fb0f1015049",
"components": []
}
]
}
]
},
{
"id": "6188857e-2d60-4974-83a2-dfd8f27dee35",
"sourceTypeId": "metafx-div",
"model": {
"guid": "6188857e-2d60-4974-83a2-dfd8f27dee35",
"id": "rowExportDirectivesByGroups",
"labelText": "ExportDirectivesByGroups"
},
"parentId": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"components": [
{
"id": "f93ba304-a937-4bed-9587-797e0b9bba5b",
"sourceTypeId": "metafx-col",
"model": {
"guid": "f93ba304-a937-4bed-9587-797e0b9bba5b",
"flexBasis": "25%",
"id": "lcExportDirectivesByGroups",
"orientation": "horizontal"
},
"parentId": "6188857e-2d60-4974-83a2-dfd8f27dee35",
"components": [
{
"id": "6f02f787-fdc7-4ef8-9a78-8e29bb07677a",
"sourceTypeId": "erp-button",
"model": {
"guid": "6f02f787-fdc7-4ef8-9a78-8e29bb07677a",
"labelText": "Download",
"id": "btnExportDirectivesByGroups"
},
"parentId": "6f02f787-fdc7-4ef8-9a78-8e29bb07677a",
"components": []
}
]
},
{
"id": "96d869ee-42d5-4c37-875e-dd084a436870",
"sourceTypeId": "metafx-col",
"model": {
"guid": "96d869ee-42d5-4c37-875e-dd084a436870",
"flexBasis": "75%",
"id": "rcExportDirectivesByGroups"
},
"parentId": "6188857e-2d60-4974-83a2-dfd8f27dee35",
"components": [
{
"id": "14cd63f5-eceb-44ed-aad2-d26ff2177d8d",
"sourceTypeId": "erp-text-box",
"model": {
"guid": "14cd63f5-eceb-44ed-aad2-d26ff2177d8d",
"labelText": "This plugin downloads all Method AND Data Directives by \"Group\".",
"id": "txtExportDirectivesByGroupsDescription",
"personalizable": false,
"customizable": false,
"disabled": true,
"width": 1000
},
"parentId": "14cd63f5-eceb-44ed-aad2-d26ff2177d8d",
"components": []
}
]
}
]
},
{
"id": "8683c36a-037d-4274-8977-bda5752765bc",
"sourceTypeId": "metafx-div",
"model": {
"guid": "8683c36a-037d-4274-8977-bda5752765bc",
"id": "rowExportMethodDirectivesByService",
"labelText": "ExportMethodDirectivesByService"
},
"parentId": "42b8f86a-e989-476f-bd72-c27b58f14dad",
"components": [
{
"id": "31dc605d-89dd-4306-bce8-22c83611492f",
"sourceTypeId": "metafx-col",
"model": {
"guid": "31dc605d-89dd-4306-bce8-22c83611492f",
"flexBasis": "25%",
"id": "lcExportMethodDirectivesByService",
"orientation": "horizontal"
},
"parentId": "8683c36a-037d-4274-8977-bda5752765bc",
"components": [
{
"id": "9cd30016-e3f6-4fc8-a363-157821f3fb11",
"sourceTypeId": "erp-button",
"model": {
"guid": "9cd30016-e3f6-4fc8-a363-157821f3fb11",
"labelText": "Download",
"id": "btnExportMethodDirectivesByService"
},
"parentId": "9cd30016-e3f6-4fc8-a363-157821f3fb11",
"components": []
}
]
},
{
"id": "666e6ff3-431a-4a14-86de-a3eb90592f37",
"sourceTypeId": "metafx-col",
"model": {
"guid": "666e6ff3-431a-4a14-86de-a3eb90592f37",
"flexBasis": "75%",
"id": "rcExportMethodDirectivesByService"
},
"parentId": "8683c36a-037d-4274-8977-bda5752765bc",
"components": [
{
"id": "396d9630-1685-4f0f-8752-039c4c34a339",
"sourceTypeId": "erp-text-box",
"model": {
"guid": "396d9630-1685-4f0f-8752-039c4c34a339",
"labelText": "This plugin downloads all Method Directives by \"Service\".",
"id": "txtExportMethodDirectivesByServiceDescription",
"personalizable": false,
"customizable": false,
"disabled": true,
"width": 1000
},
"parentId": "396d9630-1685-4f0f-8752-039c4c34a339",
"components": []
}
]
}
]
}
]
},
"layoutData": {
"flexLayout": true,
"hostId": "App"
}
}
],
"navigation": {
"dataSetId": "",
"pageCaption": "",
"tabId": "",
"enable": false,
"parentPage": "",
"epBinding": "",
"epBindingLevel": 0,
"epBindingPeerOrder": 0
},
"width": 1440
},
"Events": [
{
"trigger": {
"hook": "onClick",
"type": "Control",
"target": "btnExportAllCustomBAQs"
},
"actions": [
{
"type": "file-transfer-erp",
"param": {
"specialFolder": 5,
"transferType": "download",
"company": "MS67964",
"serverPath": "EATT://ExportAllCustomBAQs",
"clientPath": "ExportAllCustomBAQs.zip"
}
}
],
"id": "btnExportAllCustomBAQs_onClick",
"customizable": true,
"disable": false
},
{
"trigger": {
"hook": "onClick",
"type": "Control",
"target": "btnExportAllFunctionLibraries"
},
"actions": [
{
"type": "file-transfer-erp",
"param": {
"specialFolder": 5,
"transferType": "download",
"company": "MS67964",
"serverPath": "EATT://ExportAllFunctionLibraries",
"clientPath": "ExportAllFunctionLibraries.zip"
}
}
],
"id": "btnExportAllFunctionLibraries_onClick",
"customizable": true,
"disable": false
},
{
"trigger": {
"hook": "onClick",
"type": "Control",
"target": "btnExportAllUDCodes"
},
"actions": [
{
"type": "file-transfer-erp",
"param": {
"specialFolder": 5,
"transferType": "download",
"company": "MS67964",
"serverPath": "EATT://ExportAllUDCodes",
"clientPath": "ExportAllUDCodes.zip"
}
}
],
"id": "btnExportAllUDCodes_onClick",
"customizable": true,
"disable": false
},
{
"trigger": {
"hook": "onClick",
"type": "Control",
"target": "btnExportDataDirectivesByTable"
},
"actions": [
{
"type": "file-transfer-erp",
"param": {
"specialFolder": 5,
"transferType": "download",
"company": "MS67964",
"serverPath": "EATT://ExportDataDirectivesByTable",
"clientPath": "ExportDataDirectivesByTable.zip"
}
}
],
"id": "btnExportDataDirectivesByTable_onClick",
"customizable": true,
"disable": false
},
{
"trigger": {
"hook": "onClick",
"type": "Control",
"target": "btnExportDirectivesByGroups"
},
"actions": [
{
"type": "file-transfer-erp",
"param": {
"specialFolder": 5,
"transferType": "download",
"company": "MS67964",
"serverPath": "EATT://ExportDirectivesByGroups",
"clientPath": "ExportDirectivesByGroups.zip"
}
}
],
"id": "btnExportDirectivesByGroups_onClick",
"customizable": true,
"disable": false
},
{
"trigger": {
"hook": "onClick",
"type": "Control",
"target": "btnExportMethodDirectivesByService"
},
"actions": [
{
"type": "file-transfer-erp",
"param": {
"specialFolder": 5,
"transferType": "download",
"company": "MS67964",
"serverPath": "EATT://ExportMethodDirectivesByService",
"clientPath": "ExportMethodDirectivesByService.zip"
}
}
],
"id": "btnExportMethodDirectivesByService_onClick",
"customizable": true,
"disable": false
}
],
"ToolBar": [],
"DataViews": [],
"Rules": [],
"References": null,
"Pages": [],
"Properties": null,
"Wasm": null,
"IsLayerDisabled": false,
"ConfiguratorInfo": null,
"ApplicationStrings": null,
"ServerErrorCode": null,
"ServerErrors": null,
"Orphans": []
}
BPM on Ice.Lib.MetaFX.GetApp
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Directive Type: Method -> Post Processing
* Directive BO: Ice.Lib.MetaFX.GetApp
* Directive Name: InterceptGetAppRequest
* Directive Desc: Intercepts a request for a template, forward it to the appropriate place.
* Directive Group: ExportAllTheThings
* ==========================================================================================
*
* Hi Mom!
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/29/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//If we are in app studio, we only want to edit the template, not a dynamically generated app.
if(request.properties.mode == "AppStudio") return; //Bye
if(request.id == "Ice.UI.ExportAllTheThingsTemplate")
{
//Where we are going to call
string FunctionLibrary = "ExportAllTheThings";
string FunctionID = "GetApp";
try
{
//Call the function with the request and template data. This is one of the reasons we are doing this in post so the system will retrieve it for us.
var response = InvokeFunction(FunctionLibrary, FunctionID, JsonConvert.SerializeObject(request), JsonConvert.SerializeObject(result));
//So y'all can see what was returned better
var responseUnwrapped = new
{
Success = (bool)response[0],
ListErrorJson = (string)response[1],
appJson = (string)response[2]
};
//If we succeeded, we are done. Parse the Json into tokens and pass it back. The serializer will take care of it from here.
if(responseUnwrapped.Success) //Success
{
result = JToken.Parse(responseUnwrapped.appJson);
return; //Done. Stop Processing.
}
//Failure
if(!String.IsNullOrEmpty(responseUnwrapped.ListErrorJson))
{
//If we have errors, pass them along with the exception.
throw new BLException(responseUnwrapped.ListErrorJson);
}
else
{
//We didn't have any errors, so we'll pass back "something" useful lol.
throw new BLException($"Unknown error from function: {FunctionLibrary}.{FunctionID}");
}
}
catch (Exception ex)
{
//We will just rethrow anything. Catches our exceptions above, as well as unknowns.
throw ex;
}
}
BPM on Ice.Lib.FileTransfer.DownloadFileForCompany
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Directive Type: Method -> Pre Processing
* Directive BO: Ice.Lib.FileTransfer.DownloadFileForCompany
* Directive Name: InterceptFileDownloadForCompanyRequest
* Directive Desc: Intercepts the call to download a file if a custom url is used, and routes
* it appropriately.
* Directive Group: ExportAllTheThings
* ==========================================================================================
*
* Hi Mom!
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//We are only interested in requests that the server path starts with "EATT://"
if(serverPath.StartsWith("EATT://"))
{
try
{
//Get the plugin name
string plugin = serverPath.Split("//")[1];
//Call the plugin (function)
var response = InvokeFunction("ExportAllTheThings", plugin);
//So y'all can see what was returned better
var responseUnwrapped = new
{
Success = (bool)response[0],
ListErrorJson = (string)response[1],
ZipBase64 = (string)response[2]
};
//If we succeeded, we are done. Convert the Base64 Data from the plugin (function) to a byte array and return it.
if(responseUnwrapped.Success) //Success
{
if(!String.IsNullOrEmpty(responseUnwrapped.ZipBase64))
{
result = Convert.FromBase64String(responseUnwrapped.ZipBase64);
MarkCallCompleted();
}
return; //Done. Stop Processing.
}
//Failure
//Create an exception
var exception = new BLException( "Failure running plugin with path: \"" + serverPath + "\"" );
if(!String.IsNullOrEmpty(responseUnwrapped.ListErrorJson))
{
//If we have errors, pass them along with the exception.
exception.Data.Add("ErrorList", responseUnwrapped.ListErrorJson);
}
//Bam!
throw exception;
}
catch (Exception ex)
{
//We will just rethrow anything. Catches our exceptions above, as well as unknowns.
throw new BLException(ex.ToString());
}
}
ExportAllTheThings.GetApp
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: GetApp
* Description: This function parses a template app and builds a full app based off of the
* plugins found in this library. These plugins export things as "Zip" Files.
* ==========================================================================================
*
* INPUTS:
* STRING: Request -> The request for the app from the client
* STRING: TemplateData -> The json data for the template app
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: appJson -> Kinetic app Json data
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
//Use Newtonsoft to copy a token
Func<JToken, JToken> DuplicateToken = (token) => JToken.Parse(token.ToString());
try
{
//****
//Create a dictionary of "plugins" to build the app with
Dictionary<string, string> pluginDictionary = new Dictionary<string, string>();
//Load the plugins into the dictionary
CallService<Ice.Contracts.EfxLibraryDesignerSvcContract>(efxLD =>
{
//We are loading plugins from this libary, so get a list of the functions.
var functionLibrary = efxLD.GetLibrary(LibraryID);
//Populate the plugins dictionary. Only chose functions that begin with "Export".
pluginDictionary = functionLibrary.EfxFunction.Where(f => f.FunctionID.StartsWith("Export")).ToDictionary(f1 => f1.FunctionID, f2 => f2.Description);
});
//Parse the template data.
var app = JToken.Parse(TemplateData);
//Get the body template section we are interested in.
var bodyComponentsTemplate = app["Layout"]["components"][0]["model"]["bodyComponents"];
//Clear template data from the array.
app["Layout"]["components"][0]["model"]["bodyComponents"] = new JArray();
//Get the event template section we are interested in.
var eventTemplate = app["Events"][0];
//Clear template data from the array.
app["Events"] = new JArray();
//We are doing rows down the page. Get that section.
var rowTemplate = bodyComponentsTemplate[0];
//We will build a new row for each plugin.
foreach(var func in pluginDictionary)
{
var newRow = DuplicateToken(rowTemplate);
//Row
newRow["id"] = Guid.NewGuid();
newRow["model"]["guid"] = newRow["id"];
newRow["model"]["id"] = $"row{func.Key}";
newRow["model"]["labelText"] = func.Key;
//Left Column Components
newRow["components"][0]["id"] = Guid.NewGuid();
newRow["components"][0]["model"]["guid"] = newRow["components"][0]["id"];
newRow["components"][0]["model"]["id"] = $"lc{func.Key}";
newRow["components"][0]["parentId"] = newRow["id"];
//Button
newRow["components"][0]["components"][0]["id"] = Guid.NewGuid();
newRow["components"][0]["components"][0]["model"]["guid"] = newRow["components"][0]["components"][0]["id"];
newRow["components"][0]["components"][0]["model"]["id"] = $"btn{func.Key}";
newRow["components"][0]["components"][0]["parentId"] = newRow["components"][0]["components"][0]["id"];
//Right Column Components
newRow["components"][1]["id"] = Guid.NewGuid();
newRow["components"][1]["model"]["guid"] = newRow["components"][1]["id"];
newRow["components"][1]["model"]["id"] = $"rc{func.Key}";
newRow["components"][1]["parentId"] = newRow["id"];
//Plugin Description
newRow["components"][1]["components"][0]["id"] = Guid.NewGuid();
newRow["components"][1]["components"][0]["model"]["guid"] = newRow["components"][1]["components"][0]["id"];
newRow["components"][1]["components"][0]["model"]["id"] = $"txt{func.Key}Description";
newRow["components"][1]["components"][0]["model"]["labelText"] = func.Value;
newRow["components"][1]["components"][0]["parentId"] = newRow["components"][1]["components"][0]["id"];
//Add row to app.
((JArray)app["Layout"]["components"][0]["model"]["bodyComponents"]).Add(newRow);
//Events
var newEvent = DuplicateToken(eventTemplate);
//Add Event for each button / plugin.
newEvent["trigger"]["target"] = $"btn{func.Key}";
newEvent["actions"][0]["param"]["serverPath"] = $"EATT://{func.Key}";
newEvent["actions"][0]["param"]["clientPath"] = $"{func.Key}.zip";
newEvent["id"] = $"btn{func.Key}_onClick";
//Add event to app.
((JArray)app["Events"]).Add(newEvent);
}
//Get the json for the app and return it.
appJson = app.ToString();
Success = true; //Woot!
}
catch (Exception ex)
{
Success = false; //Meh
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
ExportAllTheThings.ZipFiles
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ZipFiles
* Description: This is a utility function to "Zip" files.
* ==========================================================================================
*
* INPUTS:
* STRING: fileDictionaryJson -> Json Encoded Dictionary<string, string> where the first
* string is the filename, and the second is a Base64
* endoded byte array with the file data.
*
* OUTPUTS:
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
Func<Dictionary<string, string>, byte[]> ZipByteArray = (fileDict) =>
{
byte[] retBytes = null;
using (MemoryStream zipMS = new MemoryStream())
{
using (ZipArchive zipArchive = new ZipArchive(zipMS, ZipArchiveMode.Create, true))
{
foreach(var file in fileDict)
{
var zipArchiveEntry = zipArchive.CreateEntry(file.Key, CompressionLevel.NoCompression);
using (var zipStream = zipArchiveEntry.Open())
{
byte[] fileBytes = Convert.FromBase64String(file.Value);
zipStream.Write(fileBytes, 0, fileBytes.Length);
}
}
}
zipMS.Flush();
retBytes = zipMS.ToArray();
};
return retBytes;
};
Dictionary<string, string> fileDictionary = new Dictionary<string, string>();
try
{
fileDictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(fileDictionaryJson);
}
catch {}
if(fileDictionary.Count() < 1) return; //Get out of here
byte[] zipBytes = ZipByteArray(fileDictionary);
ZipBase64 = Convert.ToBase64String(zipBytes);
ExportAllTheThings.ExportAllCustomBAQs
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportAllCustomBAQs
* Description: This plugin downloads all custom BAQs.
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
try
{
//****
CallService<Ice.Contracts.BAQDesignerSvcContract>(baqD =>
{
//Files we will be adding to the zip file
Dictionary<string, string> mainZipFileDictionary = new Dictionary<string, string>();
//Get all BAQs that are not marked "System".
bool more = false;
BAQDesignerListTableset baqListTS = baqD.GetList("SystemFlag=false", 0, 1, out more);
//Loop through the list.
foreach(DynamicQueryDesignerListRow item in baqListTS.DynamicQueryDesignerList)
{
try
{
//Export the BAQ and get the binary data.
Dictionary<string, string> options = new Dictionary<string, string>();
List<string> logResult = new List<string>(); //Needed for export call.
byte[] itemBytes = baqD.ExportBaq(item.QueryID, ref options, out logResult);
//Convert the data to a Base64 encoded string.
string itemBase64 = Convert.ToBase64String(itemBytes);
//Add the data as a file in the zip.
mainZipFileDictionary.Add($"{item.QueryID}.baq", itemBase64);
}
catch (Exception iEx)
{
//Continue processing on error, but add errors to the errors list.
iEx.Data.Add("QueryID", item.QueryID);
ListErrorJson = AddExceptionToList(iEx, ListErrorJson);
}
}
//Zip the files
string fileDictionaryJson = JsonConvert.SerializeObject(mainZipFileDictionary);
//Return the zip file data as a Base64 encoded string.
ZipBase64 = ThisLib.ZipFiles(fileDictionaryJson);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
ExportAllTheThings.ExportAllFunctionLibraries
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportAllFunctionLibraries
* Description: This plugin downloads all Function Libraries.
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
//Can't make this damn thing directly, wtf?
Func<(int kind, string startsWith, int rollOutMode, int status), Ice.Lib.EfxLibraryDesigner.LibrarySearchOptions> CreateLibrarySearchOptions = (input) =>
{
return JsonConvert.DeserializeObject<Ice.Lib.EfxLibraryDesigner.LibrarySearchOptions>( JsonConvert.SerializeObject(new {input.kind, input.startsWith, input.rollOutMode, input.status}) );
};
try
{
//****
CallService<Ice.Contracts.EfxLibraryDesignerSvcContract>(efxLD =>
{
//Files we will be adding to the zip file
Dictionary<string, string> mainZipFileDictionary = new Dictionary<string, string>();
//Get all Function Libraries
var librarySearchOptions = CreateLibrarySearchOptions((kind: 1, startsWith: "", rollOutMode: 2, status: 2));
EfxLibrarySearchTableset libraries = efxLD.GetLibraryList(librarySearchOptions);
EfxLibraryTableset defaults = efxLD.GetDefaults();
System.Version version = new System.Version($"{defaults.EfxLibrary.FirstOrDefault().EpicorVersion}.{defaults.EfxLibrary.FirstOrDefault().Revision}");
//Loop through the list.
foreach(var item in libraries.EfxLibraryList)
{
try
{
//Export the Library and get the binary data.
var exportOptions = new Ice.Lib.EfxLibraryDesigner.ExportOptions()
{
Mode = 0, Format = (Ice.Lib.EfxLibraryDesigner.ExportFileFormat)1, Package = null, PackageVersion = version, Publisher = Session.UserID, InstallAsHidden = false
};
byte[] itemBytes = efxLD.ExportLibrary(item.LibraryID, exportOptions);
//Convert the data to a Base64 encoded string.
string itemBase64 = Convert.ToBase64String(itemBytes);
//Add the data as a file in the zip.
mainZipFileDictionary.Add($"{item.LibraryID}.efxj", itemBase64);
}
catch (Exception iEx)
{
//Continue processing on error, but add errors to the errors list.
iEx.Data.Add("LibraryID", item.LibraryID);
ListErrorJson = AddExceptionToList(iEx, ListErrorJson);
}
}
//Zip the files
string fileDictionaryJson = JsonConvert.SerializeObject(mainZipFileDictionary);
//Return the zip file data as a Base64 encoded string.
ZipBase64 = ThisLib.ZipFiles(fileDictionaryJson);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
ExportAllTheThings.ExportAllUDCodes
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportAllUDCodes
* Description: This plugin exports all UD Codes. (User Codes)
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
//Serialize a whole Tableset to B64
Func<IceTableset, string> GetTablesetBytesAsB64 = (ts) =>
{
string tempJson = JsonConvert.SerializeObject(ts, Formatting.Indented);
byte[] tempBytes = System.Text.Encoding.UTF8.GetBytes(tempJson);
return Convert.ToBase64String(tempBytes);
};
try
{
//****
CallService<Ice.Contracts.UserCodesSvcContract>(udCode =>
{
//Files we will be adding to the zip file
Dictionary<string, string> mainZipFileDictionary = new Dictionary<string, string>();
//Get All UD Codes
bool morePages = false;
UserCodesTableset udCodeTS = udCode.GetRows("", "", 0, 0, out morePages);
//Add all to zip file
mainZipFileDictionary.Add("AllCodes.json", GetTablesetBytesAsB64(udCodeTS));
//Get Distinct List of UDCode Types
var udCodeTypes = udCodeTS.UDCodeType.Select(x => x.CodeTypeID).Distinct().ToList();
//Add Individual codes by CodeTypeID to zip file
foreach(var codeType in udCodeTypes)
{
//Need something to dump it into
UserCodesTableset tempUDCodeTS = new UserCodesTableset();
//Filter to the individual CodeTypeID and cheat using Newtonsoft to do the copy
UDCodesTable filteredUDCodesTable = JsonConvert.DeserializeObject<UDCodesTable>(JsonConvert.SerializeObject(udCodeTS.UDCodes.Where(x => x.CodeTypeID == codeType)));
UDCodeTypeTable filteredUDCodeTypeTable = JsonConvert.DeserializeObject<UDCodeTypeTable>(JsonConvert.SerializeObject(udCodeTS.UDCodeType.Where(x => x.CodeTypeID == codeType)));
//Add the ranges back to the TS
tempUDCodeTS.UDCodes.AddRange(filteredUDCodesTable);
tempUDCodeTS.UDCodeType.AddRange(filteredUDCodeTypeTable);
//Zip the files
Dictionary<string, string> perCodeTypeFileDictionary = new Dictionary<string, string>();
perCodeTypeFileDictionary.Add($"{codeType}.json", GetTablesetBytesAsB64(tempUDCodeTS));
string perCodefileDictionaryJson = JsonConvert.SerializeObject(perCodeTypeFileDictionary);
string perCodeZipBase64 = ThisLib.ZipFiles(perCodefileDictionaryJson);
//Add to the MAIN zip file
mainZipFileDictionary.Add($"{codeType}.zip", perCodeZipBase64);
}
//Zip the files (The main one)
string fileDictionaryJson = JsonConvert.SerializeObject(mainZipFileDictionary);
//Return the zip file data as a Base64 encoded string.
ZipBase64 = ThisLib.ZipFiles(fileDictionaryJson);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
ExportAllTheThings.ExportDataDirectivesByTable
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportDataDirectivesByTable
* Description: This plugin downloads all Data Directives by "Table".
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
try
{
//****
CallService<Ice.Contracts.BpMethodSvcContract>(bpMethod =>
{
//Files we will be adding to the zip file
Dictionary<string, string> mainZipFileDictionary = new Dictionary<string, string>();
//Get All Data Directives
bool morePages = false;
Ice.Tablesets.BpMethodListTableset methodTS = bpMethod.GetList("Source = 'DB'", 0, 0, out morePages);
//Create a Distinct List of Data Directive Methods
var methodsList = methodTS.BpMethodList.Select(x => new { x.SystemCode, x.BusinessObject }).ToList().Distinct();
//Loop through the list.
foreach(var item in methodsList)
{
try
{
//Export the Data Directive
byte[] itemBytes = bpMethod.ExportByTable(item.SystemCode, item.BusinessObject).Data;
//Convert the data to a Base64 encoded string.
string itemBase64 = Convert.ToBase64String(itemBytes);
//Add the data as a file in the zip.
mainZipFileDictionary.Add($"{item.SystemCode}.{item.BusinessObject}.bpm", itemBase64);
}
catch (Exception iEx)
{
//Continue processing on error, but add errors to the errors list.
iEx.Data.Add("Table", $"{item.SystemCode}.{item.BusinessObject}.bpm");
ListErrorJson = AddExceptionToList(iEx, ListErrorJson);
}
}
//Zip the files
string fileDictionaryJson = JsonConvert.SerializeObject(mainZipFileDictionary);
//Return the zip file data as a Base64 encoded string.
ZipBase64 = ThisLib.ZipFiles(fileDictionaryJson);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
ExportAllTheThings.ExportDirectivesByGroups
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportDirectivesByGroups
* Description: This plugin downloads all Method AND Data Directives by "Group".
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
try
{
//****
CallService<Ice.Contracts.BpMethodSvcContract>(bpMethod =>
{
//Files we will be adding to the zip file
Dictionary<string, string> mainZipFileDictionary = new Dictionary<string, string>();
//Get All Directive Groups
List<string> groupList = bpMethod.GetDirectiveGroups("BO,DB").ToList();
//Loop through the list.
foreach(var item in groupList)
{
try
{
//Export the group and get the binary data.
byte[] itemBytes = bpMethod.ExportByDirectiveGroup(item).Data;
//Convert the data to a Base64 encoded string.
string itemBase64 = Convert.ToBase64String(itemBytes);
//Create an appropriate file name.
string filename = String.IsNullOrEmpty(item) ? "Ungrouped" : item;
//Add the data as a file in the zip.
mainZipFileDictionary.Add($"{filename}.bpm", itemBase64);
}
catch (Exception iEx)
{
//Continue processing on error, but add errors to the errors list.
iEx.Data.Add("Group", item);
ListErrorJson = AddExceptionToList(iEx, ListErrorJson);
}
}
//Zip the files
string fileDictionaryJson = JsonConvert.SerializeObject(mainZipFileDictionary);
//Return the zip file data as a Base64 encoded string.
ZipBase64 = ThisLib.ZipFiles(fileDictionaryJson);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
ExportAllTheThings.ExportMethodDirectivesByService
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportMethodDirectivesByService
* Description: This plugin downloads all Method Directives by "Service".
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 08/26/2024 | klincecum | Kevin Lincecum | Initial Implementation
* 08/30/2024 | klincecum | Kevin Lincecum | Cleanup & Comments For Release
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
try
{
//****
CallService<Ice.Contracts.BpMethodSvcContract>(bpMethod =>
{
//Files we will be adding to the zip file
Dictionary<string, string> mainZipFileDictionary = new Dictionary<string, string>();
//Get all Directives for a "Service". (Also exclude BAQ BPMs)
bool morePages = false;
Ice.Tablesets.BpMethodListTableset methodTS = bpMethod.GetList("Source = 'BO' AND ObjectNS <> ''", 0, 0, out morePages);
//Create a unique list to process.
var methodsList = methodTS.BpMethodList.Select(x => new { x.SystemCode, x.ObjectNS, x.BusinessObject }).ToList().Distinct();
//Loop through the list.
foreach(var item in methodsList)
{
try
{
//Export the directive and get the binary data.
byte[] zipMethodBytes = bpMethod.ExportByService(item.SystemCode, item.ObjectNS, item.BusinessObject).Data;
//Convert the data to a Base64 encoded string.
string methodZipBase64 = Convert.ToBase64String(zipMethodBytes);
//Add the data as a file in the zip.
mainZipFileDictionary.Add($"{item.SystemCode}.{item.ObjectNS}.{item.BusinessObject}.bpm", methodZipBase64);
}
catch (Exception iEx)
{
//Continue processing on error, but add errors to the errors list.
iEx.Data.Add("Service", $"{item.SystemCode}.{item.ObjectNS}.{item.BusinessObject}");
ListErrorJson = AddExceptionToList(iEx, ListErrorJson);
}
}
//Zip the files
string fileDictionaryJson = JsonConvert.SerializeObject(mainZipFileDictionary);
//Return the zip file data as a Base64 encoded string.
ZipBase64 = ThisLib.ZipFiles(fileDictionaryJson);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
New 04 Sep 2024
ExportAllTheThings.ExportAllKineticCustomLayers
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportAllKineticCustomLayers
* Description: This plugin downloads all custom Kinetic layers.
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 09/04/2024 | klincecum | Kevin Lincecum | Initial Implementation
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
try
{
//****
CallService<Ice.Contracts.MetaFXSvcContract>(metaFX =>
{
//Create a request to list the apps
var request = new Epicor.MetaFX.Core.Models.Applications.ApplicationRequest()
{
Type = "view",
SubType = "",
SearchText = "",
IncludeAllLayers = true
};
//Get a list of apps
List<Epicor.MetaFX.Core.Models.Applications.Application> applications = metaFX.GetApplications(request);
//Create an export request list
List<Epicor.MetaFX.Core.Models.Layers.EpMetaFxLayerForApplication> applicationList = new List<Epicor.MetaFX.Core.Models.Layers.EpMetaFxLayerForApplication>();
//Loop through the list and add custom apps to the export list
foreach(var item in applications.Where(x => x.SystemFlag == false))
{
applicationList.Add(new Epicor.MetaFX.Core.Models.Layers.EpMetaFxLayerForApplication() { Id = item.Id });
}
//Export the apps and return the zip file data as a Base64 encoded string.
ZipBase64 = metaFX.ExportLayers(applicationList);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
ExportAllTheThings.ExportAllKineticSystemLayers
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportAllKineticSystemLayers
* Description: This plugin downloads all system Kinetic layers.
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 09/04/2024 | klincecum | Kevin Lincecum | Initial Implementation
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
try
{
//****
CallService<Ice.Contracts.MetaFXSvcContract>(metaFX =>
{
//Create a request to list the apps
var request = new Epicor.MetaFX.Core.Models.Applications.ApplicationRequest()
{
Type = "view",
SubType = "",
SearchText = "",
IncludeAllLayers = true
};
//Get a list of apps
List<Epicor.MetaFX.Core.Models.Applications.Application> applications = metaFX.GetApplications(request);
//Create an export request list
List<Epicor.MetaFX.Core.Models.Layers.EpMetaFxLayerForApplication> applicationList = new List<Epicor.MetaFX.Core.Models.Layers.EpMetaFxLayerForApplication>();
//Loop through the list and add custom apps to the export list
foreach(var item in applications.Where(x => x.SystemFlag == true))
{
applicationList.Add(new Epicor.MetaFX.Core.Models.Layers.EpMetaFxLayerForApplication() { Id = item.Id });
}
//Export the apps and return the zip file data as a Base64 encoded string.
ZipBase64 = metaFX.ExportLayers(applicationList);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
New 23 Sep 2024
ExportAllTheThings.ExportAllUDColumns
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportAllUDColumns
* Description: This plugin downloads all user defined column definitions.
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 2024/09/09 | klincecum | Kevin Lincecum | Initial Implementation
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
//Serialize a whole Tableset to B64
Func<IceTableset, string> GetTablesetBytesAsB64 = (ts) =>
{
string tempJson = JsonConvert.SerializeObject(ts, Formatting.Indented);
byte[] tempBytes = System.Text.Encoding.UTF8.GetBytes(tempJson);
return Convert.ToBase64String(tempBytes);
};
try
{
//****
CallService<Ice.Contracts.ZDataTableSvcContract>(zdt =>
{
//Files we will be adding to the zip file
Dictionary<string, string> mainZipFileDictionary = new Dictionary<string, string>();
//Get all User Defined Columns
bool more = false;
Ice.Tablesets.ZDataTableTableset zdtTS = zdt.GetRows("TableType = 'UD' BY DataTableID", "", "", "", "", "", "", 0, 0, out more);
//Add all to zip file
mainZipFileDictionary.Add("AllUDColumns.json", GetTablesetBytesAsB64(zdtTS));
//Get Distinct List of UD Tables
var udExtensionTables = zdtTS.ZDataTable.Select(x => x.DataTableID).Distinct().ToList();
//Loop through the list.
foreach(string item in udExtensionTables)
{
try
{
//Get the table data
Ice.Tablesets.ZDataTableTableset tempZDataTableTS = zdt.GetRows($"DataTableID = '{item}' BY DataTableID", "", "", "", "", "", "", 0, 0, out more);
//Add all to zip file
mainZipFileDictionary.Add($"{item}.json", GetTablesetBytesAsB64(tempZDataTableTS));
}
catch (Exception iEx)
{
//Continue processing on error, but add errors to the errors list.
iEx.Data.Add("DataTableID", item);
ListErrorJson = AddExceptionToList(iEx, ListErrorJson);
}
}
//Zip the files
string fileDictionaryJson = JsonConvert.SerializeObject(mainZipFileDictionary);
//Return the zip file data as a Base64 encoded string.
ZipBase64 = ThisLib.ZipFiles(fileDictionaryJson);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}
ExportAllTheThings.ExportClassicFormCustomizations
/*
* ==========================================================================================
* AUTHOR: Kevin Lincecum
* COPYRIGHT: Kevin Lincecum 2024
* LICENSE: MIT
* ==========================================================================================
* Library: ExportAllTheThings
* Function: ExportClassicFormCustomizations
* Description: This plugin downloads all classic form customizations.
* ==========================================================================================
*
* INPUTS: NONE
*
* OUTPUTS:
* BOOL: Success -> Function Success / Failure
* STRING: ListErrorsJson -> Json Serialized List<Exception>
* STRING: ZipBase64 -> Base64 Encoded Byte Array
*
* CHANGELOG:
* 2024/09/09 | klincecum | Kevin Lincecum | Initial Implementation
*
* ==========================================================================================
*/
//Helper Functions Section----------------------------------------------------------------------------------------------------------------------------------------->
Func<Exception, string, string> AddExceptionToList = (exception, exceptionListJson) =>
{
List<Exception> exceptionList = new List<Exception>(){exception};
if(!String.IsNullOrEmpty(exceptionListJson)) { try { exceptionList.AddRange( JsonConvert.DeserializeObject<List<Exception>>(exceptionListJson) ); } catch {} }
return JsonConvert.SerializeObject(exceptionList);
};
//<-----------------------------------------------------------------------------------------------------------------------------------------Helper Functions Section
//Serialize a whole Tableset to B64
Func<IceTableset, string> GetTablesetBytesAsB64 = (ts) =>
{
string tempJson = JsonConvert.SerializeObject(ts, Formatting.Indented);
byte[] tempBytes = System.Text.Encoding.UTF8.GetBytes(tempJson);
return Convert.ToBase64String(tempBytes);
};
try
{
//****
CallService<Ice.Contracts.GenXDataSvcContract>(genXData =>
{
//Files we will be adding to the zip file
Dictionary<string, string> mainZipFileDictionary = new Dictionary<string, string>();
//Get a list of customizations. Using Db context, because GetList returns too much data.
var customizations = Db.XXXDef.Where(x => x.ProductID == "EP" && x.TypeCode == "Customization" && x.Company != "000000" ).Select(x => new { x.Company, Form = x.Key2, Name = x.Key1, x.Key3}).ToList();
//Loop through the list..
foreach(var item in customizations)
{
try
{
//Get the table data
string cgCCode = "";
GenXDataTableset genXDataTS = genXData.GetByID(item.Company, "EP", "Customization", cgCCode, item.Name, item.Form, item.Key3);
//Add all to zip file
mainZipFileDictionary.Add($"{item.Company}/{item.Form}.{item.Name}.json", GetTablesetBytesAsB64(genXDataTS));
}
catch (Exception iEx)
{
//Continue processing on error, but add errors to the errors list.
iEx.Data.Add("Company.FormID.Name", $"{item.Company}{item.Form}.{item.Name}");
ListErrorJson = AddExceptionToList(iEx, ListErrorJson);
}
}
//Zip the files
string fileDictionaryJson = JsonConvert.SerializeObject(mainZipFileDictionary);
//Return the zip file data as a Base64 encoded string.
ZipBase64 = ThisLib.ZipFiles(fileDictionaryJson);
});
Success = true;
//****
}
catch (Exception ex)
{
Success = false;
ListErrorJson = AddExceptionToList(ex, ListErrorJson);
}
finally
{
//Maybe later?
}