Taylohtio/GeneralApi/GeneralApi.WcfService/TaloyhtioIntegration.svc.cs

258 lines
13 KiB
C#

using System;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.ServiceModel.Activation;
using System.Web.Security;
using GeneralApi.Core.Repositories;
using GeneralApi.Core.Services;
using Microsoft.Practices.ServiceLocation;
using NHibernate.Validator.Engine;
using Taloyhtio.GeneralApi.Common;
using Taloyhtio.GeneralApi.Common.Extensions;
using Taloyhtio.GeneralApi.Core.Common;
using Taloyhtio.GeneralApi.Core.Entities;
using Taloyhtio.GeneralApi.Core.Services;
using WcfRestContrib.ServiceModel.Description;
using TaloyhtioIntegration_resx = Taloyhtio.GeneralApi.Resources.Resources.TaloyhtioIntegration;
using WebException = WcfRestContrib.ServiceModel.Web.Exceptions.WebException;
namespace Taloyhtio.GeneralApi.WcfService
{
// NOTE: You can use the "Rename" command on the "Refactor" menu to change the class name "TaloyhtioIntegration" in code, svc and config file together.
// NOTE: In order to launch WCF Test Client for testing this service, please select TaloyhtioIntegration.svc or TaloyhtioIntegration.svc.cs at the Solution Explorer and start debugging.
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class TaloyhtioIntegration : ITaloyhtioIntegration
{
public void SaveCondoInformation(Taloyhtio.GeneralApi.Common.DTO.Condo c)
{
var securityContext = this.ensureAuthorized();
if (c == null)
{
throw new ArgumentNullException("condo");
}
// current assumption is that business id is login name
//string businessIdPMC = HttpContext.Current.User.Identity.Name;
string businessIdPMC = securityContext.PrimaryIdentity.Name;
var condoRepository = ServiceLocator.Current.GetInstance<ICondoRepository>();
var existingCondo = condoRepository.GetByBusinessId(c.BusinessId);
if (existingCondo != null)
{
// pmc may update only their own condos
if (existingCondo.BusinessIdPMC != businessIdPMC)
{
throw new WebException(HttpStatusCode.Unauthorized, string.Format(TaloyhtioIntegration_resx.SecurityIncorrectBusinessIdPMC,
businessIdPMC, existingCondo.BusinessId));
}
// we can't update properties of existing Condo before validation, because
// if validation will fail, UnitOfWork will anyway Commit changes even despite of the fact
// that condoRepository.Save(condo) was not called. See http://stackoverflow.com/questions/1380581/nhibernate-commit-db-changes-without-explict-call-to-save-or-update
// for details. It happens because existingCondo is attached to session and there is no need to call
// ISession.SaveOrUpdate()
// existingCondo.OfficialName = c.OfficialName;
// existingCondo.Address = c.Address;
// existingCondo.Postcode = c.Postcode;
// existingCondo.Town = c.Town;
// existingCondo.BuildingsType = c.BuildingsType;
// existingCondo.BuildingsNumber = c.BuildingsNumber;
// existingCondo.StaircasesNumber = c.StaircasesNumber;
// existingCondo.BuildingYear = c.BuildingYear;
// existingCondo.LastUpdated = DateTime.Now;
}
// var condo =
// new Condo
// {
// BusinessId = c.BusinessId,
// BusinessIdPMC = businessIdPMC,
// OfficialName = c.OfficialName,
// Address = c.Address,
// Postcode = c.Postcode,
// Town = c.Town,
// BuildingsType = c.BuildingsType,
// BuildingsNumber = c.BuildingsNumber,
// StaircasesNumber = c.StaircasesNumber,
// BuildingYear = c.BuildingYear,
// LastUpdated = DateTime.Now
// };
var mapper = ServiceLocator.Current.GetInstance<IMapper<Taloyhtio.GeneralApi.Common.DTO.Condo, Condo>>();
var condo = mapper.Map(c);
// the following properties are not comming from client. They are ignored in AutoMapper
// profile configuration (see DtoProfile) and should be set manually
condo.BusinessIdPMC = businessIdPMC;
condo.LastUpdated = DateTime.Now;
var validator = ServiceLocator.Current.GetInstance<ValidatorEngine>();
var errors = validator.Validate(condo);
if (!errors.IsNullOrEmpty())
{
// var fault = new CustomFaultException
// {Reason = string.Join("\n", errors.Select(e => e.ToString()).ToArray())};
// throw new FaultException<CustomFaultException>(fault);
throw new Exception(string.Join("\n", errors.Select(e => e.ToString()).ToArray()));
}
//bool statusChanged = false;
if (existingCondo != null)
{
existingCondo.OfficialName = condo.OfficialName;
existingCondo.Address = condo.Address;
existingCondo.Postcode = condo.Postcode;
existingCondo.Town = condo.Town;
existingCondo.BuildingsType = condo.BuildingsType;
existingCondo.BuildingsNumber = condo.BuildingsNumber;
existingCondo.StaircasesNumber = condo.StaircasesNumber;
existingCondo.BuildingYear = condo.BuildingYear;
existingCondo.LastUpdated = condo.LastUpdated;
//statusChanged = (existingCondo.Deactivated != condo.Deactivated);
existingCondo.Deactivated = condo.Deactivated;
// for existing Condo it is not necessary to call ISession.SaveOrUpdate() because it is
// already attached to the session. See http://stackoverflow.com/questions/1380581/nhibernate-commit-db-changes-without-explict-call-to-save-or-update
condo = existingCondo;
}
condoRepository.Save(condo);
// if (statusChanged)
// {
// this.sendEmailStatusChanged(condo,
// Core.Common.Constants.TemplateParams.CONDO,
// Core.Common.Constants.SettingsKeys.KEY_EMAIL_CONDO_STATUS_CHANGED_SUBJECT,
// Core.Common.Constants.SettingsKeys.KEY_EMAIL_CONDO_STATUS_CHANGED_BODY_TEMPLATE);
// }
}
public void SaveBoardMemberInformation(Taloyhtio.GeneralApi.Common.DTO.BoardMember b)
{
var securityContext = this.ensureAuthorized();
if (b == null)
{
throw new ArgumentNullException("boardMember");
}
// current assumption is that business id is login name
//string businessIdPMC = HttpContext.Current.User.Identity.Name;
string businessIdPMC = securityContext.PrimaryIdentity.Name;
var boardMembersRepository = ServiceLocator.Current.GetInstance<IBoardMemberRepository>();
var existingBoardMember = boardMembersRepository.GetBy(b.FirstName, b.LastName, b.CondoName);
if (existingBoardMember != null)
{
// pmc may update only board members of their own condos
if (existingBoardMember.Condo.BusinessIdPMC != businessIdPMC)
{
throw new WebException(HttpStatusCode.Unauthorized,
string.Format(TaloyhtioIntegration_resx.SecurityIncorrectBusinessIdPMC,
businessIdPMC, existingBoardMember.Condo.BusinessId));
}
}
// construct board member entity from dto object for validation and saving
var mapper = ServiceLocator.Current.GetInstance<IMapper<Taloyhtio.GeneralApi.Common.DTO.BoardMember, BoardMember>>();
var boardMember = mapper.Map(b);
boardMember.LastUpdated = DateTime.Now;
if (existingBoardMember != null)
{
boardMember.Condo = existingBoardMember.Condo;
}
else
{
var condoRepository = ServiceLocator.Current.GetInstance<ICondoRepository>();
boardMember.Condo = condoRepository.GetByOfficialName(b.CondoName);
}
var validator = ServiceLocator.Current.GetInstance<ValidatorEngine>();
var errors = validator.Validate(boardMember);
if (!errors.IsNullOrEmpty())
{
throw new Exception(string.Join("\n", errors.Select(e => e.ToString()).ToArray()));
}
bool statusChanged = false;
bool newBoardMember = existingBoardMember == null;
if (existingBoardMember != null)
{
existingBoardMember.Address = boardMember.Address;
existingBoardMember.Postcode = boardMember.Postcode;
existingBoardMember.Town = boardMember.Town;
existingBoardMember.FlatNumber = boardMember.FlatNumber;
existingBoardMember.Email = boardMember.Email;
existingBoardMember.Mobile = boardMember.Mobile;
existingBoardMember.LastUpdated = boardMember.LastUpdated;
statusChanged = (existingBoardMember.Deactivated != boardMember.Deactivated);
existingBoardMember.Deactivated = boardMember.Deactivated;
// for existing Condo it is not necessary to call ISession.SaveOrUpdate() because it is
// already attached to the session. See http://stackoverflow.com/questions/1380581/nhibernate-commit-db-changes-without-explict-call-to-save-or-update
boardMember = existingBoardMember;
}
boardMembersRepository.Save(boardMember);
if (newBoardMember)
{
this.sendEmailStatusChanged(boardMember,
Taloyhtio.GeneralApi.Core.Common.Constants.TemplateParams.BOARD_MEMBER,
Taloyhtio.GeneralApi.Core.Common.Constants.SettingsKeys.KEY_EMAIL_BOARD_MEMBER_NEW_SUBJECT,
Taloyhtio.GeneralApi.Core.Common.Constants.SettingsKeys.KEY_EMAIL_BOARD_MEMBER_NEW_BODY_TEMPLATE);
}
else if (statusChanged)
{
this.sendEmailStatusChanged(boardMember,
Taloyhtio.GeneralApi.Core.Common.Constants.TemplateParams.BOARD_MEMBER,
Taloyhtio.GeneralApi.Core.Common.Constants.SettingsKeys.KEY_EMAIL_BOARD_MEMBER_STATUS_CHANGED_SUBJECT,
Taloyhtio.GeneralApi.Core.Common.Constants.SettingsKeys.KEY_EMAIL_BOARD_MEMBER_STATUS_CHANGED_BODY_TEMPLATE);
}
}
private void sendEmailStatusChanged<T>(T item, string templateParam, string subjKey, string bodyTemplateKey)
{
try
{
var settingsProvider = ServiceLocator.Current.GetInstance<ISettingsProvider>();
string to = settingsProvider.Get<string>(Taloyhtio.GeneralApi.Core.Common.Constants.SettingsKeys.KEY_EMAIL_TO);
string subj = settingsProvider.Get<string>(subjKey);
string bodyTemplate = settingsProvider.Get<string>(bodyTemplateKey);
var templateEngine = ServiceLocator.Current.GetInstance<ITemplateEngine>();
//var propertyExtractor = ServiceLocator.Current.GetInstance<IPropertyExtractor>();
string body = templateEngine.Merge(bodyTemplate, new Pair<string, object>(templateParam, item));
body = body.Replace("\\n", "\n");
var emailService = ServiceLocator.Current.GetInstance<IEmailService>();
emailService.Send(to, subj, body);
}
catch (Exception x)
{
var logger = ServiceLocator.Current.GetInstance<ILogger>();
logger.LogError("sendEmailCondoStatusChanged:\n{0}\n{1}", x.Message, x.StackTrace);
}
}
private ServiceSecurityContext ensureAuthorized()
{
var securityContext = OperationContext.Current.ServiceSecurityContext;
if (securityContext == null || securityContext.IsAnonymous)
{
throw new WebException(HttpStatusCode.Unauthorized,
TaloyhtioIntegration_resx.SecurityNotAuthorized);
}
return securityContext;
}
}
}