🌟 ExportAllTheThings - Export Your Custom Objects

This is a little project I started working on last year, and finally got back to.

This is a plugin based, dynamic Kinetic app that will download pretty much whatever you want as a zip file, provided there is a plugin for it…

Video:
ExportAllTheThingsAgaiin

Current Example: (at release)

Plugins at Release:

  • ExportAllCustomBAQs
  • ExportAllFunctionLibraries
  • ExportAllUDCodes
  • ExportDataDirectivesByTable
  • ExportDirectivesByGroups
  • ExportMethodDirectivesByService

Plugins added 04 Sep 2024

  • ExportAllKineticCustomLayers
  • ExportAllKineticSystemLayers

Plugins added 23 Sep 2024

  • ExportAllUDColumns
  • ExportClassicFormCustomizations

GitHub

Files

Kinetic App Template

BPMs

Function Libraries (Updated: 23 Sep 2024)

Instructions:

  • Import the files above.
  • (Don’t forget to add your company to the security in the library.)
  • Create a menu item for the Template.
  • Profit

star trek rom GIF

12 Likes
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?
  }
3 Likes

I haven’t forgotten.

2 Likes

Devopsalooza!

2 Likes

Dance Dancing GIF

1 Like

Actually, even more. No one says you have to use the app. Just use the functions, or use the technique to enhance it!

I kept it simple, a plugin (function) does one thing.

Don’t plan to do it now, but later, probably modify the templating to add checkboxes and text fields that could be passed to the plugins, for more advanced exports.

That kind of stuff needs to be stored per plugin, so need to figure out the best avenue for that.

I foolishly let this go out late Friday, on a holiday weekend.

Shamelessly bringing it up for discussion.

season 6 showtime GIF by Shameless

1 Like

Since someone said the magic word…

To me anyway, the Ops in DevOps is about deployment. Being able to export our objects is certainly helpful to compare versions between environments. What’s still missing from Epicor is a way to manage these custom objects. A recent feature that @hkeric.wci wrote about is the IceCommon Database. Currently, it appears to store objects by major version, but imagine that it also contained the Environment (Live, Test, Pilot, Dev, etc.) when an object is stored. Now comparing multiple versions of objects would be a snap. Storing the custom objects in a central area (in the ICECommon Database or a new ERPCommon Database) would also prevent the accidental deletion of work in progress (overwriting Pilot for example), and it may even help in a recovery scenario for a particular environment. History of deployment could be tracked as well knowing who deployed an item, which version, and when.

I’m not saying ExportAllTheThings isn’t a useful tool! But if we’re going to mention DevOps or Platform Engineering, the brass ring is still out there. :ring_buoy:

3 Likes

Are all you people asleep, or did I create a dud?

Approval Self Esteem GIF by DefyTV

1 Like

Day after a holiday, peeps might be catching up!

1 Like

I was just talking to my manager about how we’re going to export everything from Dev and get it into our clean install later this month - this is definitely something I will check out and present to him!

1 Like

I thought at least @aosemwengie1 would be like… “I need X, you should have thought of that…” :rofl:

I kid girl.

2 Likes

I see it! I haven’t had time to test it yet!

1 Like

Nice Kevin! How are you using it in your operations?

So far just to back up my crap from Pilot. I need to push my live data over and I still have work there. (My last data is from February lol)

Is there an import all things? did i miss that?

3 Likes

Kinetic layers?

(App studio, for those of you who have never seen Kinetic firsthand… @klincecum )

1 Like

Not currently… but…

2 Likes

Absolutely, but as these individual items come up, we may need to have a conversation on the best way to export them.

Some things are obvious, like BAQs already have their own export format etc.