programmatically mark a shipping email as sent - email

I have set up an observer to send out an email as soon as a tracking number is added to a shipment, but I need to be able to some how show in the admin that the email has been sent instead of displaying "the shipment email is not sent."
Here is the code I am currently using. There is an issue with it because it some how ends up sending out a ton of emails, as if it is some how stuck in a loop. I could really use some help in figuring out why this is happening.
class WR_TrackingEmail_Model_Observer
{
public function sendTrackEmail($observer)
{
$track = $observer->getEvent()->getTrack();
$shipment = $track->getShipment(true);
$shipment->sendEmail();
$shipment->setEmailSent(true);
$saveTransaction = Mage::getModel('core/resource_transaction')
->addObject($shipment)
->addObject($shipment->getOrder())
->save();
}
}

You are calling save() on the shipment object. The shipment class has an _afterSave() function that triggers save on the track objects. Since you are creating an observer for track_save_after, you are very likely causing a loop.

Related

Salesforce send Email by Apex

I'm making by a requirement a code able to send an E-mail to an specific list of E-mails, due the fact that I must to include the attachments of the record I decided to use an apex class instead an e-mail alert. This object (A custom object ) must populate some fields in an email template with some of the record´s fields. I implemented the following code
Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
mail.setToAddresses(lista);
mail.setTemplateId('00X21000000QR22');
//mail.setWhatId(idMinuta);
mail.setTargetObjectId('005d0000005NMIx');
mail.setSaveAsActivity(false);
List<Messaging.Emailfileattachment> fileAttachments = new List<Messaging.Emailfileattachment>();
for (ContentVersion document: documents)
{
Messaging.Emailfileattachment efa = new Messaging.Emailfileattachment();
efa.setFileName(document.Title);
efa.setBody(document.VersionData);
fileAttachments.add(efa);
}
mail.setFileAttachments(fileAttachments);
Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
I understood that to make the fields merge it´s necesary to use the WhatId method. In the related code, I have commented it because It generates an error (INVALID_ID_FIELD, WhatId is not available for sending emails to UserIds.)
My question is, if is it possible to do this with a custom object. I´m a little confuse with salesforce documentation beacuse it looks like the method supports a custom object, or maybe If I am forggeting something to include in the code.
If i keep the WhatID line commented, effectively the email is sent with the attachments and the Template but it is not populated.
I really need this kind of solution because the org have in this object at least 20 email templates, for me will be easier just to pass the Id of the template instead of makig a code with 20 different html codes for each situation
Thanks a lot
Please publish this question at Salesforce StackExcahnge https://salesforce.stackexchange.com/

CRM Plugin that Fires on Send Email

I'm trying to create plugin that fires when an email is sent.
At first I tried using SetState and SetStateDynamicEntity to when the status is changed to completed. However the plugin never gets fired when an email is sent.
So I tried using the "Send" message using OnExecute method. Is it possible to retrieve the sent email entity info? I'm stumped in trying to return the Entity. The code below keeps returning "The given key was not present in the dictionary" error message.
I tried using either "Entity" or "EntityReference" but no luck.
I know that the Send message returns the EmailId. Is the only way to return the Entity from this EmailId?
public override void OnExecute(IServiceProvider serviceProvider, IPluginExecutionContext context)
{
var trace = (ITracingService)serviceProvider.GetService(typeof(ITracingService));
if (!context.InputParameters.Contains("EmailId"))
{
return;
}
var emailId = (Guid)context.InputParameters["EmailId"];
Entity emailEntity = (Entity)context.InputParameters["Target"];
So the way you mentioned is the only correct way to get email records. Totaling up:
Retrieve identifier of email from context.
Retrieve email record using crm endpoint.
Following article contains description that is relevant to CRM 4.0 - http://www.patrickverbeeten.com/Blog/2008/01/25/CRM-40-Plug-in-message-input-parameters haven't seen something similar that was done for CRM 2011/2013/2015/2016.

How to send email notification after creating lead in sugarcrm through webservice(nusoap)

I have successfully created a lead in sugarcrm 6.5 using nusoap. But now problem is, How to send email notification to assigned user?
Please help me!!
Based on your situation, what I would do is use a after_save logic hook to send your email. Logic Hooks allow you to plug into the SugarCRM logic. The code below allows you to do something after a Lead is saved.
Create a logic_hooks.php or add the following if it already exists in custom/modules/Leads/logic_hooks.php
<?php
$hook_version = 1;
$hook_array = Array();
$hook_array['after_save'] = Array();
$hook_array['after_save'][] = Array(1, 'Send Notification', 'custom/modules/Leads/Leads_custom.php','Leads_custom', 'send_notification');
After any Lead is saved, it'll run the following code in custom/modules/Leads/Leads_custom.php
<?php
class Leads_custom
{
function send_notification($bean, $event, $arguments)
{
// write your code here to send the notification to the head(Manager)
}
}
This will fire anytime Leads are created or edited. If you need to only send notifications on new Leads, you can use this technique: http://developers.sugarcrm.com/wordpress/2013/08/21/doing-beforeafter-field-comparisons-in-after_save-logic-hooks/
If you have the process manager available in your Sugar Version (entrprise+) then you just have to create a process definition that triggers an email when a new lead is created. If not then it's a logic hook.

Changing the From field for an email activity in a plug-in

When an email is sent to a queue and there is a contact associated with the "From" email in CRM, upon promoting an email to an email activity the system automatically fills in the "From" field with the contact information. However, if a user with the same email exists in CRM, too, then the system always picks up the system user instead of the contact. I need to override this behaviour to ALWAYS pick up the contact if one with the email exists.
I created a post-operation plug-in (tried a pre-operation plug-in, too) for the event Create for email, trying to override the From field. The problem is, it does not work. When I debug the plug-in, it goes quietly past the assignment without any errors and then the same plug-in fires for the same email again. And again. And again.
When I try instead to create a new email and use the same ActivityList[] I was trying to use for the entity that triggered the event, it works. It seems that the problem is that CRM does not allow changing the From field from a plug-in, or am I doing something wrong? If it's a limitation enforced by CRM, is there a way around it?
My code is below:
var email = ((Entity)context.InputParameters["Target"]).ToEntity<Email>();
...
var oldFrom = ((EntityCollection)email.Attributes["from"]).Entities;
List<ActivityParty> newFrom = new List<ActivityParty>();
foreach (Entity party in oldFrom)
{
EntityReference entRef = (EntityReference)party.Attributes["partyid"];
if (entRef.LogicalName == SystemUser.EntityLogicalName)
user = userLogic.Get(new Guid(entRef.Id.ToString()));
if (user == null) return;
string emailAddress = user.InternalEMailAddress;
Contact contact = contactLogic.LookupPASIndividual("", emailAddress);
if (contact != null)
{ newFrom.Add(new ActivityParty() {PartyId = new EntityReference(Contact.EntityLogicalName, contact.ContactId.Value) });
}
else
return;
}
email.From = newFrom;
Update: So I registered the plug-in on Pre-validation now and it's not triggered when an email activity is created by a router, it IS triggered when a user creates an email in CRM though...
The problem is that you aren't changing the email which is processed at all.
var email = ((Entity)context.InputParameters["Target"]).ToEntity<Email>();
This line converts the record which is currently processed to an object of type email. You modify the record which is not in scope of the operation. You have to modify the From of the target (either directly or write it back).
For the processing stages: take a look at the Event Execution Pipeline. Pre-Validation is to early for your task. I'am not quite sure when the address resolution is done, but I would try to do your conversion Pre-Create.
I ended up using a workaround: created an async Post-Event that associates the email activity with the contact if a contact with the same email exists, leaving the user associated with the email in the "From" field.

Send a empty Message or Notification with MVVM toolkit light

I'm using the MVVM Light Toolkit. I could not find any Ctor of Messenger or Notification class to send a empty message.
ViewModel1:
private int _selectedWeeklyRotation;
public int SelectedWeeklyRotation
{
get { return _selectedWeeklyRotation; }
set
{
if(_selectedWeeklyRotation == value)
return;
_selectedWeeklyRotation = value;
this.OnPropertyChanged("SelectedWeeklyRotation");
if(value > 1)
Messenger.Default.Send();
}
}
ViewModel2:
Ctor:
Messenger.Default.Register(this, CreateAnotherTimeTable);
private void CreateAnotherTimeTable()
{
}
I just need to send a Notification to another ViewModel, no sending of data at all.
Is that possible with MVVM Light Toolkit library?
Unless I'm misunderstanding something, couldn't you accomplish this by creating and sending a custom "signal message" type via the Messenger?
public class WeeklyRotationSignal {}
Messenger.Default.Send(new WeeklyRotationSignal());
Then register to that in another view model:
Messenger.Default.Register<WeeklyRotationSignal>(this, msg => doWork);
You can try sending a simple message with a string tag and receive that message by matching the string tag. Something like this:
Sender portion of the code located possibly in something like ViewModel1.cs
Messenger.Default.Send<string>("Dummy text message", "String_ToHelpMatchTheMsg");
Receiving end portion of the code responding to that message above, possibly located in some other file, something like ViewModel2.cs
...
Messenger.Default.Register<string>(this, "String_ToHelpMatchTheMsg", executeThisFunction);
private void executeThisFunction(string strMsg)
{
//your code would go here to run upon receiving the message
// The following line will display: "Dummy text message"
System.Windows.Browser.HtmlPage.Window.Alert("msg passed: " + strMsg);
}
Please note that you dont have to do anything with the text message that is passed around with the messaging code above. Just one part of the code sending some ping to another part of the code to ask some other section to execute some code. The important string is the one where I used "String_ToHelpMatchTheMsg" because that is the key used to match the sender and the receiver. Almost like creating your own quasi-event, once the Send method runs, the Register method is notified and fire its own function to run also.
I used this with a Close button on a Child Window to close it. The Close button on the View of the Child Window binds to a relay command on its childWindowViewModel. That relay command has the code above to send a message to the ParentViewModel. The Register portion on the ParentViewModel responds to that message by firing a method that closes the ChildWindow which was initially instantied from that parentViewModel.
Once you get more familiar with messaging, there are more attributes that you will be able to use so that the receiver can call back the sender to give a status or some data back. Look for Delegates and lambda function to achieve this.
All this to avoid placing code in the code behind to close the child window! :-)
Use as you see fit.
Cheers.
Mario
There really isn't a way to accomplish this and in someways defies the point of the messenger class. I didn't want to write a your doing it wrong post, but I feel I am stuck. The way the messenger class works is that you have two parties that both subscribe to the same concept, its an observer model. Without that similar concept or message there really isn't a way to tie the two objects together. The generic message whether a simple string or custom message act as the meeting point of the Subscribing and Publishing classes.
If the ViewModel publishing knows the type of ViewModel its trying to Send to it could...
Messenger.Default.Send<Type>(typeof(ViewModelToSendTo);
This would act as a very simple interaction point, you also wouldn't have to create a custom class. Some purist may have an issue with this approach as it couples the publishing class to the subscriber.
I don't think that it is possible and frankly I don't see the point of having that kind of message. You could just as well send a string "SelectedWeeklyRotation". It seems strange to have an empty message that has some kind of meaning as you increase the number of broadcast messages - and receivers in your application.
In the version of MVVM Light that I'm using it is not even possible to send an empty message.
However I did see a method in the ViewModelBase that is :
// Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
RaisePropertyChanged(MyPropertyPropertyName, oldValue, value, true);
This might be of interest for you.