Files
ayanova7/API/plugins/CSSamplePlugin/CSSamplePlugin/Class1.cs
2018-06-29 19:47:36 +00:00

471 lines
22 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using AyaNova.PlugIn;//Required Plugin interface definition
using GZTW.AyaNova.BLL;//Required to interact with the business object library
//Required for icon and image handling even if you don't use them
using System.Windows.Forms;//Required only if you want a Windows Forms UI for your plugin
namespace CSSamplePlugin
{
/// <summary>
/// This is an example to show the minimal required code to implement a plugin
/// with a UI
///
/// Your class must implement IAyaNovaPlugin defined in AyaNova.PlugIn.dll
///
/// References that were added
/// --------------------------
/// From the AyaNova program file directory:
/// AyaNova.PlugIn.dll - Required plugin interface definition
/// GZTW.AyaNova.BLL.dll - Required AyaNova business object library fully documented here: http://api.ayanova.com/
/// CSLA - required by the business object library
/// CSLA.Core.Bindablebase- required by the business object library
/// CSLA.Server.DataPortal- required by the business object library
/// CSLA.Server.ServicedDataPortal- required by the business object library
///
/// System.Windows.Forms - Required only if your plugin requires a windows user interface
/// --------------------------
///
/// Distributing your plugin
/// =-=-=-=-=-=-=-=-=-=-=-=-
/// Note that *none* of the above referenced assemblies need to be included with your plugin when it is distributed
/// as, at runtime, your plugin will use the assemblies installed with AyaNova.
///
/// So, for example, this sample plugin will generate a file called CSSamplePlugin.dll.
/// To use it in AyaNova, copy that single file anywhere in the plugins folder or in a subdirectory beneath (recommended)
/// in the AyaNova program files folder.
///
/// AyaNova will look for any files in the plugins folder and subfolders that end in .dll and check if they implement IAyaNovaPlugin
///
/// If your plugin needs to persist data please note that the AyaNova business object library contains three objects for exactly that purpose
/// you can use the "Integration" object to store overall data, you can use the IntegrationMaps object to map data between an external programs database
/// and specific AyaNova objects and the IntegrationLog object is provided for logging purposes.
///
/// </summary>
public class Class1 : IAyaNovaPlugin
{
//Note: In Visual Studio, if you right click on IAyaNovaPlugin in the class declaration you can select Implement Interface and
//all the stubs will be created for you of the entire interface, no need to type them in or copy and paste
#region IAyaNovaPlugin Members
#region Properties / general
//OPTIONAL: Currently unused in AyaNova UI but may be in future
//so you really should return a string here
public string About
{
get { return "My plugin, copyright my company 2009 etc etc"; }
}
/// <summary>
/// REQUIRED: This must be a unique Guid value and is required.
///
/// Normally you would not change this value even upon new releases of your
/// plugin, it's simply used to uniquely identify the plugin during runtime by
/// AyaNova.
///
/// (do not use Guid.Empty and don't use the sample value provided here
/// that's just asking for trouble :) )
/// </summary>
public Guid PluginID
{
get { return new Guid("{5B1D1F74-04E3-464a-88DA-FA9E207EB2A7}"); }
}
/// <summary>
/// REQUIRED: Will be displayed in various areas but most importantly
/// it's used to display the menu item in the root level Plugin menu
/// for activating your plugin
/// </summary>
public string PluginName
{
get { return "My Plugin"; }
}
/// <summary>
/// REQUIRED: Your plugin's version as a string
/// for display only
/// </summary>
public string PluginVersion
{
get { return "1.0alpha"; }
}
/// <summary>
/// OPTIONAL: 32px icon that will be displayed beside the plugin name
/// on the root level plugin menu if the AyaNova User has chosen Large
/// icons on menus
/// </summary>
public System.Drawing.Image PluginLargeIcon
{
//since this is meant to be a simple example
//we'll return null, but generally speaking you would
//add a resource to your plugin and embed your icons inside it
//and return them here like: return Resource.MyIcon;
get { return null; }
}
/// <summary>
/// OPTIONAL: 16px icon that will be displayed beside the plugin name
/// on the root level plugin menu if the AyaNova User has chosen Small
/// icons on menus
/// </summary>
public System.Drawing.Image PluginSmallIcon
{
get { return null; }
}
/// <summary>
/// OPTIONAL: This will be set by AyaNova when the plugin is initialized
/// the resource manager contains the same icons and images used
/// in AyaNova itself and is useful for consistency if you want
/// your plugin's GUI to appear more integrated with AyaNova
/// </summary>
public System.Resources.ResourceManager AyaNovaResourceManager
{
//Since this is a simple example, we'll ignore it when set.
//However if you wish to use it
//you can set a class variable (for example "resman") of ResourceManger to the value passed in here
//and get resources like this:
//Image i=(Image)resman.GetObject("ServiceWorkorder24");
//or
//Icon i=(Icon)resman.GetObject("Client16icon");
set { ; }
}
#endregion
#region Initialize and close
//this is a convenient way to deal with supported object types
private static List<RootObjectTypes> ObjectsWeCanDealWith = null;
/// <summary>
/// OPTIONAL: you don't need to do anything here, but it's a good idea.
///
/// This is called immediately after login and is the first opportunity your plugin gets access to the business object library
/// to determine if it's prepared to work with the current AyaNova user / database / conditions
/// it finds itself in.
///
/// Note that this is called for all plugins found, be a good citizen and don't consume a lot of time here
/// as it will block AyaNova between the moment the user has clicked login and they get the opening screen.
///
/// Instead you should do "lazy" initialization; as late as possible, ideally only just in time to perform a user selected command
/// and cache your intialization when it's done.
///
/// If you are familiar with using the AyaNova business object library you can treat a plugin as
/// all the code that takes place immediately after a user has initialized the AyaNova connection and logged in successfully.
///
/// </summary>
/// <param name="AyaNovaVersion">The version of AyaNova calling</param>
/// <param name="localizedText">A localized text object if your plugin wants to
/// use the same localized text as AyaNova itself</param>
/// <returns>False if you don't want your plugin to be accessible, true if you do</returns>
public bool Initialize(Version AyaNovaVersion, GZTW.AyaNova.BLL.LocalizedTextTable localizedText)
{
//This is a good place to check if the version of AyaNova being used is one you want your plugin to work
//with:
//if (AyaNovaVersion.Major != 5)
//{
// MessageBox.Show("My Plugin requires AyaNova version 5");
// return false;
//}
//or that the current user has sufficent rights to even use your plugin
//if(AyaBizUtils.Right(RootObjectTypes.Client)< (int)SecurityLevelTypes.ReadWrite) return false;
//or that the user is the right type to use your plugin
//if(!User.IsAdmin) return false;
//or that the environment your plugin finds itself in is suitable
//or that there is a license for your plugin if it's licensed
//etc
//This is also an excellent time to build a list of AyaNova RootObjectTypes your plugin supports:
//remember: Initialize might be called more than once if a user logs in and out
if (ObjectsWeCanDealWith == null)
ObjectsWeCanDealWith = new List<RootObjectTypes>();
if (ObjectsWeCanDealWith.Count == 0)
{
//AyaNova asks if a plugin can deal with the type Nothing
//when it's about to display the Plugins menu option in the main AyaNova screen
//This is useful for plugins that have commands that are not specific to a particular
//type of object such as an About dialog or a general setup form or a utility that
//acts in general on multiple AyaNova objects
//for this example we'll have an About dialog that we want to display from the main AyaNova form
ObjectsWeCanDealWith.Add(RootObjectTypes.Nothing);
//For this example we want to deal with Client objects
ObjectsWeCanDealWith.Add(RootObjectTypes.Client);
}
return true;
}
/// <summary>
/// OPTIONAL: This is called after a user has just logged out of AyaNova.
/// Note that this is often when they are closing AyaNova, but not necessarily, they may
/// have logged out so another user can login.
///
/// This is where you can release resources that are user specific if you have any.
///
/// </summary>
public void Close()
{
;
}
#endregion
#region Whether to particpate in a particular scenario
//Note: these methods exist for the purposes of lazy initialization
//just because your plugin can deal with a particular type of object
//doesn't mean you have to necessarily do a time consuming startup for your
//plugin yet because the user may not select your plugin from the plugin list
//(99.9% of the time they are just opening a form to work in AyaNova)
/// <summary>
/// This is called by AyaNova when a single object is about to be opened in AyaNova
/// Here is where you decide if you support that type of object
/// or not.
///
/// </summary>
/// <param name="objectType">The RootObjectTypes AyaNova object type</param>
/// <returns>true - display this plugin in the plugins menu, false - don't display this plugin as an option</returns>
public bool SingleObjectMenuShow(GZTW.AyaNova.BLL.RootObjectTypes objectType)
{
//You could have a giant switch statement here but it's easier to just check a collection
return ObjectsWeCanDealWith.Contains(objectType);
}
/// <summary>
/// This is called by AyaNova when a list object is about to be opened in AyaNova
/// generally in a grid.
///
/// Here is where you decide if you support that type of object
/// or not in multiples.
///
/// </summary>
/// <param name="objectType">The RootObjectTypes AyaNova object type</param>
/// <returns>true - display this plugin in the plugins menu, false - don't display this plugin as an option</returns>
public bool MultipleObjectsMenuShow(GZTW.AyaNova.BLL.RootObjectTypes objectType)
{
//for this example we'll deal with a selected list of client objects
//from the Clients grid display
return ObjectsWeCanDealWith.Contains(objectType);
}
#endregion
#region What options to display
//These methods are called when a user selects your plugin from the plugin menu
//they are used to build the popup menu of options your plugin supports
//If possible you should still defer initialization if it's time consuming
//even at this point if possible because the user may not actually select an option
//they may have just clicked on it in error or to see what's offered
/// <summary>
/// Here is where you provide a list of commands your plugin supports for the object type
/// (and possibly even the exact object) in question.
///
/// The items you provide here will be displayed to the end user in a popup menu list immediately after
/// they have selected your plugin from the root plugins menu in a form in AyaNova where a single object
/// is being viewed / edited
/// </summary>
/// <param name="objectType">RootObjectType</param>
/// <param name="ayaNovaObject">A generic list of a type defined in AyaNova.PlugIn</param>
/// <returns></returns>
public List<AyaNovaPluginMenuItem> SingleObjectMenuOptions(GZTW.AyaNova.BLL.RootObjectTypes objectType, object ayaNovaObject)
{
//First off we can double check that this is an object type we support:
if (!ObjectsWeCanDealWith.Contains(objectType)) return null;
//Now we build the list:
//AyaNovaPluginMenuItem is a structure defined in AyaNova.PlugIn assembly
//and is the mechanism to convey your menu options to AyaNova so it
//can use them to build a popup menu
//Initialize a list of potential menu items
List<AyaNovaPluginMenuItem> list = new List<AyaNovaPluginMenuItem>();
//Add items to the list based on the object type
switch (objectType)
{
case RootObjectTypes.Nothing://Our main menu about box
list.Add(new AyaNovaPluginMenuItem("ABOUT", "About MyPlugin", null,null));
break;
case RootObjectTypes.Client://Our command when in a single client editing form
list.Add(new AyaNovaPluginMenuItem("CLIENT_DO_SOMETHING", "Do something with this client", null, null));
break;
}
return list;
}
/// <summary>
/// Same as single item, but the menu above a grid or list of AyaNova objects of the same type
/// If your plugin can't deal with a list of items then return null;
/// </summary>
/// <param name="objectType"></param>
/// <returns></returns>
public List<AyaNovaPluginMenuItem> MultipleObjectsMenuOptions(GZTW.AyaNova.BLL.RootObjectTypes objectType)
{
//First off we can double check that this is an object type we support:
if (!ObjectsWeCanDealWith.Contains(objectType)) return null;
//Initialize a list of potential menu items
List<AyaNovaPluginMenuItem> list = new List<AyaNovaPluginMenuItem>();
//Add items to the list based on the object type
switch (objectType)
{
case RootObjectTypes.Client://Our command when in a list of clients
list.Add(new AyaNovaPluginMenuItem("CLIENT_DO_SOMETHING", "Do something else with the selected Clients", null, null));
break;
}
return list;
}
#endregion
#region Execute the chosen command
//These methods are called when a user actually clicks on a command for your plugin from the popup menu
//This is the ideal place to do time consuming initialization if necessary and cache it for later
//because this is the first point you know the user actually needs to use your plugin
/// <summary>
/// A command was selected for a single object
/// </summary>
/// <param name="commandKey">command key you provided when you built the menu options list</param>
/// <param name="objectType">the type of the object</param>
/// <param name="ayaNovaObject">a pointer to the live object being edited or displayed</param>
public void CommandSelectedForSingleObject(string commandKey, GZTW.AyaNova.BLL.RootObjectTypes objectType, object ayaNovaObject)
{
//Since we have used unique commands we don't need to double check the
//object type here
switch (commandKey)
{
case "ABOUT":
AboutBox1 dlgAbout = new AboutBox1();
dlgAbout.ShowDialog();
break;
case "CLIENT_DO_SOMETHING":
//We want to do something with the client being edited
//we have the object in ayaNovaObject so we just need to cast it to
//the type of object we expect.
//let's do it defensively though; who knows what those crazy AyaNova programmers might have passed to us ;) ...
//Is it null for some reason?
if (ayaNovaObject == null)
return;//Yes so ignore the command
//Is it not the type of object we expected?
if (!(ayaNovaObject is GZTW.AyaNova.BLL.Client))
return;
//Ok, seems safe to deal with so let's get a reference to it we can work with
//directly:
GZTW.AyaNova.BLL.Client c = (GZTW.AyaNova.BLL.Client)ayaNovaObject;
//Now we can operate on it using any of the Client object method's and properties
//in the AyaNova business object API (http://api.ayanova.com/)
c.Notes = c.Notes + "\r\nHello " + c.Name + " from " + PluginName + " @ " + DateTime.Now.ToString();
//You will notice that after your plugin exits the client's "General Notes" are immediately updated
//in the AyaNova user interface, this is because your plugin is working with the live object
//that is bound to the AyaNova edit form controls so changes are immediate.
//NOTE: do not Save or Update a business object you modify here. Leave the regular AyaNova UI to deal with that
//properly.
break;
}
}
/// <summary>
/// A command was selected for a list of objects
/// </summary>
/// <param name="commandKey">Your plugins command key from the menu item</param>
/// <param name="objectType">The RootObjectTypes object type</param>
/// <param name="objectIDList">A list of Guid's of the AyaNova object type selected by the user. May be empty or null or zero selected.</param>
/// <param name="listObject">The unederlying AyaNova List object that is being displayed to the user from which they made their selections</param>
/// <returns>true if you want to trigger a refresh of the display of the list in AyaNova, false if not necessary (i.e. you didn't modify any of the objects displayed)</returns>
public bool CommandSelectedForList(string commandKey, GZTW.AyaNova.BLL.RootObjectTypes objectType, List<Guid> objectIDList, object listObject)
{
//We only have one command that could display for a list but we'll leave room for expansion later:
switch (commandKey)
{
case "CLIENT_DO_SOMETHING":
//We want to do something with all the clients that were selected from the client list
//We let's see if any are selected first
if (objectIDList == null || objectIDList.Count == 0)
{
MessageBox.Show("Nothing to do, you didn't select any clients.");
return false;
}
//Ok, we now know that 1 or more clients are selected and we have a list of their ID's
//so let's do something (non destructive) with them
System.Text.StringBuilder sb = new StringBuilder();
sb.Append("Selected clients website and email address\r\n");
foreach (Guid id in objectIDList)
{
//You don't want your plugin to crash right?
//use appropriate exception handling
try
{
Client c = Client.GetItem(id);
sb.Append(c.Name);
sb.Append(" Email: ");
sb.Append(c.Email);
sb.Append(" Website: ");
sb.Append(c.WebAddress);
sb.Append("\r\n");
}
catch (Exception ex)
{
sb.Append("Client ID: ");
sb.Append(id.ToString());
sb.Append(" Error: ");
sb.Append(ex.Message);
sb.Append("\r\n");
}
}
MessageBox.Show(sb.ToString());
break;
}
return false;
}
#endregion
#endregion
}
}