I am developing a plugin which consumes Address insert/update event. I need to perform custom actions when customer add address OR update existing address from My Account -> Addresses. I developed plugin and it is working fine for address update event, but it is not working for address inserted event.
Here is my plugin code.
namespace Nop.Plugin.Misc.MyPlugin
{
public class AddressInsertEventConsumer :
IConsumer<EntityUpdated<Address>>,
IConsumer<EntityInserted<Address>>
{
private readonly AddressLogsSettings _addressLogsSettings;
private readonly IPluginFinder _pluginFinder;
private readonly IOrderService _orderService;
private readonly IStoreContext _storeContext;
private readonly IWorkContext _workContext;
public AddressInsertEventConsumer(AddressLogsSettings addressLogsSettings,
IPluginFinder pluginFinder,
IOrderService orderService,
IStoreContext storeContext,
IWorkContext workContext
)
{
this._addressLogsSettings = addressLogsSettings;
this._pluginFinder = pluginFinder;
this._orderService = orderService;
this._storeContext = storeContext;
this._workContext = workContext;
}
#region :: Updated ::
public void HandleEvent(EntityUpdated<Address> eventMessage)
{
//Code which I need when Address is Updated
}
#endregion
#region :: Inserted ::
public void HandleEvent(EntityInserted<Address> eventMessage)
{
//Code which I need when Address is Inserted
}
#endregion
}
}
I tried to debug code from customer controller to plugin code I find that it is not actually adding event for address inserted.
See code of
Customer Controller -> Add new Address
[HttpPost]
[PublicAntiForgery]
[ValidateInput(false)]
public ActionResult AddressAdd(CustomerAddressEditModel model, FormCollection form)
{
if (!_workContext.CurrentCustomer.IsRegistered())
return new HttpUnauthorizedResult();
var customer = _workContext.CurrentCustomer;
//custom address attributes
var customAttributes = form.ParseCustomAddressAttributes(_addressAttributeParser, _addressAttributeService);
var customAttributeWarnings = _addressAttributeParser.GetAttributeWarnings(customAttributes);
foreach (var error in customAttributeWarnings)
{
ModelState.AddModelError("", error);
}
if (ModelState.IsValid)
{
var address = model.Address.ToEntity();
address.CustomAttributes = customAttributes;
address.CreatedOnUtc = DateTime.UtcNow;
//some validation
if (address.CountryId == 0)
address.CountryId = null;
if (address.StateProvinceId == 0)
address.StateProvinceId = null;
customer.Addresses.Add(address);
_customerService.UpdateCustomer(customer);
return RedirectToRoute("CustomerAddresses");
}
Here I can see that it is adding new address to customer.Addresses list and calling _customerService.UpdateCustomer service. If we go to UpdateCustomer service it is adding event for customer updated but not for address update.
While customer address update code is actually calling service _addressService.UpdateAddress(address);
Customer Controller -> Edit Address
[HttpPost]
[PublicAntiForgery]
[ValidateInput(false)]
public ActionResult AddressEdit(CustomerAddressEditModel model, int addressId, FormCollection form)
{
if (!_workContext.CurrentCustomer.IsRegistered())
return new HttpUnauthorizedResult();
var customer = _workContext.CurrentCustomer;
//find address (ensure that it belongs to the current customer)
var address = customer.Addresses.FirstOrDefault(a => a.Id == addressId);
if (address == null)
//address is not found
return RedirectToRoute("CustomerAddresses");
//custom address attributes
var customAttributes = form.ParseCustomAddressAttributes(_addressAttributeParser, _addressAttributeService);
var customAttributeWarnings = _addressAttributeParser.GetAttributeWarnings(customAttributes);
foreach (var error in customAttributeWarnings)
{
ModelState.AddModelError("", error);
}
if (ModelState.IsValid)
{
address = model.Address.ToEntity(address);
address.CustomAttributes = customAttributes;
_addressService.UpdateAddress(address);
return RedirectToRoute("CustomerAddresses");
}
//If we got this far, something failed, redisplay form
model.Address.PrepareModel(
address: address,
excludeProperties: true,
addressSettings: _addressSettings,
localizationService: _localizationService,
stateProvinceService: _stateProvinceService,
addressAttributeService: _addressAttributeService,
addressAttributeParser: _addressAttributeParser,
loadCountries: () => _countryService.GetAllCountries(_workContext.WorkingLanguage.Id),
overrideAttributesXml: customAttributes);
return View(model);
}
So here it is not actually calling _addressService.Insert method from customer address address add method.
Address Service -> Add new Address
/// <summary>
/// Inserts an address
/// </summary>
/// <param name="address">Address</param>
public virtual void InsertAddress(Address address)
{
if (address == null)
throw new ArgumentNullException("address");
address.CreatedOnUtc = DateTime.UtcNow;
//some validation
if (address.CountryId == 0)
address.CountryId = null;
if (address.StateProvinceId == 0)
address.StateProvinceId = null;
_addressRepository.Insert(address);
//cache
_cacheManager.RemoveByPattern(ADDRESSES_PATTERN_KEY);
//event notification
_eventPublisher.EntityInserted(address);
}
So _eventPublisher.EntityInserted(address); is not called when customer adds address the same scenario is happening in admin panel address add function as well. So Ultimately no address add event is fired and my plugin is not able to catch this event.
Can anybody please provide me solution?
How can I actually get EntityInserted Event for Address entity?
Thanks,
Ajay