Files
ayanova7/source/Plugins/AyaNova.Plugin.Dump/Dump.cs
2018-08-29 17:40:11 +00:00

477 lines
17 KiB
C#

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.StartedImport();
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");
progress.FinishedImport();
//-----------------------------------
//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
}