This commit is contained in:
472
source/Plugins/AyaNova.Plugin.Dump/Dump.cs
Normal file
472
source/Plugins/AyaNova.Plugin.Dump/Dump.cs
Normal file
@@ -0,0 +1,472 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Windows.Forms;
|
||||
using System.Reflection;
|
||||
using AyaNova.PlugIn;
|
||||
using GZTW.AyaNova.BLL;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using ICSharpCode.SharpZipLib.Zip;
|
||||
|
||||
namespace AyaNova.Plugin.Dump
|
||||
{
|
||||
class Dump : IAyaNovaPlugin
|
||||
{
|
||||
|
||||
#region Plugin interface
|
||||
System.Resources.ResourceManager resman = null;
|
||||
private static List<RootObjectTypes> ObjectsWeCanDealWith = null;
|
||||
|
||||
|
||||
public string PluginName
|
||||
{
|
||||
get { return "DBDump export database"; }
|
||||
}
|
||||
|
||||
public string PluginVersion
|
||||
{
|
||||
get { return "7.5"; }
|
||||
}
|
||||
|
||||
public string About
|
||||
{
|
||||
get
|
||||
{
|
||||
return "AyaNova DBDump plugin\r\n" +
|
||||
"Built " + AyaNova.PlugIn.Dump.Timestamp.BuildAt.ToString() + "\r\n" +
|
||||
"Copyright 2018 Ground Zero Tech-Works Inc.";
|
||||
}
|
||||
}
|
||||
|
||||
public Guid PluginID
|
||||
{
|
||||
get { return new Guid("{73D7B77F-C96A-4198-9449-6529AFB6AA5B}"); }
|
||||
}
|
||||
|
||||
public System.Drawing.Image PluginSmallIcon
|
||||
{
|
||||
get { return Resource1.Dump16; }
|
||||
}
|
||||
|
||||
public System.Drawing.Image PluginLargeIcon
|
||||
{
|
||||
get { return Resource1.Dump32; }
|
||||
}
|
||||
|
||||
public System.Resources.ResourceManager AyaNovaResourceManager
|
||||
{
|
||||
set { resman = value; }
|
||||
get { return resman; }
|
||||
}
|
||||
|
||||
public bool Initialize(Version AyaNovaVersion, LocalizedTextTable localizedText)
|
||||
{
|
||||
if (AyaNovaVersion.Major < 7)
|
||||
{
|
||||
MessageBox.Show("This DBDump plugin requires AyaNova version 7.5 or newer");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (AyaNovaVersion.Minor < 5)
|
||||
{
|
||||
MessageBox.Show("This DBDump plugin requires AyaNova version 7.5 or newer");
|
||||
return false;
|
||||
}
|
||||
|
||||
ObjectsWeCanDealWith = new List<RootObjectTypes>();
|
||||
ObjectsWeCanDealWith.Add(RootObjectTypes.Nothing);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Close()
|
||||
{
|
||||
;
|
||||
}
|
||||
|
||||
public bool SingleObjectMenuShow(RootObjectTypes objectType)
|
||||
{
|
||||
return (ObjectsWeCanDealWith.Contains(objectType));
|
||||
}
|
||||
|
||||
public bool MultipleObjectsMenuShow(RootObjectTypes objectType)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<AyaNovaPluginMenuItem> SingleObjectMenuOptions(RootObjectTypes objectType, object ayaNovaObject)
|
||||
{
|
||||
if (!ObjectsWeCanDealWith.Contains(objectType)) return null;
|
||||
List<AyaNovaPluginMenuItem> list = new List<AyaNovaPluginMenuItem>();
|
||||
list.Add(new AyaNovaPluginMenuItem("DBDump", "Dump database to export file", null, null));
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<AyaNovaPluginMenuItem> MultipleObjectsMenuOptions(RootObjectTypes objectType)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool CommandSelectedForList(string commandKey, RootObjectTypes objectType, List<Guid> objectIDList, object listObject)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public void CommandSelectedForSingleObject(string commandKey, RootObjectTypes objectType, object ayaNovaObject)
|
||||
{
|
||||
|
||||
if (!User.CurrentUserIsAnAdministrator)
|
||||
{
|
||||
MessageBox.Show("This action can only be done by the AyaNova Administrator account");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!AyaBizUtils.AyaNovaConnectionSetting.SingleUserConnection)
|
||||
{
|
||||
MessageBox.Show("** WARNING: before proceeding ensure no other users are logged into AyaNova to ensure the integrity of your exported data. Failing to do so could result in damaged data. ***");
|
||||
MessageBox.Show("** WARNING: before proceeding make sure your AyaNova Generator service is STOPPED to ensure the integrity of your exported data. Failing to do so could result in damaged data. ***");
|
||||
}
|
||||
|
||||
//Only one command
|
||||
DumpIt();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Dump the objects into a temporary directory as a series of JSON files
|
||||
/// then zip it all up into a single archive file and then erase the temporary folder
|
||||
/// </summary>
|
||||
private void DumpIt()
|
||||
{
|
||||
|
||||
string dumpname = "ayanova.data.dump." + DateTime.Now.ToString("yyyy-MM-d--HH-mm-ss");
|
||||
string dumpfolder = string.Empty;
|
||||
#if(DEBUG)
|
||||
dumpfolder = @"c:\temp";
|
||||
#else
|
||||
MessageBox.Show("Select a location to dump AyaNova data");
|
||||
using (var folderDialog = new FolderBrowserDialog())
|
||||
{
|
||||
if (folderDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
dumpfolder = folderDialog.SelectedPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//create a temporary folder to generate JSON in
|
||||
string tempArchiveFolder = dumpfolder + Path.DirectorySeparatorChar + dumpname;
|
||||
string zipName = dumpfolder + Path.DirectorySeparatorChar + dumpname + ".zip";
|
||||
makeFolderIfNotExist(tempArchiveFolder, true);
|
||||
|
||||
//Show progress form
|
||||
|
||||
ProgressForm progress = new ProgressForm();
|
||||
progress.Show();
|
||||
progress.Append("Dumping data to " + tempArchiveFolder);
|
||||
|
||||
//DUMP IT!
|
||||
dumpGlobalSettings(tempArchiveFolder, progress);
|
||||
dumpLocales(tempArchiveFolder, progress);
|
||||
dumpRegions(tempArchiveFolder, progress);
|
||||
dumpSeedNumbers(tempArchiveFolder, progress);
|
||||
dumpClients(tempArchiveFolder, progress);
|
||||
dumpHeadOffices(tempArchiveFolder, progress);
|
||||
|
||||
|
||||
|
||||
progress.Append("Zipping up archive");
|
||||
FastZip fastZip = new FastZip();
|
||||
fastZip.CreateZip(zipName, tempArchiveFolder, true, null);
|
||||
|
||||
progress.Append("Cleaning up temporary folder");
|
||||
Directory.Delete(tempArchiveFolder, true);
|
||||
|
||||
progress.Append("Dump completed");
|
||||
//-----------------------------------
|
||||
//endof method
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#region Object dump methods
|
||||
|
||||
#region Global settings
|
||||
private void dumpGlobalSettings(string tempArchiveFolder, ProgressForm progress)
|
||||
{
|
||||
List<string> objectExcludeProperties = new List<string>(standardExcludePropertiesList);
|
||||
progress.Append("Dumping Global Settings");
|
||||
DumpObjectToFolder(tempArchiveFolder, AyaBizUtils.GlobalSettings, "globalsettings", objectExcludeProperties);
|
||||
}
|
||||
#endregion globalsettings
|
||||
|
||||
#region locales
|
||||
private void dumpLocales(string tempArchiveFolder, ProgressForm progress)
|
||||
{
|
||||
List<string> objectExcludeProperties = new List<string>(standardExcludePropertiesList);
|
||||
|
||||
//Skip stock locales already handled in Raven
|
||||
List<string> SkipLocales = new List<string>();
|
||||
SkipLocales.Add("Deutsch");
|
||||
SkipLocales.Add("English");
|
||||
SkipLocales.Add("Español");
|
||||
SkipLocales.Add("Français");
|
||||
|
||||
LocaleList l = LocaleList.GetList();
|
||||
progress.Append("Dumping " + l.Count.ToString() + " Locales");
|
||||
foreach (LocaleList.LocaleListInfo i in l)
|
||||
{
|
||||
if (!SkipLocales.Contains(i.Locale))
|
||||
{
|
||||
LocalizedTextTable lt = LocalizedTextTable.Load(i.Locale);
|
||||
DumpObjectToFolder(tempArchiveFolder, lt.LT, "locale." + EnsureValidFileName(i.Locale), objectExcludeProperties, "GZTW.AyaNova.BLL.Locale");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion locales
|
||||
|
||||
#region REGIONS
|
||||
private void dumpRegions(string tempArchiveFolder, ProgressForm progress)
|
||||
{
|
||||
List<string> objectExcludeProperties = new List<string>(standardExcludePropertiesList);
|
||||
objectExcludeProperties.Add("ContractName");
|
||||
objectExcludeProperties.Add("uiHasTechNotes");
|
||||
RegionList l = RegionList.GetList(string.Empty);
|
||||
progress.Append("Dumping " + l.Count.ToString() + " Regions");
|
||||
foreach (RegionList.RegionListInfo i in l)
|
||||
{
|
||||
|
||||
Region o = Region.GetItem(i.LT_Region_Label_Name.Value);
|
||||
DumpObjectToFolder(tempArchiveFolder, o, "region." + o.ID.ToString(), objectExcludeProperties);
|
||||
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Seeds
|
||||
private class GZSeeds
|
||||
{
|
||||
public int InventoryAdjustmentStartSeed = 1;
|
||||
public int PurchaseOrderStartSeed = 1;
|
||||
public int QuoteNumberStartSeed = 1;
|
||||
public int WorkorderNumberStartSeed = 1;
|
||||
public int PreventiveMaintenanceNumberStartSeed = 1;
|
||||
}
|
||||
private void dumpSeedNumbers(string tempArchiveFolder, ProgressForm progress)
|
||||
{
|
||||
List<string> objectExcludeProperties = new List<string>(standardExcludePropertiesList);
|
||||
progress.Append("Dumping seeds");
|
||||
//create a new object with the id numbers in it and then dump it
|
||||
WorkorderPMList pml = WorkorderPMList.GetList("<?xml version=\"1.0\" encoding=\"utf-16\" standalone=\"yes\"?> \r\n" +
|
||||
"<GRIDCRITERIA> \r\n" +
|
||||
" <COLUMNITEM CM=\"aWorkorderPreventiveMaintenance.aPreventiveMaintenanceNumber\" UI=\"LT_O_WorkorderPreventiveMaintenance\" PIN=\"0\" WIDTH=\"150\" SORT=\"DESC\" /> \r\n" +
|
||||
"</GRIDCRITERIA> ");
|
||||
|
||||
int PMStartSeed = 0;
|
||||
if (pml.Count > 0)
|
||||
{
|
||||
PMStartSeed = int.Parse(pml[0].LT_O_WorkorderPreventiveMaintenance.Display);
|
||||
}
|
||||
|
||||
var seeds = new GZSeeds();
|
||||
seeds.InventoryAdjustmentStartSeed = AyaBizUtils.GlobalSettings.InventoryAdjustmentStartSeed+1;
|
||||
seeds.PurchaseOrderStartSeed = AyaBizUtils.GlobalSettings.PurchaseOrderStartSeed+1;
|
||||
seeds.QuoteNumberStartSeed = AyaBizUtils.GlobalSettings.QuoteNumberStartSeed+1;
|
||||
seeds.WorkorderNumberStartSeed = AyaBizUtils.GlobalSettings.WorkorderNumberStartSeed+1;
|
||||
seeds.PreventiveMaintenanceNumberStartSeed = PMStartSeed+1;
|
||||
|
||||
DumpObjectToFolder(tempArchiveFolder, seeds, "seeds", objectExcludeProperties, "GZTW.AyaNova.BLL.Seed");
|
||||
}
|
||||
#endregion globalsettings
|
||||
|
||||
#region clients
|
||||
private void dumpClients(string tempArchiveFolder, ProgressForm progress)
|
||||
{
|
||||
List<string> objectExcludeProperties = new List<string>(standardExcludePropertiesList);
|
||||
objectExcludeProperties.Add("ContractName");
|
||||
objectExcludeProperties.Add("uiHasTechNotes");
|
||||
ClientPickList pl = ClientPickList.GetList();
|
||||
progress.Append("Dumping " + pl.Count.ToString() + " Clients");
|
||||
foreach (ClientPickList.ClientPickListInfo i in pl)
|
||||
{
|
||||
Client c = Client.GetItem(i.ID);
|
||||
DumpObjectToFolder(tempArchiveFolder, c, "client." + c.ID.ToString(), objectExcludeProperties);
|
||||
|
||||
}
|
||||
}
|
||||
#endregion clients
|
||||
|
||||
#region headoffices
|
||||
private void dumpHeadOffices(string tempArchiveFolder, ProgressForm progress)
|
||||
{
|
||||
List<string> excludes = new List<string>(standardExcludePropertiesList);
|
||||
//excludes.Add("ContractInEffect");
|
||||
//excludes.Add("uiHasTechNotes");
|
||||
PickListAutoComplete pl = PickListAutoComplete.GetList("**", "headoffice");
|
||||
|
||||
progress.Append("Dumping " + pl.Count.ToString() + " Head offices");
|
||||
foreach (PickListAutoComplete.PickListAutoCompleteInfo i in pl)
|
||||
{
|
||||
HeadOffice c = HeadOffice.GetItem(i.ID);
|
||||
DumpObjectToFolder(tempArchiveFolder, c, "headoffice." + c.ID.ToString(), excludes);
|
||||
}
|
||||
}
|
||||
#endregion clients
|
||||
|
||||
|
||||
|
||||
#endregion object dump methods
|
||||
|
||||
|
||||
#region Dump
|
||||
|
||||
/// <summary>
|
||||
/// Write out the object properties as JSON
|
||||
/// </summary>
|
||||
/// <param name="tempArchiveFolder"></param>
|
||||
/// <param name="o"></param>
|
||||
private void DumpObjectToFolder(string tempArchiveFolder, object o, string objectFileName, List<string> excludeProperties, string forceTypeString = "")
|
||||
{
|
||||
|
||||
var typestring = o.GetType().ToString();
|
||||
if (!string.IsNullOrWhiteSpace(forceTypeString))
|
||||
{
|
||||
typestring = forceTypeString;
|
||||
}
|
||||
|
||||
var dumpFolder = tempArchiveFolder + Path.DirectorySeparatorChar + typestring;
|
||||
makeFolderIfNotExist(dumpFolder);
|
||||
|
||||
var outputFileName = dumpFolder + Path.DirectorySeparatorChar + objectFileName + ".json";
|
||||
|
||||
JsonSerializer serializer = new JsonSerializer();
|
||||
serializer.NullValueHandling = NullValueHandling.Include;
|
||||
serializer.ContractResolver = new ExcludeNamedPropertiesContractResolver(excludeProperties);
|
||||
serializer.ReferenceLoopHandling = ReferenceLoopHandling.Serialize;
|
||||
|
||||
|
||||
#if(DEBUG)
|
||||
serializer.Formatting = Formatting.Indented;
|
||||
#endif
|
||||
// serializer.Converters.Add(new JavaScriptDateTimeConverter());
|
||||
// serializer.NullValueHandling = NullValueHandling.Ignore;
|
||||
|
||||
//generate file name, should be ID of object plus .json
|
||||
|
||||
|
||||
using (StreamWriter sw = new StreamWriter(outputFileName))
|
||||
using (JsonWriter writer = new JsonTextWriter(sw))
|
||||
{
|
||||
serializer.Serialize(writer, o);
|
||||
// {"ExpiryDate":new Date(1230375600000),"Price":0}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion dump
|
||||
|
||||
#region Utility methods
|
||||
|
||||
private static string EnsureValidFileName(string fileName)
|
||||
{
|
||||
//make lower and replace spaces with dashes
|
||||
fileName = fileName.ToLowerInvariant().Replace(" ", "-");
|
||||
|
||||
//ensure each character is a valid path character
|
||||
foreach (char c in System.IO.Path.GetInvalidFileNameChars())
|
||||
{
|
||||
fileName = fileName.Replace(c, '_');
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
|
||||
|
||||
private static void makeFolderIfNotExist(string fldr, bool shouldNotExist = false)
|
||||
{
|
||||
if (Directory.Exists(fldr))
|
||||
{
|
||||
if (shouldNotExist)
|
||||
throw new System.Exception("Error: path already exists and shouldn't:\r\n" + fldr);
|
||||
return;
|
||||
}
|
||||
Directory.CreateDirectory(fldr);
|
||||
}
|
||||
|
||||
private List<string> standardExcludePropertiesList
|
||||
{
|
||||
get
|
||||
{
|
||||
return new List<string>()
|
||||
{
|
||||
"CanWiki",
|
||||
"CanDuplicate",
|
||||
"IsValid",
|
||||
"IsDirty",
|
||||
"CurrentUserID",
|
||||
"IsEditing",
|
||||
"IsNew",
|
||||
"IsDeleted",
|
||||
"IsSavable",
|
||||
"Notify",
|
||||
"BrokenRulesText",
|
||||
"Docs",
|
||||
"MapQuestURL",
|
||||
"FullAddress"
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX",
|
||||
//"XXX"
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region contract resolver
|
||||
public class ExcludeNamedPropertiesContractResolver : DefaultContractResolver
|
||||
{
|
||||
private readonly List<string> _excludeProperties;
|
||||
|
||||
public ExcludeNamedPropertiesContractResolver(List<string> excludeProperties)
|
||||
{
|
||||
_excludeProperties = excludeProperties;
|
||||
}
|
||||
|
||||
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
|
||||
{
|
||||
IList<JsonProperty> properties = base.CreateProperties(type, memberSerialization);
|
||||
|
||||
// only serializer properties that start with the specified character
|
||||
//properties = properties.Where(p => p.PropertyName.StartsWith(_startingWithChar.ToString())).ToList();
|
||||
properties = properties.Where(p => !_excludeProperties.Contains(p.PropertyName)).ToList();
|
||||
|
||||
return properties;
|
||||
}
|
||||
}
|
||||
#endregion contract resolver
|
||||
|
||||
|
||||
//eoc
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
//eons
|
||||
}
|
||||
Reference in New Issue
Block a user