How to set GL codes on a Sales Invoice in Microsoft Dynamics GP? - dynamics-crm

I'm using Microsoft Dynamics GP 2015. We have a C# .Net project to create a sales invoice through web services. Accounting has the following request: "We would like to code the revenue for {an item} to GL code xx-xx-xxxx." Looking at the code for creating a sales invoice, I don't see anywhere to set a GL code. I suggested GL codes might be set on an item in GP, but was told to "see if the distribution or account codes can be set at creation time." Is there anyway to set the GL code on a sales invoice? If so, what's the code for setting a GL code?
Here's the code I'm modifiying:
private string createGPSalesInvoice(ItemReceived itemsReceived, DateTime salesOrderDate)
{
CompanyKey companyKey;
companyKey = new CompanyKey();
Context context;
SalesInvoice salesInvoice;
SalesDocumentTypeKey salesInvoiceType;
CustomerKey customerKey;
customerKey = new CustomerKey();
BatchKey batchKey;
SalesInvoiceLine salesInvoiceLine;
ItemKey invoiceItem;
Quantity invoiceCount;
Policy salesInvoiceCreatePolicy;
salesInvoiceCreatePolicy = new Policy();
string salesInvoiceNumber = "";
try
{
// Create an instance of the service
DynamicsGPClient wsDynamicsGP = new DynamicsGPClient();
// Create a context with which to call the service
context = new Context();
// Specify which company to use (sample company)
companyKey.Id = xxx;
// Set up the context object
context.OrganizationKey = (OrganizationKey)companyKey;
// Create a sales invoice object
salesInvoice = new SalesInvoice();
// Create a sales document type key for the sales invoice
salesInvoiceType = new SalesDocumentTypeKey();
salesInvoiceType.Type = SalesDocumentType.Invoice;
// Populate the document type key for the sales invoice
salesInvoice.DocumentTypeKey = salesInvoiceType;
// Create a customer key
customerKey.Id = xxx;
// Set the customer key property of the sales invoice
salesInvoice.CustomerKey = customerKey;
salesInvoice.PostedDate = parms.endDate;
// Create a batch key
batchKey = new BatchKey();
batchKey.Id = xxx;
// Set the batch key property of the sales invoice object
salesInvoice.BatchKey = batchKey;
// Create a sales invoice line to specify the invoiced item
salesInvoiceLine = new SalesInvoiceLine();
// Create an item key
invoiceItem = new ItemKey();
invoiceItem.Id = itemsReceived.GPPartNumber;
// Set the item key property of the sales invoice line object
salesInvoiceLine.ItemKey = invoiceItem;
// Create a sales invoice quatity object
invoiceCount = new Quantity();
invoiceCount.Value = itemsReceived.Quantity;
// Set the quantity of the sales invoice line object
salesInvoiceLine.Quantity = invoiceCount;
MoneyAmount unitCost = new MoneyAmount()
{
Value = itemsReceived.CostEach
};
salesInvoiceLine.UnitPrice = unitCost;
// Create an array of sales invoice lines
// Initialize the array with the sales invoice line object
SalesInvoiceLine[] invoiceLines = { salesInvoiceLine };
// Add the sales invoice line array to the sales line object
salesInvoice.Lines = invoiceLines;
try
{
// Get the create policy for the sales invoice object
salesInvoiceCreatePolicy = wsDynamicsGP.GetPolicyByOperation("CreateSalesInvoice", context);
}
catch (Exception ex)
{
throw ex;
}
try
{
// Create the sales invoice
wsDynamicsGP.CreateSalesInvoice(salesInvoice, context, salesInvoiceCreatePolicy);
}
catch (Exception ex)
{
throw ex;
}
//CREATE A RESTRICION OF THE BATCH ID TO FIND THE SALES DOC JUST CREATED
LikeRestrictionOfstring batchKeyRestriction = new LikeRestrictionOfstring();
batchKeyRestriction.EqualValue = batchKey.Id;
//CREATE SEARCH CRITERIA
SalesDocumentCriteria salesDocumentCriteria = new SalesDocumentCriteria();
salesDocumentCriteria.BatchId = batchKeyRestriction;
try
{
SalesDocumentSummary[] salesDocumentSummary = wsDynamicsGP.GetSalesDocumentList(salesDocumentCriteria, context);
salesInvoiceNumber = salesDocumentSummary.FirstOrDefault().Key.Id;
}
catch (Exception ex)
{
throw ex;
}
// Close the service
if (wsDynamicsGP.State != CommunicationState.Faulted)
{
wsDynamicsGP.Close();
}
return salesInvoiceNumber;
}
catch (Exception ex)
{
throw ex;
}
}

Related

Not receiving Change Notification of Calendar Events containing custom properties

We want to receive change notifications from our user's Outlook calendars. We'd like to limit those notifications to only those calendar items that contain our custom property.
CODE WHICH CREATES CALENDAR EVENT
private static async Task<Event> CreateAppointmentAsync(GraphServiceClient graphClient)
{
var newEvent = new Microsoft.Graph.Event
{
Subject = "Test Calendar Appointmnt",
Start = new DateTimeTimeZone() { TimeZone = TimeZoneInfo.Local.Id, DateTime = "2020-11-21T21:00:00" },
End = new DateTimeTimeZone() { TimeZone = TimeZoneInfo.Local.Id, DateTime = "2020-11-21T22:00:00" },
Location = new Location() { DisplayName = "Somewhere" },
Body = new ItemBody { Content = "Some Random Text" },
};
Microsoft.Graph.Event addedEvent;
try
{
newEvent.SingleValueExtendedProperties = new EventSingleValueExtendedPropertiesCollectionPage();
newEvent.SingleValueExtendedProperties.Add(new SingleValueLegacyExtendedProperty { Id = "String {00020329-0000-0000-C000-000000000046} Name CompanyID", Value = "12345" });
addedEvent = await graphClient.Me.Calendar.Events.Request().AddAsync(newEvent);
}
catch (Exception e)
{
throw e;
}
return addedEvent;
}
THE SUBSCRIPTION CODE SNIPPET
var subscription = new Subscription
{
ChangeType = "created",
NotificationUrl ="<OUR-URL>",
Resource = "me/events/?$filter=singleValueExtendedProperties/any(ep: ep/id eq 'String {00020329-0000-0000-C000-000000000046} Name CompanyID' and ep/value ne null)",
ExpirationDateTime = DateTimeOffset.Parse("2020-11-13T18:23:45.9356913Z"),
ClientState = "custom_data_state",
LatestSupportedTlsVersion = "v1_2"
};
The subscription is created successfully, but notifications are not being sent for those items containing the specific custom property described above.
It turns out I was only capturing the "created" notification. I neglected to add "updated" and "deleted".
I was testing with an event that already existed in my calendar. No events were being fired because I didn't create the subscription to detect updates and deletes.
Here is the corrected subscription:
var subscription = new Subscription
{
ChangeType = "created,updated,deleted",
NotificationUrl ="<OUR-URL>",
Resource = "me/events/?$filter=singleValueExtendedProperties/any(ep: ep/id eq 'String {00020329-0000-0000-C000-000000000046} Name CompanyID' and ep/value ne null)",
ExpirationDateTime = DateTimeOffset.Parse("2020-11-13T18:23:45.9356913Z"),
ClientState = "custom_data_state",
LatestSupportedTlsVersion = "v1_2"
};

CRM SDK 2013 Activity doesn't exist just after creating it

I have a custom comment activity which I'm updating in code and this used to work but has started failing recently. It creates the activity but when I try to retrieve it or execute SetStateResponse on it, I get "tk_comment With Id = 9a1686d1-7d9d-e611-80e3-00155d001104 Does Not Exist" - which doesn't make sense as I've just created it! The activity record shows up against the account but I can't click on it there or do anything (Record is unavailable - The requested record was not found or you do not have sufficient permissions to view it.).
This is the code I'm using. I'd love you to tell me I've made some simple mistake :)
using (_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig))
{
_serviceProxy.EnableProxyTypes();
try
{
tk_comment comment = new tk_comment();
int maxLength = 190; //subject has a max length of 200 characters
if (subject.Length > maxLength)
{
comment.Subject = subject.Substring(0, maxLength);
comment.Description = subject.Substring(maxLength, subject.Length - maxLength);
}
else
{
comment.Subject = subject;
}
comment.RegardingObjectId = entity.ToEntityReference();
comment.ActualStart = CommentDate;
comment.ActualEnd = CommentDate;
comment.ScheduledStart = CommentDate;
comment.ScheduledEnd = CommentDate;
Guid commentID = _serviceProxy.Create(comment);
try
{
tk_comment aComment = (tk_comment)_serviceProxy.Retrieve(tk_comment.EntityLogicalName, commentID, new ColumnSet(allColumns: true));
}
catch (Exception ex)
{
SingletonLogger.Instance.Error("Always an error here " + ex.Message);
}
Account test = (Account) _serviceProxy.Retrieve(Account.EntityLogicalName, entity.Id, new ColumnSet(allColumns: true));
// tk_comment newComment = (tk_comment)_serviceProxy.Retrieve(tk_comment.EntityLogicalName, commentID, new ColumnSet(allColumns: true));
SetStateRequest request = new SetStateRequest();
request.EntityMoniker = new EntityReference(tk_comment.EntityLogicalName, commentID);
request.State = new OptionSetValue((int) tk_commentState.Completed); //completed
request.Status = new OptionSetValue(2); //completed
SetStateResponse response = (SetStateResponse)_serviceProxy.Execute(request); //always an error here too
}
Appreciate any suggestions
Cheers, Mick
It seems like you don't have proper read permission of this custom activity entity.
OR You need to validate all the permissions of this custom entity.

Entity Framework cycle of data

I have an Account object, which has many Transactions related to it.
In one method, I get all transactions for a particular account.
var transactionlines = (from p in Context.account_transaction
.Include("account_transaction_line")
// .Include("Account")
.Include("account.z_account_type")
.Include("account.institution")
.Include("third_party")
.Include("third_party.z_third_party_type")
.Include("z_account_transaction_type")
.Include("account_transaction_line.transaction_sub_category")
.Include("account_transaction_line.transaction_sub_category.transaction_category")
.Include("z_account_transaction_entry_type")
.Include("account_transaction_line.cost_centre")
where p.account_id == accountId
&& p.deleted == null
select p).ToList();
This is meant to return me a list of transactions, with their related objects. I then pass each object to a Translator, which translates them into data transfer objects, which are then passed back to my main application.
public TransactionDto TranslateTransaction(account_transaction source)
{
LogUserActivity("in TranslateTransaction");
var result = new TransactionDto
{
Id = source.id,
Version = source.version,
AccountId = source.account_id,
// Account = TranslateAccount(source.account, false),
ThirdPartyId = source.third_party_id,
ThirdParty = TranslateThirdParty(source.third_party),
Amount = source.transaction_amount,
EntryTypeId = source.account_transaction_entry_type_id,
EntryType = new ReferenceItemDto
{
Id = source.account_transaction_entry_type_id,
Description = source.z_account_transaction_entry_type.description,
Deleted = source.z_account_transaction_entry_type.deleted != null
},
Notes = source.notes,
TransactionDate = source.transaction_date,
TransactionTypeId = source.account_transaction_type_id,
TransactionType = new ReferenceItemDto
{
Id = source.z_account_transaction_type.id,
Description = source.z_account_transaction_type.description,
Deleted = source.z_account_transaction_type.deleted != null
}
};
... return my object
}
The problem is:
An account has Transactions, and a Transaction therefore belongs to an Account. It seems my translators are being called way too much, and reloading a lot of data because of this.
When I load my transaction object, it's 'account' property has a'transactions' propery, which has a list of all the transactions associated to that account. Each transaction then has an account property... and those account peroprties again, have a list of all the transactions... and on and on it goes.
Is there a way I can limit the loading to one level or something?
I have this set:
Context.Configuration.LazyLoadingEnabled = false;
I was hoping my 'Includes' would be all that is loaded... Don't load 'un-included' related data?
As requested, here is my TranslateAccount method:
public AccountDto TranslateAccount(account p, bool includeCardsInterestRateDataAndBalance)
{
LogUserActivity("in TranslateAccount");
if (p == null)
return null;
var result =
new AccountDto
{
Id = p.id,
Description = p.description,
PortfolioId = p.institution.account_portfolio_id,
AccountNumber = p.account_number,
Institution = TranslateInstitution(p.institution),
AccountType = new ReferenceItemDto
{
Id = p.account_type_id,
Description = p.z_account_type.description
},
AccountTypeId = p.account_type_id,
InstitutionId = p.institution_id,
MinimumBalance = p.min_balance,
OpeningBalance = p.opening_balance,
OpeningDate = p.opening_date
};
if (includeCardsInterestRateDataAndBalance)
{
// Add the assigned cards collection
foreach (var card in p.account_card)
{
result.Cards.Add(new AccountCardDto
{
Id = card.id,
AccountId = card.account_id,
Active = card.active,
CardHolderName = card.card_holder_name,
CardNumber = card.card_number,
ExpiryDate = card.expiry
});
}
// Populate the current interest rate
result.CurrentRate = GetCurrentInterestRate(result.Id);
// Add all rates to the account
foreach (var rate in p.account_rate)
{
result.Rates.Add(
new AccountRateDto
{
Id = rate.id,
Description = rate.description,
Deleted = rate.deleted != null,
AccountId = rate.account_id,
EndDate = rate.end_date,
Rate = rate.rate,
StartDate = rate.start_date
});
}
result.CurrentBalance = CurrentBalance(result.Id);
}
LogUserActivity("out TranslateAccount");
return result;
}
The entity framework context maintains a cache of data that has been pulled out of the database. Regardless of lazy loading being enabled/disabled, you can call Transaction.Account.Transactions[0].Account.Transactions[0]... as much as you want without loading anything else from the database.
The problem is not in the cyclical nature of entity framework objects - it is somewhere in the logic of your translation objects.

Custom Plugin Does Not Execute -- Need Assistance With Some Basic Understanding

I am new to CRM and I have created a new AutoNumber plugin (actually modified an existing plugin).
I am having issues getting this plugin to work on the CRM side.
I have created the plugin, and I have created a CREATE step. I am confused with the IMAGE creation, and how I need to go about doing this.
Also, I am using the localContext.Trace and I am not sure where to view this information.
Can anyone help me with understanding the exact steps I need to follow to implement this plugin. I will include my code here in case I am doing something wrong. Again, this was a working plugin and I just modified it. I tried to follow the pattern used by the previous developer.
FYI -- I have purchased the CRM Solution Manager utility to help with the deployment process, but still not having any luck.
Thanks in advance for your time.
Here is the code..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IccPlugin.ProxyClasses;
using IccPlugin.ProxyClasses.ProxyClasses;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Query;
namespace IccPlugin {
public class ProgramReportAutoNumber : PluginBase {
private readonly string imageAlias = "ProgramReport";
private new_programreport preImage { get; set; }
private new_programreport postImage { get; set; }
private new_programreport targetEntity { get; set; }
private readonly string imageAlias_program = "Program";
private new_program preImage_program { get; set; }
private new_program postImage_program { get; set; }
private new_program targetEntity_program { get; set; }
public ProgramReportAutoNumber(string unsecure, string secure)
: base(typeof(ProgramReportAutoNumber), unsecure, secure) {
base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PreOperation, "Create", "new_programreport", new Action<LocalPluginContext>(Execute)));
//base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PostOperation, "Update", "new_programreport", new Action<LocalPluginContext>(Execute)));
//base.RegisteredEvents.Add(new Tuple<int, string, string, Action<LocalPluginContext>>((int)CrmPluginStepStage.PostOperation, "Delete", "new_programreport", new Action<LocalPluginContext>(Execute)));
}
protected void Execute(LocalPluginContext localContext) {
if (localContext == null) {
throw new ArgumentNullException("localContext");
}
IPluginExecutionContext context = localContext.PluginExecutionContext;
if (context.PreEntityImages.Contains(imageAlias) && (context.PreEntityImages[imageAlias] is Entity)) {
preImage = new new_programreport((Entity)context.PreEntityImages[imageAlias]);
}
if (context.PostEntityImages.Contains(imageAlias) && (context.PostEntityImages[imageAlias] is Entity)) {
postImage = new new_programreport((Entity)context.PostEntityImages[imageAlias]);
}
if (context.PreEntityImages.Contains(imageAlias_program) && (context.PreEntityImages[imageAlias_program] is Entity)) {
preImage_program = new new_program((Entity)context.PreEntityImages[imageAlias_program]);
}
if (context.PostEntityImages.Contains(imageAlias_program) && (context.PostEntityImages[imageAlias_program] is Entity)) {
postImage_program = new new_program((Entity)context.PostEntityImages[imageAlias_program]);
}
if (context.InputParameters.Contains("Target") && (context.InputParameters["Target"] is Entity)) {
targetEntity = new new_programreport((Entity)context.InputParameters["Target"]);
}
switch (context.MessageName) {
case "Create":
HandleCreate(localContext);
break;
case "Update":
HandleUpdate(localContext);
break;
case "Delete":
HandleDelete(localContext);
break;
default:
throw new ArgumentException("Invalid Message Name: " + context.MessageName);
}
}
private void HandleDelete(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleDelete");
try {
if (preImage == null) {
throw new Exception("IccPlugin.ProgramReport.AutoNumber.HandleDelete: preImage is null, unable to process the delete message.");
}
// TODO: Add code here to implement delete message.
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleDelete: Exception while processing the delete message, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleDelete");
}
return;
}
private void HandleUpdate(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleUpdate");
if (preImage == null) {
string msg = "IccPlugin.ProgramReport.AutoNumber.HandleUpdate : The Update step is not registered correctly. Unable to retrieve the pre-operation image using alias" + imageAlias;
localContext.Trace(msg);
throw new Exception(msg);
}
if (postImage == null) {
string msg = "IccPlugin.ProgramReport.AutoNumber.HandleUpdate : The Update step is not registered correctly. Unable to retrieve the post-operation image using alias" + imageAlias;
localContext.Trace(msg);
throw new Exception(msg);
}
if (preImage_program == null) {
string msg = "IccPlugin.Program.AutoNumber.HandleUpdate : The Update step is not registered correctly. Unable to retrieve the pre-operation image using alias" + imageAlias_program;
localContext.Trace(msg);
throw new Exception(msg);
}
if (postImage_program == null) {
string msg = "IccPlugin.Program.AutoNumber.HandleUpdate : The Update step is not registered correctly. Unable to retrieve the post-operation image using alias" + imageAlias_program;
localContext.Trace(msg);
throw new Exception(msg);
}
try {
// TODO: Add code here to implement update message.
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleUpdate: Exception while processing the update message, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleUpdate");
}
return;
}
private void HandleCreate(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.HandleCreate");
if (targetEntity == null) {
string msg = "IccPlugin.ProgramReport.AutoNumber.HandleCreate : The Create step is not registered correctly. Unable to retrieve the target entity using alias Target.";
localContext.Trace(msg);
throw new Exception(msg);
}
try {
// if the target entity does not have the new_filenumber attribute set we will set it now.
if (targetEntity.new_filenumber != null && targetEntity.new_filenumber != "") {
// log a warning message and do not change this value.
localContext.Trace("The Program Report being created already has a value for File Number, skipping the auto number assignment for this field.");
} else {
SetFileNumber(localContext);
}
if (targetEntity.new_name != null && targetEntity.new_name != "") {
localContext.Trace("The Program Report being created already has a value for Report Number, skipping the auto number assignment for this field.");
} else {
SetReportNumber(localContext);
}
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.HandleCreate: Exception while processing the create message, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.HandleCreate");
}
return;
}
private void SetFileNumber(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.SetFileNumber");
string s_new_filenumberformat = string.Empty;
string s_new_reportnumberprefix = string.Empty;
string s_new_filenumbercode = string.Empty;
try {
IOrganizationService service = localContext.OrganizationService;
string fileNumberValue = "";
emds_autonumbersequence fileNumberSequence = null;
// ##################################################################################################
// 05/02/2013 -- BEP -- Code added for the following change to the auto-number for file numbering
// ##################################################################################################
// 1 - Year/Month/Sequence
// [Year]-[Month]-[Sequence] = [Year] is the current year / [Month] is the current month / [Sequence] is a number series for each Year & Month and resets to 1 when the Month changes
// 2 - Year/PMG/Sequence - PMG
// [Year]-[PMGProductType][Sequence] = [Year] is the current year / [PMGProductType] is 1st letter from the PMG Product Type on the Program Report / [Sequence] is a single number series for this Format
// 3 - Year/Letter/Sequence - ESL,VAR
// [Year]-[FileCode][Sequence] = [Year] is the current year / [FileCode] is from a new field on the Program entity / [Sequence] is a number series for each Format & File Code
// ##################################################################################################
localContext.Trace("Look at the File Number Format to determine which format to use for the Auto-Number, will default to 1 if not set");
if (targetEntity_program.new_filenumberformat.ToString() != "") {
localContext.Trace("A value was set for the new_filenumberformat field, so we will be using this value.");
s_new_filenumberformat = targetEntity_program.new_filenumberformat.ToString();
} else {
localContext.Trace("A value was NOT set for the new_filenumberformat field, so we will be using 1 as the default.");
s_new_filenumberformat = "1";
}
localContext.Trace("File Number Format Being Used = " + s_new_filenumberformat);
switch (s_new_filenumberformat) {
case "1":
#region File Format #1
fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), DateTime.Now.ToString("MM"));
localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");
QueryExpression qeFileNumberSequence_1 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
qeFileNumberSequence_1.ColumnSet = new ColumnSet(true);
qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
qeFileNumberSequence_1.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, fileNumberValue);
localContext.Trace("Getting FileNumber sequence record.");
List<emds_autonumbersequence> lFileNumberSequences_1 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_1);
if (lFileNumberSequences_1 == null || lFileNumberSequences_1.Count == 0) {
localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");
// no matching sequence records. Lets start a new sequence index record for this month and year.
fileNumberSequence = new emds_autonumbersequence();
fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
fileNumberSequence.emds_index = 1;
fileNumberSequence.emds_prefix = fileNumberValue;
fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
fileNumberSequence.Create(service);
} else {
localContext.Trace("A FileNumber sequence record was found, using it.");
// a file number sequence record was returned. Even if there happen to be multiple we are going to just use the first one returned.
fileNumberSequence = lFileNumberSequences_1[0];
}
// ###############################################################################
// 05/02/2013 -- BEP -- Changed the format from "###" to be "##" for seq number
// ###############################################################################
fileNumberValue = String.Format("{0}-{1:00}", fileNumberValue, fileNumberSequence.emds_index);
fileNumberSequence.emds_index++;
fileNumberSequence.Update(service);
#endregion
break;
case "2":
#region File Format #2
if (targetEntity_program.new_reportnumberprefix != null && targetEntity_program.new_reportnumberprefix != "") {
localContext.Trace("A value was set for the new_reportnumberprefix field, so we will be using this value.");
s_new_reportnumberprefix = targetEntity_program.new_reportnumberprefix;
} else {
localContext.Trace("A value was NOT set for the new_reportnumberprefix field, so we will be using P as the default.");
s_new_reportnumberprefix = "P";
}
fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), s_new_reportnumberprefix);
localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");
QueryExpression qeFileNumberSequence_2 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
qeFileNumberSequence_2.ColumnSet = new ColumnSet(true);
qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
qeFileNumberSequence_2.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, "PMG");
localContext.Trace("Getting FileNumber sequence record.");
List<emds_autonumbersequence> lFileNumberSequences_2 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_2);
if (lFileNumberSequences_2 == null || lFileNumberSequences_2.Count == 0) {
localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");
// no matching sequence records. Lets start a new sequence index record for this month and year.
fileNumberSequence = new emds_autonumbersequence();
fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
fileNumberSequence.emds_index = 1;
fileNumberSequence.emds_prefix = "PMG";
fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
fileNumberSequence.Create(service);
} else {
localContext.Trace("A FileNumber sequence record was found, using it.");
// a file number sequence record was returned. Even if there happen to be multiple we are going to just use the first one returned.
fileNumberSequence = lFileNumberSequences_2[0];
}
fileNumberValue = String.Format("{0}-{1:0000}", fileNumberValue, fileNumberValue + fileNumberSequence.emds_index.ToString());
fileNumberSequence.emds_index++;
fileNumberSequence.Update(service);
#endregion
break;
case "3":
#region File Format #3
if (targetEntity_program.new_filenumbercode != null && targetEntity_program.new_filenumbercode != "") {
localContext.Trace("A value was set for the new_filenumbercode field, so we will be using this value.");
s_new_filenumbercode = targetEntity_program.new_filenumbercode;
} else {
localContext.Trace("A value was NOT set for the new_filenumbercode field, so we will be using L as the default.");
s_new_filenumbercode = "l";
}
fileNumberValue = String.Format("{0}-{1}", DateTime.Now.ToString("yy"), s_new_filenumbercode);
localContext.Trace("Building QueryExpression to retrieve FileNumber Sequence record.");
QueryExpression qeFileNumberSequence_3 = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
qeFileNumberSequence_3.ColumnSet = new ColumnSet(true);
qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_filenumber);
qeFileNumberSequence_3.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, fileNumberValue);
localContext.Trace("Getting FileNumber sequence record.");
List<emds_autonumbersequence> lFileNumberSequences_3 = service.RetrieveProxies<emds_autonumbersequence>(qeFileNumberSequence_3);
if (lFileNumberSequences_3 == null || lFileNumberSequences_3.Count == 0) {
localContext.Trace("No FileNumber sequence record was returned, creatign a new one.");
// no matching sequence records. Lets start a new sequence index record for this month and year.
fileNumberSequence = new emds_autonumbersequence();
fileNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_filenumber;
fileNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
fileNumberSequence.emds_index = 1;
fileNumberSequence.emds_prefix = fileNumberValue;
fileNumberSequence.emds_name = String.Format("File Number Sequence For: {0}", fileNumberValue);
fileNumberSequence.Create(service);
} else {
localContext.Trace("A FileNumber sequence record was found, using it.");
// a file number sequence record was returned. Even if there happen to be multiple we are going to just use the first one returned.
fileNumberSequence = lFileNumberSequences_3[0];
}
fileNumberValue = String.Format("{0}-{1:0000}", fileNumberValue, fileNumberValue + fileNumberSequence.emds_index.ToString());
fileNumberSequence.emds_index++;
fileNumberSequence.Update(service);
#endregion
break;
default:
break;
}
targetEntity.new_filenumber = fileNumberValue;
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.SetFileNumber: Exception while setting the File Number value, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.SetFileNumber");
}
}
private void SetReportNumber(LocalPluginContext localContext) {
localContext.Trace("START - IccPlugin.ProgramReport.AutoNumber.SetReportNumber");
string s_new_reportnumberprefix = string.Empty;
try {
IOrganizationService service = localContext.OrganizationService;
string reportNumberValue = "";
emds_autonumbersequence reportNumberSequence = null;
// ##################################################################################################
// 05/02/2013 -- BEP -- Code added for the following change to the auto-number for file numbering
// ##################################################################################################
// Currently the plugin uses the GP Class Id as the prefix for the Report Number.
// It now needs to use the Report Number Prefix field.
// ##################################################################################################
if (targetEntity_program.new_reportnumberprefix != null && targetEntity_program.new_reportnumberprefix != "") {
localContext.Trace("A value was set for the new_reportnumberprefix field, so we will be using this value.");
s_new_reportnumberprefix = targetEntity_program.new_reportnumberprefix;
} else {
localContext.Trace("A value was NOT set for the new_reportnumberprefix field, so we will be using P as the default.");
s_new_reportnumberprefix = "P";
}
localContext.Trace("Building QueryExpression to retrieve parent new_program record.");
// #################################################################################
// 05/02/2013 -- BEP -- The above code replaces the need to pull the GP Class ID
// #################################################################################
//new_program program = targetEntity.new_programid.RetrieveProxy<new_program>(service, new ColumnSet(true));
// going to assume that we were able to get the parent program record. If not an exception will be thrown.
// could add a check here and throw our own detailed exception if needed.
reportNumberValue = String.Format("{0}", s_new_reportnumberprefix); // using Trim just to be safe.
// now lets get the sequence record for this Report Number Prefix
QueryExpression qeReportNumberSequence = new QueryExpression(BaseProxyClass.GetLogicalName<emds_autonumbersequence>());
qeReportNumberSequence.ColumnSet = new ColumnSet(true);
qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_entitylogicalname, ConditionOperator.Equal, BaseProxyClass.GetLogicalName<new_programreport>());
qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_attributelogicalname, ConditionOperator.Equal, new_programreport.Properties.new_name);
qeReportNumberSequence.Criteria.AddCondition(emds_autonumbersequence.Properties.emds_prefix, ConditionOperator.Equal, reportNumberValue);
localContext.Trace("Getting Report Number sequence record.");
List<emds_autonumbersequence> lReportNumberSequences = service.RetrieveProxies<emds_autonumbersequence>(qeReportNumberSequence);
if (lReportNumberSequences == null || lReportNumberSequences.Count == 0) {
localContext.Trace("No Report Number sequence record was returned, creatign a new one.");
// no matching sequence records. Lets start a new sequence index record for this month and year.
reportNumberSequence = new emds_autonumbersequence();
reportNumberSequence.emds_attributelogicalname = new_programreport.Properties.new_name;
reportNumberSequence.emds_entitylogicalname = BaseProxyClass.GetLogicalName<new_programreport>();
reportNumberSequence.emds_index = 1;
reportNumberSequence.emds_prefix = reportNumberValue;
reportNumberSequence.emds_name = String.Format("Report Number Sequence For Report Number Prefix: {0}", reportNumberValue);
reportNumberSequence.Create(service);
} else {
localContext.Trace("A Report Number sequence record was found, using it.");
// a file number sequence record was returned. Even if there happen to be multiple we are going to just use the first one returned.
reportNumberSequence = lReportNumberSequences[0];
}
reportNumberValue = String.Format("{0}-{1}", reportNumberValue, reportNumberSequence.emds_index);
reportNumberSequence.emds_index++;
reportNumberSequence.Update(service);
targetEntity.new_name = reportNumberValue;
} catch (Exception ex) {
localContext.Trace(String.Format("IccPlugin.ProgramReport.AutoNumber.SetReportNumber: Exception while setting the File Number value, Error Message: {0}", ex.Message), ex);
throw ex;
} finally {
localContext.Trace("END - IccPlugin.ProgramReport.AutoNumber.SetReportNumber");
}
}
}
}
This is specifically to response to:
I am using the localContext.Trace and I am not sure where to view this
information
From the MSDN; Debug a Plug-In - Logging and Tracing
During execution and only when that plug-in passes an exception back
to the platform at run-time, tracing information is displayed to the
user. For a synchronous registered plug-in, the tracing information is
displayed in a dialog box of the Microsoft Dynamics CRM web
application. For an asynchronous registered plug-in, the tracing
information is shown in the Details area of the System Job form in the
web application.

How to the Outlook Appointment series master from a single occurence

I need to get the master appointment of the meeting series, when an appointment instance is opened.
I have tried the following (currentAppointment variable is of type AppointmentItem)
DateTime sd = currentAppointment.GetRecurrencePattern().PatternStartDate;
DateTime st = currentAppointment.GetRecurrencePattern().StartTime;
AppointmentItem ai = currentAppointment.GetRecurrencePattern().GetOccurrence(sd+st.TimeOfDay);
However, while this gets me the first appointment in the series, it has a RecurrenceState of olApptOccurrence.
How can I get a reference to the olApptMaster - ie the meeting series?
AppointmentItem.Parent will return the parent AppointmentItem for the recurrence instances and exceptions.
I have a method to create an appointment item with recurrence, but it´s almost the same as modifying one, tell me if that helps you and if you need further information.
Here is the code in C#
private void CreateNewRecurringAppointment(Outlook._Application OutlookApp)
{
Outlook.AppointmentItem appItem = null;
Outlook.RecurrencePattern pattern = null;
try
{
appItem = OutlookApp.CreateItem(Outlook.OlItemType.olAppointmentItem)
as Outlook.AppointmentItem;
// create a recurrence
pattern = appItem.GetRecurrencePattern();
pattern.RecurrenceType = Outlook.OlRecurrenceType.olRecursWeekly;
pattern.StartTime = DateTime.Parse("9:00:00 AM");
pattern.EndTime = DateTime.Parse("10:00:00 AM");
// we can specify the duration instead of using the EndTime property
// pattern.Duration = 60;
pattern.PatternStartDate = DateTime.Parse("11/11/2011");
pattern.PatternEndDate = DateTime.Parse("12/25/2011");
appItem.Subject = "Meeting with the Boss";
appItem.Save();
appItem.Display(true);
}
catch (Exception ex)
{
System.Windows.Forms.MessageBox.Show(ex.Message);
}
finally
{
if (pattern != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(pattern);
if (appItem != null)
System.Runtime.InteropServices.Marshal.ReleaseComObject(appItem);
}
}
source: http://www.add-in-express.com/creating-addins-blog/2011/11/07/outlook-recurring-appointment/

Resources