crm: migrate Api to EF Core

This commit is contained in:
Alexey Bannov 2020-04-16 22:41:37 +03:00
parent b78b8c00c7
commit 35762e45ee
58 changed files with 15673 additions and 151 deletions

View File

@ -14,12 +14,27 @@
<Compile Remove="Classes\TwilioController.cs" />
<Compile Remove="Configuration\SearchHandler.cs" />
<Compile Remove="Configuration\VoipModule.cs" />
<Compile Remove="Controllers\CRMApi.Cases.cs" />
<Compile Remove="Controllers\CRMApi.cs" />
<Compile Remove="Controllers\CRMApi.CurrencyRates.cs" />
<Compile Remove="Controllers\CRMApi.CustomFields.cs" />
<Compile Remove="Controllers\CRMApi.Deals.cs" />
<Compile Remove="Controllers\CRMApi.Invoices.cs" />
<Compile Remove="Controllers\CRMApi.ListItem.cs" />
<Compile Remove="Controllers\CRMApi.RelationshipEvent.cs" />
<Compile Remove="Controllers\CRMApi.Reports.cs" />
<Compile Remove="Controllers\CRMApi.Tag.cs" />
<Compile Remove="Controllers\CRMApi.TaskTemplate.cs" />
<Compile Remove="Controllers\CRMApi.Utils.cs" />
<Compile Remove="Controllers\CRMApiBase.cs" />
<Compile Remove="Controllers\CRMBootstrap.cs" />
<Compile Remove="HttpHandlers\ContactPhotoHandler.cs" />
<Compile Remove="HttpHandlers\FileHandler.ashx.cs" />
<Compile Remove="HttpHandlers\FileUploaderHandler.cs" />
<Compile Remove="HttpHandlers\ImportFileHandler.cs" />
<Compile Remove="HttpHandlers\OrganisationLogoHandler.cs" />
<Compile Remove="HttpHandlers\WebToLeadFromHandler.ashx.cs" />
<Compile Remove="Model\VoipCallWrapper.cs" />
<Compile Remove="Utils\ExportToCSV.cs" />
<Compile Remove="Utils\MailSender.cs" />
<Compile Remove="Utils\PdfQueueWorker.cs" />

View File

@ -57,8 +57,8 @@ namespace ASC.Web.CRM.Classes
CRMSecurity cRMSecurity,
TenantManager tenantManager,
SettingsManager settingsManager,
IConfiguration configuration,
PdfCreator pdfCreator
IConfiguration configuration
// PdfCreator pdfCreator
)
{
StorageFactory = storageFactory;
@ -69,10 +69,10 @@ namespace ASC.Web.CRM.Classes
TenantID = tenantManager.GetCurrentTenant().TenantId;
SettingsManager = settingsManager;
Configuration = configuration;
PdfCreator = pdfCreator;
// PdfCreator = pdfCreator;
}
public PdfCreator PdfCreator { get; }
// public PdfCreator PdfCreator { get; }
public IConfiguration Configuration { get; }
public SettingsManager SettingsManager { get; }
@ -184,22 +184,22 @@ namespace ASC.Web.CRM.Classes
SettingsManager.Save<CRMSettings>(tenantSettings);
}
public ASC.Files.Core.File<int> GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory)
{
var existingFile = invoice.GetInvoiceFile(factory);
if (existingFile != null)
{
return existingFile;
}
else
{
var newFile = PdfCreator.CreateFile(invoice, factory);
invoice.FileID = Int32.Parse(newFile.ID.ToString());
factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID);
factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID });
return newFile;
}
}
//public ASC.Files.Core.File<int> GetInvoicePdfExistingOrCreate(ASC.CRM.Core.Entities.Invoice invoice, DaoFactory factory)
//{
// var existingFile = invoice.GetInvoiceFile(factory);
// if (existingFile != null)
// {
// return existingFile;
// }
// else
// {
// var newFile = PdfCreator.CreateFile(invoice, factory);
// invoice.FileID = Int32.Parse(newFile.ID.ToString());
// factory.GetInvoiceDao().UpdateInvoiceFileID(invoice.ID, invoice.FileID);
// factory.GetRelationshipEventDao().AttachFiles(invoice.ContactID, invoice.EntityType, invoice.EntityID, new[] { invoice.FileID });
// return newFile;
// }
//}
//Code snippet

View File

@ -689,8 +689,8 @@ namespace ASC.Web.CRM.Classes
{
services.TryAddScoped<InvoiceFormattedData>();
return services.AddOrganisationLogoManagerService()
.AddDaoFactoryService();
return services.AddOrganisationLogoManagerService();
// .AddDaoFactoryService();
}
}
}

View File

@ -202,9 +202,8 @@ namespace ASC.Web.CRM.Classes
{
services.TryAddScoped<OrganisationLogoManager>();
return services.AddWebImageSupplierService()
.AddGlobalService()
.AddDaoFactoryService();
return services.AddWebImageSupplierService();
}
}

View File

@ -339,7 +339,7 @@ namespace ASC.Web.CRM.Configuration
//{
// if (registered)
// {
// NotifyClient.Instance.Client.UnregisterSendMethod(NotifyClient.SendAutoReminderAboutTask);
// NotifyClient.Client.UnregisterSendMethod(NotifyClient.SendAutoReminderAboutTask);
// }
//}
@ -352,7 +352,7 @@ namespace ASC.Web.CRM.Configuration
// {
// registered = true;
// NotifyClient.Instance.Client.RegisterSendMethod(NotifyClient.SendAutoReminderAboutTask, "0 * * ? * *");
// NotifyClient.Client.RegisterSendMethod(NotifyClient.SendAutoReminderAboutTask, "0 * * ? * *");
// }
// }

View File

@ -0,0 +1,889 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.CRM.Wrappers;
using ASC.Api.Utils;
using ASC.Core.Tenants;
using ASC.CRM.Core;
using ASC.Data.Storage;
using ASC.VoipService;
using ASC.VoipService.Dao;
using ASC.VoipService.Twilio;
using ASC.Web.CRM.Classes;
using ASC.Web.Studio.Utility;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Security;
using SecurityContext = ASC.Core.SecurityContext;
namespace ASC.Api.CRM
{
public partial class CRMController
{
#region Numbers
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
/// <exception cref="ArgumentException"></exception>
[Read(@"voip/numbers/available")]
public IEnumerable<VoipPhone> GetAvailablePhoneNumbers(PhoneNumberType numberType, string isoCountryCode)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
if (string.IsNullOrEmpty(isoCountryCode)) throw new ArgumentException();
return VoipProvider.GetAvailablePhoneNumbers(numberType, isoCountryCode);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Read(@"voip/numbers/unlinked")]
public IEnumerable<VoipPhone> GetUnlinkedPhoneNumbers()
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var listPhones = VoipProvider.GetExistingPhoneNumbers();
var buyedPhones = DaoFactory.VoipDao.GetNumbers();
return listPhones.Where(r => buyedPhones.All(b => r.Id != b.Id)).ToList();
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Read(@"voip/numbers/existing")]
public IEnumerable<VoipPhone> GetExistingPhoneNumbers()
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
return DaoFactory.VoipDao.GetNumbers();
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Create(@"voip/numbers")]
public VoipPhone BuyNumber(string number)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var newPhone = VoipProvider.BuyNumber(number);
VoipProvider.CreateQueue(newPhone);
SetDefaultAudio(newPhone);
VoipProvider.UpdateSettings(newPhone);
return DaoFactory.VoipDao.SaveOrUpdateNumber(newPhone);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Create(@"voip/numbers/link")]
public VoipPhone LinkNumber(string id)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var newPhone = VoipProvider.GetPhone(id);
VoipProvider.CreateQueue(newPhone);
SetDefaultAudio(newPhone);
VoipProvider.UpdateSettings(newPhone);
return DaoFactory.VoipDao.SaveOrUpdateNumber(newPhone);
}
public void SetDefaultAudio(VoipPhone newPhone)
{
var storage = StorageFactory.GetStorage("", "crm");
const string path = "default/";
var files = storage.ListFilesRelative("voip", path, "*.*", true)
.Select(filePath => new
{
path = CommonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()),
audioType = (AudioType)Enum.Parse(typeof (AudioType), Directory.GetParent(filePath).Name, true)
}).ToList();
var audio = files.Find(r => r.audioType == AudioType.Greeting);
newPhone.Settings.GreetingAudio = audio != null ? audio.path : "";
audio = files.Find(r => r.audioType == AudioType.HoldUp);
newPhone.Settings.HoldAudio = audio != null ? audio.path : "";
audio = files.Find(r => r.audioType == AudioType.VoiceMail);
newPhone.Settings.VoiceMail = audio != null ? audio.path : "";
audio = files.Find(r => r.audioType == AudioType.Queue);
newPhone.Settings.Queue.WaitUrl = audio != null ? audio.path : "";
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Delete(@"voip/numbers/{numberId:\w+}")]
public VoipPhone DeleteNumber(string numberId)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var dao = DaoFactory.VoipDao;
var phone = dao.GetNumber(numberId).NotFoundIfNull();
VoipProvider.DisablePhone(phone);
dao.DeleteNumber(numberId);
new SignalRHelper(phone.Number).Reload();
return phone;
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Read(@"voip/numbers/{numberId:\w+}")]
public VoipPhone GetNumber(string numberId)
{
return DaoFactory.VoipDao.GetNumber(numberId).NotFoundIfNull();
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Read(@"voip/numbers/current")]
public VoipPhone GetCurrentNumber()
{
return DaoFactory.VoipDao.GetCurrentNumber().NotFoundIfNull();
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Read(@"voip/token")]
public string GetToken()
{
return VoipProvider.GetToken(GetCurrentNumber().Caller);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Update(@"voip/numbers/{numberId:\w+}/settings")]
public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, string wait, string voiceMail, WorkingHours workingHours, bool? allowOutgoingCalls, bool? record, string alias)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var dao = DaoFactory.VoipDao;
var number = dao.GetNumber(numberId).NotFoundIfNull();
number.Alias = Update.IfNotEmptyAndNotEquals(number.Alias, alias);
number.Settings.GreetingAudio = Update.IfNotEmptyAndNotEquals(number.Settings.GreetingAudio, greeting);
number.Settings.HoldAudio = Update.IfNotEmptyAndNotEquals(number.Settings.HoldAudio, holdUp);
number.Settings.VoiceMail = Update.IfNotEmptyAndNotEquals(number.Settings.VoiceMail, voiceMail);
number.Settings.WorkingHours = Update.IfNotEmptyAndNotEquals(number.Settings.WorkingHours, workingHours);
if (!string.IsNullOrEmpty(wait))
{
number.Settings.Queue.WaitUrl = wait;
}
if (allowOutgoingCalls.HasValue)
{
number.Settings.AllowOutgoingCalls = allowOutgoingCalls.Value;
if (!number.Settings.AllowOutgoingCalls)
{
number.Settings.Operators.ForEach(r => r.AllowOutgoingCalls = false);
}
}
if (record.HasValue)
{
number.Settings.Record = record.Value;
if (!number.Settings.Record)
{
number.Settings.Operators.ForEach(r => r.Record = false);
}
}
dao.SaveOrUpdateNumber(number);
return number;
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Update(@"voip/numbers/settings")]
public object UpdateSettings(Queue queue, bool pause)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var dao = DaoFactory.VoipDao;
var numbers = dao.GetNumbers();
if (queue != null)
{
foreach (var number in numbers)
{
if (number.Settings.Queue == null || string.IsNullOrEmpty(number.Settings.Queue.Id))
{
var phone = number as TwilioPhone;
if (phone != null)
{
queue = phone.CreateQueue(phone.Number, queue.Size, queue.WaitUrl, queue.WaitTime * 60);
}
queue.Name = number.Number;
number.Settings.Queue = queue;
}
else
{
var oldQueue = number.Settings.Queue;
oldQueue.Size = Update.IfNotEmptyAndNotEquals(oldQueue.Size, queue.Size);
oldQueue.WaitTime = Update.IfNotEmptyAndNotEquals(oldQueue.WaitTime, queue.WaitTime * 60);
oldQueue.WaitUrl = Update.IfNotEmptyAndNotEquals(oldQueue.WaitUrl, queue.WaitUrl);
}
number.Settings.Pause = pause;
dao.SaveOrUpdateNumber(number);
}
}
return new {queue, pause};
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Read(@"voip/numbers/settings")]
public object GetVoipSettings()
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var dao = DaoFactory.VoipDao;
var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null);
if (number != null)
{
return new {queue = number.Settings.Queue, pause = number.Settings.Pause};
}
var files = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true);
var file = files.FirstOrDefault();
return new { queue = new Queue(null, "Default", 5, file != null ? CommonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false };
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Read(@"voip/uploads")]
public IEnumerable<VoipUpload> GetUploadedFilesUri()
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var result = new List<VoipUpload>();
foreach (var audioType in Enum.GetNames(typeof (AudioType)))
{
var type = (AudioType)Enum.Parse(typeof (AudioType), audioType);
var path = audioType.ToLower();
var store = Global.GetStore();
var filePaths = store.ListFilesRelative("voip", path, "*", true);
result.AddRange(
filePaths.Select(filePath =>
GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type)));
path = "default/" + audioType.ToLower();
store = StorageFactory.GetStorage("", "crm");
filePaths = store.ListFilesRelative("voip", path, "*.*", true);
result.AddRange(
filePaths.Select(filePath =>
GetVoipUpload(store.GetUri("voip", Path.Combine(path, filePath)), Path.GetFileName(filePath), type, true)));
}
return result;
}
private static VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false)
{
return new VoipUpload
{
Path = CommonLinkUtility.GetFullAbsolutePath(link.ToString()),
Name = fileName,
AudioType = audioType,
IsDefault = isDefault
};
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
[Delete(@"voip/uploads")]
public VoipUpload DeleteUploadedFile(AudioType audioType, string fileName)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var store = Global.GetStore();
var path = Path.Combine(audioType.ToString().ToLower(), fileName);
var result = new VoipUpload
{
AudioType = audioType,
Name = fileName,
Path = CommonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString())
};
if (!store.IsFile("voip", path)) throw new ItemNotFoundException();
store.Delete("voip", path);
var dao = DaoFactory.VoipDao;
var numbers = dao.GetNumbers();
var defAudio = StorageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault();
if (defAudio == null) return result;
foreach (var number in numbers)
{
switch (audioType)
{
case AudioType.Greeting:
if (number.Settings.GreetingAudio == result.Path)
{
number.Settings.GreetingAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString());
}
break;
case AudioType.HoldUp:
if (number.Settings.HoldAudio == result.Path)
{
number.Settings.HoldAudio = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString());
}
break;
case AudioType.Queue:
var queue = number.Settings.Queue;
if (queue != null && queue.WaitUrl == result.Path)
{
queue.WaitUrl = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString());
}
break;
case AudioType.VoiceMail:
if (number.Settings.VoiceMail == result.Path)
{
number.Settings.VoiceMail = CommonLinkUtility.GetFullAbsolutePath(defAudio.ToString());
}
break;
}
dao.SaveOrUpdateNumber(number);
}
return result;
}
#endregion
#region Operators
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Read(@"voip/numbers/{numberId:\w+}/oper")]
public IEnumerable<Guid> GetOperators(string numberId)
{
return DaoFactory.VoipDao.GetNumber(numberId).Settings.Operators.Select(r => r.Id);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
/// <exception cref="ArgumentException"></exception>
[Update(@"voip/numbers/{numberId:\w+}/oper")]
public IEnumerable<Agent> AddOperators(string numberId, IEnumerable<Guid> operators)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
if (DaoFactory.VoipDao.GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id)))
{
throw new ArgumentException("Duplicate", "operators");
}
var dao = DaoFactory.VoipDao;
var phone = dao.GetNumber(numberId);
var lastOper = phone.Settings.Operators.LastOrDefault();
var startOperId = lastOper != null ? Convert.ToInt32(lastOper.PostFix) + 1 : 100;
var addedOperators = operators.Select(o => new Agent(o, AnswerType.Client, phone, (startOperId++).ToString(CultureInfo.InvariantCulture))).ToList();
phone.Settings.Operators.AddRange(addedOperators);
dao.SaveOrUpdateNumber(phone);
return addedOperators;
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Delete(@"voip/numbers/{numberId:\w+}/oper")]
public Guid DeleteOperator(string numberId, Guid oper)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var dao = DaoFactory.VoipDao;
var phone = dao.GetNumber(numberId);
var startOperId = 100;
phone.Settings.Operators.RemoveAll(r => r.Id == oper);
phone.Settings.Operators.ToList()
.ForEach(r =>
{
r.PhoneNumber = phone.Number;
r.PostFix = startOperId.ToString(CultureInfo.InvariantCulture);
startOperId++;
});
dao.SaveOrUpdateNumber(phone);
return oper;
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Update(@"voip/opers/{operatorId}")]
public Agent UpdateOperator(Guid operatorId, AgentStatus? status, bool? allowOutgoingCalls, bool? record, AnswerType? answerType, string redirectToNumber)
{
if (!CRMSecurity.IsAdmin && !operatorId.Equals(SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException();
var dao = DaoFactory.VoipDao;
var phone = dao.GetNumbers().FirstOrDefault(r => r.Settings.Operators.Exists(a => a.Id == operatorId)).NotFoundIfNull();
var oper = phone.Settings.Operators.Find(r => r.Id == operatorId);
if (status.HasValue)
{
oper.Status = status.Value;
}
if (allowOutgoingCalls.HasValue)
{
oper.AllowOutgoingCalls = phone.Settings.AllowOutgoingCalls && allowOutgoingCalls.Value;
}
if (record.HasValue)
{
oper.Record = phone.Settings.Record && record.Value;
}
if (answerType.HasValue)
{
oper.Answer = answerType.Value;
}
if (!string.IsNullOrEmpty(redirectToNumber))
{
oper.RedirectToNumber = redirectToNumber;
}
dao.SaveOrUpdateNumber(phone);
if (allowOutgoingCalls.HasValue)
{
new SignalRHelper(phone.Number).Reload(operatorId.ToString());
}
return oper;
}
#endregion
#region Calls
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
/// <exception cref="SecurityException"></exception>
[Create(@"voip/call")]
public VoipCallWrapper MakeCall(string to, string contactId)
{
var number = DaoFactory.VoipDao.GetCurrentNumber().NotFoundIfNull();
if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied);
var contactPhone = to.TrimStart('+');
var contact = string.IsNullOrEmpty(contactId) ?
GetContactsByContactInfo(ContactInfoType.Phone, contactPhone, null, null).FirstOrDefault() :
GetContactByID(Convert.ToInt32(contactId));
if (contact == null)
{
contact = ToContactWrapper(new VoipEngine(DaoFactory).CreateContact(contactPhone));
}
contact = GetContactWithFotos(contact);
var call = number.Call(to, contact.ID.ToString(CultureInfo.InvariantCulture));
return new VoipCallWrapper(call, contact);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Create(@"voip/call/{callId:\w+}/answer")]
public VoipCallWrapper AnswerCall(string callId)
{
var dao = DaoFactory.VoipDao;
var call = dao.GetCall(callId).NotFoundIfNull();
var number = dao.GetCurrentNumber().NotFoundIfNull();
number.AnswerQueueCall(call.Id);
return new VoipCallWrapper(call);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Create(@"voip/call/{callId:\w+}/reject")]
public VoipCallWrapper RejectCall(string callId)
{
var dao = DaoFactory.VoipDao;
var call = dao.GetCall(callId).NotFoundIfNull();
var number = dao.GetCurrentNumber().NotFoundIfNull();
number.RejectQueueCall(call.Id);
return new VoipCallWrapper(call);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Create(@"voip/call/{callId:\w+}/redirect")]
public VoipCallWrapper ReditectCall(string callId, string to)
{
var dao = DaoFactory.VoipDao;
var call = dao.GetCall(callId).NotFoundIfNull();
var number = dao.GetCurrentNumber().NotFoundIfNull();
if (call.ContactId != 0)
{
var contact = DaoFactory.ContactDao.GetByID(call.ContactId);
var managers = CRMSecurity.GetAccessSubjectGuidsTo(contact);
if (!managers.Contains(Guid.Parse(to)))
{
managers.Add(Guid.Parse(to));
CRMSecurity.SetAccessTo(contact, managers);
}
}
number.RedirectCall(call.Id, to);
return new VoipCallWrapper(call);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Create(@"voip/call/{callId:\w+}")]
public VoipCallWrapper SaveCall(string callId, string from, string to, Guid answeredBy, VoipCallStatus? status, string contactId, decimal? price)
{
var dao = DaoFactory.VoipDao;
var call = dao.GetCall(callId) ?? new VoipCall();
call.Id = callId;
call.From = Update.IfNotEmptyAndNotEquals(call.From, from);
call.To = Update.IfNotEmptyAndNotEquals(call.To, to);
call.AnsweredBy = Update.IfNotEmptyAndNotEquals(call.AnsweredBy, answeredBy);
try
{
if (call.ContactId == 0)
{
var contactPhone = call.Status == VoipCallStatus.Incoming || call.Status == VoipCallStatus.Answered ? call.From : call.To;
if (!string.IsNullOrEmpty(contactId))
{
call.ContactId = Convert.ToInt32(contactId);
}
else
{
new VoipEngine(DaoFactory).GetContact(call);
}
if (call.ContactId == 0)
{
contactPhone = contactPhone.TrimStart('+');
var person = CreatePerson(contactPhone, TenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"), null, 0, null, ShareType.None, new List<Guid> { SecurityContext.CurrentAccount.ID }, null, null);
DaoFactory.ContactInfoDao.Save(new ContactInfo { ContactID = person.ID, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone });
call.ContactId = person.ID;
}
}
}
catch (Exception)
{
}
if (status.HasValue)
{
call.Status = status.Value;
}
if (call.Price == 0 && price.HasValue)
{
call.Price = price.Value;
}
call = dao.SaveOrUpdateCall(call);
if (call.ContactId == 0) return new VoipCallWrapper(call);
try
{
var contact = GetContactByID(call.ContactId);
contact = GetContactWithFotos(contact);
return new VoipCallWrapper(call, contact);
}
catch (Exception)
{
return new VoipCallWrapper(call);
}
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Create(@"voip/price/{callId:\w+}")]
public void SavePrice(string callId)
{
new VoipEngine(DaoFactory).SaveAdditionalInfo(callId);
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Read(@"voip/call")]
public IEnumerable<VoipCallWrapper> GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID)
{
var voipDao = DaoFactory.VoipDao;
var filter = new VoipCallFilter
{
Type = callType,
FromDate = from != null ? from.UtcTime : (DateTime?)null,
ToDate = to != null ? to.UtcTime.AddDays(1).AddMilliseconds(-1) : (DateTime?)null,
Agent = agent,
Client = client,
ContactID = contactID,
SortBy = _context.SortBy,
SortOrder = !_context.SortDescending,
SearchText = _context.FilterValue,
Offset = _context.StartIndex,
Max = _context.Count,
};
_context.SetDataPaginated();
_context.SetDataFiltered();
_context.SetDataSorted();
_context.TotalCount = voipDao.GetCallsCount(filter);
var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false);
var calls = voipDao.GetCalls(filter).Select(
r =>
{
ContactWrapper contact;
if (r.ContactId != 0)
{
contact = r.ContactIsCompany
? (ContactWrapper)new CompanyWrapper(r.ContactId) {DisplayName = r.ContactTitle}
: new PersonWrapper(r.ContactId) {DisplayName = r.ContactTitle};
contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany);
}
else
{
contact = new PersonWrapper(-1) { SmallFotoUrl = defaultSmallPhoto };
}
return new VoipCallWrapper(r, contact);
}).ToList();
return calls;
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Read(@"voip/call/missed")]
public IEnumerable<VoipCallWrapper> GetMissedCalls()
{
var voipDao = DaoFactory.VoipDao;
var defaultSmallPhoto = ContactPhotoManager.GetSmallSizePhoto(-1, false);
var calls = voipDao.GetMissedCalls(SecurityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select(
r =>
{
ContactWrapper contact;
if (r.ContactId != 0)
{
contact = r.ContactIsCompany
? (ContactWrapper)new CompanyWrapper(r.ContactId) { DisplayName = r.ContactTitle }
: new PersonWrapper(r.ContactId) { DisplayName = r.ContactTitle };
contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany);
}
else
{
contact = new PersonWrapper(-1) { SmallFotoUrl = defaultSmallPhoto };
}
return new VoipCallWrapper(r, contact);
}).ToList();
_context.SetDataPaginated();
_context.SetDataFiltered();
_context.SetDataSorted();
_context.TotalCount = calls.Count;
return calls;
}
/// <summary>
///
/// </summary>
/// <short></short>
/// <category>Voip</category>
/// <returns></returns>
[Read(@"voip/call/{callId:\w+}")]
public VoipCallWrapper GetCall(string callId)
{
var call = DaoFactory.VoipDao.GetCall(callId);
new VoipEngine(DaoFactory).GetContact(call);
if (call.ContactId == 0) return new VoipCallWrapper(call);
var contact = GetContactByID(call.ContactId);
contact = GetContactWithFotos(contact);
return new VoipCallWrapper(call, contact);
}
#endregion
private static ContactWrapper GetContactWithFotos(ContactWrapper contact)
{
contact.SmallFotoUrl = ContactPhotoManager.GetSmallSizePhoto(contact.ID, contact.IsCompany);
contact.MediumFotoUrl = ContactPhotoManager.GetMediumSizePhoto(contact.ID, contact.IsCompany);
return contact;
}
}
}

View File

@ -0,0 +1,65 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Web;
using ASC.Api.Exceptions;
using ASC.Api.Impl;
using ASC.Api.Interfaces;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
namespace ASC.Api.CRM
{
public partial class CRMApi : CRMApiBase, IApiEntryPoint
{
private readonly ApiContext _context;
///<summary>
/// Api name entry
///</summary>
public string Name
{
get { return "crm"; }
}
///<summary>
/// Constructor
///</summary>
///<param name="context"></param>
public CRMApi(ApiContext context)
{
_context = context;
}
private static HttpRequest Request
{
get { return HttpContext.Current.Request; }
}
}
}

View File

@ -0,0 +1,84 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using ASC.Common.Web;
using ASC.Core;
using ASC.CRM.Core;
using ASC.CRM.Core.Dao;
using ASC.Files.Core;
using ASC.VoipService;
using ASC.VoipService.Dao;
using ASC.Web.Projects.Core;
using Autofac;
using FilesGlobal = ASC.Web.Files.Classes.Global;
namespace ASC.Api.CRM
{
public class CRMApiBase : IDisposable
{
private IDaoFactory filesDaoFactory;
private readonly ILifetimeScope scope;
private readonly ILifetimeScope crmScope;
public CRMApiBase()
{
scope = DIHelper.Resolve();
ProjectsDaoFactory = scope.Resolve<Projects.Core.DataInterfaces.IDaoFactory>();
crmScope = Web.CRM.Core.DIHelper.Resolve();
DaoFactory = crmScope.Resolve<DaoFactory>();
}
protected DaoFactory DaoFactory { get; private set; }
protected IVoipProvider VoipProvider
{
get { return VoipDao.GetProvider(); }
}
protected Projects.Core.DataInterfaces.IDaoFactory ProjectsDaoFactory { get; private set; }
protected IDaoFactory FilesDaoFactory
{
get { return filesDaoFactory ?? (filesDaoFactory = FilesGlobal.DaoFactory); }
}
public void Dispose()
{
if (scope != null)
{
scope.Dispose();
}
if (crmScope != null)
{
crmScope.Dispose();
}
}
}
}

View File

@ -0,0 +1,58 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System.Collections.Generic;
using ASC.Api.Interfaces;
using ASC.Core;
using ASC.CRM.Core;
using ASC.CRM.Core.Dao;
using ASC.Web.Core;
using ASC.Web.Core.Calendars;
using ASC.Web.Files.Api;
namespace ASC.Api.CRM
{
public class CRMBootstrap : IApiBootstrapper
{
public void Configure()
{
if (!FilesIntegration.IsRegisteredFileSecurityProvider("crm", "crm_common"))
{
FilesIntegration.RegisterFileSecurityProvider("crm", "crm_common", new FileSecurityProvider());
}
//Register prodjects' calendar events
CalendarManager.Instance.RegistryCalendarProvider(userid =>
{
if (WebItemSecurity.IsAvailableForUser(WebItemManager.CRMProductID, userid))
{
return new List<BaseCalendar> {new CRMCalendar(userid)};
}
return new List<BaseCalendar>();
});
}
}
}

View File

@ -0,0 +1,122 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using ASC.Web.Core.Calendars;
using ASC.Core;
using ASC.CRM.Core.Dao;
using ASC.CRM.Core;
using ASC.Projects.Engine;
using ASC.Web.Core;
using ASC.Web.CRM.Core;
using Autofac;
using ASC.CRM.Resources;
using ASC.CRM.Core.Enums;
using ASC.Core.Tenants;
namespace ASC.Api.CRM
{
public sealed class CRMCalendar : BaseCalendar
{
[AllDayLongUTCAttribute]
private class Event : BaseEvent
{
}
public CRMCalendar(Guid userId)
{
Context.HtmlBackgroundColor = "";
Context.HtmlTextColor = "";
Context.CanChangeAlertType = false;
Context.CanChangeTimeZone = false;
Context.GetGroupMethod = () => CRMCommonResource.ProductName;
Id = "crm_calendar";
EventAlertType = EventAlertType.Never;
Name = CRMCommonResource.ProductName;
Description = "";
SharingOptions = new SharingOptions();
SharingOptions.PublicItems.Add(new SharingOptions.PublicItem {Id = userId, IsGroup = false});
}
public override List<IEvent> LoadEvents(Guid userId, DateTime startDate, DateTime endDate)
{
using (var scope = DIHelper.Resolve())
{
var _daoFactory = scope.Resolve<DaoFactory>();
var events = new List<IEvent>();
if (
!WebItemSecurity.IsAvailableForMe(WebItemManager.CRMProductID))
{
return events;
}
var tasks = _daoFactory.GetTaskDao().GetTasks(String.Empty, userId, 0, false, DateTime.MinValue,
DateTime.MinValue, EntityType.Any, 0, 0, 0, null);
foreach (var t in tasks)
{
if (t.DeadLine == DateTime.MinValue) continue;
var allDayEvent = t.DeadLine.Hour == 0 && t.DeadLine.Minute == 0;
var utcDate = allDayEvent ? t.DeadLine.Date : TenantUtil.DateTimeToUtc(t.DeadLine);
var e = new Event
{
AlertType = EventAlertType.Never,
AllDayLong = allDayEvent,
CalendarId = Id,
UtcStartDate = utcDate,
UtcEndDate = utcDate,
Id = "crm_task_" + t.ID.ToString(CultureInfo.InvariantCulture),
Name = Web.CRM.Resources.CRMCommonResource.ProductName + ": " + t.Title,
Description = t.Description
};
if (IsVisibleEvent(startDate, endDate, e.UtcStartDate, e.UtcEndDate))
events.Add(e);
}
return events;
}
}
public override TimeZoneInfo TimeZone
{
get { return TenantManager.GetCurrentTenant().TimeZone; }
}
private bool IsVisibleEvent(DateTime startDate, DateTime endDate, DateTime eventStartDate, DateTime eventEndDate)
{
return (startDate <= eventStartDate && eventStartDate <= endDate) ||
(startDate <= eventEndDate && eventEndDate <= endDate) ||
(eventStartDate < startDate && eventEndDate > endDate);
}
}
}

View File

@ -0,0 +1,758 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Collections;
using ASC.Api.CRM.Wrappers;
using ASC.Common.Web;
using ASC.Core;
using ASC.Core.Users;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.ElasticSearch;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.Files.Services.WCFService;
using System;
using System.Collections.Generic;
using System.Linq;
using EnumExtension = ASC.Web.CRM.Classes.EnumExtension;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Close the case with the ID specified in the request
/// </summary>
/// <short>Close case</short>
/// <category>Cases</category>
/// <param name="caseid" optional="false">Case ID</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Case
/// </returns>
[Update(@"case/{caseid:int}/close")]
public CasesWrapper CloseCases(int caseid)
{
if (caseid <= 0) throw new ArgumentException();
var cases = DaoFactory.GetCasesDao().CloseCases(caseid);
if (cases == null) throw new ItemNotFoundException();
MessageService.Send( MessageAction.CaseClosed, MessageTarget.Create(cases.ID), cases.Title);
return ToCasesWrapper(cases);
}
/// <summary>
/// Resume the case with the ID specified in the request
/// </summary>
/// <short>Resume case</short>
/// <category>Cases</category>
/// <param name="caseid" optional="false">Case ID</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Case
/// </returns>
[Update(@"case/{caseid:int}/reopen")]
public CasesWrapper ReOpenCases(int caseid)
{
if (caseid <= 0) throw new ArgumentException();
var cases = DaoFactory.GetCasesDao().ReOpenCases(caseid);
if (cases == null) throw new ItemNotFoundException();
MessageService.Send( MessageAction.CaseOpened, MessageTarget.Create(cases.ID), cases.Title);
return ToCasesWrapper(cases);
}
/// <summary>
/// Creates the case with the parameters specified in the request
/// </summary>
/// <short>Create case</short>
/// <param name="title" optional="false">Case title</param>
/// <param name="members" optional="true">Participants</param>
/// <param name="customFieldList" optional="true">User field list</param>
/// <param name="isPrivate" optional="true">Case privacy: private or not</param>
/// <param name="accessList" optional="true">List of users with access to the case</param>
/// <param name="isNotify" optional="true">Notify users in accessList about the case</param>
/// <returns>Case</returns>
/// <category>Cases</category>
/// <exception cref="ArgumentException"></exception>
/// <example>
/// <![CDATA[
///
/// Data transfer in application/json format:
///
/// data: {
/// title: "Exhibition organization",
/// isPrivate: false,
/// customFieldList: [{1: "value for text custom field with id = 1"}]
/// }
///
/// ]]>
/// </example>
[Create(@"case")]
public CasesWrapper CreateCases(
string title,
IEnumerable<int> members,
IEnumerable<ItemKeyValuePair<int, string>> customFieldList,
bool isPrivate,
IEnumerable<Guid> accessList,
bool isNotify)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentException();
var casesID = DaoFactory.GetCasesDao().CreateCases(title);
var cases = new Cases
{
ID = casesID,
Title = title,
CreateBy = SecurityContext.CurrentAccount.ID,
CreateOn = DateTime.UtcNow
};
FactoryIndexer<Web.CRM.Core.Search.CasesWrapper>.IndexAsync(cases);
SetAccessToCases(cases, isPrivate, accessList, isNotify, false);
var membersList = members != null ? members.ToList() : new List<int>();
if (membersList.Any())
{
var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList();
membersList = contacts.Select(m => m.ID).ToList();
DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray());
}
if (customFieldList != null)
{
var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList();
foreach (var field in customFieldList)
{
if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue;
DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value);
}
}
return ToCasesWrapper(DaoFactory.GetCasesDao().GetByID(casesID));
}
/// <summary>
/// Updates the selected case with the parameters specified in the request
/// </summary>
/// <short>Update case</short>
/// <param name="caseid" optional="false">Case ID</param>
/// <param name="title" optional="false">Case title</param>
/// <param name="members" optional="true">Participants</param>
/// <param name="customFieldList" optional="true">User field list</param>
/// <param name="isPrivate" optional="true">Case privacy: private or not</param>
/// <param name="accessList" optional="true">List of users with access to the case</param>
/// <param name="isNotify" optional="true">Notify users in accessList about the case</param>
/// <category>Cases</category>
/// <returns>Case</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <example>
/// <![CDATA[
///
/// Data transfer in application/json format:
///
/// data: {
/// caseid: 0,
/// title: "Exhibition organization",
/// isPrivate: false,
/// customFieldList: [{1: "value for text custom field with id = 1"}]
/// }
///
/// ]]>
/// </example>
[Update(@"case/{caseid:int}")]
public CasesWrapper UpdateCases(
int caseid,
string title,
IEnumerable<int> members,
IEnumerable<ItemKeyValuePair<int, string>> customFieldList,
bool isPrivate,
IEnumerable<Guid> accessList,
bool isNotify)
{
if ((caseid <= 0) || (string.IsNullOrEmpty(title))) throw new ArgumentException();
var cases = DaoFactory.GetCasesDao().GetByID(caseid);
if (cases == null) throw new ItemNotFoundException();
cases.Title = title;
DaoFactory.GetCasesDao().UpdateCases(cases);
if (CRMSecurity.IsAdmin || cases.CreateBy == Core.SecurityContext.CurrentAccount.ID)
{
SetAccessToCases(cases, isPrivate, accessList, isNotify, false);
}
var membersList = members != null ? members.ToList() : new List<int>();
if (membersList.Any())
{
var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList();
membersList = contacts.Select(m => m.ID).ToList();
DaoFactory.GetCasesDao().SetMembers(cases.ID, membersList.ToArray());
}
if (customFieldList != null)
{
var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Case).Select(fd => fd.ID).ToList();
foreach (var field in customFieldList)
{
if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue;
DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Case, cases.ID, field.Key, field.Value);
}
}
return ToCasesWrapper(cases);
}
/// <summary>
/// Sets access rights for the selected case with the parameters specified in the request
/// </summary>
/// <param name="caseid" optional="false">Case ID</param>
/// <param name="isPrivate" optional="false">Case privacy: private or not</param>
/// <param name="accessList" optional="false">List of users with access to the case</param>
/// <short>Set rights to case</short>
/// <category>Cases</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Case
/// </returns>
[Update(@"case/{caseid:int}/access")]
public CasesWrapper SetAccessToCases(int caseid, bool isPrivate, IEnumerable<Guid> accessList)
{
if (caseid <= 0) throw new ArgumentException();
var cases = DaoFactory.GetCasesDao().GetByID(caseid);
if (cases == null) throw new ItemNotFoundException();
if (!(CRMSecurity.IsAdmin || cases.CreateBy == Core.SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException();
return SetAccessToCases(cases, isPrivate, accessList, false, true);
}
private CasesWrapper SetAccessToCases(Cases cases, bool isPrivate, IEnumerable<Guid> accessList, bool isNotify, bool isMessageServicSende)
{
var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List<Guid>();
if (isPrivate && accessListLocal.Any())
{
if (isNotify)
{
accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList();
NotifyClient.SendAboutSetAccess(EntityType.Case, cases.ID, DaoFactory, accessListLocal.ToArray());
}
if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID))
{
accessListLocal.Add(SecurityContext.CurrentAccount.ID);
}
CRMSecurity.SetAccessTo(cases, accessListLocal);
if (isMessageServicSende)
{
var users = GetUsersByIdList(accessListLocal);
MessageService.Send( MessageAction.CaseRestrictedAccess, MessageTarget.Create(cases.ID), cases.Title, users.Select(x => x.DisplayUserName(false)));
}
}
else
{
CRMSecurity.MakePublic(cases);
if (isMessageServicSende)
{
MessageService.Send( MessageAction.CaseOpenedAccess, MessageTarget.Create(cases.ID), cases.Title);
}
}
return ToCasesWrapper(cases);
}
/// <summary>
/// Sets access rights for other users to the list of cases with the IDs specified in the request
/// </summary>
/// <param name="casesid">Case ID list</param>
/// <param name="isPrivate">Case privacy: private or not</param>
/// <param name="accessList">List of users with access</param>
/// <short>Set case access rights</short>
/// <category>Cases</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Case list
/// </returns>
[Update(@"case/access")]
public IEnumerable<CasesWrapper> SetAccessToBatchCases(IEnumerable<int> casesid, bool isPrivate, IEnumerable<Guid> accessList)
{
var result = new List<Cases>();
var cases = DaoFactory.GetCasesDao().GetCases(casesid);
if (!cases.Any()) return new List<CasesWrapper>();
foreach (var c in cases)
{
if (c == null) throw new ItemNotFoundException();
if (!(CRMSecurity.IsAdmin || c.CreateBy == Core.SecurityContext.CurrentAccount.ID)) continue;
SetAccessToCases(c, isPrivate, accessList, false, true);
result.Add(c);
}
return ToListCasesWrappers(result);
}
/// <summary>
/// Sets access rights for other users to the list of all cases matching the parameters specified in the request
/// </summary>
/// <param optional="true" name="contactid">Contact ID</param>
/// <param optional="true" name="isClosed">Case status</param>
/// <param optional="true" name="tags">Tags</param>
/// <param name="isPrivate">Case privacy: private or not</param>
/// <param name="accessList">List of users with access</param>
/// <short>Set case access rights</short>
/// <category>Cases</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Case list
/// </returns>
[Update(@"case/filter/access")]
public IEnumerable<CasesWrapper> SetAccessToBatchCases(
int contactid,
bool? isClosed,
IEnumerable<string> tags,
bool isPrivate,
IEnumerable<Guid> accessList
)
{
var result = new List<Cases>();
var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null);
if (!caseses.Any()) return new List<CasesWrapper>();
foreach (var casese in caseses)
{
if (casese == null) throw new ItemNotFoundException();
if (!(CRMSecurity.IsAdmin || casese.CreateBy == Core.SecurityContext.CurrentAccount.ID)) continue;
SetAccessToCases(casese, isPrivate, accessList, false, true);
result.Add(casese);
}
return ToListCasesWrappers(result);
}
/// <summary>
/// Returns the detailed information about the case with the ID specified in the request
/// </summary>
/// <short>Get case by ID</short>
/// <category>Cases</category>
/// <param name="caseid">Case ID</param>
///<exception cref="ArgumentException"></exception>
///<exception cref="ItemNotFoundException"></exception>
[Read(@"case/{caseid:int}")]
public CasesWrapper GetCaseByID(int caseid)
{
if (caseid <= 0) throw new ItemNotFoundException();
var cases = DaoFactory.GetCasesDao().GetByID(caseid);
if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException();
return ToCasesWrapper(cases);
}
/// <summary>
/// Returns the list of all cases matching the parameters specified in the request
/// </summary>
/// <short>Get case list</short>
/// <param optional="true" name="contactid">Contact ID</param>
/// <param optional="true" name="isClosed">Case status</param>
/// <param optional="true" name="tags">Tags</param>
/// <category>Cases</category>
/// <returns>
/// Case list
/// </returns>
[Read(@"case/filter")]
public IEnumerable<CasesWrapper> GetCases(int contactid, bool? isClosed, IEnumerable<string> tags)
{
IEnumerable<CasesWrapper> result;
SortedByType sortBy;
OrderBy casesOrderBy;
var searchString = ApiContext.FilterValue;
if (EnumExtension.TryParse(ApiContext.SortBy, true, out sortBy))
{
casesOrderBy = new OrderBy(sortBy, !ApiContext.SortDescending);
}
else if (string.IsNullOrEmpty(ApiContext.SortBy))
{
casesOrderBy = new OrderBy(SortedByType.Title, true);
}
else
{
casesOrderBy = null;
}
var fromIndex = (int)ApiContext.StartIndex;
var count = (int)ApiContext.Count;
if (casesOrderBy != null)
{
result = ToListCasesWrappers(
DaoFactory
.GetCasesDao()
.GetCases(
searchString,
contactid,
isClosed,
tags,
fromIndex,
count,
casesOrderBy)).ToList();
ApiContext.SetDataPaginated();
ApiContext.SetDataFiltered();
ApiContext.SetDataSorted();
}
else
{
result = ToListCasesWrappers(
DaoFactory
.GetCasesDao()
.GetCases(
searchString, contactid, isClosed,
tags,
0,
0,
null)).ToList();
}
int totalCount;
if (result.Count() < count)
{
totalCount = fromIndex + result.Count();
}
else
{
totalCount = DaoFactory.GetCasesDao().GetCasesCount(searchString, contactid, isClosed, tags);
}
ApiContext.SetTotalCount(totalCount);
return result.ToSmartList();
}
/// <summary>
/// Deletes the case with the ID specified in the request
/// </summary>
/// <short>Delete case</short>
/// <param name="caseid">Case ID</param>
/// <category>Cases</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Case
/// </returns>
[Delete(@"case/{caseid:int}")]
public CasesWrapper DeleteCase(int caseid)
{
if (caseid <= 0) throw new ArgumentException();
var cases = DaoFactory.GetCasesDao().DeleteCases(caseid);
if (cases == null) throw new ItemNotFoundException();
FactoryIndexer<Web.CRM.Core.Search.CasesWrapper>.DeleteAsync(cases);
MessageService.Send( MessageAction.CaseDeleted, MessageTarget.Create(cases.ID), cases.Title);
return ToCasesWrapper(cases);
}
/// <summary>
/// Deletes the group of cases with the IDs specified in the request
/// </summary>
/// <param name="casesids">Case ID list</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <short>Delete case group</short>
/// <category>Cases</category>
/// <returns>
/// Case list
/// </returns>
[Update(@"case")]
public IEnumerable<CasesWrapper> DeleteBatchCases(IEnumerable<int> casesids)
{
if (casesids == null) throw new ArgumentException();
casesids = casesids.Distinct();
var caseses = DaoFactory.GetCasesDao().DeleteBatchCases(casesids.ToArray());
if (caseses == null || !caseses.Any()) return new List<CasesWrapper>();
MessageService.Send( MessageAction.CasesDeleted, MessageTarget.Create(casesids), caseses.Select(c => c.Title));
return ToListCasesWrappers(caseses);
}
/// <summary>
/// Deletes the list of all cases matching the parameters specified in the request
/// </summary>
/// <param optional="true" name="contactid">Contact ID</param>
/// <param optional="true" name="isClosed">Case status</param>
/// <param optional="true" name="tags">Tags</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <short>Delete case group</short>
/// <category>Cases</category>
/// <returns>
/// Case list
/// </returns>
[Delete(@"case/filter")]
public IEnumerable<CasesWrapper> DeleteBatchCases(int contactid, bool? isClosed, IEnumerable<string> tags)
{
var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null);
if (!caseses.Any()) return new List<CasesWrapper>();
caseses = DaoFactory.GetCasesDao().DeleteBatchCases(caseses);
MessageService.Send( MessageAction.CasesDeleted, MessageTarget.Create(caseses.Select(c => c.ID)), caseses.Select(c => c.Title));
return ToListCasesWrappers(caseses);
}
/// <summary>
/// Returns the list of all contacts associated with the case with the ID specified in the request
/// </summary>
/// <short>Get all case contacts</short>
/// <param name="caseid">Case ID</param>
/// <category>Cases</category>
/// <returns>Contact list</returns>
///<exception cref="ArgumentException"></exception>
[Read(@"case/{caseid:int}/contact")]
public IEnumerable<ContactWrapper> GetCasesMembers(int caseid)
{
var contactIDs = DaoFactory.GetCasesDao().GetMembers(caseid);
return contactIDs == null
? new ItemList<ContactWrapper>()
: ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs));
}
/// <summary>
/// Adds the selected contact to the case with the ID specified in the request
/// </summary>
/// <short>Add case contact</short>
/// <category>Cases</category>
/// <param name="caseid">Case ID</param>
/// <param name="contactid">Contact ID</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Participant
/// </returns>
[Create(@"case/{caseid:int}/contact")]
public ContactWrapper AddMemberToCases(int caseid, int contactid)
{
if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException();
var cases = DaoFactory.GetCasesDao().GetByID(caseid);
if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException();
DaoFactory.GetCasesDao().AddMember(caseid, contactid);
var messageAction = contact is Company ? MessageAction.CaseLinkedCompany : MessageAction.CaseLinkedPerson;
MessageService.Send( messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle());
return ToContactWrapper(contact);
}
/// <summary>
/// Delete the selected contact from the case with the ID specified in the request
/// </summary>
/// <short>Delete case contact</short>
/// <category>Cases</category>
/// <param name="caseid">Case ID</param>
/// <param name="contactid">Contact ID</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Participant
/// </returns>
[Delete(@"case/{caseid:int}/contact/{contactid:int}")]
public ContactWrapper DeleteMemberFromCases(int caseid, int contactid)
{
if ((caseid <= 0) || (contactid <= 0)) throw new ArgumentException();
var cases = DaoFactory.GetCasesDao().GetByID(caseid);
if (cases == null || !CRMSecurity.CanAccessTo(cases)) throw new ItemNotFoundException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException();
var result = ToContactWrapper(contact);
DaoFactory.GetCasesDao().RemoveMember(caseid, contactid);
var messageAction = contact is Company ? MessageAction.CaseUnlinkedCompany : MessageAction.CaseUnlinkedPerson;
MessageService.Send( messageAction, MessageTarget.Create(cases.ID), cases.Title, contact.GetTitle());
return result;
}
/// <summary>
/// Returns the list of 30 cases in the CRM module with prefix
/// </summary>
/// <param optional="true" name="prefix"></param>
/// <param optional="true" name="contactID"></param>
/// <category>Cases</category>
/// <returns>
/// Cases list
/// </returns>
/// <visible>false</visible>
[Read(@"case/byprefix")]
public IEnumerable<CasesWrapper> GetCasesByPrefix(string prefix, int contactID)
{
var result = new List<CasesWrapper>();
if (contactID > 0)
{
var findedCases = DaoFactory.GetCasesDao().GetCases(string.Empty, contactID, null, null, 0, 0, null);
foreach (var item in findedCases)
{
if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1)
{
result.Add(ToCasesWrapper(item));
}
}
ApiContext.SetTotalCount(findedCases.Count);
}
else
{
const int maxItemCount = 30;
var findedCases = DaoFactory.GetCasesDao().GetCasesByPrefix(prefix, 0, maxItemCount);
foreach (var item in findedCases)
{
result.Add(ToCasesWrapper(item));
}
}
return result;
}
private IEnumerable<CasesWrapper> ToListCasesWrappers(ICollection<Cases> items)
{
if (items == null || items.Count == 0) return new List<CasesWrapper>();
var result = new List<CasesWrapper>();
var contactIDs = new List<int>();
var casesIDs = items.Select(item => item.ID).ToArray();
var customFields = DaoFactory.GetCustomFieldDao()
.GetEnityFields(EntityType.Case, casesIDs)
.GroupBy(item => item.EntityID)
.ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper));
var casesMembers = DaoFactory.GetCasesDao().GetMembers(casesIDs);
foreach (var value in casesMembers.Values)
{
contactIDs.AddRange(value);
}
var contacts = DaoFactory
.ContactDao
.GetContacts(contactIDs.Distinct().ToArray())
.ToDictionary(item => item.ID, ToContactBaseWrapper);
foreach (var cases in items)
{
var casesWrapper = new CasesWrapper(cases)
{
CustomFields = customFields.ContainsKey(cases.ID)
? customFields[cases.ID]
: new List<CustomFieldBaseWrapper>(),
Members = casesMembers.ContainsKey(cases.ID)
? casesMembers[cases.ID].Where(contacts.ContainsKey).Select(item => contacts[item])
: new List<ContactBaseWrapper>()
};
result.Add(casesWrapper);
}
return result;
}
private CasesWrapper ToCasesWrapper(Cases cases)
{
var casesWrapper = new CasesWrapper(cases)
{
CustomFields = DaoFactory
.CustomFieldDao
.GetEnityFields(EntityType.Case, cases.ID, false)
.ConvertAll(item => new CustomFieldBaseWrapper(item))
.ToSmartList(),
Members = new List<ContactBaseWrapper>()
};
var memberIDs = DaoFactory.GetCasesDao().GetMembers(cases.ID);
var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs);
var membersWrapperList = new List<ContactBaseWrapper>();
foreach (var member in membersList)
{
if (member == null) continue;
membersWrapperList.Add(ToContactBaseWrapper(member));
}
casesWrapper.Members = membersWrapperList;
return casesWrapper;
}
private IEnumerable<UserInfo> GetUsersByIdList(IEnumerable<Guid> ids)
{
return UserManager.GetUsers().Where(x => ids.Contains(x.ID));
}
}
}

View File

@ -0,0 +1,534 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.CRM.Wrappers;
using ASC.Common.Web;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.ElasticSearch;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Core.Search;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Returns the list of all available contact categories
/// </summary>
/// <param name="infoType">
/// Contact information type
/// </param>
/// <short>Get all categories</short>
/// <category>Contacts</category>
/// <returns>
/// List of all available contact categories
/// </returns>
[Read(@"contact/data/{infoType}/category")]
public IEnumerable<string> GetContactInfoCategory(ContactInfoType infoType)
{
return Enum.GetNames(ContactInfo.GetCategory(infoType)).ToItemList();
}
/// <summary>
/// Returns the list of all available contact information types
/// </summary>
/// <short>Get all contact info types</short>
/// <category>Contacts</category>
/// <returns></returns>
[Read(@"contact/data/infoType")]
public IEnumerable<string> GetContactInfoType()
{
return Enum.GetNames(typeof(ContactInfoType)).ToItemList();
}
/// <summary>
/// Returns the detailed information for the contact
/// </summary>
/// <param name="contactid">Contact ID</param>
/// <short>Get contact information</short>
/// <category>Contacts</category>
/// <returns>
/// Contact information
/// </returns>
[Read(@"contact/{contactid:int}/data")]
public IEnumerable<ContactInfoWrapper> GetContactInfo(int contactid)
{
if (contactid <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException();
return DaoFactory.GetContactInfoDao().GetList(contactid, null, null, null)
.OrderByDescending(info => info.ID)
.ToList()
.ConvertAll(ToContactInfoWrapper);
}
/// <summary>
/// Returns the detailed list of all information available for the contact with the ID specified in the request
/// </summary>
/// <param name="contactid">Contact ID</param>
/// <param name="id">Contact information ID</param>
/// <short>Get contact info</short>
/// <category>Contacts</category>
/// <returns>Contact information</returns>
///<exception cref="ArgumentException"></exception>
[Read(@"contact/{contactid:int}/data/{id:int}")]
public ContactInfoWrapper GetContactInfoByID(int contactid, int id)
{
if (contactid <= 0 || id <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException();
var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id);
if (contactInfo == null || contactInfo.ContactID != contactid) throw new ArgumentException();
return ToContactInfoWrapper(contactInfo);
}
/// <summary>
/// Adds the information with the parameters specified in the request to the contact with the selected ID
/// </summary>
///<param name="contactid">Contact ID</param>
///<param name="infoType">Contact information type</param>
///<param name="data">Data</param>
///<param name="isPrimary">Contact importance: primary or not</param>
///<param name="category">Category</param>
///<short> Add contact info</short>
///<category>Contacts</category>
/// <seealso cref="GetContactInfoType"/>
/// <seealso cref="GetContactInfoCategory"/>
/// <returns>
/// Contact information
/// </returns>
///<exception cref="ArgumentException"></exception>
[Create(@"contact/{contactid:int}/data")]
public ContactInfoWrapper CreateContactInfo(int contactid, ContactInfoType infoType, string data, bool isPrimary, string category)
{
if (string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null) throw new ItemNotFoundException();
if (infoType == ContactInfoType.Twitter)
{
if (!CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException();
}
else
{
if (!CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException();
}
var categoryType = ContactInfo.GetCategory(infoType);
if (!Enum.IsDefined(categoryType, category)) throw new ArgumentException();
var contactInfo = new ContactInfo
{
Data = data,
InfoType = infoType,
ContactID = contactid,
IsPrimary = isPrimary,
Category = (int)Enum.Parse(categoryType, category)
};
if (contactInfo.InfoType == ContactInfoType.Address)
{
Address res;
if (!Address.TryParse(contactInfo, out res))
throw new ArgumentException();
}
var contactInfoID = DaoFactory.GetContactInfoDao().Save(contactInfo);
var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo;
MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle());
var contactInfoWrapper = ToContactInfoWrapper(contactInfo);
contactInfoWrapper.ID = contactInfoID;
return contactInfoWrapper;
}
/// <summary>
/// Adds the address information to the contact with the selected ID
/// </summary>
/// <param name="contactid">Contact ID</param>
/// <param name="address">Address data</param>
/// <short>Add address info</short>
/// <category>Contacts</category>
/// <seealso cref="GetContactInfoType"/>
/// <seealso cref="GetContactInfoCategory"/>
/// <returns>
/// Contact information
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
[Create(@"contact/{contactid:int}/addressdata")]
public ContactInfoWrapper CreateContactInfoAddress(int contactid, Address address)
{
if (contactid <= 0) throw new ArgumentException("Invalid value", "contactid");
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException();
if (address == null) throw new ArgumentException("Value cannot be null", "address");
if (!Enum.IsDefined(typeof(AddressCategory), address.Category)) throw new ArgumentException("Value does not fall within the expected range.", "address.Category");
address.CategoryName = ((AddressCategory)address.Category).ToLocalizedString();
var settings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
},
Formatting = Formatting.Indented
};
var contactInfo = new ContactInfo
{
InfoType = ContactInfoType.Address,
ContactID = contactid,
IsPrimary = address.IsPrimary,
Category = address.Category,
Data = JsonConvert.SerializeObject(address, settings)
};
contactInfo.ID = DaoFactory.GetContactInfoDao().Save(contactInfo);
var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo;
MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle());
return ToContactInfoWrapper(contactInfo);
}
/// <summary>
/// Creates contact information (add new information to the old list) with the parameters specified in the request for the contact with the selected ID
/// </summary>
///<short>Group contact info</short>
/// <param name="contactid">Contact ID</param>
/// <param name="items">Contact information</param>
/// <remarks>
/// <![CDATA[
/// items has format
/// [{infoType : 1, category : 1, categoryName : 'work', data : "myemail@email.com", isPrimary : true}, {infoType : 0, category : 0, categoryName : 'home', data : "+8999111999111", isPrimary : true}]
/// ]]>
/// </remarks>
/// <category>Contacts</category>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Contact information
/// </returns>
/// <visible>false</visible>
[Create(@"contact/{contactid:int}/batch")]
public IEnumerable<ContactInfoWrapper> CreateBatchContactInfo(int contactid, IEnumerable<ContactInfoWrapper> items)
{
if (contactid <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException();
var itemsList = items != null ? items.ToList() : new List<ContactInfoWrapper>();
var contactInfoList = itemsList.Select(FromContactInfoWrapper).ToList();
foreach (var contactInfo in contactInfoList)
{
if (contactInfo.InfoType == ContactInfoType.Address)
{
Address res;
if(!Address.TryParse(contactInfo, out res))
throw new ArgumentException();
}
contactInfo.ContactID = contactid;
}
var ids = DaoFactory.GetContactInfoDao().SaveList(contactInfoList, contact);
for (var index = 0; index < itemsList.Count; index++)
{
var infoWrapper = itemsList[index];
infoWrapper.ID = ids[index];
}
return itemsList;
}
/// <summary>
/// Updates the information with the parameters specified in the request for the contact with the selected ID
/// </summary>
///<param name="id">Contact information record ID</param>
///<param name="contactid">Contact ID</param>
///<param optional="true" name="infoType">Contact information type</param>
///<param name="data">Data</param>
///<param optional="true" name="isPrimary">Contact importance: primary or not</param>
///<param optional="true" name="category">Contact information category</param>
///<short>Update contact info</short>
///<category>Contacts</category>
///<exception cref="ArgumentException"></exception>
/// <returns>
/// Contact information
/// </returns>
[Update(@"contact/{contactid:int}/data/{id:int}")]
public ContactInfoWrapper UpdateContactInfo(int id, int contactid, ContactInfoType? infoType, string data, bool? isPrimary, string category)
{
if (id <= 0 || string.IsNullOrEmpty(data) || contactid <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException();
var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id);
if (infoType != null)
{
var categoryType = ContactInfo.GetCategory(infoType.Value);
if (!string.IsNullOrEmpty(category) && Enum.IsDefined(categoryType, category))
{
contactInfo.Category = (int)Enum.Parse(categoryType, category);
}
contactInfo.InfoType = infoType.Value;
}
contactInfo.ContactID = contactid;
if (isPrimary != null)
{
contactInfo.IsPrimary = isPrimary.Value;
}
contactInfo.Data = data;
if (contactInfo.InfoType == ContactInfoType.Address)
{
Address res;
if (!Address.TryParse(contactInfo, out res))
throw new ArgumentException();
}
DaoFactory.GetContactInfoDao().Update(contactInfo);
var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo;
MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle());
var contactInfoWrapper = ToContactInfoWrapper(contactInfo);
return contactInfoWrapper;
}
/// <summary>
/// Updates the address information with the parameters specified in the request for the contact with the selected ID
/// </summary>
/// <param name="id">Contact information record ID</param>
/// <param name="contactid">Contact ID</param>
/// <param name="address">Address data</param>
/// <short>Update address info</short>
/// <category>Contacts</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Contact information
/// </returns>
[Update(@"contact/{contactid:int}/addressdata/{id:int}")]
public ContactInfoWrapper UpdateContactInfoAddress(int id, int contactid, Address address)
{
if (id <= 0) throw new ArgumentException("Invalid value", "id");
var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id);
if (contactInfo == null || contactInfo.InfoType != ContactInfoType.Address) throw new ItemNotFoundException();
if (contactid <= 0) throw new ArgumentException("Invalid value", "contactid");
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanEdit(contact) || contactInfo.ContactID != contactid) throw new ItemNotFoundException();
if (address == null) throw new ArgumentException("Value cannot be null", "address");
if (!Enum.IsDefined(typeof(AddressCategory), address.Category)) throw new ArgumentException("Value does not fall within the expected range.", "address.Category");
address.CategoryName = ((AddressCategory) address.Category).ToLocalizedString();
var settings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy()
},
Formatting = Formatting.Indented
};
contactInfo.IsPrimary = address.IsPrimary;
contactInfo.Category = address.Category;
contactInfo.Data = JsonConvert.SerializeObject(address, settings);
DaoFactory.GetContactInfoDao().Update(contactInfo);
var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo;
MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle());
return ToContactInfoWrapper(contactInfo);
}
/// <summary>
/// Updates contact information (delete old information and add new list) with the parameters specified in the request for the contact with the selected ID
/// </summary>
///<short>Group contact info update</short>
///<param name="contactid">Contact ID</param>
///<param name="items">Contact information</param>
/// <![CDATA[
/// items has format
/// [{infoType : 1, category : 1, categoryName : 'work', data : "myemail@email.com", isPrimary : true}, {infoType : 0, category : 0, categoryName : 'home', data : "+8999111999111", isPrimary : true}]
/// ]]>
///<category>Contacts</category>
///<exception cref="ArgumentException"></exception>
/// <returns>
/// Contact information
/// </returns>
/// <visible>false</visible>
[Update(@"contact/{contactid:int}/batch")]
public IEnumerable<ContactInfoWrapper> UpdateBatchContactInfo(int contactid, IEnumerable<ContactInfoWrapper> items)
{
if (contactid <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException();
var itemsList = items != null ? items.ToList() : new List<ContactInfoWrapper>();
var contactInfoList = itemsList.Select(FromContactInfoWrapper).ToList();
foreach (var contactInfo in contactInfoList)
{
if (contactInfo.InfoType == ContactInfoType.Address)
{
Address res;
if (!Address.TryParse(contactInfo, out res))
throw new ArgumentException();
}
contactInfo.ContactID = contactid;
}
DaoFactory.GetContactInfoDao().DeleteByContact(contactid);
var ids = DaoFactory.GetContactInfoDao().SaveList(contactInfoList, contact);
for (var index = 0; index < itemsList.Count; index++)
{
var infoWrapper = itemsList[index];
infoWrapper.ID = ids[index];
}
return itemsList;
}
/// <summary>
/// Returns the detailed information for the contact with the selected ID by the information type specified in the request
/// </summary>
/// <param name="contactid">Contact ID</param>
/// <param name="infoType">Contact information type</param>
/// <short>Get contact information by type</short>
/// <category>Contacts</category>
/// <returns>
/// Contact information
/// </returns>
[Read(@"contact/{contactid:int}/data/{infoType}")]
public IEnumerable<string> GetContactInfo(int contactid, ContactInfoType infoType)
{
if (contactid <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException();
return DaoFactory.GetContactInfoDao().GetListData(contactid, infoType);
}
/// <summary>
/// Deletes the contact information for the contact with the ID specified in the request
/// </summary>
/// <param name="contactid">Contact ID</param>
/// <param name="id">Contact information record ID</param>
/// <short>Delete contact info</short>
/// <category>Contacts</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Contact information
/// </returns>
[Delete(@"contact/{contactid:int}/data/{id:int}")]
public ContactInfoWrapper DeleteContactInfo(int contactid, int id)
{
if (id <= 0 || contactid <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanEdit(contact)) throw new ItemNotFoundException();
var contactInfo = DaoFactory.GetContactInfoDao().GetByID(id);
if (contactInfo == null) throw new ItemNotFoundException();
var wrapper = ToContactInfoWrapper(contactInfo);
DaoFactory.GetContactInfoDao().Delete(id);
var messageAction = contact is Company ? MessageAction.CompanyUpdatedPrincipalInfo : MessageAction.PersonUpdatedPrincipalInfo;
MessageService.Send( messageAction, MessageTarget.Create(contact.ID), contact.GetTitle());
if (contactInfo.InfoType == ContactInfoType.Email)
{
FactoryIndexer<EmailWrapper>.DeleteAsync(EmailWrapper.ToEmailWrapper(contact, new List<ContactInfo> { contactInfo}));
}
FactoryIndexer<InfoWrapper>.DeleteAsync(contactInfo);
return wrapper;
}
private static ContactInfoWrapper ToContactInfoWrapper(ContactInfo contactInfo)
{
return new ContactInfoWrapper(contactInfo);
}
private static ContactInfo FromContactInfoWrapper(ContactInfoWrapper contactInfoWrapper)
{
return new ContactInfo
{
ID = contactInfoWrapper.ID,
Category = contactInfoWrapper.Category,
Data = contactInfoWrapper.Data,
InfoType = contactInfoWrapper.InfoType,
IsPrimary = contactInfoWrapper.IsPrimary
};
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,297 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.CRM.Core;
using ASC.CRM.Resources;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ASC.Api.CRM
{
public partial class CRMController
{
//TABLE `crm_currency_rate` column `rate` DECIMAL(10,2) NOT NULL
public const decimal MaxRateValue = (decimal) 99999999.99;
/// <summary>
/// Get the list of currency rates
/// </summary>
/// <short>Get currency rates list</short>
/// <category>Common</category>
/// <returns>
/// List of currency rates
/// </returns>
[Read(@"currency/rates")]
public IEnumerable<CurrencyRateWrapper> GetCurrencyRates()
{
return DaoFactory.GetCurrencyRateDao().GetAll().ConvertAll(ToCurrencyRateWrapper);
}
/// <summary>
/// Get currency rate by id
/// </summary>
/// <short>Get currency rate</short>
/// <category>Common</category>
/// <returns>
/// Currency rate
/// </returns>
/// <exception cref="ArgumentException"></exception>
[Read(@"currency/rates/{id:int}")]
public CurrencyRateWrapper GetCurrencyRate(int id)
{
if (id <= 0) throw new ArgumentException();
var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id);
return ToCurrencyRateWrapper(currencyRate);
}
/// <summary>
/// Get currency rate by currencies
/// </summary>
/// <short>Get currency rate</short>
/// <category>Common</category>
/// <returns>
/// Currency rate
/// </returns>
/// <exception cref="ArgumentException"></exception>
[Read(@"currency/rates/{fromCurrency}/{toCurrency}")]
public CurrencyRateWrapper GetCurrencyRate(string fromCurrency, string toCurrency)
{
if (string.IsNullOrEmpty(fromCurrency) || string.IsNullOrEmpty(toCurrency))
throw new ArgumentException();
var currencyRate = DaoFactory.GetCurrencyRateDao().GetByCurrencies(fromCurrency, toCurrency);
return ToCurrencyRateWrapper(currencyRate);
}
/// <summary>
/// Create new currency rate object
/// </summary>
/// <short></short>
/// <category>Common</category>
/// <returns></returns>
[Create(@"currency/rates")]
public CurrencyRateWrapper CreateCurrencyRate(string fromCurrency, string toCurrency, decimal rate)
{
ValidateRate(rate);
ValidateCurrencies(new[] {fromCurrency, toCurrency});
var currencyRate = new CurrencyRate
{
FromCurrency = fromCurrency,
ToCurrency = toCurrency,
Rate = rate
};
currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate);
MessageService.Send( MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency);
return ToCurrencyRateWrapper(currencyRate);
}
/// <summary>
/// Update currency rate object
/// </summary>
/// <short></short>
/// <category>Common</category>
/// <returns></returns>
[Update(@"currency/rates/{id:int}")]
public CurrencyRateWrapper UpdateCurrencyRate(int id, string fromCurrency, string toCurrency, decimal rate)
{
if (id <= 0)
throw new ArgumentException();
ValidateRate(rate);
ValidateCurrencies(new[] {fromCurrency, toCurrency});
var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id);
if (currencyRate == null)
throw new ArgumentException();
currencyRate.FromCurrency = fromCurrency;
currencyRate.ToCurrency = toCurrency;
currencyRate.Rate = rate;
currencyRate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(currencyRate);
MessageService.Send( MessageAction.CurrencyRateUpdated, fromCurrency, toCurrency);
return ToCurrencyRateWrapper(currencyRate);
}
/// <summary>
/// Set currency rates
/// </summary>
/// <short></short>
/// <category>Common</category>
/// <returns></returns>
[Create(@"currency/setrates")]
public List<CurrencyRateWrapper> SetCurrencyRates(String currency, List<CurrencyRate> rates)
{
if (!CRMSecurity.IsAdmin)
throw CRMSecurity.CreateSecurityException();
if (string.IsNullOrEmpty(currency))
throw new ArgumentException();
ValidateCurrencyRates(rates);
currency = currency.ToUpper();
if (Global.TenantSettings.DefaultCurrency.Abbreviation != currency)
{
var cur = CurrencyProvider.Get(currency);
if (cur == null)
throw new ArgumentException();
Global.SaveDefaultCurrencySettings(cur);
MessageService.Send( MessageAction.CrmDefaultCurrencyUpdated);
}
rates = DaoFactory.GetCurrencyRateDao().SetCurrencyRates(rates);
foreach (var rate in rates)
{
MessageService.Send( MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency);
}
return rates.Select(ToCurrencyRateWrapper).ToList();
}
/// <summary>
/// Add currency rates
/// </summary>
/// <short></short>
/// <category>Common</category>
/// <returns></returns>
[Create(@"currency/addrates")]
public List<CurrencyRateWrapper> AddCurrencyRates(List<CurrencyRate> rates)
{
if (!CRMSecurity.IsAdmin)
throw CRMSecurity.CreateSecurityException();
ValidateCurrencyRates(rates);
var existingRates = DaoFactory.GetCurrencyRateDao().GetAll();
foreach (var rate in rates)
{
var exist = false;
foreach (var existingRate in existingRates)
{
if (rate.FromCurrency != existingRate.FromCurrency || rate.ToCurrency != existingRate.ToCurrency)
continue;
existingRate.Rate = rate.Rate;
DaoFactory.GetCurrencyRateDao().SaveOrUpdate(existingRate);
MessageService.Send( MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency);
exist = true;
break;
}
if (exist) continue;
rate.ID = DaoFactory.GetCurrencyRateDao().SaveOrUpdate(rate);
MessageService.Send( MessageAction.CurrencyRateUpdated, rate.FromCurrency, rate.ToCurrency);
existingRates.Add(rate);
}
return existingRates.Select(ToCurrencyRateWrapper).ToList();
}
/// <summary>
/// Delete currency rate object
/// </summary>
/// <short></short>
/// <category>Common</category>
/// <returns></returns>
[Delete(@"currency/rates/{id:int}")]
public CurrencyRateWrapper DeleteCurrencyRate(int id)
{
if (id <= 0)
throw new ArgumentException();
var currencyRate = DaoFactory.GetCurrencyRateDao().GetByID(id);
if (currencyRate == null)
throw new ArgumentException();
DaoFactory.GetCurrencyRateDao().Delete(id);
return ToCurrencyRateWrapper(currencyRate);
}
private static void ValidateCurrencyRates(IEnumerable<CurrencyRate> rates)
{
var currencies = new List<string>();
foreach (var rate in rates)
{
ValidateRate(rate.Rate);
currencies.Add(rate.FromCurrency);
currencies.Add(rate.ToCurrency);
}
ValidateCurrencies(currencies.ToArray());
}
private static void ValidateCurrencies(string[] currencies)
{
if (currencies.Any(string.IsNullOrEmpty))
throw new ArgumentException();
var available = CurrencyProvider.GetAll().Select(x => x.Abbreviation);
var unknown = currencies.Where(x => !available.Contains(x)).ToArray();
if (!unknown.Any()) return;
throw new ArgumentException(string.Format(CRMErrorsResource.UnknownCurrency, string.Join(",", unknown)));
}
private static void ValidateRate(decimal rate)
{
if (rate < 0 || rate > MaxRateValue)
throw new ArgumentException(string.Format(CRMErrorsResource.InvalidCurrencyRate, rate));
}
private static CurrencyRateWrapper ToCurrencyRateWrapper(CurrencyRate currencyRate)
{
return new CurrencyRateWrapper(currencyRate);
}
}
}

View File

@ -0,0 +1,415 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.CRM.Wrappers;
using ASC.Common.Web;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.ElasticSearch;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Core.Search;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Returns the list of descriptions for all existing user fields
/// </summary>
/// <param name="entityType" remark="Allowed values: contact,person,company,opportunity,case">Type</param>
/// <short>Get user field list</short>
/// <category>User fields</category>
///<returns>
/// User field list
/// </returns>
///<exception cref="ArgumentException"></exception>
[Read(@"{entityType:(contact|person|company|opportunity|case)}/customfield/definitions")]
public IEnumerable<CustomFieldWrapper> GetCustomFieldDefinitions(string entityType)
{
return DaoFactory.GetCustomFieldDao().GetFieldsDescription(ToEntityType(entityType)).ConvertAll(ToCustomFieldWrapper).ToSmartList();
}
/// <summary>
/// Returns the list of all user field values using the entity type and entity ID specified in the request
/// </summary>
/// <param name="entityType" remark="Allowed values: contact,person,company,opportunity,case">Type</param>
/// <param name="entityid">ID</param>
/// <short>Get user field values</short>
/// <category>User fields</category>
/// <returns></returns>
[Read(@"{entityType:(contact|person|company|opportunity|case)}/{entityid:int}/customfield")]
public IEnumerable<CustomFieldBaseWrapper> GetCustomFieldForSubject(string entityType, int entityid)
{
return DaoFactory.GetCustomFieldDao().GetEnityFields(ToEntityType(entityType), entityid, false).ConvertAll(ToCustomFieldBaseWrapper).ToItemList();
}
/// <summary>
/// Sets the new user field value using the entity type, ID, field ID and value specified in the request
/// </summary>
/// <param name="entityType" remark="Allowed values: contact,person,company,opportunity,case">Type</param>
/// <param name="entityid">ID</param>
/// <param name="fieldid">Field ID</param>
/// <param name="fieldValue">Field Value</param>
/// <short>Set user field value</short>
/// <category>User fields</category>
/// <returns>
/// User field
/// </returns>
[Create(@"{entityType:(contact|person|company|opportunity|case)}/{entityid:int}/customfield/{fieldid:int}")]
public CustomFieldBaseWrapper SetEntityCustomFieldValue(string entityType, int entityid, int fieldid, string fieldValue)
{
var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid);
var entityTypeStr = ToEntityType(entityType);
customField.EntityID = entityid;
customField.Value = fieldValue;
DaoFactory.GetCustomFieldDao().SetFieldValue(entityTypeStr, entityid, fieldid, fieldValue);
return ToCustomFieldBaseWrapper(customField);
}
/// <summary>
/// Creates a new user field with the parameters (entity type, field title, type, etc.) specified in the request
/// </summary>
/// <param optional="false" name="entityType" remark="Allowed values: contact,person,company,opportunity,case">Entity type</param>
/// <param optional="false" name="label">Field title</param>
/// <param name="fieldType"
/// remark="Allowed values: TextField, TextArea, SelectBox, CheckBox, Heading or Date">
/// User field value
/// </param>
/// <param optional="true" name="position">Field position</param>
/// <param optional="true" name="mask" remark="Sent in json format only" >Mask</param>
/// <short>Create user field</short>
/// <category>User fields</category>
/// <returns>
/// User field
/// </returns>
///<example>
/// <![CDATA[
///
/// Data transfer in application/json format:
///
/// 1) Creation of a user field of TextField type
///
/// data: {
/// entityType: "contact",
/// label: "Sample TextField",
/// fieldType: 0,
/// position: 0,
/// mask: {"size":"40"} - this is the text field size. All other values are ignored.
/// }
///
///
/// 2) Creation of a user field of TextArea type
///
/// data: {
/// entityType: "contact",
/// label: "Sample TextArea",
/// fieldType: 1,
/// position: 1,
/// mask: '{"rows":"2","cols":"30"}' - this is the TextArea size. All other values are ignored.
/// }
///
///
/// 3) Creation of a user field of SelectBox type
///
/// data: {
/// entityType: "contact",
/// label: "Sample SelectBox",
/// fieldType: 2,
/// position: 0,
/// mask: ["1","2","3"] - SelectBox values.
/// }
///
///
///
/// 4) Creation of a user field of CheckBox type
///
/// data: {
/// entityType: "contact",
/// label: "Sample CheckBox",
/// fieldType: 3,
/// position: 0,
/// mask: ""
/// }
///
///
///
/// 5) Creation of a user field of Heading type
///
/// data: {
/// entityType: "contact",
/// label: "Sample Heading",
/// fieldType: 4,
/// position: 0,
/// mask: ""
/// }
///
///
///
/// 6) Creation of a user field of Date type
///
/// data: {
/// entityType: "contact",
/// label: "Sample Date",
/// fieldType: 5,
/// position: 0,
/// mask: ""
/// }
///
///
/// ]]>
/// </example>
[Create(@"{entityType:(contact|person|company|opportunity|case)}/customfield")]
public CustomFieldWrapper CreateCustomFieldValue(string entityType, string label, int fieldType, int position, string mask)
{
if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException();
var entityTypeObj = ToEntityType(entityType);
var fieldID = DaoFactory.GetCustomFieldDao().CreateField(entityTypeObj, label, (CustomFieldType)fieldType, mask);
var wrapper = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID);
var messageAction = GetCustomFieldCreatedAction(entityTypeObj);
MessageService.Send( messageAction, MessageTarget.Create(wrapper.ID), wrapper.Label);
return ToCustomFieldWrapper(DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldID));
}
/// <summary>
/// Updates the selected user field with the parameters (entity type, field title, type, etc.) specified in the request
/// </summary>
/// <param name="id">User field id</param>
/// <param name="entityType" remark="Allowed values: contact,person,company,opportunity,case">Entity type</param>
/// <param optional="false" name="label">Field title</param>
/// <param name="fieldType"
/// remark="Allowed values: 0 (TextField),1 (TextArea),2 (SelectBox),3 (CheckBox),4 (Heading) or 5 (Date)">
/// User field value
/// </param>
/// <param optional="true" name="position">Field position</param>
/// <param optional="true" name="mask" remark="Sent in json format only" >Mask</param>
/// <short> Updates the selected user field</short>
/// <category>User fields</category>
/// <returns>
/// User field
/// </returns>
///<remarks>
/// <![CDATA[
/// You can update field if there is no related elements. If such elements exist there will be updated only label and mask, other parameters will be ignored.
/// ]]>
/// </remarks>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
[Update(@"{entityType:(contact|person|company|opportunity|case)}/customfield/{id:int}")]
public CustomFieldWrapper UpdateCustomFieldValue(int id, string entityType, string label, int fieldType, int position, string mask)
{
if (id <= 0) throw new ArgumentException();
if (!DaoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException();
var entityTypeObj = ToEntityType(entityType);
var customField = new CustomField
{
EntityType = entityTypeObj,
FieldType = (CustomFieldType)fieldType,
ID = id,
Mask = mask,
Label = label,
Position = position
};
DaoFactory.GetCustomFieldDao().EditItem(customField);
customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(id);
var messageAction = GetCustomFieldUpdatedAction(entityTypeObj);
MessageService.Send( messageAction, MessageTarget.Create(customField.ID), customField.Label);
return ToCustomFieldWrapper(customField);
}
/// <summary>
/// Deletes the user field with the ID specified in the request
/// </summary>
/// <param name="entityType" remark="Allowed values: contact,person,company,opportunity,case">Type</param>
/// <param name="fieldid">Field ID</param>
/// <short>Delete user field</short>
/// <category>User fields</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// User field
/// </returns>
[Delete(@"{entityType:(contact|person|company|opportunity|case)}/customfield/{fieldid:int}")]
public CustomFieldWrapper DeleteCustomField(string entityType, int fieldid)
{
if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException();
if (fieldid <= 0) throw new ArgumentException();
var customField = DaoFactory.GetCustomFieldDao().GetFieldDescription(fieldid);
if (customField == null) throw new ItemNotFoundException();
var result = ToCustomFieldWrapper(customField);
DaoFactory.GetCustomFieldDao().DeleteField(fieldid);
FactoryIndexer<FieldsWrapper>.DeleteAsync(customField);
var messageAction = GetCustomFieldDeletedAction(ToEntityType(entityType));
MessageService.Send( messageAction, MessageTarget.Create(customField.ID), result.Label);
return result;
}
/// <summary>
/// Updates user fields order
/// </summary>
/// <param name="fieldids">User field ID list</param>
/// <param name="entityType" remark="Allowed values: contact,person,company,opportunity,case">Entity type</param>
/// <category>User fields</category>
/// <returns>
/// User fields
/// </returns>
/// <exception cref="SecurityException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
[Update(@"{entityType:(contact|person|company|opportunity|case)}/customfield/reorder")]
public IEnumerable<CustomFieldBaseWrapper> UpdateCustomFieldsOrder(IEnumerable<int> fieldids, string entityType)
{
if (fieldids == null) throw new ArgumentException();
if (!(CRMSecurity.IsAdmin)) throw CRMSecurity.CreateSecurityException();
var customFields = new List<CustomField>();
foreach (var id in fieldids)
{
if (!DaoFactory.GetCustomFieldDao().IsExist(id)) throw new ItemNotFoundException();
customFields.Add(DaoFactory.GetCustomFieldDao().GetFieldDescription(id));
}
DaoFactory.GetCustomFieldDao().ReorderFields(fieldids.ToArray());
var messageAction = GetCustomFieldsUpdatedOrderAction(ToEntityType(entityType));
MessageService.Send( messageAction, MessageTarget.Create(fieldids), customFields.Select(x => x.Label));
return customFields.Select(ToCustomFieldBaseWrapper);
}
private static CustomFieldBaseWrapper ToCustomFieldBaseWrapper(CustomField customField)
{
return new CustomFieldBaseWrapper(customField);
}
private CustomFieldWrapper ToCustomFieldWrapper(CustomField customField)
{
var result = new CustomFieldWrapper(customField)
{
RelativeItemsCount = DaoFactory.GetCustomFieldDao().GetContactLinkCount(customField.EntityType, customField.ID)
};
return result;
}
private static MessageAction GetCustomFieldCreatedAction(EntityType entityType)
{
switch (entityType)
{
case EntityType.Contact:
return MessageAction.ContactUserFieldCreated;
case EntityType.Person:
return MessageAction.PersonUserFieldCreated;
case EntityType.Company:
return MessageAction.CompanyUserFieldCreated;
case EntityType.Opportunity:
return MessageAction.OpportunityUserFieldCreated;
case EntityType.Case:
return MessageAction.CaseUserFieldCreated;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private static MessageAction GetCustomFieldUpdatedAction(EntityType entityType)
{
switch (entityType)
{
case EntityType.Contact:
return MessageAction.ContactUserFieldUpdated;
case EntityType.Person:
return MessageAction.PersonUserFieldUpdated;
case EntityType.Company:
return MessageAction.CompanyUserFieldUpdated;
case EntityType.Opportunity:
return MessageAction.OpportunityUserFieldUpdated;
case EntityType.Case:
return MessageAction.CaseUserFieldUpdated;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private static MessageAction GetCustomFieldDeletedAction(EntityType entityType)
{
switch (entityType)
{
case EntityType.Contact:
return MessageAction.ContactUserFieldDeleted;
case EntityType.Person:
return MessageAction.PersonUserFieldDeleted;
case EntityType.Company:
return MessageAction.CompanyUserFieldDeleted;
case EntityType.Opportunity:
return MessageAction.OpportunityUserFieldDeleted;
case EntityType.Case:
return MessageAction.CaseUserFieldDeleted;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private static MessageAction GetCustomFieldsUpdatedOrderAction(EntityType entityType)
{
switch (entityType)
{
case EntityType.Contact:
return MessageAction.ContactUserFieldsUpdatedOrder;
case EntityType.Person:
return MessageAction.PersonUserFieldsUpdatedOrder;
case EntityType.Company:
return MessageAction.CompanyUserFieldsUpdatedOrder;
case EntityType.Opportunity:
return MessageAction.OpportunityUserFieldsUpdatedOrder;
case EntityType.Case:
return MessageAction.CaseUserFieldsUpdatedOrder;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
}
}

View File

@ -0,0 +1,969 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Collections;
using ASC.Api.Core;
using ASC.Api.CRM.Wrappers;
using ASC.Common.Web;
using ASC.Core;
using ASC.Core.Users;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.MessagingSystem;
using ASC.Web.Api.Models;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Classes;
using ASC.Web.Files.Services.WCFService;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Returns the detailed information about the opportunity with the ID specified in the request
/// </summary>
/// <param name="opportunityid">Opportunity ID</param>
/// <returns>
/// Opportunity
/// </returns>
/// <short>Get opportunity by ID</short>
/// <category>Opportunities</category>
///<exception cref="ArgumentException"></exception>
///<exception cref="ItemNotFoundException"></exception>
[Read(@"opportunity/{opportunityid:int}")]
public OpportunityWrapper GetDealByID(int opportunityid)
{
if (opportunityid <= 0) throw new ArgumentException();
var deal = DaoFactory.GetDealDao().GetByID(opportunityid);
if (deal == null || !CRMSecurity.CanAccessTo(deal)) throw new ItemNotFoundException();
return ToOpportunityWrapper(deal);
}
/// <summary>
/// Updates the selected opportunity to the stage with the ID specified in the request
/// </summary>
/// <param name="opportunityid">Opportunity ID</param>
/// <param name="stageid">Opportunity stage ID</param>
/// <returns>
/// Opportunity
/// </returns>
/// <short>Update opportunity stage</short>
/// <category>Opportunities</category>
///<exception cref="ArgumentException"></exception>
///<exception cref="ItemNotFoundException"></exception>
[Update(@"opportunity/{opportunityid:int}/stage/{id:int}")]
public OpportunityWrapper UpdateToDealMilestone(int opportunityid, int stageid)
{
if (opportunityid <= 0 || stageid <= 0) throw new ArgumentException();
var deal = DaoFactory.GetDealDao().GetByID(opportunityid);
if (deal == null || !CRMSecurity.CanEdit(deal)) throw new ItemNotFoundException();
var stage = DaoFactory.GetDealMilestoneDao().GetByID(stageid);
if (stage == null) throw new ItemNotFoundException();
deal.DealMilestoneID = stageid;
deal.DealMilestoneProbability = stage.Probability;
deal.ActualCloseDate = stage.Status != DealMilestoneStatus.Open ? DateTime.UtcNow : DateTime.MinValue;
DaoFactory.GetDealDao().EditDeal(deal);
MessageService.Send( MessageAction.OpportunityUpdatedStage, MessageTarget.Create(deal.ID), deal.Title);
return ToOpportunityWrapper(deal);
}
/// <summary>
/// Sets access rights for the selected opportunity with the parameters specified in the request
/// </summary>
/// <param name="opportunityid">Opportunity ID</param>
/// <param name="isPrivate">Opportunity privacy: private or not</param>
/// <param name="accessList">List of users with access</param>
/// <short>Set rights to opportunity</short>
/// <category>Opportunities</category>
///<exception cref="ArgumentException"></exception>
///<exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Opportunity
/// </returns>
[Update(@"opportunity/{opportunityid:int}/access")]
public OpportunityWrapper SetAccessToDeal(int opportunityid, bool isPrivate, IEnumerable<Guid> accessList)
{
if (opportunityid <= 0) throw new ArgumentException();
var deal = DaoFactory.GetDealDao().GetByID(opportunityid);
if (deal == null) throw new ItemNotFoundException();
if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) throw CRMSecurity.CreateSecurityException();
return SetAccessToDeal(deal, isPrivate, accessList, false, true);
}
private OpportunityWrapper SetAccessToDeal(Deal deal, bool isPrivate, IEnumerable<Guid> accessList, bool isNotify, bool isMessageServicSende)
{
var accessListLocal = accessList != null ? accessList.Distinct().ToList() : new List<Guid>();
if (isPrivate && accessListLocal.Count > 0)
{
if (isNotify)
{
accessListLocal = accessListLocal.Where(u => u != SecurityContext.CurrentAccount.ID).ToList();
NotifyClient.SendAboutSetAccess(EntityType.Opportunity, deal.ID, DaoFactory, accessListLocal.ToArray());
}
if (!accessListLocal.Contains(SecurityContext.CurrentAccount.ID))
{
accessListLocal.Add(SecurityContext.CurrentAccount.ID);
}
CRMSecurity.SetAccessTo(deal, accessListLocal);
if (isMessageServicSende)
{
var users = GetUsersByIdList(accessListLocal);
MessageService.Send( MessageAction.OpportunityRestrictedAccess, MessageTarget.Create(deal.ID), deal.Title, users.Select(x => x.DisplayUserName(false)));
}
}
else
{
CRMSecurity.MakePublic(deal);
if (isMessageServicSende)
{
MessageService.Send( MessageAction.OpportunityOpenedAccess, MessageTarget.Create(deal.ID), deal.Title);
}
}
return ToOpportunityWrapper(deal);
}
/// <summary>
/// Sets access rights for other users to the list of all opportunities matching the parameters specified in the request
/// </summary>
/// <param optional="true" name="responsibleid">Opportunity responsible</param>
/// <param optional="true" name="opportunityStagesid">Opportunity stage ID</param>
/// <param optional="true" name="tags">Tags</param>
/// <param optional="true" name="contactid">Contact ID</param>
/// <param optional="true" name="contactAlsoIsParticipant">Participation status: take into account opportunities where the contact is a participant or not</param>
/// <param optional="true" name="fromDate">Start date</param>
/// <param optional="true" name="toDate">End date</param>
/// <param optional="true" name="stageType" remark="Allowed values: {Open, ClosedAndWon, ClosedAndLost}">Opportunity stage type</param>
/// <param name="isPrivate">Opportunity privacy: private or not</param>
/// <param name="accessList">List of users with access</param>
/// <short>Set opportunity access rights</short>
/// <category>Opportunities</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Opportunity list
/// </returns>
[Update(@"opportunity/filter/access")]
public IEnumerable<OpportunityWrapper> SetAccessToBatchDeal(
Guid responsibleid,
int opportunityStagesid,
IEnumerable<string> tags,
int contactid,
DealMilestoneStatus? stageType,
bool? contactAlsoIsParticipant,
ApiDateTime fromDate,
ApiDateTime toDate,
bool isPrivate,
IEnumerable<Guid> accessList
)
{
var result = new List<Deal>();
var deals = DaoFactory.GetDealDao()
.GetDeals(ApiContext.FilterValue,
responsibleid,
opportunityStagesid,
tags,
contactid,
stageType,
contactAlsoIsParticipant,
fromDate, toDate, 0, 0, null);
if (!deals.Any()) return Enumerable.Empty<OpportunityWrapper>();
foreach (var deal in deals)
{
if (deal == null) throw new ItemNotFoundException();
if (!(CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)) continue;
SetAccessToDeal(deal.ID, isPrivate, accessList);
result.Add(deal);
}
return ToListOpportunityWrapper(result);
}
/// <summary>
/// Sets access rights for other users to the list of opportunities with the IDs specified in the request
/// </summary>
/// <param name="opportunityid">Opportunity ID list</param>
/// <param name="isPrivate">Opportunity privacy: private or not</param>
/// <param name="accessList">List of users with access</param>
/// <short>Set opportunity access rights</short>
/// <category>Opportunities</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Opportunity list
/// </returns>
[Update(@"opportunity/access")]
public IEnumerable<OpportunityWrapper> SetAccessToBatchDeal(IEnumerable<int> opportunityid, bool isPrivate, IEnumerable<Guid> accessList)
{
if(opportunityid == null) throw new ArgumentException();
var result = new List<Deal>();
var deals = DaoFactory.GetDealDao().GetDeals(opportunityid.ToArray());
if (!deals.Any()) return new List<OpportunityWrapper>();
foreach (var d in deals)
{
if (d == null) throw new ItemNotFoundException();
if (!(CRMSecurity.IsAdmin || d.CreateBy == SecurityContext.CurrentAccount.ID)) continue;
SetAccessToDeal(d, isPrivate, accessList, false, true);
result.Add(d);
}
return ToListOpportunityWrapper(result);
}
/// <summary>
/// Deletes the group of opportunities with the IDs specified in the request
/// </summary>
/// <param name="opportunityids">Opportunity ID list</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <short>Delete opportunity group</short>
/// <category>Opportunities</category>
/// <returns>
/// Opportunity list
/// </returns>
[Update(@"opportunity")]
public IEnumerable<OpportunityWrapper> DeleteBatchDeals(IEnumerable<int> opportunityids)
{
if (opportunityids == null || !opportunityids.Any()) throw new ArgumentException();
var opportunities = DaoFactory.GetDealDao().DeleteBatchDeals(opportunityids.ToArray());
MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(opportunityids), opportunities.Select(o => o.Title));
return ToListOpportunityWrapper(opportunities);
}
/// <summary>
/// Deletes the list of all opportunities matching the parameters specified in the request
/// </summary>
/// <param optional="true" name="responsibleid">Opportunity responsible</param>
/// <param optional="true" name="opportunityStagesid">Opportunity stage ID</param>
/// <param optional="true" name="tags">Tags</param>
/// <param optional="true" name="contactid">Contact ID</param>
/// <param optional="true" name="contactAlsoIsParticipant">Participation status: take into account opportunities where the contact is a participant or not</param>
/// <param optional="true" name="fromDate">Start date</param>
/// <param optional="true" name="toDate">End date</param>
/// <param optional="true" name="stageType" remark="Allowed values: {Open, ClosedAndWon, ClosedAndLost}">Opportunity stage type</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <short>Delete opportunity group</short>
/// <category>Opportunities</category>
/// <returns>
/// Opportunity list
/// </returns>
[Delete(@"opportunity/filter")]
public IEnumerable<OpportunityWrapper> DeleteBatchDeals(
Guid responsibleid,
int opportunityStagesid,
IEnumerable<string> tags,
int contactid,
DealMilestoneStatus? stageType,
bool? contactAlsoIsParticipant,
ApiDateTime fromDate,
ApiDateTime toDate)
{
var deals = DaoFactory.GetDealDao().GetDeals(ApiContext.FilterValue,
responsibleid,
opportunityStagesid,
tags,
contactid,
stageType,
contactAlsoIsParticipant,
fromDate, toDate, 0, 0, null);
if (!deals.Any()) return Enumerable.Empty<OpportunityWrapper>();
deals = DaoFactory.GetDealDao().DeleteBatchDeals(deals);
MessageService.Send( MessageAction.OpportunitiesDeleted, MessageTarget.Create(deals.Select(x => x.ID)), deals.Select(d => d.Title));
return ToListOpportunityWrapper(deals);
}
/// <summary>
/// Returns the list of all opportunities matching the parameters specified in the request
/// </summary>
/// <param optional="true" name="responsibleid">Opportunity responsible</param>
/// <param optional="true" name="opportunityStagesid">Opportunity stage ID</param>
/// <param optional="true" name="tags">Tags</param>
/// <param optional="true" name="contactid">Contact ID</param>
/// <param optional="true" name="contactAlsoIsParticipant">Participation status: take into account opportunities where the contact is a participant or not</param>
/// <param optional="true" name="fromDate">Start date</param>
/// <param optional="true" name="toDate">End date</param>
/// <param optional="true" name="stageType" remark="Allowed values: {Open, ClosedAndWon, ClosedAndLost}">Opportunity stage type</param>
/// <short>Get opportunity list</short>
/// <category>Opportunities</category>
/// <returns>
/// Opportunity list
/// </returns>
[Read(@"opportunity/filter")]
public IEnumerable<OpportunityWrapper> GetDeals(
Guid responsibleid,
int opportunityStagesid,
IEnumerable<string> tags,
int contactid,
DealMilestoneStatus? stageType,
bool? contactAlsoIsParticipant,
ApiDateTime fromDate,
ApiDateTime toDate)
{
DealSortedByType dealSortedByType;
IEnumerable<OpportunityWrapper> result;
var searchString = ApiContext.FilterValue;
OrderBy dealsOrderBy;
if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out dealSortedByType))
{
dealsOrderBy = new OrderBy(dealSortedByType, !ApiContext.SortDescending);
}
else if (string.IsNullOrEmpty(ApiContext.SortBy))
{
dealsOrderBy = new OrderBy(DealSortedByType.Stage, true);
}
else
{
dealsOrderBy = null;
}
var fromIndex = (int)ApiContext.StartIndex;
var count = (int)ApiContext.Count;
if (dealsOrderBy != null)
{
result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals(
searchString,
responsibleid,
opportunityStagesid,
tags,
contactid,
stageType,
contactAlsoIsParticipant,
fromDate,
toDate,
fromIndex,
count,
dealsOrderBy)).ToList();
ApiContext.SetDataPaginated();
ApiContext.SetDataFiltered();
ApiContext.SetDataSorted();
}
else
{
result = ToListOpportunityWrapper(DaoFactory.GetDealDao().GetDeals(
searchString,
responsibleid,
opportunityStagesid,
tags,
contactid,
stageType,
contactAlsoIsParticipant,
fromDate,
toDate,
0, 0, null)).ToList();
}
int totalCount;
if (result.Count() < count)
{
totalCount = fromIndex + result.Count();
}
else
{
totalCount = DaoFactory
.DealDao
.GetDealsCount(searchString,
responsibleid,
opportunityStagesid,
tags,
contactid,
stageType,
contactAlsoIsParticipant,
fromDate,
toDate);
}
ApiContext.SetTotalCount(totalCount);
return result.ToSmartList();
}
/// <summary>
/// Deletes the opportunity with the ID specified in the request
/// </summary>
/// <param name="opportunityid">Opportunity ID</param>
/// <short>Delete opportunity</short>
/// <category>Opportunities</category>
///<exception cref="ArgumentException"></exception>
///<exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Opportunity
/// </returns>
[Delete(@"opportunity/{opportunityid:int}")]
public OpportunityWrapper DeleteDeal(int opportunityid)
{
if (opportunityid <= 0) throw new ArgumentException();
var deal = DaoFactory.GetDealDao().DeleteDeal(opportunityid);
if (deal == null) throw new ItemNotFoundException();
MessageService.Send( MessageAction.OpportunityDeleted, MessageTarget.Create(deal.ID), deal.Title);
return ToOpportunityWrapper(deal);
}
/// <summary>
/// Creates the opportunity with the parameters specified in the request
/// </summary>
/// <short>Create opportunity</short>
/// <param name="contactid">Opportunity primary contact</param>
/// <param optional="true" name="members">Participants</param>
/// <param name="title">Opportunity title</param>
/// <param optional="true" name="description">Opportunity description</param>
/// <param name="responsibleid">Opportunity responsible</param>
/// <param name="bidType" remark="Allowed values: FixedBid, PerHour, PerDay,PerWeek, PerMonth, PerYear">Bid</param>
/// <param optional="true" name="bidValue">Amount of transaction</param>
/// <param name="bidCurrencyAbbr">Currency (Abbreviation)</param>
/// <param name="perPeriodValue">Period</param>
/// <param name="stageid">Stage ID</param>
/// <param optional="true" name="successProbability">Opportunity success probability</param>
/// <param optional="true" name="actualCloseDate">Actual opportunity closure date</param>
/// <param optional="true" name="expectedCloseDate">Expected opportunity closure date</param>
/// <param optional="true" name="customFieldList">User field list</param>
/// <param name="isPrivate">Opportunity privacy: private or not</param>
/// <param optional="true" name="accessList">List of users with access to the opportunity</param>
/// <param name="isNotify" optional="true">Notify users in accessList about the opportunity</param>
/// <category>Opportunities</category>
/// <returns>
/// Opportunity
/// </returns>
///<exception cref="ArgumentException"></exception>
[Create(@"opportunity")]
public OpportunityWrapper CreateDeal(
int contactid,
IEnumerable<int> members,
string title,
string description,
Guid responsibleid,
BidType bidType,
decimal bidValue,
string bidCurrencyAbbr,
int perPeriodValue,
int stageid,
int successProbability,
ApiDateTime actualCloseDate,
ApiDateTime expectedCloseDate,
IEnumerable<ItemKeyValuePair<int, string>> customFieldList,
bool isPrivate,
IEnumerable<Guid> accessList,
bool isNotify)
{
var deal = new Deal
{
Title = title,
Description = description,
ResponsibleID = responsibleid,
BidType = bidType,
BidValue = bidValue,
PerPeriodValue = perPeriodValue,
DealMilestoneID = stageid,
DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability),
ContactID = contactid,
ActualCloseDate = actualCloseDate,
ExpectedCloseDate = expectedCloseDate,
BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null,
};
CRMSecurity.DemandCreateOrUpdate(deal);
deal.ID = DaoFactory.GetDealDao().CreateNewDeal(deal);
deal.CreateBy = SecurityContext.CurrentAccount.ID;
deal.CreateOn = DateTime.UtcNow;
SetAccessToDeal(deal, isPrivate, accessList, isNotify, false);
var membersList = members != null ? members.ToList() : new List<int>();
if (deal.ContactID > 0)
membersList.Add(deal.ContactID);
if (membersList.Any())
{
var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList();
membersList = contacts.Select(m => m.ID).ToList();
DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray());
}
if (customFieldList != null)
{
var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList();
foreach (var field in customFieldList)
{
if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue;
DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value);
}
}
return ToOpportunityWrapper(deal);
}
/// <summary>
/// Updates the selected opportunity with the parameters specified in the request
/// </summary>
/// <short>Update opportunity</short>
///<param name="opportunityid">Opportunity ID</param>
///<param name="contactid">Opportunity primary contact</param>
/// <param optional="true" name="members">Participants</param>
/// <param name="title">Opportunity title</param>
/// <param optional="true" name="description">Opportunity description</param>
/// <param name="responsibleid">Opportunity responsible</param>
/// <param name="bidType" remark="Allowed values: FixedBid, PerHour, PerDay,PerWeek, PerMonth, PerYear">Bid</param>
/// <param optional="true" name="bidValue">Amount of transaction</param>
/// <param optional="true" name="bidCurrencyAbbr">Currency (Abbreviation)</param>
/// <param name="perPeriodValue">Period</param>
/// <param name="stageid">Stage ID</param>
/// <param optional="true" name="successProbability">Opportunity success probability</param>
/// <param optional="true" name="actualCloseDate">Actual opportunity closure date</param>
/// <param optional="true" name="expectedCloseDate">Expected opportunity closure date</param>
/// <param optional="true" name="customFieldList">User field list</param>
/// <param name="isPrivate">Opportunity privacy: private or not</param>
/// <param optional="true" name="accessList">List of users with access to the opportunity</param>
/// <param name="isNotify" optional="true">Notify users in accessList about the opportunity</param>
/// <category>Opportunities</category>
/// <returns>
/// Opportunity
/// </returns>
///<exception cref="ArgumentException"></exception>
[Update(@"opportunity/{opportunityid:int}")]
public OpportunityWrapper UpdateDeal(
int opportunityid,
int contactid,
IEnumerable<int> members,
string title,
string description,
Guid responsibleid,
BidType bidType,
decimal bidValue,
string bidCurrencyAbbr,
int perPeriodValue,
int stageid,
int successProbability,
ApiDateTime actualCloseDate,
ApiDateTime expectedCloseDate,
IEnumerable<ItemKeyValuePair<int, string>> customFieldList,
bool isPrivate,
IEnumerable<Guid> accessList,
bool isNotify)
{
var deal = DaoFactory.GetDealDao().GetByID(opportunityid);
if (deal == null) throw new ItemNotFoundException();
deal.Title = title;
deal.Description = description;
deal.ResponsibleID = responsibleid;
deal.BidType = bidType;
deal.BidValue = bidValue;
deal.PerPeriodValue = perPeriodValue;
deal.DealMilestoneID = stageid;
deal.DealMilestoneProbability = successProbability < 0 ? 0 : (successProbability > 100 ? 100 : successProbability);
deal.ContactID = contactid;
deal.ActualCloseDate = actualCloseDate;
deal.ExpectedCloseDate = expectedCloseDate;
deal.BidCurrency = !String.IsNullOrEmpty(bidCurrencyAbbr) ? bidCurrencyAbbr.ToUpper() : null;
CRMSecurity.DemandCreateOrUpdate(deal);
DaoFactory.GetDealDao().EditDeal(deal);
deal = DaoFactory.GetDealDao().GetByID(opportunityid);
var membersList = members != null ? members.ToList() : new List<int>();
if (membersList.Any())
{
var contacts = DaoFactory.GetContactDao().GetContacts(membersList.ToArray()).Where(CRMSecurity.CanAccessTo).ToList();
membersList = contacts.Select(m => m.ID).ToList();
DaoFactory.GetDealDao().SetMembers(deal.ID, membersList.ToArray());
}
if (CRMSecurity.IsAdmin || deal.CreateBy == SecurityContext.CurrentAccount.ID)
{
SetAccessToDeal(deal, isPrivate, accessList, isNotify, false);
}
if (customFieldList != null)
{
var existingCustomFieldList = DaoFactory.GetCustomFieldDao().GetFieldsDescription(EntityType.Opportunity).Select(fd => fd.ID).ToList();
foreach (var field in customFieldList)
{
if (string.IsNullOrEmpty(field.Value) || !existingCustomFieldList.Contains(field.Key)) continue;
DaoFactory.GetCustomFieldDao().SetFieldValue(EntityType.Opportunity, deal.ID, field.Key, field.Value);
}
}
return ToOpportunityWrapper(deal);
}
/// <summary>
/// Returns the list of all contacts associated with the opportunity with the ID specified in the request
/// </summary>
/// <param name="opportunityid">Opportunity ID</param>
/// <short>Get all opportunity contacts</short>
/// <category>Opportunities</category>
/// <returns>Contact list</returns>
///<exception cref="ArgumentException"></exception>
///<exception cref="ItemNotFoundException"></exception>
[Read(@"opportunity/{opportunityid:int}/contact")]
public IEnumerable<ContactWrapper> GetDealMembers(int opportunityid)
{
var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid);
if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException();
var contactIDs = DaoFactory.GetDealDao().GetMembers(opportunityid);
if (contactIDs == null) return new ItemList<ContactWrapper>();
var result = ToListContactWrapper(DaoFactory.GetContactDao().GetContacts(contactIDs)).ToList();
result.ForEach(item => { if (item.ID == opportunity.ContactID) item.CanEdit = false; });
return result;
}
/// <summary>
/// Adds the selected contact to the opportunity with the ID specified in the request
/// </summary>
/// <param name="opportunityid">Opportunity ID</param>
/// <param name="contactid">Contact ID</param>
/// <short>Add opportunity contact</short>
/// <category>Opportunities</category>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Participant
/// </returns>
[Create(@"opportunity/{opportunityid:int}/contact/{contactid:int}")]
public ContactWrapper AddMemberToDeal(int opportunityid, int contactid)
{
if (opportunityid <= 0 || contactid <= 0) throw new ArgumentException();
var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid);
if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException();
var result = ToContactWrapper(contact);
DaoFactory.GetDealDao().AddMember(opportunityid, contactid);
var messageAction = contact is Company ? MessageAction.OpportunityLinkedCompany : MessageAction.OpportunityLinkedPerson;
MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle());
return result;
}
/// <summary>
/// Deletes the selected contact from the opportunity with the ID specified in the request
/// </summary>
/// <param name="opportunityid">Opportunity ID</param>
/// <param name="contactid">Contact ID</param>
/// <short>Delete opportunity contact</short>
/// <category>Opportunities</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Participant
/// </returns>
[Delete(@"opportunity/{opportunityid:int}/contact/{contactid:int}")]
public ContactWrapper DeleteMemberFromDeal(int opportunityid, int contactid)
{
if ((opportunityid <= 0) || (contactid <= 0)) throw new ArgumentException();
var opportunity = DaoFactory.GetDealDao().GetByID(opportunityid);
if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity)) throw new ItemNotFoundException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanAccessTo(contact)) throw new ItemNotFoundException();
var result = ToContactWrapper(contact);
DaoFactory.GetDealDao().RemoveMember(opportunityid, contactid);
var messageAction = contact is Company ? MessageAction.OpportunityUnlinkedCompany : MessageAction.OpportunityUnlinkedPerson;
MessageService.Send( messageAction, MessageTarget.Create(opportunity.ID), opportunity.Title, contact.GetTitle());
return result;
}
/// <summary>
/// Returns the list of 30 opportunities in the CRM module with prefix
/// </summary>
/// <param optional="true" name="prefix"></param>
/// <param optional="true" name="contactID"></param>
/// <param optional="true" name="internalSearch"></param>
/// <category>Opportunities</category>
/// <returns>
/// Opportunities list
/// </returns>
/// <visible>false</visible>
[Read(@"opportunity/byprefix")]
public IEnumerable<OpportunityWrapper> GetDealsByPrefix(string prefix, int contactID, bool internalSearch = true)
{
var result = new List<OpportunityWrapper>();
if (contactID > 0 && internalSearch)
{
var findedDeals = DaoFactory.GetDealDao().GetDealsByContactID(contactID);
foreach (var item in findedDeals)
{
if (item.Title.IndexOf(prefix, StringComparison.Ordinal) != -1)
{
result.Add(ToOpportunityWrapper(item));
}
}
ApiContext.SetTotalCount(result.Count);
}
else
{
const int maxItemCount = 30;
var findedDeals = DaoFactory.GetDealDao().GetDealsByPrefix(prefix, 0, maxItemCount, contactID, internalSearch);
foreach (var item in findedDeals)
{
result.Add(ToOpportunityWrapper(item));
}
}
return result;
}
/// <summary>
/// Returns the list of all contact opportunities
/// </summary>
/// <param optional="true" name="contactid">Contact ID</param>
/// <short>Get opportunity list</short>
/// <category>Opportunities</category>
/// <returns>
/// Opportunity list
/// </returns>
[Read(@"opportunity/bycontact/{contactid:int}")]
public IEnumerable<OpportunityWrapper> GetDeals(int contactid)
{
var deals = DaoFactory.GetDealDao().GetDealsByContactID(contactid);
return ToListOpportunityWrapper(deals);
}
/// <visible>false</visible>
[Update(@"opportunity/{opportunityid:int}/creationdate")]
public void SetDealCreationDate(int opportunityid, ApiDateTime creationDate)
{
var dao = DaoFactory.GetDealDao();
var opportunity = dao.GetByID(opportunityid);
if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity))
throw new ItemNotFoundException();
dao.SetDealCreationDate(opportunityid, creationDate);
}
/// <visible>false</visible>
[Update(@"opportunity/{opportunityid:int}/lastmodifeddate")]
public void SetDealLastModifedDate(int opportunityid, ApiDateTime lastModifedDate)
{
var dao = DaoFactory.GetDealDao();
var opportunity = dao.GetByID(opportunityid);
if (opportunity == null || !CRMSecurity.CanAccessTo(opportunity))
throw new ItemNotFoundException();
dao.SetDealLastModifedDate(opportunityid, lastModifedDate);
}
private IEnumerable<OpportunityWrapper> ToListOpportunityWrapper(ICollection<Deal> deals)
{
if (deals == null || deals.Count == 0) return new List<OpportunityWrapper>();
var result = new List<OpportunityWrapper>();
var contactIDs = new List<int>();
var dealIDs = new List<int>();
var dealMilestoneIDs = new List<int>();
foreach (var deal in deals)
{
contactIDs.Add(deal.ContactID);
dealIDs.Add(deal.ID);
dealMilestoneIDs.Add(deal.DealMilestoneID);
}
dealMilestoneIDs = dealMilestoneIDs.Distinct().ToList();
var contacts = new Dictionary<int, ContactBaseWrapper>();
var customFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, dealIDs.ToArray())
.GroupBy(item => item.EntityID)
.ToDictionary(item => item.Key, item => item.Select(ToCustomFieldBaseWrapper));
var dealMilestones = DaoFactory.GetDealMilestoneDao().GetAll(dealMilestoneIDs.ToArray())
.ToDictionary(item => item.ID, item => new DealMilestoneBaseWrapper(item));
var dealMembers = DaoFactory.GetDealDao().GetMembers(dealIDs.ToArray());
foreach (var value in dealMembers.Values)
{
contactIDs.AddRange(value);
}
contactIDs = contactIDs.Distinct().ToList();
if (contactIDs.Count > 0)
{
DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ForEach(item =>
{
if (item == null) return;
contacts.Add(item.ID, ToContactBaseWrapper(item));
});
}
foreach (var deal in deals)
{
var dealWrapper = new OpportunityWrapper(deal);
if (contacts.ContainsKey(deal.ContactID))
{
dealWrapper.Contact = contacts[deal.ContactID];
}
dealWrapper.CustomFields = customFields.ContainsKey(deal.ID)
? customFields[deal.ID]
: new List<CustomFieldBaseWrapper>();
dealWrapper.Members = dealMembers.ContainsKey(dealWrapper.ID)
? dealMembers[dealWrapper.ID].Where(contacts.ContainsKey).Select(item => contacts[item])
: new List<ContactBaseWrapper>();
if (dealMilestones.ContainsKey(deal.DealMilestoneID))
{
dealWrapper.Stage = dealMilestones[deal.DealMilestoneID];
}
dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal);
if (dealWrapper.IsPrivate)
{
dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal).Select(item => EmployeeWraper.Get(item.Key)).ToItemList();
}
if (!string.IsNullOrEmpty(deal.BidCurrency))
{
dealWrapper.BidCurrency = ToCurrencyInfoWrapper(CurrencyProvider.Get(deal.BidCurrency));
}
result.Add(dealWrapper);
}
return result;
}
private OpportunityWrapper ToOpportunityWrapper(Deal deal)
{
var dealWrapper = new OpportunityWrapper(deal);
if (deal.ContactID > 0)
dealWrapper.Contact = ToContactBaseWrapper(DaoFactory.GetContactDao().GetByID(deal.ContactID));
if (deal.DealMilestoneID > 0)
{
var dealMilestone = DaoFactory.GetDealMilestoneDao().GetByID(deal.DealMilestoneID);
if (dealMilestone == null)
throw new ItemNotFoundException();
dealWrapper.Stage = new DealMilestoneBaseWrapper(dealMilestone);
}
dealWrapper.AccessList = CRMSecurity.GetAccessSubjectTo(deal)
.Select(item => EmployeeWraper.Get(item.Key)).ToItemList();
dealWrapper.IsPrivate = CRMSecurity.IsPrivate(deal);
if (!string.IsNullOrEmpty(deal.BidCurrency))
dealWrapper.BidCurrency = ToCurrencyInfoWrapper(CurrencyProvider.Get(deal.BidCurrency));
dealWrapper.CustomFields = DaoFactory.GetCustomFieldDao().GetEnityFields(EntityType.Opportunity, deal.ID, false).ConvertAll(item => new CustomFieldBaseWrapper(item)).ToSmartList();
dealWrapper.Members = new List<ContactBaseWrapper>();
var memberIDs = DaoFactory.GetDealDao().GetMembers(deal.ID);
var membersList = DaoFactory.GetContactDao().GetContacts(memberIDs);
var membersWrapperList = new List<ContactBaseWrapper>();
foreach (var member in membersList)
{
if (member == null) continue;
membersWrapperList.Add(ToContactBaseWrapper(member));
}
dealWrapper.Members = membersWrapperList;
return dealWrapper;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,846 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.CRM.Wrappers;
using ASC.Common.Web;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Services.NotifyService;
using ASC.Web.Files.Classes;
using ASC.Web.Files.Utils;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Mime;
using System.Text;
using System.Text.RegularExpressions;
using OrderBy = ASC.CRM.Core.Entities.OrderBy;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Returns the list of all events matching the parameters specified in the request
/// </summary>
/// <short>
/// Get event list
/// </short>
/// <category>History</category>
/// <param optional="true" name="entityType" remark="Allowed values: opportunity, contact or case">Related entity type</param>
/// <param optional="true" name="entityId">Related entity ID</param>
/// <param optional="true" name="categoryId">Task category ID</param>
/// <param optional="true" name="createBy">Event author</param>
/// <param optional="true" name="fromDate">Earliest task due date</param>
/// <param optional="true" name="toDate">Latest task due date</param>
/// <returns>
/// Event list
/// </returns>
[Read(@"history/filter")]
public IEnumerable<RelationshipEventWrapper> GetHistory(
string entityType,
int entityId,
int categoryId,
Guid createBy,
ApiDateTime fromDate,
ApiDateTime toDate)
{
var entityTypeObj = ToEntityType(entityType);
switch (entityTypeObj) {
case EntityType.Contact:
var contact = DaoFactory.GetContactDao().GetByID(entityId);
if (contact == null || !CRMSecurity.CanAccessTo(contact))
throw new ItemNotFoundException();
break;
case EntityType.Case:
var cases = DaoFactory.GetCasesDao().GetByID(entityId);
if (cases == null || !CRMSecurity.CanAccessTo(cases))
throw new ItemNotFoundException();
break;
case EntityType.Opportunity:
var deal = DaoFactory.GetDealDao().GetByID(entityId);
if (deal == null || !CRMSecurity.CanAccessTo(deal))
throw new ItemNotFoundException();
break;
default:
if (entityId != 0)
{
throw new ArgumentException();
}
break;
}
RelationshipEventByType eventByType;
IEnumerable<RelationshipEventWrapper> result;
OrderBy eventOrderBy;
if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out eventByType))
{
eventOrderBy = new OrderBy(eventByType, !ApiContext.SortDescending);
}
else if (string.IsNullOrEmpty(ApiContext.SortBy))
{
eventOrderBy = new OrderBy(RelationshipEventByType.Created, false);
}
else
{
eventOrderBy = null;
}
if (eventOrderBy != null)
{
result = ToListRelationshipEventWrapper(DaoFactory.GetRelationshipEventDao().GetItems(
ApiContext.FilterValue,
entityTypeObj,
entityId,
createBy,
categoryId,
fromDate,
toDate,
(int)ApiContext.StartIndex,
(int)ApiContext.Count,
eventOrderBy));
ApiContext.SetDataPaginated();
ApiContext.SetDataFiltered();
ApiContext.SetDataSorted();
}
else
{
result = ToListRelationshipEventWrapper(DaoFactory.GetRelationshipEventDao().GetItems(
ApiContext.FilterValue,
entityTypeObj,
entityId,
createBy,
categoryId,
fromDate,
toDate,
0,
0,
null));
}
return result.ToSmartList();
}
/// <summary>
/// Deletes the event with the ID specified in the request and all the files associated with this event
/// </summary>
/// <short>
/// Delete event and related files
/// </short>
/// <category>History</category>
/// <param name="id">Event ID</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Event
/// </returns>
[Delete(@"history/{id:int}")]
public RelationshipEventWrapper DeleteHistory(int id)
{
if (id <= 0) throw new ArgumentException();
var item = DaoFactory.GetRelationshipEventDao().GetByID(id);
if (item == null) throw new ItemNotFoundException();
var wrapper = ToRelationshipEventWrapper(item);
DaoFactory.GetRelationshipEventDao().DeleteItem(id);
var messageAction = GetHistoryDeletedAction(item.EntityType, item.ContactID);
var entityTitle = wrapper.Contact == null ? wrapper.Entity.EntityTitle : wrapper.Contact.DisplayName;
MessageService.Send( messageAction, MessageTarget.Create(item.ID), entityTitle, wrapper.Category.Title);
return wrapper;
}
/// <summary>
/// Creates a text (.txt) file in the selected folder with the title and contents sent in the request
/// </summary>
/// <short>Create txt</short>
/// <category>Files</category>
/// <param name="entityType">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <param name="title">File title</param>
/// <param name="content">File contents</param>
/// <returns>
/// File info
/// </returns>
[Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/text")]
public FileWrapper CreateTextFile(string entityType, int entityid, string title, string content)
{
if (title == null) throw new ArgumentNullException("title");
if (content == null) throw new ArgumentNullException("content");
var folderid = GetRootFolderID();
FileWrapper result;
var extension = ".txt";
if (!string.IsNullOrEmpty(content))
{
if (Regex.IsMatch(content, @"<([^\s>]*)(\s[^<]*)>"))
{
extension = ".html";
}
}
using (var memStream = new MemoryStream(Encoding.UTF8.GetBytes(content)))
{
title = title.EndsWith(extension, StringComparison.OrdinalIgnoreCase) ? title : (title + extension);
result = SaveFile(folderid, memStream, title);
}
AttachFiles(entityType, entityid, new List<int> {(int)result.Id});
return result;
}
/// <summary>
/// Upload file
/// </summary>
/// <short>Upload file</short>
/// <category>Files</category>
/// <remarks>
/// <![CDATA[
/// Upload can be done in 2 different ways:
/// <ol>
/// <li>Single file upload. You should set Content-Type &amp; Content-Disposition header to specify filename and content type, and send file in request body</li>
/// <li>Using standart multipart/form-data method</li>
/// </ol>]]>
/// </remarks>
/// <param name="entityType">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <param name="file" visible="false">Request Input stream</param>
/// <param name="contentType" visible="false">Content-Type Header</param>
/// <param name="contentDisposition" visible="false">Content-Disposition Header</param>
/// <param name="files" visible="false">List of files when posted as multipart/form-data</param>
/// <param name="storeOriginalFileFlag" visible="false">If True, upload documents in original formats as well</param>
/// <returns>
/// File info
/// </returns>
[Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files/upload")]
public FileWrapper UploadFileInCRM(
string entityType,
int entityid,
Stream file,
ContentType contentType,
ContentDisposition contentDisposition,
IEnumerable<System.Web.HttpPostedFileBase> files,
bool storeOriginalFileFlag
)
{
FilesSettings.StoreOriginalFiles = storeOriginalFileFlag;
var folderid = GetRootFolderID();
var fileNames = new List<string>();
FileWrapper uploadedFile = null;
if (files != null && files.Any())
{
//For case with multiple files
foreach (var postedFile in files)
{
uploadedFile = SaveFile(folderid, postedFile.InputStream, postedFile.FileName);
fileNames.Add(uploadedFile.Title);
}
}
else if (file != null)
{
uploadedFile = SaveFile(folderid, file, contentDisposition.FileName);
fileNames.Add(uploadedFile.Title);
}
return uploadedFile;
}
private static FileWrapper SaveFile(object folderid, Stream file, string fileName)
{
var resultFile = FileUploader.Exec(folderid.ToString(), fileName, file.Length, file);
return new FileWrapper(resultFile);
}
/// <summary>
/// Creates the event with the parameters specified in the request
/// </summary>
/// <short>
/// Create event
/// </short>
/// <category>History</category>
/// <param optional="true" name="contactId">Contact ID</param>
/// <param optional="true" name="entityType" remark="Allowed values: opportunity or case">Related entity type</param>
/// <param optional="true" name="entityId">Related entity ID</param>
/// <remarks>
/// <![CDATA[
/// You should obligatorily set the value for 'contactId' if 'entityId' is not set or the value for parameters 'entityId' and 'entityType' if 'contactId' is not set.
/// ]]>
/// </remarks>
/// <param optional="false" name="content">Contents</param>
/// <param optional="false" name="categoryId">Category ID</param>
/// <param optional="true" name="created">Event creation date</param>
/// <param optional="true" name="fileId">List of IDs of the files associated with the event</param>
/// <param optional="true" name="notifyUserList">User field list</param>
/// <returns>
/// Created event
/// </returns>
[Create(@"history")]
public RelationshipEventWrapper AddHistoryTo(
string entityType,
int entityId,
int contactId,
string content,
int categoryId,
ApiDateTime created,
IEnumerable<int> fileId,
IEnumerable<Guid> notifyUserList)
{
if (!string.IsNullOrEmpty(entityType) &&
!(
string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0)
)
throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
var entityTitle = "";
if (contactId > 0) {
var contact = DaoFactory.GetContactDao().GetByID(contactId);
if (contact == null || !CRMSecurity.CanAccessTo(contact))
throw new ArgumentException();
entityTitle = contact.GetTitle();
}
if (entityTypeObj == EntityType.Case) {
var cases = DaoFactory.GetCasesDao().GetByID(entityId);
if (cases == null || !CRMSecurity.CanAccessTo(cases))
throw new ArgumentException();
if (contactId <= 0)
{
entityTitle = cases.Title;
}
}
if (entityTypeObj == EntityType.Opportunity)
{
var deal = DaoFactory.GetDealDao().GetByID(entityId);
if (deal == null || !CRMSecurity.CanAccessTo(deal))
throw new ArgumentException();
if (contactId <= 0)
{
entityTitle = deal.Title;
}
}
var relationshipEvent = new RelationshipEvent
{
CategoryID = categoryId,
EntityType = entityTypeObj,
EntityID = entityId,
Content = content,
ContactID = contactId,
CreateOn = created,
CreateBy = Core.SecurityContext.CurrentAccount.ID
};
var category = DaoFactory.GetListItemDao().GetByID(categoryId);
if (category == null) throw new ArgumentException();
var item = DaoFactory.GetRelationshipEventDao().CreateItem(relationshipEvent);
notifyUserList = notifyUserList != null ? notifyUserList.ToList() : new List<Guid>();
var needNotify = notifyUserList.Any();
var fileListInfoHashtable = new Hashtable();
if (fileId != null)
{
var fileIds = fileId.ToList();
var files = FilesDaoFactory.GetFileDao().GetFiles(fileIds.Cast<object>().ToArray());
if (needNotify)
{
foreach (var file in files)
{
var extension = Path.GetExtension(file.Title);
if (extension == null) continue;
var fileInfo = string.Format("{0} ({1})", file.Title, extension.ToUpper());
if (!fileListInfoHashtable.ContainsKey(fileInfo))
{
fileListInfoHashtable.Add(fileInfo, file.DownloadUrl);
}
else
{
fileInfo = string.Format("{0} ({1}, {2})", file.Title, extension.ToUpper(), file.UniqID);
fileListInfoHashtable.Add(fileInfo, file.DownloadUrl);
}
}
}
DaoFactory.GetRelationshipEventDao().AttachFiles(item.ID, fileIds.ToArray());
if (files.Any())
{
var fileAttachAction = GetFilesAttachAction(entityTypeObj, contactId);
MessageService.Send( fileAttachAction, MessageTarget.Create(item.ID), entityTitle, files.Select(x => x.Title));
}
}
if (needNotify)
{
NotifyClient.SendAboutAddRelationshipEventAdd(item, fileListInfoHashtable, DaoFactory, notifyUserList.ToArray());
}
var wrapper = ToRelationshipEventWrapper(item);
var historyCreatedAction = GetHistoryCreatedAction(entityTypeObj, contactId);
MessageService.Send( historyCreatedAction, MessageTarget.Create(item.ID), entityTitle, category.Title);
return wrapper;
}
/// <summary>
/// Associates the selected file(s) with the entity with the ID or type specified in the request
/// </summary>
/// <short>
/// Associate file with entity
/// </short>
/// <param name="entityType">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <param name="fileids">List of IDs of the files</param>
/// <category>Files</category>
/// <returns>Entity with the file attached</returns>
[Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files")]
public RelationshipEventWrapper AttachFiles(string entityType, int entityid, IEnumerable<int> fileids)
{
if (entityid <= 0 || fileids == null) throw new ArgumentException();
var files = FilesDaoFactory.GetFileDao().GetFiles(fileids.Cast<object>().ToArray());
var folderid = GetRootFolderID();
if (files.Exists(file => file.FolderID.ToString() != folderid.ToString()))
throw new ArgumentException("invalid file folder");
var entityTypeObj = ToEntityType(entityType);
DomainObject entityObj;
var entityTitle = GetEntityTitle(entityTypeObj, entityid, true, out entityObj);
switch (entityTypeObj)
{
case EntityType.Contact:
var relationshipEvent1 = DaoFactory.GetRelationshipEventDao().AttachFiles(entityid, EntityType.Any, 0, fileids.ToArray());
var messageAction = entityObj is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles;
MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title));
return ToRelationshipEventWrapper(relationshipEvent1);
case EntityType.Opportunity:
var relationshipEvent2 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray());
MessageService.Send( MessageAction.OpportunityAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title));
return ToRelationshipEventWrapper(relationshipEvent2);
case EntityType.Case:
var relationshipEvent3 = DaoFactory.GetRelationshipEventDao().AttachFiles(0, entityTypeObj, entityid, fileids.ToArray());
MessageService.Send( MessageAction.CaseAttachedFiles, MessageTarget.Create(entityid), entityTitle, files.Select(x => x.Title));
return ToRelationshipEventWrapper(relationshipEvent3);
default:
throw new ArgumentException();
}
}
/// <summary>
/// Returns the ID for the root folder used to store the files for the CRM module
/// </summary>
/// <short>Get root folder ID</short>
/// <category>Files</category>
/// <returns>
/// Root folder ID
/// </returns>
[Read(@"files/root")]
public object GetRootFolderID()
{
return DaoFactory.GetFileDao().GetRoot();
}
/// <summary>
/// Returns the list of all files for the entity with the ID or type specified in the request
/// </summary>
/// <param name="entityType">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <short>Get file list</short>
/// <category>Files</category>
/// <returns>
/// File list
/// </returns>
[Read(@"{entityType:(contact|opportunity|case)}/{entityid:int}/files")]
public IEnumerable<FileWrapper> GetFiles(string entityType, int entityid)
{
if (entityid <= 0) throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
switch (entityTypeObj)
{
case EntityType.Contact:
return DaoFactory.GetRelationshipEventDao().GetAllFiles(new[] {entityid}, EntityType.Any, 0).ConvertAll(file => new FileWrapper(file));
case EntityType.Opportunity:
case EntityType.Case:
return DaoFactory.GetRelationshipEventDao().GetAllFiles(null, entityTypeObj, entityid).ConvertAll(file => new FileWrapper(file));
default:
throw new ArgumentException();
}
}
/// <summary>
/// Deletes the file with the ID specified in the request
/// </summary>
/// <short>Delete file</short>
/// <category>Files</category>
/// <param name="fileid">File ID</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// File Info
/// </returns>
[Delete(@"files/{fileid:int}")]
public FileWrapper DeleteCRMFile(int fileid)
{
if (fileid < 0) throw new ArgumentException();
var file = FilesDaoFactory.GetFileDao().GetFile(fileid);
if (file == null) throw new ItemNotFoundException();
var result = new FileWrapper(file);
var _eventsDao = DaoFactory.GetRelationshipEventDao();
var eventIDs = _eventsDao.RemoveFile(file);
var events = new List<RelationshipEvent>();
eventIDs.ForEach(id => events.Add(_eventsDao.GetByID(id)));
foreach (var evt in events)
{
DomainObject entityObj;
var entityTitle = evt.ContactID > 0
? GetEntityTitle(EntityType.Contact, evt.ContactID, false, out entityObj)
: GetEntityTitle(evt.EntityType, evt.EntityID, false, out entityObj);
var messageAction = GetFilesDetachAction(evt.EntityType, evt.ContactID);
MessageService.Send( messageAction, MessageTarget.Create(file.ID), entityTitle, file.Title);
}
return result;
}
private IEnumerable<RelationshipEventWrapper> ToListRelationshipEventWrapper(List<RelationshipEvent> itemList)
{
if (itemList.Count == 0) return new List<RelationshipEventWrapper>();
var result = new List<RelationshipEventWrapper>();
var contactIDs = new List<int>();
var eventIDs = new List<int>();
var categoryIDs = new List<int>();
var entityWrappersIDs = new Dictionary<EntityType, List<int>>();
foreach (var item in itemList)
{
eventIDs.Add(item.ID);
if (!categoryIDs.Contains(item.CategoryID))
{
categoryIDs.Add(item.CategoryID);
}
if (item.ContactID > 0 && !contactIDs.Contains(item.ContactID))
{
contactIDs.Add(item.ContactID);
}
if (item.EntityID <= 0) continue;
if (!entityWrappersIDs.ContainsKey(item.EntityType))
{
entityWrappersIDs.Add(item.EntityType, new List<int>
{
item.EntityID
});
}
else if (!entityWrappersIDs[item.EntityType].Contains(item.EntityID))
{
entityWrappersIDs[item.EntityType].Add(item.EntityID);
}
}
var entityWrappers = new Dictionary<string, EntityWrapper>();
foreach (var entityType in entityWrappersIDs.Keys)
{
switch (entityType)
{
case EntityType.Opportunity:
DaoFactory.GetDealDao().GetDeals(entityWrappersIDs[entityType].Distinct().ToArray())
.ForEach(item =>
{
if (item == null) return;
entityWrappers.Add(
string.Format("{0}_{1}", (int)entityType, item.ID),
new EntityWrapper
{
EntityId = item.ID,
EntityTitle = item.Title,
EntityType = "opportunity"
});
});
break;
case EntityType.Case:
DaoFactory.GetCasesDao().GetByID(entityWrappersIDs[entityType].ToArray())
.ForEach(item =>
{
if (item == null) return;
entityWrappers.Add(
string.Format("{0}_{1}", (int)entityType, item.ID),
new EntityWrapper
{
EntityId = item.ID,
EntityTitle = item.Title,
EntityType = "case"
});
});
break;
default:
throw new ArgumentException();
}
}
var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => new HistoryCategoryBaseWrapper(x));
var files = DaoFactory.GetRelationshipEventDao().GetFiles(eventIDs.ToArray());
var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWrapper);
foreach (var item in itemList)
{
var eventObjWrap = new RelationshipEventWrapper(item);
if (contacts.ContainsKey(item.ContactID))
{
eventObjWrap.Contact = contacts[item.ContactID];
}
if (item.EntityID > 0)
{
var entityStrKey = string.Format("{0}_{1}", (int)item.EntityType, item.EntityID);
if (entityWrappers.ContainsKey(entityStrKey))
{
eventObjWrap.Entity = entityWrappers[entityStrKey];
}
}
eventObjWrap.Files = files.ContainsKey(item.ID) ? files[item.ID].ConvertAll(file => new FileWrapper(file)) : new List<FileWrapper>();
if (categories.ContainsKey(item.CategoryID))
{
eventObjWrap.Category = categories[item.CategoryID];
}
result.Add(eventObjWrap);
}
return result;
}
private RelationshipEventWrapper ToRelationshipEventWrapper(RelationshipEvent relationshipEvent)
{
var result = new RelationshipEventWrapper(relationshipEvent);
var historyCategory = DaoFactory.GetListItemDao().GetByID(relationshipEvent.CategoryID);
if (historyCategory != null)
{
result.Category = new HistoryCategoryBaseWrapper(historyCategory);
}
if (relationshipEvent.EntityID > 0)
{
result.Entity = ToEntityWrapper(relationshipEvent.EntityType, relationshipEvent.EntityID);
}
result.Files = DaoFactory.GetRelationshipEventDao().GetFiles(relationshipEvent.ID).ConvertAll(file => new FileWrapper(file));
if (relationshipEvent.ContactID > 0)
{
var relativeContact = DaoFactory.GetContactDao().GetByID(relationshipEvent.ContactID);
if (relativeContact != null)
{
result.Contact = ToContactBaseWrapper(relativeContact);
}
}
result.CanEdit = CRMSecurity.CanAccessTo(relationshipEvent);
return result;
}
private EntityWrapper ToEntityWrapper(EntityType entityType, int entityID)
{
if (entityID == 0) return null;
var result = new EntityWrapper
{
EntityId = entityID
};
switch (entityType)
{
case EntityType.Case:
var caseObj = DaoFactory.GetCasesDao().GetByID(entityID);
if (caseObj == null)
return null;
result.EntityType = "case";
result.EntityTitle = caseObj.Title;
break;
case EntityType.Opportunity:
var dealObj = DaoFactory.GetDealDao().GetByID(entityID);
if (dealObj == null)
return null;
result.EntityType = "opportunity";
result.EntityTitle = dealObj.Title;
break;
default:
return null;
}
return result;
}
private MessageAction GetHistoryCreatedAction(EntityType entityType, int contactId)
{
if (contactId > 0)
{
var contact = DaoFactory.GetContactDao().GetByID(contactId);
return contact is Company ? MessageAction.CompanyCreatedHistoryEvent : MessageAction.PersonCreatedHistoryEvent;
}
switch (entityType)
{
case EntityType.Opportunity:
return MessageAction.OpportunityCreatedHistoryEvent;
case EntityType.Case:
return MessageAction.CaseCreatedHistoryEvent;
case EntityType.Any:
var contact = DaoFactory.GetContactDao().GetByID(contactId);
return contact is Company ? MessageAction.CompanyCreatedHistoryEvent : MessageAction.PersonCreatedHistoryEvent;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private MessageAction GetHistoryDeletedAction(EntityType entityType, int contactId)
{
if (contactId > 0)
{
var contact = DaoFactory.GetContactDao().GetByID(contactId);
return contact is Company ? MessageAction.CompanyDeletedHistoryEvent : MessageAction.PersonDeletedHistoryEvent;
}
switch (entityType)
{
case EntityType.Opportunity:
return MessageAction.OpportunityDeletedHistoryEvent;
case EntityType.Case:
return MessageAction.CaseDeletedHistoryEvent;
case EntityType.Any:
var contact = DaoFactory.GetContactDao().GetByID(contactId);
return contact is Company ? MessageAction.CompanyDeletedHistoryEvent : MessageAction.PersonDeletedHistoryEvent;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private MessageAction GetFilesAttachAction(EntityType entityType, int contactId)
{
if (contactId > 0)
{
var contact = DaoFactory.GetContactDao().GetByID(contactId);
return contact is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles;
}
switch (entityType)
{
case EntityType.Opportunity:
return MessageAction.OpportunityAttachedFiles;
case EntityType.Case:
return MessageAction.CaseAttachedFiles;
case EntityType.Any:
var contact = DaoFactory.GetContactDao().GetByID(contactId);
return contact is Company ? MessageAction.CompanyAttachedFiles : MessageAction.PersonAttachedFiles;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private MessageAction GetFilesDetachAction(EntityType entityType, int contactId)
{
if (contactId > 0)
{
var contact = DaoFactory.GetContactDao().GetByID(contactId);
return contact is Company ? MessageAction.CompanyDetachedFile : MessageAction.PersonDetachedFile;
}
switch (entityType)
{
case EntityType.Opportunity:
return MessageAction.OpportunityDetachedFile;
case EntityType.Case:
return MessageAction.CaseDetachedFile;
case EntityType.Any:
var contact = DaoFactory.GetContactDao().GetByID(contactId);
return contact is Company ? MessageAction.CompanyDetachedFile : MessageAction.PersonAttachedFiles;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
}
}

View File

@ -0,0 +1,157 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.CRM.Core;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Classes;
using ASC.Web.Files.Services.DocumentService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>Returns a list of all user report files</summary>
/// <short>Get report files</short>
/// <category>Reports</category>
/// <returns>Report files</returns>
/// <exception cref="SecurityException">if user can't create reports</exception>
[Read(@"report/files")]
public IEnumerable<FileWrapper> GetFiles()
{
if (!Global.CanCreateReports)
throw CRMSecurity.CreateSecurityException();
var reportDao = DaoFactory.ReportDao;
var files = reportDao.GetFiles();
if (!files.Any())
{
var sampleSettings = CRMReportSampleSettings.LoadForCurrentUser();
if (sampleSettings.NeedToGenerate)
{
files = reportDao.SaveSampleReportFiles();
sampleSettings.NeedToGenerate = false;
sampleSettings.SaveForCurrentUser();
}
}
return files.ConvertAll(file => new FileWrapper(file)).OrderByDescending(file => file.Id);
}
/// <summary>Delete the report file with the ID specified in the request</summary>
/// <param name="fileid">File ID</param>
/// <short>Delete report file</short>
/// <category>Reports</category>
/// <exception cref="SecurityException">if user can't create reports</exception>
/// <exception cref="ArgumentException">if fileid les than 0</exception>
/// <exception cref="ItemNotFoundException">if file not found</exception>
[Delete(@"report/file/{fileid:int}")]
public void DeleteFile(int fileid)
{
if (!Global.CanCreateReports)
throw CRMSecurity.CreateSecurityException();
if (fileid < 0) throw new ArgumentException();
var file = DaoFactory.ReportDao.GetFile(fileid);
if (file == null) throw new ItemNotFoundException("File not found");
DaoFactory.ReportDao.DeleteFile(fileid);
}
/// <summary>Get the state of the report generation task</summary>
/// <short>Get report generation state</short>
/// <category>Reports</category>
/// <returns>Report state</returns>
/// <exception cref="SecurityException">if user can't create reports</exception>
[Read(@"report/status")]
public ReportState GetStatus()
{
if (!Global.CanCreateReports)
throw CRMSecurity.CreateSecurityException();
return DocbuilderReportsUtility.Status(ReportOrigin.CRM);
}
/// <summary>Terminate the report generation task</summary>
/// <short>Terminate report generation</short>
/// <category>Reports</category>
/// <exception cref="SecurityException">if user can't create reports</exception>
[Read(@"report/terminate")]
public void Terminate()
{
if (!Global.CanCreateReports)
throw CRMSecurity.CreateSecurityException();
DocbuilderReportsUtility.Terminate(ReportOrigin.CRM);
}
/// <summary>Check data availability for a report</summary>
/// <param name="type">Report type</param>
/// <param name="timePeriod">Time period</param>
/// <param name="managers">Managers</param>
/// <short>Check report data</short>
/// <category>Reports</category>
/// <returns>Object</returns>
/// <exception cref="SecurityException">if user can't create reports</exception>
[Create(@"report/check")]
public object CheckReportData(ReportType type, ReportTimePeriod timePeriod, Guid[] managers)
{
if (!Global.CanCreateReports)
throw CRMSecurity.CreateSecurityException();
return new
{
hasData = ReportHelper.CheckReportData(type, timePeriod, managers),
missingRates = ReportHelper.GetMissingRates(type)
};
}
/// <summary>Run the report generation task</summary>
/// <param name="type">Report type</param>
/// <param name="timePeriod">Time period</param>
/// <param name="managers">Managers</param>
/// <short>Generate report</short>
/// <category>Reports</category>
/// <returns>Report state</returns>
/// <exception cref="SecurityException">if user can't create reports</exception>
[Create(@"report/generate")]
public ReportState GenerateReport(ReportType type, ReportTimePeriod timePeriod, Guid[] managers)
{
if (!Global.CanCreateReports)
throw CRMSecurity.CreateSecurityException();
return ReportHelper.RunGenareteReport(type, timePeriod, managers);
}
}
}

View File

@ -0,0 +1,677 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.Api.CRM.Wrappers;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Returns the list of all tags associated with the entity with the ID and type specified in the request
/// </summary>
/// <param name="entityType" remark="Allowed values: contact,opportunity,case">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <short>Get entity tags</short>
/// <category>Tags</category>
/// <returns>
/// Tag
/// </returns>
///<exception cref="ArgumentException"></exception>
[Read(@"{entityType:(contact|opportunity|case)}/tag/{entityid:int}")]
public IEnumerable<string> GetEntityTags(string entityType, int entityid)
{
if (string.IsNullOrEmpty(entityType) || entityid <= 0) throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
switch (entityTypeObj) {
case EntityType.Contact:
case EntityType.Person:
case EntityType.Company:
var contact = DaoFactory.GetContactDao().GetByID(entityid);
if (contact == null || !CRMSecurity.CanAccessTo(contact))
throw new ItemNotFoundException();
break;
case EntityType.Case:
var cases = DaoFactory.GetCasesDao().GetByID(entityid);
if (cases == null || !CRMSecurity.CanAccessTo(cases))
throw new ItemNotFoundException();
break;
case EntityType.Opportunity:
var deal = DaoFactory.GetDealDao().GetByID(entityid);
if (deal == null || !CRMSecurity.CanAccessTo(deal))
throw new ItemNotFoundException();
break;
}
return DaoFactory.GetTagDao().GetEntityTags(entityTypeObj, entityid);
}
/// <summary>
/// Returns the list of all tags for the contact with the ID specified in the request
/// </summary>
/// <param name="contactid">Contact ID</param>
/// <short>Get all contact tags</short>
/// <category>Tags</category>
/// <returns>
/// List of contact tags
/// </returns>
///<exception cref="ArgumentException"></exception>
[Read(@"contact/{contactid:int}/tag")]
public IEnumerable<string> GetContactTags(int contactid)
{
if (contactid <= 0) throw new ArgumentException();
var contact = DaoFactory.GetContactDao().GetByID(contactid);
if (contact == null || !CRMSecurity.CanAccessTo(contact))
throw new ItemNotFoundException();
return DaoFactory.GetTagDao().GetEntityTags(EntityType.Contact, contactid).ToItemList();
}
/// <summary>
/// Creates the tag for the selected entity with the tag name specified in the request
/// </summary>
/// <param name="entityType" remark="Allowed values: contact,opportunity,case">Entity type</param>
/// <param name="tagName">Tag name</param>
/// <short>Create tag</short>
/// <category>Tags</category>
/// <returns>
/// Tag
/// </returns>
///<exception cref="ArgumentException"></exception>
[Create(@"{entityType:(contact|opportunity|case)}/tag")]
public string CreateTag(string entityType, string tagName)
{
if (string.IsNullOrEmpty(tagName)) throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
var messageAction = GetEntityTagCreatedAction(entityTypeObj);
DaoFactory.GetTagDao().AddTag(entityTypeObj, tagName);
MessageService.Send( messageAction, tagName);
return tagName;
}
/// <summary>
/// Returns the list of all tags associated with the entity type specified in the request
/// </summary>
/// <param name="entityType" remark="Allowed values: contact,opportunity,case">Entity type</param>
/// <short>Get tags for entity type</short>
/// <category>Tags</category>
/// <returns>
/// Tag
/// </returns>
///<exception cref="ArgumentException"></exception>
[Read(@"{entityType:(contact|opportunity|case)}/tag")]
public IEnumerable<TagWrapper> GetAllTags(string entityType)
{
if (string.IsNullOrEmpty(entityType)) throw new ArgumentException();
var entType = ToEntityType(entityType);
var tagTitles = DaoFactory.GetTagDao().GetAllTags(entType).ToList();
var relativeItemsCountArrayJSON = DaoFactory.GetTagDao().GetTagsLinkCount(entType).ToList();
if (tagTitles.Count != relativeItemsCountArrayJSON.Count) throw new ArgumentException();
var result = new List<TagWrapper>();
for (var i = 0; i < tagTitles.Count; i++) {
result.Add(new TagWrapper(tagTitles[i], relativeItemsCountArrayJSON[i]));
}
return result.OrderBy(x => x.Title.Trim(), StringComparer.OrdinalIgnoreCase).ToList();
}
/// <summary>
/// Adds a group of tags to the entity with the ID specified in the request
/// </summary>
/// <short>Add tag group to entity</short>
/// <category>Tags</category>
/// <param name="entityType" remark="Allowed values: contact,opportunity,case">Tag type</param>
/// <param name="entityid">Entity ID</param>
/// <param name="tagName">Tag name</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Tag
/// </returns>
[Create(@"{entityType:(contact|opportunity|case)}/taglist")]
public string AddTagToBatch(string entityType, IEnumerable<int> entityid, string tagName)
{
var ids = entityid.ToList();
if (entityid == null || !ids.Any()) throw new ArgumentException();
foreach (var entityID in ids)
{
AddTagTo(entityType, entityID, tagName);
}
return tagName;
}
/// <summary>
/// Adds the selected tag to the group of contacts with the parameters specified in the request
/// </summary>
/// <short>Add tag to contact group</short>
/// <category>Tags</category>
/// <param optional="true" name="tags">Tag</param>
/// <param optional="true" name="contactStage">Contact stage ID (warmth)</param>
/// <param optional="true" name="contactType">Contact type ID</param>
/// <param optional="true" name="contactListView" remark="Allowed values: Company, Person, WithOpportunity"></param>
/// <param optional="true" name="fromDate">Start date</param>
/// <param optional="true" name="toDate">End date</param>
/// <param name="tagName">Tag name</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Tag
/// </returns>
[Create(@"contact/filter/taglist")]
public string AddTagToBatchContacts(
IEnumerable<string> tags,
int contactStage,
int contactType,
ContactListViewType contactListView,
ApiDateTime fromDate,
ApiDateTime toDate,
string tagName)
{
var contacts = DaoFactory
.ContactDao
.GetContacts(ApiContext.FilterValue,
tags,
contactStage,
contactType,
contactListView,
fromDate,
toDate,
0,
0,
null).Where(CRMSecurity.CanEdit).ToList();
foreach (var contact in contacts)
{
AddTagTo("contact", contact.ID, tagName);
}
return tagName;
}
/// <summary>
/// Adds the selected tag to the group of opportunities with the parameters specified in the request
/// </summary>
/// <short>Add tag to opportunity group</short>
/// <category>Tags</category>
/// <param optional="true" name="responsibleid">Opportunity responsible</param>
/// <param optional="true" name="opportunityStagesid">Opportunity stage ID</param>
/// <param optional="true" name="tags">Tags</param>
/// <param optional="true" name="contactid">Contact ID</param>
/// <param optional="true" name="contactAlsoIsParticipant">Participation status: take into account opportunities where the contact is a participant or not</param>
/// <param optional="true" name="fromDate">Start date</param>
/// <param optional="true" name="toDate">End date</param>
/// <param optional="true" name="stageType" remark="Allowed values: {Open, ClosedAndWon, ClosedAndLost}">Opportunity stage type</param>
/// <param name="tagName">Tag name</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Tag
/// </returns>
[Create(@"opportunity/filter/taglist")]
public string AddTagToBatchDeals(
Guid responsibleid,
int opportunityStagesid,
IEnumerable<string> tags,
int contactid,
DealMilestoneStatus? stageType,
bool? contactAlsoIsParticipant,
ApiDateTime fromDate,
ApiDateTime toDate,
string tagName)
{
var deals = DaoFactory
.DealDao
.GetDeals(
ApiContext.FilterValue,
responsibleid,
opportunityStagesid,
tags,
contactid,
stageType,
contactAlsoIsParticipant,
fromDate, toDate, 0, 0, null).Where(CRMSecurity.CanAccessTo).ToList();
foreach (var deal in deals)
{
AddTagTo("opportunity", deal.ID, tagName);
}
return tagName;
}
/// <summary>
/// Adds the selected tag to the group of cases with the parameters specified in the request
/// </summary>
/// <short>Add tag to case group</short>
/// <category>Tags</category>
/// <param optional="true" name="contactid">Contact ID</param>
/// <param optional="true" name="isClosed">Case status</param>
/// <param optional="true" name="tags">Tags</param>
/// <param name="tagName">Tag name</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Tag
/// </returns>
[Create(@"case/filter/taglist")]
public string AddTagToBatchCases(int contactid, bool? isClosed, IEnumerable<string> tags, string tagName)
{
var caseses = DaoFactory.GetCasesDao().GetCases(ApiContext.FilterValue, contactid, isClosed, tags, 0, 0, null)
.Where(CRMSecurity.CanAccessTo).ToList();
if (!caseses.Any()) return tagName;
foreach (var casese in caseses)
{
AddTagTo("case", casese.ID, tagName);
}
return tagName;
}
/// <summary>
/// Deletes all the unused tags from the entities with the type specified in the request
/// </summary>
/// <short>Delete unused tags</short>
/// <category>Tags</category>
/// <param name="entityType" remark="Allowed values: contact,opportunity,case">Entity type</param>
/// <returns>Tags</returns>
[Delete(@"{entityType:(contact|opportunity|case)}/tag/unused")]
public IEnumerable<string> DeleteUnusedTag(string entityType)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var entityTypeObj = ToEntityType(entityType);
var result = DaoFactory.GetTagDao().GetUnusedTags(entityTypeObj);
DaoFactory.GetTagDao().DeleteUnusedTags(entityTypeObj);
return new List<string>(result);
}
/// <summary>
/// Adds the selected tag to the entity with the type and ID specified in the request
/// </summary>
/// <short>Add tag</short>
/// <category>Tags</category>
/// <param name="entityType" remark="Allowed values: contact,opportunity,case">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <param name="tagName">Tag name</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Tag
/// </returns>
[Create(@"{entityType:(contact|opportunity|case)}/{entityid:int}/tag")]
public string AddTagTo(string entityType, int entityid, string tagName)
{
if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
DomainObject entityObj;
var entityTitle = GetEntityTitle(entityTypeObj, entityid, true, out entityObj);
if (entityTypeObj == EntityType.Contact && !CRMSecurity.CanEdit(entityObj as Contact)) throw CRMSecurity.CreateSecurityException();
DaoFactory.GetTagDao().AddTagToEntity(entityTypeObj, entityid, tagName);
var messageAction = GetTagCreatedAction(entityTypeObj, entityid);
MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, tagName);
return tagName;
}
/// <summary>
/// Adds the selected tag to the entity (company or person) specified in the request and to all related contacts
/// </summary>
/// <short>Add tag</short>
/// <param name="entityType" remark="Allowed values: company,person">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <param name="tagName">Tag name</param>
/// <category>Tags</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <exception cref="Exception"></exception>
/// <returns>
/// Tag
/// </returns>
[Create(@"{entityType:(company|person)}/{entityid:int}/tag/group")]
public string AddContactTagToGroup(string entityType, int entityid, string tagName)
{
if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
if (entityTypeObj != EntityType.Company && entityTypeObj != EntityType.Person) throw new ArgumentException();
var contactInst = DaoFactory.GetContactDao().GetByID(entityid);
if (contactInst == null || !CRMSecurity.CanAccessTo(contactInst)) throw new ItemNotFoundException();
if (contactInst is Person && entityTypeObj == EntityType.Company) throw new Exception(CRMErrorsResource.ContactIsNotCompany);
if (contactInst is Company && entityTypeObj == EntityType.Person) throw new Exception(CRMErrorsResource.ContactIsNotPerson);
var contactIDsToAddTag = new List<int>();
if (contactInst is Company)
{
contactIDsToAddTag.Add(contactInst.ID);
var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(contactInst.ID);
foreach (var m in members)
{
if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0))
{
contactIDsToAddTag.Add(m.Key);
}
}
}
else
{
var CompanyID = ((Person)contactInst).CompanyID;
if (CompanyID != 0)
{
var cnt = DaoFactory.GetContactDao().GetByID(CompanyID);
if (cnt != null && cnt is Company && CRMSecurity.CanAccessTo(cnt))
{
contactIDsToAddTag.Add(CompanyID);
var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(CompanyID);
foreach (var m in members)
{
if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0))
{
contactIDsToAddTag.Add(m.Key);
}
}
}
else
{
contactIDsToAddTag.Add(contactInst.ID);
}
}
else
{
contactIDsToAddTag.Add(contactInst.ID);
}
}
DaoFactory.GetTagDao().AddTagToContacts(contactIDsToAddTag.ToArray(), tagName);
var entityTitle = contactInst.GetTitle();
var messageActions = GetTagCreatedGroupAction(entityTypeObj);
foreach (var messageAction in messageActions)
{
MessageService.Send( messageAction, MessageTarget.Create(contactInst.ID), entityTitle, tagName);
}
return tagName;
}
/// <summary>
/// Deletes the selected tag from the entity with the type specified in the request
/// </summary>
/// <short>Delete tag</short>
/// <param name="entityType" remark="Allowed values: contact,opportunity,case">Entity type</param>
/// <param name="tagName">Tag name</param>
/// <category>Tags</category>
/// <exception cref="ArgumentException"></exception>
///<exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Tag
/// </returns>
[Delete(@"{entityType:(contact|opportunity|case)}/tag")]
public string DeleteTag(string entityType, string tagName)
{
if (string.IsNullOrEmpty(entityType) || string.IsNullOrEmpty(tagName)) throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
if (!DaoFactory.GetTagDao().IsExist(entityTypeObj, tagName)) throw new ItemNotFoundException();
DaoFactory.GetTagDao().DeleteTag(entityTypeObj, tagName);
var messageAction = GetEntityTagDeletedAction(entityTypeObj);
MessageService.Send( messageAction, tagName);
return tagName;
}
/// <summary>
/// Deletes the selected tag from the entity with the type and ID specified in the request
/// </summary>
/// <short>Remove tag</short>
/// <category>Tags</category>
/// <param name="entityType" remark="Allowed values: contact,opportunity,case">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <param name="tagName">Tag name</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Tag
/// </returns>
[Delete(@"{entityType:(contact|opportunity|case)}/{entityid:int}/tag")]
public string DeleteTagFrom(string entityType, int entityid, string tagName)
{
if (string.IsNullOrEmpty(entityType) || entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
DomainObject entityObj;
var entityTitle = GetEntityTitle(entityTypeObj, entityid, true, out entityObj);
if (entityTypeObj == EntityType.Contact && !CRMSecurity.CanEdit(entityObj as Contact)) throw CRMSecurity.CreateSecurityException();
if (!DaoFactory.GetTagDao().IsExist(entityTypeObj, tagName)) throw new ItemNotFoundException();
DaoFactory.GetTagDao().DeleteTagFromEntity(entityTypeObj, entityid, tagName);
var messageAction = GetTagDeletedAction(entityTypeObj, entityid);
MessageService.Send( messageAction, MessageTarget.Create(entityid), entityTitle, tagName);
return tagName;
}
/// <summary>
/// Deletes the selected tag from the entity (company or person) specified in the request and from all related contacts
/// </summary>
/// <short>Delete tag</short>
/// <param name="entityType" remark="Allowed values: company,person">Entity type</param>
/// <param name="entityid">Entity ID</param>
/// <param name="tagName">Tag name</param>
/// <category>Tags</category>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <exception cref="Exception"></exception>
/// <returns>
/// Tag
/// </returns>
[Delete(@"{entityType:(company|person)}/{entityid:int}/tag/group")]
public string DeleteContactTagFromGroup(string entityType, int entityid, string tagName)
{
if (entityid <= 0 || string.IsNullOrEmpty(tagName)) throw new ArgumentException();
var entityTypeObj = ToEntityType(entityType);
if (entityTypeObj != EntityType.Company && entityTypeObj != EntityType.Person) throw new ArgumentException();
var contactInst = DaoFactory.GetContactDao().GetByID(entityid);
if (contactInst == null) throw new ItemNotFoundException();
if (contactInst is Person && entityTypeObj == EntityType.Company) throw new Exception(CRMErrorsResource.ContactIsNotCompany);
if (contactInst is Company && entityTypeObj == EntityType.Person) throw new Exception(CRMErrorsResource.ContactIsNotPerson);
var contactIDsForDeleteTag = new List<int>();
if (contactInst is Company)
{
contactIDsForDeleteTag.Add(contactInst.ID);
var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(contactInst.ID);
foreach (var m in members)
{
if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0))
{
contactIDsForDeleteTag.Add(m.Key);
}
}
}
else
{
var CompanyID = ((Person)contactInst).CompanyID;
if (CompanyID != 0)
{
var cnt = DaoFactory.GetContactDao().GetByID(CompanyID);
if (cnt != null && cnt is Company && CRMSecurity.CanAccessTo(cnt))
{
contactIDsForDeleteTag.Add(CompanyID);
var members = DaoFactory.GetContactDao().GetMembersIDsAndShareType(CompanyID);
foreach (var m in members)
{
if (CRMSecurity.CanAccessTo(m.Key, EntityType.Person, m.Value, 0))
{
contactIDsForDeleteTag.Add(m.Key);
}
}
}
else
{
contactIDsForDeleteTag.Add(contactInst.ID);
}
}
else
{
contactIDsForDeleteTag.Add(contactInst.ID);
}
}
DaoFactory.GetTagDao().DeleteTagFromContacts(contactIDsForDeleteTag.ToArray(), tagName);
return tagName;
}
private static MessageAction GetEntityTagCreatedAction(EntityType entityType)
{
switch (entityType)
{
case EntityType.Contact:
return MessageAction.ContactsCreatedTag;
case EntityType.Opportunity:
return MessageAction.OpportunitiesCreatedTag;
case EntityType.Case:
return MessageAction.CasesCreatedTag;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private static MessageAction GetEntityTagDeletedAction(EntityType entityType)
{
switch (entityType)
{
case EntityType.Contact:
return MessageAction.ContactsDeletedTag;
case EntityType.Opportunity:
return MessageAction.OpportunitiesDeletedTag;
case EntityType.Case:
return MessageAction.CasesDeletedTag;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private MessageAction GetTagCreatedAction(EntityType entityType, int entityId)
{
switch (entityType)
{
case EntityType.Contact:
var entity = DaoFactory.GetContactDao().GetByID(entityId);
return entity is Company ? MessageAction.CompanyCreatedTag : MessageAction.PersonCreatedTag;
case EntityType.Company:
return MessageAction.CompanyCreatedTag;
case EntityType.Person:
return MessageAction.PersonCreatedTag;
case EntityType.Opportunity:
return MessageAction.OpportunityCreatedTag;
case EntityType.Case:
return MessageAction.CaseCreatedTag;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private static IEnumerable<MessageAction> GetTagCreatedGroupAction(EntityType entityType)
{
switch (entityType)
{
case EntityType.Company:
return new List<MessageAction> {MessageAction.CompanyCreatedTag, MessageAction.CompanyCreatedPersonsTag};
case EntityType.Person:
return new List<MessageAction> {MessageAction.PersonCreatedTag, MessageAction.PersonCreatedCompanyTag};
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
private MessageAction GetTagDeletedAction(EntityType entityType, int entityId)
{
switch (entityType)
{
case EntityType.Contact:
var entity = DaoFactory.GetContactDao().GetByID(entityId);
return entity is Company ? MessageAction.CompanyDeletedTag : MessageAction.PersonDeletedTag;
case EntityType.Company:
return MessageAction.CompanyDeletedTag;
case EntityType.Person:
return MessageAction.PersonDeletedTag;
case EntityType.Opportunity:
return MessageAction.OpportunityDeletedTag;
case EntityType.Case:
return MessageAction.CaseDeletedTag;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
}
}

View File

@ -0,0 +1,387 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.CRM.Wrappers;
using ASC.Common.Web;
using ASC.CRM.Core.Entities;
using ASC.Web.Api.Routing;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Creates a new task template container with the type and title specified in the request
/// </summary>
/// <param name="entityType">Type</param>
/// <param name="title">Title</param>
/// <short>Create task template container</short>
/// <category>Task Templates</category>
/// <returns>
/// Task template container
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <visible>false</visible>
[Create(@"{entityType:(contact|person|company|opportunity|case)}/tasktemplatecontainer")]
public TaskTemplateContainerWrapper CreateTaskTemplateContainer(string entityType, string title)
{
if (string.IsNullOrEmpty(title)) throw new ArgumentException();
var taskTemplateContainer = new TaskTemplateContainer
{
EntityType = ToEntityType(entityType),
Title = title
};
taskTemplateContainer.ID = DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(taskTemplateContainer);
return ToTaskTemplateContainerWrapper(taskTemplateContainer);
}
/// <summary>
/// Returns the complete list of all the task template containers available on the portal
/// </summary>
/// <param name="entityType">Type</param>
/// <short>Get task template container list</short>
/// <category>Task Templates</category>
/// <returns>
/// Task template container list
/// </returns>
/// <visible>false</visible>
[Read(@"{entityType:(contact|person|company|opportunity|case)}/tasktemplatecontainer")]
public IEnumerable<TaskTemplateContainerWrapper> GetTaskTemplateContainers(string entityType)
{
return ToTaskListTemplateContainerWrapper(DaoFactory.GetTaskTemplateContainerDao().GetItems(ToEntityType(entityType)));
}
/// <summary>
/// Deletes the task template container with the ID specified in the request
/// </summary>
/// <param name="containerid">Task template container ID</param>
/// <short>Delete task template container</short>
/// <category>Task Templates</category>
/// <returns>
/// Deleted task template container
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <visible>false</visible>
[Delete(@"tasktemplatecontainer/{containerid:int}")]
public TaskTemplateContainerWrapper DeleteTaskTemplateContainer(int containerid)
{
if (containerid <= 0) throw new ArgumentException();
var result = ToTaskTemplateContainerWrapper(DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid));
if (result == null) throw new ItemNotFoundException();
DaoFactory.GetTaskTemplateContainerDao().Delete(containerid);
return result;
}
/// <summary>
/// Updates the task template container with the ID specified in the request
/// </summary>
/// <param name="containerid">Task template container ID</param>
/// <param name="title">Title</param>
/// <short>Update task template container</short>
/// <category>Task Templates</category>
/// <returns>
/// Task template container
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <visible>false</visible>
[Update(@"tasktemplatecontainer/{containerid:int}")]
public TaskTemplateContainerWrapper UpdateTaskTemplateContainer(int containerid, string title)
{
if (containerid <= 0 || string.IsNullOrEmpty(title)) throw new ArgumentException();
var result = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid);
if (result == null) throw new ItemNotFoundException();
result.Title = title;
DaoFactory.GetTaskTemplateContainerDao().SaveOrUpdate(result);
return ToTaskTemplateContainerWrapper(result);
}
/// <summary>
/// Returns the detailed information on the task template container with the ID specified in the request
/// </summary>
/// <param name="containerid">Task template container ID</param>
/// <short>Get task template container by ID</short>
/// <category>Task Templates</category>
/// <returns>
/// Task template container
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <visible>false</visible>
[Read(@"tasktemplatecontainer/{containerid:int}")]
public TaskTemplateContainerWrapper GetTaskTemplateContainerByID(int containerid)
{
if (containerid <= 0) throw new ArgumentException();
var item = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid);
if (item == null) throw new ItemNotFoundException();
return ToTaskTemplateContainerWrapper(item);
}
/// <summary>
/// Returns the list of all tasks in the container with the ID specified in the request
/// </summary>
/// <param name="containerid">Task template container ID</param>
/// <short>Get task template list by contaier ID</short>
/// <category>Task Templates</category>
/// <returns>
/// Task template list
/// </returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <visible>false</visible>
[Read(@"tasktemplatecontainer/{containerid:int}/tasktemplate")]
public IEnumerable<TaskTemplateWrapper> GetTaskTemplates(int containerid)
{
if (containerid <= 0) throw new ArgumentException();
var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid);
if (container == null) throw new ItemNotFoundException();
return DaoFactory.GetTaskTemplateDao().GetList(containerid).ConvertAll(ToTaskTemplateWrapper);
}
/// <summary>
/// Creates a new task template with the parameters specified in the request in the container with the selected ID
/// </summary>
/// <param name="containerid">Task template container ID</param>
/// <param name="title">Title</param>
/// <param name="description">Description</param>
/// <param name="responsibleid">Responsible ID</param>
/// <param name="categoryid">Category ID</param>
/// <param name="isNotify">Responsible notification: notify or not</param>
/// <param name="offsetTicks">Ticks offset</param>
/// <param name="deadLineIsFixed"></param>
/// <short>Create task template</short>
/// <category>Task Templates</category>
/// <returns>Task template</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <visible>false</visible>
[Create(@"tasktemplatecontainer/{containerid:int}/tasktemplate")]
public TaskTemplateWrapper CreateTaskTemplate(
int containerid,
string title,
string description,
Guid responsibleid,
int categoryid,
bool isNotify,
long offsetTicks,
bool deadLineIsFixed
)
{
if (containerid <= 0 || string.IsNullOrEmpty(title) || categoryid <= 0) throw new ArgumentException();
var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid);
if (container == null) throw new ItemNotFoundException();
var item = new TaskTemplate
{
CategoryID = categoryid,
ContainerID = containerid,
DeadLineIsFixed = deadLineIsFixed,
Description = description,
isNotify = isNotify,
ResponsibleID = responsibleid,
Title = title,
Offset = TimeSpan.FromTicks(offsetTicks)
};
item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item);
return ToTaskTemplateWrapper(item);
}
/// <summary>
/// Updates the selected task template with the parameters specified in the request in the container with the selected ID
/// </summary>
/// <param name="id">Task template ID</param>
/// <param name="containerid">Task template container ID</param>
/// <param name="title">Title</param>
/// <param name="description">Description</param>
/// <param name="responsibleid">Responsible ID</param>
/// <param name="categoryid">Category ID</param>
/// <param name="isNotify">Responsible notification: notify or not</param>
/// <param name="offsetTicks">Ticks offset</param>
/// <param name="deadLineIsFixed"></param>
/// <short>Update task template</short>
/// <category>Task Templates</category>
/// <returns>Task template</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <visible>false</visible>
[Update(@"tasktemplatecontainer/{containerid:int}/tasktemplate")]
public TaskTemplateWrapper UpdateTaskTemplate(
int id,
int containerid,
string title,
string description,
Guid responsibleid,
int categoryid,
bool isNotify,
long offsetTicks,
bool deadLineIsFixed
)
{
if (containerid <= 0 || string.IsNullOrEmpty(title) || categoryid <= 0) throw new ArgumentException();
var updatingItem = DaoFactory.GetTaskTemplateDao().GetByID(id);
if (updatingItem == null) throw new ItemNotFoundException();
var container = DaoFactory.GetTaskTemplateContainerDao().GetByID(containerid);
if (container == null) throw new ItemNotFoundException();
var item = new TaskTemplate
{
CategoryID = categoryid,
ContainerID = containerid,
DeadLineIsFixed = deadLineIsFixed,
Description = description,
isNotify = isNotify,
ResponsibleID = responsibleid,
Title = title,
ID = id,
Offset = TimeSpan.FromTicks(offsetTicks)
};
item.ID = DaoFactory.GetTaskTemplateDao().SaveOrUpdate(item);
return ToTaskTemplateWrapper(item);
}
/// <summary>
/// Deletes the task template with the ID specified in the request
/// </summary>
/// <param name="id">Task template ID</param>
/// <short>Delete task template</short>
/// <category>Task Templates</category>
/// <returns>Task template</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <visible>false</visible>
[Delete(@"tasktemplatecontainer/tasktemplate/{id:int}")]
public TaskTemplateWrapper DeleteTaskTemplate(int id)
{
if (id <= 0) throw new ArgumentException();
var taskTemplate = DaoFactory.GetTaskTemplateDao().GetByID(id);
if (taskTemplate == null) throw new ItemNotFoundException();
var result = ToTaskTemplateWrapper(taskTemplate);
DaoFactory.GetTaskTemplateDao().Delete(id);
return result;
}
/// <summary>
/// Return the task template with the ID specified in the request
/// </summary>
/// <param name="id">Task template ID</param>
/// <short>Get task template by ID</short>
/// <category>Task Templates</category>
/// <returns>Task template</returns>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <visible>false</visible>
[Read(@"tasktemplatecontainer/tasktemplate/{id:int}")]
public TaskTemplateWrapper GetTaskTemplateByID(int id)
{
if (id <= 0) throw new ArgumentException();
var taskTemplate = DaoFactory.GetTaskTemplateDao().GetByID(id);
if (taskTemplate == null) throw new ItemNotFoundException();
return ToTaskTemplateWrapper(taskTemplate);
}
protected TaskTemplateWrapper ToTaskTemplateWrapper(TaskTemplate taskTemplate)
{
return new TaskTemplateWrapper
{
Category = GetTaskCategoryByID(taskTemplate.CategoryID),
ContainerID = taskTemplate.ContainerID,
DeadLineIsFixed = taskTemplate.DeadLineIsFixed,
Description = taskTemplate.Description,
ID = taskTemplate.ID,
isNotify = taskTemplate.isNotify,
Title = taskTemplate.Title,
OffsetTicks = taskTemplate.Offset.Ticks,
Responsible = EmployeeWraper.Get(taskTemplate.ResponsibleID)
};
}
protected IEnumerable<TaskTemplateContainerWrapper> ToTaskListTemplateContainerWrapper(IEnumerable<TaskTemplateContainer> items)
{
var result = new List<TaskTemplateContainerWrapper>();
var taskTemplateDictionary = DaoFactory.GetTaskTemplateDao().GetAll()
.GroupBy(item => item.ContainerID)
.ToDictionary(x => x.Key, y => y.Select(ToTaskTemplateWrapper));
foreach (var item in items)
{
var taskTemplateContainer = new TaskTemplateContainerWrapper
{
Title = item.Title,
EntityType = item.EntityType.ToString(),
ID = item.ID
};
if (taskTemplateDictionary.ContainsKey(taskTemplateContainer.ID))
{
taskTemplateContainer.Items = taskTemplateDictionary[taskTemplateContainer.ID];
}
result.Add(taskTemplateContainer);
}
return result;
}
protected TaskTemplateContainerWrapper ToTaskTemplateContainerWrapper(TaskTemplateContainer item)
{
return ToTaskListTemplateContainerWrapper(new List<TaskTemplateContainer>
{
item
}).FirstOrDefault();
}
}
}

View File

@ -0,0 +1,699 @@
using ASC.Api.Core;
using ASC.Api.CRM.Wrappers;
using ASC.Common;
using ASC.Common.Web;
using ASC.CRM.Core;
using ASC.CRM.Core.Dao;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.CRM.Resources;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Classes;
using ASC.Web.CRM.Services.NotifyService;
using ASC.Web.Files.Services.WCFService;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Returns the detailed information about the task with the ID specified in the request
/// </summary>
/// <param name="taskid">Task ID</param>
/// <returns>Task</returns>
/// <short>Get task by ID</short>
/// <category>Tasks</category>
///<exception cref="ArgumentException"></exception>
///<exception cref="ItemNotFoundException"></exception>
[Read(@"task/{taskid:int}")]
public TaskWrapper GetTaskByID(int taskid)
{
if (taskid <= 0) throw new ArgumentException();
var task = DaoFactory.GetTaskDao().GetByID(taskid);
if (task == null) throw new ItemNotFoundException();
if (!CRMSecurity.CanAccessTo(task))
{
throw CRMSecurity.CreateSecurityException();
}
return TaskWrapperHelper.Get(task);
}
/// <summary>
/// Returns the list of tasks matching the creteria specified in the request
/// </summary>
/// <param optional="true" name="responsibleid">Task responsible</param>
/// <param optional="true" name="categoryid">Task category ID</param>
/// <param optional="true" name="isClosed">Show open or closed tasks only</param>
/// <param optional="true" name="fromDate">Earliest task due date</param>
/// <param optional="true" name="toDate">Latest task due date</param>
/// <param name="entityType" remark="Allowed values: opportunity, contact or case">Related entity type</param>
/// <param name="entityid">Related entity ID</param>
/// <exception cref="ArgumentException"></exception>
/// <short>Get task list</short>
/// <category>Tasks</category>
/// <returns>
/// Task list
/// </returns>
[Read(@"task/filter")]
public IEnumerable<TaskWrapper> GetAllTasks(
Guid responsibleid,
int categoryid,
bool? isClosed,
ApiDateTime fromDate,
ApiDateTime toDate,
string entityType,
int entityid)
{
TaskSortedByType taskSortedByType;
if (!string.IsNullOrEmpty(entityType) &&
!(
string.Compare(entityType, "contact", StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0)
)
throw new ArgumentException();
var searchText = ApiContext.FilterValue;
IEnumerable<TaskWrapper> result;
OrderBy taskOrderBy;
if (Web.CRM.Classes.EnumExtension.TryParse(ApiContext.SortBy, true, out taskSortedByType))
{
taskOrderBy = new OrderBy(taskSortedByType, !ApiContext.SortDescending);
}
else if (string.IsNullOrEmpty(ApiContext.SortBy))
{
taskOrderBy = new OrderBy(TaskSortedByType.DeadLine, true);
}
else
{
taskOrderBy = null;
}
var fromIndex = (int)ApiContext.StartIndex;
var count = (int)ApiContext.Count;
if (taskOrderBy != null)
{
result = ToTaskListWrapper(
DaoFactory.GetTaskDao()
.GetTasks(
searchText,
responsibleid,
categoryid,
isClosed,
fromDate,
toDate,
ToEntityType(entityType),
entityid,
fromIndex,
count,
taskOrderBy)).ToList();
ApiContext.SetDataPaginated();
ApiContext.SetDataFiltered();
ApiContext.SetDataSorted();
}
else
result = ToTaskListWrapper(
DaoFactory
.GetTaskDao()
.GetTasks(
searchText,
responsibleid,
categoryid,
isClosed,
fromDate,
toDate,
ToEntityType(entityType),
entityid,
0,
0, null)).ToList();
int totalCount;
if (result.Count() < count)
{
totalCount = fromIndex + result.Count();
}
else
{
totalCount = DaoFactory
.GetTaskDao()
.GetTasksCount(
searchText,
responsibleid,
categoryid,
isClosed,
fromDate,
toDate,
ToEntityType(entityType),
entityid);
}
ApiContext.SetTotalCount(totalCount);
return result;
}
/// <summary>
/// Open anew the task with the ID specified in the request
/// </summary>
/// <short>Resume task</short>
/// <category>Tasks</category>
/// <param name="taskid">Task ID</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Task
/// </returns>
[Update(@"task/{taskid:int}/reopen")]
public TaskWrapper ReOpenTask(int taskid)
{
if (taskid <= 0) throw new ArgumentException();
DaoFactory.GetTaskDao().OpenTask(taskid);
var task = DaoFactory.GetTaskDao().GetByID(taskid);
MessageService.Send(MessageAction.CrmTaskOpened, MessageTarget.Create(task.ID), task.Title);
return TaskWrapperHelper.Get(task);
}
/// <summary>
/// Close the task with the ID specified in the request
/// </summary>
/// <short>Close task</short>
/// <category>Tasks</category>
/// <param name="taskid">Task ID</param>
/// <exception cref="ArgumentException"></exception>
/// <returns>
/// Task
/// </returns>
[Update(@"task/{taskid:int}/close")]
public TaskWrapper CloseTask(int taskid)
{
if (taskid <= 0) throw new ArgumentException();
DaoFactory.GetTaskDao().CloseTask(taskid);
var task = DaoFactory.GetTaskDao().GetByID(taskid);
MessageService.Send(MessageAction.CrmTaskClosed, MessageTarget.Create(task.ID), task.Title);
return TaskWrapperHelper.Get(task);
}
/// <summary>
/// Delete the task with the ID specified in the request
/// </summary>
/// <short>Delete task</short>
/// <category>Tasks</category>
/// <param name="taskid">Task ID</param>
/// <exception cref="ArgumentException"></exception>
/// <exception cref="ItemNotFoundException"></exception>
/// <returns>
/// Deleted task
/// </returns>
[Delete(@"task/{taskid:int}")]
public TaskWrapper DeleteTask(int taskid)
{
if (taskid <= 0) throw new ArgumentException();
var task = DaoFactory.GetTaskDao().GetByID(taskid);
if (task == null) throw new ItemNotFoundException();
DaoFactory.GetTaskDao().DeleteTask(taskid);
MessageService.Send(MessageAction.CrmTaskDeleted, MessageTarget.Create(task.ID), task.Title);
return TaskWrapperHelper.Get(task);
}
/// <summary>
/// Creates the task with the parameters (title, description, due date, etc.) specified in the request
/// </summary>
/// <param name="title">Task title</param>
/// <param optional="true" name="description">Task description</param>
/// <param name="deadline">Task due date</param>
/// <param name="responsibleId">Task responsible ID</param>
/// <param name="categoryId">Task category ID</param>
/// <param optional="true" name="contactId">Contact ID</param>
/// <param optional="true" name="entityType" remark="Allowed values: opportunity or case">Related entity type</param>
/// <param optional="true" name="entityId">Related entity ID</param>
/// <param optional="true" name="isNotify">Notify the responsible about the task</param>
/// <param optional="true" name="alertValue">Time period in minutes for reminder to the responsible about the task</param>
/// <exception cref="ArgumentException"></exception>
/// <short>Create task</short>
/// <category>Tasks</category>
/// <returns>Task</returns>
[Create(@"task")]
public TaskWrapper CreateTask(
string title,
string description,
ApiDateTime deadline,
Guid responsibleId,
int categoryId,
int contactId,
string entityType,
int entityId,
bool isNotify,
int alertValue
)
{
if (!string.IsNullOrEmpty(entityType) &&
!(
string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0
)
|| categoryId <= 0)
throw new ArgumentException();
var listItem = DaoFactory.GetListItemDao().GetByID(categoryId);
if (listItem == null) throw new ItemNotFoundException(CRMErrorsResource.TaskCategoryNotFound);
var task = new Task
{
Title = title,
Description = description,
ResponsibleID = responsibleId,
CategoryID = categoryId,
DeadLine = deadline,
ContactID = contactId,
EntityType = ToEntityType(entityType),
EntityID = entityId,
IsClosed = false,
AlertValue = alertValue
};
task = DaoFactory.GetTaskDao().SaveOrUpdateTask(task);
if (isNotify)
{
Contact taskContact = null;
Cases taskCase = null;
Deal taskDeal = null;
if (task.ContactID > 0)
{
taskContact = DaoFactory.GetContactDao().GetByID(task.ContactID);
}
if (task.EntityID > 0)
{
switch (task.EntityType)
{
case EntityType.Case:
taskCase = DaoFactory.GetCasesDao().GetByID(task.EntityID);
break;
case EntityType.Opportunity:
taskDeal = DaoFactory.GetDealDao().GetByID(task.EntityID);
break;
}
}
NotifyClient.SendAboutResponsibleByTask(task, listItem.Title, taskContact, taskCase, taskDeal, null);
}
MessageService.Send(MessageAction.CrmTaskCreated, MessageTarget.Create(task.ID), task.Title);
return TaskWrapperHelper.Get(task);
}
/// <summary>
/// Creates the group of the same task with the parameters (title, description, due date, etc.) specified in the request for several contacts
/// </summary>
/// <param name="title">Task title</param>
/// <param optional="true" name="description">Task description</param>
/// <param name="deadline">Task due date</param>
/// <param name="responsibleId">Task responsible ID</param>
/// <param name="categoryId">Task category ID</param>
/// <param name="contactId">contact ID list</param>
/// <param optional="true" name="entityType" remark="Allowed values: opportunity or case">Related entity type</param>
/// <param optional="true" name="entityId">Related entity ID</param>
/// <param optional="true" name="isNotify">Notify the responsible about the task</param>
/// <param optional="true" name="alertValue">Time period in minutes for reminder to the responsible about the task</param>
/// <exception cref="ArgumentException"></exception>
/// <short>Create task list</short>
/// <category>Tasks</category>
/// <returns>Tasks</returns>
/// <visible>false</visible>
[Create(@"contact/task/group")]
public IEnumerable<TaskWrapper> CreateTaskGroup(
string title,
string description,
ApiDateTime deadline,
Guid responsibleId,
int categoryId,
int[] contactId,
string entityType,
int entityId,
bool isNotify,
int alertValue)
{
var tasks = new List<Task>();
if (
!string.IsNullOrEmpty(entityType) &&
!(string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0)
)
throw new ArgumentException();
foreach (var cid in contactId)
{
tasks.Add(new Task
{
Title = title,
Description = description,
ResponsibleID = responsibleId,
CategoryID = categoryId,
DeadLine = deadline,
ContactID = cid,
EntityType = ToEntityType(entityType),
EntityID = entityId,
IsClosed = false,
AlertValue = alertValue
});
}
tasks = DaoFactory.GetTaskDao().SaveOrUpdateTaskList(tasks).ToList();
string taskCategory = null;
if (isNotify)
{
if (categoryId > 0)
{
var listItem = DaoFactory.GetListItemDao().GetByID(categoryId);
if (listItem == null) throw new ItemNotFoundException();
taskCategory = listItem.Title;
}
}
for (var i = 0; i < tasks.Count; i++)
{
if (!isNotify) continue;
Contact taskContact = null;
Cases taskCase = null;
Deal taskDeal = null;
if (tasks[i].ContactID > 0)
{
taskContact = DaoFactory.GetContactDao().GetByID(tasks[i].ContactID);
}
if (tasks[i].EntityID > 0)
{
switch (tasks[i].EntityType)
{
case EntityType.Case:
taskCase = DaoFactory.GetCasesDao().GetByID(tasks[i].EntityID);
break;
case EntityType.Opportunity:
taskDeal = DaoFactory.GetDealDao().GetByID(tasks[i].EntityID);
break;
}
}
NotifyClient.SendAboutResponsibleByTask(tasks[i], taskCategory, taskContact, taskCase, taskDeal, null);
}
if (tasks.Any())
{
var contacts = DaoFactory.GetContactDao().GetContacts(contactId);
var task = tasks.First();
MessageService.Send( MessageAction.ContactsCreatedCrmTasks, MessageTarget.Create(tasks.Select(x => x.ID)), contacts.Select(x => x.GetTitle()), task.Title);
}
return ToTaskListWrapper(tasks);
}
/// <summary>
/// Updates the selected task with the parameters (title, description, due date, etc.) specified in the request
/// </summary>
/// <param name="taskid">Task ID</param>
/// <param name="title">Task title</param>
/// <param name="description">Task description</param>
/// <param name="deadline">Task due date</param>
/// <param name="responsibleid">Task responsible ID</param>
/// <param name="categoryid">Task category ID</param>
/// <param name="contactid">Contact ID</param>
/// <param name="entityType" remark="Allowed values: opportunity or case">Related entity type</param>
/// <param name="entityid">Related entity ID</param>
/// <param name="isNotify">Notify or not</param>
/// <param optional="true" name="alertValue">Time period in minutes for reminder to the responsible about the task</param>
/// <short> Update task</short>
/// <category>Tasks</category>
/// <returns>Task</returns>
[Update(@"task/{taskid:int}")]
public TaskWrapper UpdateTask(
int taskid,
string title,
string description,
ApiDateTime deadline,
Guid responsibleid,
int categoryid,
int contactid,
string entityType,
int entityid,
bool isNotify,
int alertValue)
{
if (!string.IsNullOrEmpty(entityType) &&
!(string.Compare(entityType, "opportunity", StringComparison.OrdinalIgnoreCase) == 0 ||
string.Compare(entityType, "case", StringComparison.OrdinalIgnoreCase) == 0
) || categoryid <= 0)
throw new ArgumentException();
var listItem = DaoFactory.GetListItemDao().GetByID(categoryid);
if (listItem == null) throw new ItemNotFoundException(CRMErrorsResource.TaskCategoryNotFound);
var task = new Task
{
ID = taskid,
Title = title,
Description = description,
DeadLine = deadline,
AlertValue = alertValue,
ResponsibleID = responsibleid,
CategoryID = categoryid,
ContactID = contactid,
EntityID = entityid,
EntityType = ToEntityType(entityType)
};
task = DaoFactory.GetTaskDao().SaveOrUpdateTask(task);
if (isNotify)
{
Contact taskContact = null;
Cases taskCase = null;
Deal taskDeal = null;
if (task.ContactID > 0)
{
taskContact = DaoFactory.GetContactDao().GetByID(task.ContactID);
}
if (task.EntityID > 0)
{
switch (task.EntityType)
{
case EntityType.Case:
taskCase = DaoFactory.GetCasesDao().GetByID(task.EntityID);
break;
case EntityType.Opportunity:
taskDeal = DaoFactory.GetDealDao().GetByID(task.EntityID);
break;
}
}
NotifyClient.SendAboutResponsibleByTask(task, listItem.Title, taskContact, taskCase, taskDeal, null);
}
MessageService.Send(MessageAction.CrmTaskUpdated, MessageTarget.Create(task.ID), task.Title);
return TaskWrapperHelper.Get(task);
}
/// <visible>false</visible>
[Update(@"task/{taskid:int}/creationdate")]
public void SetTaskCreationDate(int taskId, ApiDateTime creationDate)
{
var dao = DaoFactory.GetTaskDao();
var task = dao.GetByID(taskId);
if (task == null || !CRMSecurity.CanAccessTo(task))
throw new ItemNotFoundException();
dao.SetTaskCreationDate(taskId, creationDate);
}
/// <visible>false</visible>
[Update(@"task/{taskid:int}/lastmodifeddate")]
public void SetTaskLastModifedDate(int taskId, ApiDateTime lastModifedDate)
{
var dao = DaoFactory.GetTaskDao();
var task = dao.GetByID(taskId);
if (task == null || !CRMSecurity.CanAccessTo(task))
throw new ItemNotFoundException();
dao.SetTaskLastModifedDate(taskId, lastModifedDate);
}
private IEnumerable<TaskWrapper> ToTaskListWrapper(IEnumerable<Task> itemList)
{
var result = new List<TaskWrapper>();
var contactIDs = new List<int>();
var taskIDs = new List<int>();
var categoryIDs = new List<int>();
var entityWrappersIDs = new Dictionary<EntityType, List<int>>();
foreach (var item in itemList)
{
taskIDs.Add(item.ID);
if (!categoryIDs.Contains(item.CategoryID))
{
categoryIDs.Add(item.CategoryID);
}
if (item.ContactID > 0 && !contactIDs.Contains(item.ContactID))
{
contactIDs.Add(item.ContactID);
}
if (item.EntityID > 0)
{
if (item.EntityType != EntityType.Opportunity && item.EntityType != EntityType.Case) continue;
if (!entityWrappersIDs.ContainsKey(item.EntityType))
{
entityWrappersIDs.Add(item.EntityType, new List<int>
{
item.EntityID
});
}
else if (!entityWrappersIDs[item.EntityType].Contains(item.EntityID))
{
entityWrappersIDs[item.EntityType].Add(item.EntityID);
}
}
}
var entityWrappers = new Dictionary<string, EntityWrapper>();
foreach (var entityType in entityWrappersIDs.Keys)
{
switch (entityType)
{
case EntityType.Opportunity:
DaoFactory.GetDealDao().GetDeals(entityWrappersIDs[entityType].Distinct().ToArray())
.ForEach(item =>
{
if (item == null) return;
entityWrappers.Add(
string.Format("{0}_{1}", (int)entityType, item.ID),
new EntityWrapper
{
EntityId = item.ID,
EntityTitle = item.Title,
EntityType = "opportunity"
});
});
break;
case EntityType.Case:
DaoFactory.GetCasesDao().GetByID(entityWrappersIDs[entityType].ToArray())
.ForEach(item =>
{
if (item == null) return;
entityWrappers.Add(
string.Format("{0}_{1}", (int)entityType, item.ID),
new EntityWrapper
{
EntityId = item.ID,
EntityTitle = item.Title,
EntityType = "case"
});
});
break;
}
}
var categories = DaoFactory.GetListItemDao().GetItems(categoryIDs.ToArray()).ToDictionary(x => x.ID, x => new TaskCategoryBaseWrapper(x));
var contacts = DaoFactory.GetContactDao().GetContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWithEmailWrapper);
var restrictedContacts = DaoFactory.GetContactDao().GetRestrictedContacts(contactIDs.ToArray()).ToDictionary(item => item.ID, ToContactBaseWithEmailWrapper);
foreach (var item in itemList)
{
var taskWrapper = new TaskWrapper(item) { CanEdit = CRMSecurity.CanEdit(item) };
if (contacts.ContainsKey(item.ContactID))
{
taskWrapper.Contact = contacts[item.ContactID];
}
if (restrictedContacts.ContainsKey(item.ContactID))
{
taskWrapper.Contact = restrictedContacts[item.ContactID];
/*Hide some fields. Should be refactored! */
taskWrapper.Contact.Currency = null;
taskWrapper.Contact.Email = null;
taskWrapper.Contact.AccessList = null;
}
if (item.EntityID > 0)
{
var entityStrKey = string.Format("{0}_{1}", (int)item.EntityType, item.EntityID);
if (entityWrappers.ContainsKey(entityStrKey))
{
taskWrapper.Entity = entityWrappers[entityStrKey];
}
}
if (categories.ContainsKey(item.CategoryID))
{
taskWrapper.Category = categories[item.CategoryID];
}
result.Add(taskWrapper);
}
return result;
}
}
//public CRMController(CRMSecurity cRMSecurity,
// DaoFactory daoFactory,
// ApiContext apiContext,
// MessageTarget messageTarget,
// NotifyClient notifyClient,
// TaskWrapperHelper taskWrapperHelper)
}

View File

@ -0,0 +1,545 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Common.Threading.Progress;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.Core.Utility;
using ASC.Web.CRM.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
namespace ASC.Api.CRM
{
public partial class CRMController
{
/// <summary>
/// Returns the list of all currencies currently available on the portal
/// </summary>
/// <short>Get currency list</short>
/// <category>Common</category>
/// <returns>
/// List of available currencies
/// </returns>
[Read(@"settings/currency")]
public IEnumerable<CurrencyInfoWrapper> GetAvaliableCurrency()
{
return CurrencyProvider.GetAll().ConvertAll(item => new CurrencyInfoWrapper(item)).ToItemList();
}
/// <summary>
/// Returns the result of convertation from one currency to another
/// </summary>
/// <param name="amount">Amount to convert</param>
/// <param name="fromcurrency">Old currency key</param>
/// <param name="tocurrency">New currency key</param>
/// <short>Get the result of convertation</short>
/// <category>Common</category>
/// <returns>
/// Decimal result of convertation
/// </returns>
[Read(@"settings/currency/convert")]
public Decimal ConvertAmount(Decimal amount, String fromcurrency, String tocurrency)
{
return CurrencyProvider.MoneyConvert(amount, fromcurrency, tocurrency);
}
/// <summary>
/// Returns the summary table with rates for selected currency
/// </summary>
/// <param name="currency" remark="Allowed values: EUR, RUB etc. You can get the whole list of available currencies by api">Currency (Abbreviation)</param>
/// <short>Get the summary table</short>
/// <category>Common</category>
/// <returns>
/// Dictionary of currencies and rates
/// </returns>
/// <exception cref="ArgumentException"></exception>
[Read(@"settings/currency/summarytable")]
public IEnumerable<CurrencyRateInfoWrapper> GetSummaryTable(String currency)
{
var result = new List<CurrencyRateInfoWrapper>();
if (string.IsNullOrEmpty(currency))
{
throw new ArgumentException();
}
var cur = CurrencyProvider.Get(currency.ToUpper());
if (cur == null) throw new ArgumentException();
var table = CurrencyProvider.MoneyConvert(cur);
table.ToList().ForEach(tableItem => result.Add(ToCurrencyRateInfoWrapper(tableItem.Key, tableItem.Value)));
return result;
}
/// <summary>
///
/// </summary>
/// <param name="changeContactStatusGroupAuto" remark="true, false or null">Change contact status group auto</param>
/// <short></short>
/// <category>Contacts</category>
/// <returns>
/// ChangeContactStatusGroupAuto setting value (true, false or null)
/// </returns>
/// <exception cref="SecurityException"></exception>
[Update(@"contact/status/settings")]
public Boolean? UpdateCRMContactStatusSettings(Boolean? changeContactStatusGroupAuto)
{
var tenantSettings = Global.TenantSettings;
tenantSettings.ChangeContactStatusGroupAuto = changeContactStatusGroupAuto;
tenantSettings.Save();
MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated);
return changeContactStatusGroupAuto;
}
/// <summary>
///
/// </summary>
/// <param name="writeMailToHistoryAuto" remark="true or false">Write mail to history auto</param>
/// <short></short>
/// <category>Contacts</category>
/// <returns>
/// WriteMailToHistoryAuto setting value (true or false)
/// </returns>
/// <exception cref="SecurityException"></exception>
[Update(@"contact/mailtohistory/settings")]
public Boolean UpdateCRMWriteMailToHistorySettings(Boolean writeMailToHistoryAuto)
{
var tenantSettings = Global.TenantSettings;
tenantSettings.WriteMailToHistoryAuto = writeMailToHistoryAuto;
tenantSettings.Save();
//MessageService.Send( MessageAction.ContactTemperatureLevelSettingsUpdated);
return writeMailToHistoryAuto;
}
/// <summary>
///
/// </summary>
/// <param name="addTagToContactGroupAuto" remark="true, false or null">add tag to contact group auto</param>
/// <short></short>
/// <category>Contacts</category>
/// <returns>
/// AddTagToContactGroupAuto setting value (true, false or null)
/// </returns>
/// <exception cref="SecurityException"></exception>
[Update(@"contact/tag/settings")]
public Boolean? UpdateCRMContactTagSettings(Boolean? addTagToContactGroupAuto)
{
var tenantSettings = Global.TenantSettings;
tenantSettings.AddTagToContactGroupAuto = addTagToContactGroupAuto;
tenantSettings.Save();
MessageService.Send( MessageAction.ContactsTagSettingsUpdated);
return addTagToContactGroupAuto;
}
/// <summary>
/// Set IsConfiguredPortal tenant setting and website contact form key specified in the request
/// </summary>
/// <short>Set tenant settings</short>
/// <category>Common</category>
/// <returns>
/// IsConfiguredPortal setting value (true or false)
/// </returns>
[Update(@"settings")]
public Boolean SetIsPortalConfigured(Boolean? configured, Guid? webFormKey)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var tenantSettings = Global.TenantSettings;
tenantSettings.IsConfiguredPortal = configured ?? true;
tenantSettings.WebFormKey = webFormKey ?? Guid.NewGuid();
tenantSettings.Save();
return tenantSettings.IsConfiguredPortal;
}
/// <summary>
/// Save organisation company name
/// </summary>
/// <param name="companyName">Organisation company name</param>
/// <short>Save organisation company name</short>
/// <category>Organisation</category>
/// <returns>Organisation company name</returns>
/// <exception cref="SecurityException"></exception>
[Update(@"settings/organisation/base")]
public String UpdateOrganisationSettingsCompanyName(String companyName)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var tenantSettings = Global.TenantSettings;
if (tenantSettings.InvoiceSetting == null)
{
tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings;
}
tenantSettings.InvoiceSetting.CompanyName = companyName;
tenantSettings.Save();
MessageService.Send( MessageAction.OrganizationProfileUpdatedCompanyName, companyName);
return companyName;
}
/// <summary>
/// Save organisation company address
/// </summary>
/// <param name="street">Organisation company street/building/apartment address</param>
/// <param name="city">City</param>
/// <param name="state">State</param>
/// <param name="zip">Zip</param>
/// <param name="country">Country</param>
/// <short>Save organisation company address</short>
/// <category>Organisation</category>
/// <returns>Returns a JSON object with the organization company address details</returns>
/// <exception cref="SecurityException"></exception>
[Update(@"settings/organisation/address")]
public String UpdateOrganisationSettingsCompanyAddress(String street, String city, String state, String zip, String country)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var tenantSettings = Global.TenantSettings;
if (tenantSettings.InvoiceSetting == null)
{
tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings;
}
var companyAddress = Newtonsoft.Json.JsonConvert.SerializeObject(new
{
type = AddressCategory.Billing.ToString(),
street,
city,
state,
zip,
country
});
tenantSettings.InvoiceSetting.CompanyAddress = companyAddress;
tenantSettings.Save();
MessageService.Send( MessageAction.OrganizationProfileUpdatedAddress);
return companyAddress;
}
/// <summary>
/// Save organisation logo
/// </summary>
/// <param name="reset">Reset organisation logo</param>
/// <short>Save organisation logo</short>
/// <category>Organisation</category>
/// <returns>Organisation logo ID</returns>
/// <exception cref="SecurityException"></exception>
/// <exception cref="Exception"></exception>
[Update(@"settings/organisation/logo")]
public Int32 UpdateOrganisationSettingsLogo(bool reset)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
int companyLogoID;
if (!reset)
{
companyLogoID = OrganisationLogoManager.TryUploadOrganisationLogoFromTmp(DaoFactory);
if (companyLogoID == 0)
{
throw new Exception("Downloaded image not found");
}
}
else
{
companyLogoID = 0;
}
var tenantSettings = Global.TenantSettings;
if (tenantSettings.InvoiceSetting == null)
{
tenantSettings.InvoiceSetting = InvoiceSetting.DefaultSettings;
}
tenantSettings.InvoiceSetting.CompanyLogoID = companyLogoID;
tenantSettings.Save();
MessageService.Send( MessageAction.OrganizationProfileUpdatedInvoiceLogo);
return companyLogoID;
}
/// <summary>
/// Get organisation logo in base64 format (if 'id' is 0 then take current logo)
/// </summary>
/// <param name="id">organisation logo id</param>
/// <short>Get organisation logo</short>
/// <category>Organisation</category>
/// <returns>Organisation logo content in base64</returns>
/// <exception cref="Exception"></exception>
[Read(@"settings/organisation/logo")]
public String GetOrganisationSettingsLogo(int id)
{
if (id != 0)
{
return OrganisationLogoManager.GetOrganisationLogoBase64(id);
}
else
{
var tenantSettings = Global.TenantSettings;
if (tenantSettings.InvoiceSetting == null)
{
return string.Empty;
}
return OrganisationLogoManager.GetOrganisationLogoBase64(tenantSettings.InvoiceSetting.CompanyLogoID);
}
}
/// <summary>
/// Change Website Contact Form key
/// </summary>
/// <short>Change web form key</short>
/// <category>Common</category>
/// <returns>Web form key</returns>
/// <exception cref="SecurityException"></exception>
[Update(@"settings/webformkey/change")]
public string ChangeWebToLeadFormKey()
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
var tenantSettings = Global.TenantSettings;
tenantSettings.WebFormKey = Guid.NewGuid();
tenantSettings.Save();
MessageService.Send( MessageAction.WebsiteContactFormUpdatedKey);
return tenantSettings.WebFormKey.ToString();
}
/// <summary>
/// Change default CRM currency
/// </summary>
/// <param name="currency" remark="Allowed values: EUR, RUB etc. You can get the whole list of available currencies by api">Currency (Abbreviation)</param>
/// <short>Change currency</short>
/// <category>Common</category>
/// <returns>currency</returns>
/// <exception cref="SecurityException"></exception>
/// <exception cref="ArgumentException"></exception>
[Update(@"settings/currency")]
public CurrencyInfoWrapper UpdateCRMCurrency(String currency)
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
if (string.IsNullOrEmpty(currency))
{
throw new ArgumentException();
}
currency = currency.ToUpper();
var cur = CurrencyProvider.Get(currency);
if (cur == null) throw new ArgumentException();
Global.SaveDefaultCurrencySettings(cur);
MessageService.Send( MessageAction.CrmDefaultCurrencyUpdated);
return ToCurrencyInfoWrapper(cur);
}
/// <visible>false</visible>
[Create(@"{entityType:(contact|opportunity|case|task)}/import/start")]
public string StartImportFromCSV(string entityType, string csvFileURI, string jsonSettings)
{
EntityType entityTypeObj;
if (string.IsNullOrEmpty(entityType) || string.IsNullOrEmpty(csvFileURI) || string.IsNullOrEmpty(jsonSettings)) throw new ArgumentException();
switch (entityType.ToLower())
{
case "contact":
entityTypeObj = EntityType.Contact;
break;
case "opportunity":
entityTypeObj = EntityType.Opportunity;
break;
case "case":
entityTypeObj = EntityType.Case;
break;
case "task":
entityTypeObj = EntityType.Task;
break;
default:
throw new ArgumentException();
}
new ImportFromCSVManager().StartImport(entityTypeObj, csvFileURI, jsonSettings);
return "";
}
/// <visible>false</visible>
[Read(@"{entityType:(contact|opportunity|case|task)}/import/status")]
public IProgressItem GetImportFromCSVStatus(string entityType)
{
EntityType entityTypeObj;
if (string.IsNullOrEmpty(entityType)) throw new ArgumentException();
switch (entityType.ToLower())
{
case "contact":
entityTypeObj = EntityType.Contact;
break;
case "opportunity":
entityTypeObj = EntityType.Opportunity;
break;
case "case":
entityTypeObj = EntityType.Case;
break;
case "task":
entityTypeObj = EntityType.Task;
break;
default:
throw new ArgumentException();
}
return ImportFromCSV.GetStatus(entityTypeObj);
}
/// <visible>false</visible>
[Read(@"import/samplerow")]
public String GetImportFromCSVSampleRow(string csvFileURI, int indexRow, string jsonSettings)
{
if (String.IsNullOrEmpty(csvFileURI) || indexRow < 0) throw new ArgumentException();
if (!Global.GetStore().IsFile("temp", csvFileURI)) throw new ArgumentException();
var CSVFileStream = Global.GetStore().GetReadStream("temp", csvFileURI);
return ImportFromCSV.GetRow(CSVFileStream, indexRow, jsonSettings);
}
/// <visible>false</visible>
[Create(@"import/uploadfake")]
public FileUploadResult ProcessUploadFake(string csvFileURI, string jsonSettings)
{
return new ImportFromCSVManager().ProcessUploadFake(csvFileURI, jsonSettings);
}
/// <visible>false</visible>
[Read(@"export/status")]
public IProgressItem GetExportStatus()
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
return ExportToCsv.GetStatus(false);
}
/// <visible>false</visible>
[Update(@"export/cancel")]
public IProgressItem CancelExport()
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
ExportToCsv.Cancel(false);
return ExportToCsv.GetStatus(false);
}
/// <visible>false</visible>
[Create(@"export/start")]
public IProgressItem StartExport()
{
if (!CRMSecurity.IsAdmin) throw CRMSecurity.CreateSecurityException();
MessageService.Send( MessageAction.CrmAllDataExported);
return ExportToCsv.Start(null, CRMSettingResource.Export + ".zip");
}
/// <visible>false</visible>
[Read(@"export/partial/status")]
public IProgressItem GetPartialExportStatus()
{
return ExportToCsv.GetStatus(true);
}
/// <visible>false</visible>
[Update(@"export/partial/cancel")]
public IProgressItem CancelPartialExport()
{
ExportToCsv.Cancel(true);
return ExportToCsv.GetStatus(true);
}
/// <visible>false</visible>
[Create(@"export/partial/{entityType:(contact|opportunity|case|task|invoiceitem)}/start")]
public IProgressItem StartPartialExport(string entityType, string base64FilterString)
{
if (string.IsNullOrEmpty(base64FilterString)) throw new ArgumentException();
FilterObject filterObject;
String fileName;
switch (entityType.ToLower())
{
case "contact":
filterObject = new ContactFilterObject(base64FilterString);
fileName = CRMContactResource.Contacts + ".csv";
MessageService.Send( MessageAction.ContactsExportedToCsv);
break;
case "opportunity":
filterObject = new DealFilterObject(base64FilterString);
fileName = CRMCommonResource.DealModuleName + ".csv";
MessageService.Send( MessageAction.OpportunitiesExportedToCsv);
break;
case "case":
filterObject = new CasesFilterObject(base64FilterString);
fileName = CRMCommonResource.CasesModuleName + ".csv";
MessageService.Send( MessageAction.CasesExportedToCsv);
break;
case "task":
filterObject = new TaskFilterObject(base64FilterString);
fileName = CRMCommonResource.TaskModuleName + ".csv";
MessageService.Send( MessageAction.CrmTasksExportedToCsv);
break;
case "invoiceitem":
fileName = CRMCommonResource.ProductsAndServices + ".csv";
filterObject = new InvoiceItemFilterObject(base64FilterString);
break;
default:
throw new ArgumentException();
}
return ExportToCsv.Start(filterObject, fileName);
}
protected CurrencyInfoWrapper ToCurrencyInfoWrapper(CurrencyInfo currencyInfo)
{
return currencyInfo == null ? null : new CurrencyInfoWrapper(currencyInfo);
}
protected CurrencyRateInfoWrapper ToCurrencyRateInfoWrapper(CurrencyInfo currencyInfo, Decimal rate)
{
return currencyInfo == null ? null : new CurrencyRateInfoWrapper(currencyInfo, rate);
}
}
}

View File

@ -0,0 +1,138 @@
using ASC.Api.Core;
using ASC.Api.CRM.Wrappers;
using ASC.Common;
using ASC.Common.Web;
using ASC.Core;
using ASC.CRM.Core;
using ASC.CRM.Core.Dao;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.MessagingSystem;
using ASC.Web.Api.Routing;
using ASC.Web.CRM.Classes;
using ASC.Web.CRM.Services.NotifyService;
using ASC.Web.Files.Services.WCFService;
using Microsoft.AspNetCore.Mvc;
using System;
namespace ASC.Api.CRM
{
[DefaultRoute]
[ApiController]
public partial class CRMController : ControllerBase
{
public CRMController(CRMSecurity cRMSecurity,
DaoFactory daoFactory,
ApiContext apiContext,
MessageTarget messageTarget,
MessageService messageService,
NotifyClient notifyClient,
TaskWrapperHelper taskWrapperHelper,
SecurityContext securityContext,
UserManager userManager,
CurrencyProvider currencyProvider)
{
DaoFactory = daoFactory;
ApiContext = apiContext;
CRMSecurity = cRMSecurity;
MessageTarget = messageTarget;
MessageService = messageService;
NotifyClient = notifyClient;
TaskWrapperHelper = taskWrapperHelper;
SecurityContext = securityContext;
UserManager = userManager;
CurrencyProvider = currencyProvider;
}
public CurrencyProvider CurrencyProvider { get; }
public UserManager UserManager { get; }
public SecurityContext SecurityContext { get; }
public TaskWrapperHelper TaskWrapperHelper { get; }
public NotifyClient NotifyClient { get; }
private readonly ApiContext ApiContext;
public MessageService MessageService { get; }
public MessageTarget MessageTarget { get; }
public CRMSecurity CRMSecurity { get; }
public DaoFactory DaoFactory { get; }
private static EntityType ToEntityType(string entityTypeStr)
{
EntityType entityType;
if (string.IsNullOrEmpty(entityTypeStr)) return EntityType.Any;
switch (entityTypeStr.ToLower())
{
case "person":
entityType = EntityType.Person;
break;
case "company":
entityType = EntityType.Company;
break;
case "contact":
entityType = EntityType.Contact;
break;
case "opportunity":
entityType = EntityType.Opportunity;
break;
case "case":
entityType = EntityType.Case;
break;
default:
entityType = EntityType.Any;
break;
}
return entityType;
}
private string GetEntityTitle(EntityType entityType, int entityId, bool checkAccess, out DomainObject entity)
{
switch (entityType)
{
case EntityType.Contact:
case EntityType.Company:
case EntityType.Person:
var conatct = (entity = DaoFactory.GetContactDao().GetByID(entityId)) as Contact;
if (conatct == null || (checkAccess && !CRMSecurity.CanAccessTo(conatct)))
throw new ItemNotFoundException();
return conatct.GetTitle();
case EntityType.Opportunity:
var deal = (entity = DaoFactory.GetDealDao().GetByID(entityId)) as Deal;
if (deal == null || (checkAccess && !CRMSecurity.CanAccessTo(deal)))
throw new ItemNotFoundException();
return deal.Title;
case EntityType.Case:
var cases = (entity = DaoFactory.GetCasesDao().GetByID(entityId)) as Cases;
if (cases == null || (checkAccess && !CRMSecurity.CanAccessTo(cases)))
throw new ItemNotFoundException();
return cases.Title;
default:
throw new ArgumentException("Invalid entityType: " + entityType);
}
}
}
public static class CRMControllerExtention
{
public static DIHelper AddCRMControllerService(this DIHelper services)
{
return services.AddCRMSecurityService()
.AddDaoFactoryService()
.AddApiContextService()
.AddGlobalService()
.AddMessageTargetService()
.AddTaskWrapperHelperService()
.AddFileStorageService()
.AddNotifyClientService()
.AddSecurityContextService()
.AddUserManagerService()
.AddCurrencyProviderService();
}
}
}

View File

@ -1,17 +0,0 @@
using ASC.Web.Api.Routing;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace ASC.Api.CRM
{
[DefaultRoute]
[ApiController]
public class CurrencyRateController : ControllerBase
{
}
}

View File

@ -1,12 +0,0 @@
using ASC.Web.Api.Routing;
using Microsoft.AspNetCore.Mvc;
namespace ASC.Api.CRM
{
[DefaultRoute]
[ApiController]
public class TasksController : ControllerBase
{
}
}

View File

@ -164,7 +164,56 @@ namespace ASC.CRM.Core.Dao
{
services.TryAddScoped<DaoFactory>();
return services;
// return services;
return services.AddTaskDaoService()
.AddListItemDaoService()
.AddContactDaoService()
.AddCustomFieldDaoService()
.AddDealDaoService()
.AddDealMilestoneDaoService()
.AddTagDaoService()
.AddSearchDaoService()
.AddRelationshipEventDaoService()
.AddFileDaoService()
.AddCasesDaoService()
.AddTaskTemplateDaoService()
.AddTaskTemplateContainerDaoService()
// .AddReportDaoService()
.AddCurrencyRateDaoService()
.AddCurrencyInfoDaoService()
.AddContactInfoDaoService()
.AddInvoiceDaoService()
.AddInvoiceLineDaoService()
.AddInvoiceTaxDaoService()
.AddInvoiceLineDaoService();
}
}
}
//TaskDao
//ListItemDao
//ContactDao
//CustomFieldDao
//DealDao
//DealMilestoneDao
//TagDao
//SearchDao
//RelationshipEventDao
//FileDao
//CasesDao
//TaskTemplateContainerDao
//TaskTemplateDao
//ReportDao
//CurrencyRateDao
//CurrencyInfoDao
//ContactInfoDao
//InvoiceDao
//InvoiceItemDao
//InvoiceTaxDao
//InvoiceLineDao
//VoipDao

View File

@ -987,7 +987,7 @@ namespace ASC.CRM.Core.Dao
public static class InvoiceDaoExtention
{
public static DIHelper AddFileDaoService(this DIHelper services)
public static DIHelper AddInvoiceDaoService(this DIHelper services)
{
services.TryAddScoped<InvoiceDao>();

View File

@ -719,7 +719,7 @@ namespace ASC.CRM.Core.Dao
public static class RelationshipEventDaoExtention
{
public static DIHelper AddListItemDaoService(this DIHelper services)
public static DIHelper AddRelationshipEventDaoService(this DIHelper services)
{
services.TryAddScoped<RelationshipEventDao>();

View File

@ -2234,7 +2234,7 @@ namespace ASC.CRM.Core.Dao
.AddFilesIntegrationService()
.AddTenantUtilService()
.AddSettingsManagerService()
.AddGlobalService()
// .AddGlobalService()
.AddUserManagerService();
}
}

View File

@ -293,4 +293,17 @@ namespace ASC.CRM.Core.Dao
.AddSecurityContextService();
}
}
public static class TaskTemplateContainerDaoExtention
{
public static DIHelper AddTaskTemplateContainerDaoService(this DIHelper services)
{
services.TryAddScoped<TaskTemplateContainerDao>();
return services.AddCRMDbContextService()
.AddTenantManagerService()
.AddSecurityContextService();
}
}
}

View File

@ -36,13 +36,6 @@ namespace ASC.CRM.Core.EF
public virtual DbSet<DbVoipCalls> VoipCalls { get; set; }
public virtual DbSet<DbVoipNumber> VoipNumber { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
}
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<DbCase>(entity =>

View File

@ -225,7 +225,10 @@ namespace ASC.Web.CRM.Core.Search
public static class BundleSearchExtention
{
public static DIHelper AddBundleSearchService(this DIHelper services)
{
{
services.TryAddScoped<BundleSearch>();
return services.AddFactoryIndexerService<ContactsWrapper>()
.AddFactoryIndexerService<InfoWrapper>()
.AddFactoryIndexerService<FieldsWrapper>()

View File

@ -870,7 +870,7 @@ namespace ASC.CRM.Core
.AddAuthorizationManagerService()
.AddUserManagerService()
.AddDisplayUserSettingsService()
.AddDaoFactoryService()
// .AddDaoFactoryService()
.AddWebItemSecurity()
.AddPermissionContextService()
.AddCurrencyProviderService()

View File

@ -0,0 +1,145 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.Common;
using ASC.Core.Users;
using ASC.CRM.Core;
using ASC.CRM.Core.Dao;
using ASC.CRM.Core.Entities;
using ASC.Web.Api.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
[DataContract(Name = "case", Namespace = "")]
public class CasesWrapper
{
public CasesWrapper()
{
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<ContactBaseWrapper> Members { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EmployeeWraper CreateBy { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ApiDateTime Created { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Title { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool IsClosed { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool IsPrivate { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<EmployeeWraper> AccessList { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanEdit { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<CustomFieldBaseWrapper> CustomFields { get; set; }
public static CasesWrapper GetSample()
{
return new CasesWrapper
{
IsClosed = false,
Title = "Exhibition organization",
Created = ApiDateTime.GetSample(),
CreateBy = EmployeeWraper.GetSample(),
IsPrivate = false,
CustomFields = new[] { CustomFieldBaseWrapper.GetSample() },
CanEdit = true
};
}
}
public class CasesWrapperHelper
{
public CasesWrapperHelper(ApiDateTimeHelper apiDateTimeHelper,
EmployeeWraperHelper employeeWraperHelper,
CRMSecurity cRMSecurity)
{
ApiDateTimeHelper = apiDateTimeHelper;
EmployeeWraperHelper = employeeWraperHelper;
CRMSecurity = cRMSecurity;
}
public CRMSecurity CRMSecurity { get; }
public ApiDateTimeHelper ApiDateTimeHelper { get; }
public EmployeeWraperHelper EmployeeWraperHelper { get; }
public CasesWrapper Get(Cases cases)
{
var result = new CasesWrapper
{
Title = cases.Title,
IsClosed = cases.IsClosed,
IsPrivate = CRMSecurity.IsPrivate(cases),
Created = ApiDateTimeHelper.Get(cases.CreateOn),
CreateBy = EmployeeWraperHelper.Get(cases.CreateBy),
CanEdit = CRMSecurity.CanEdit(cases)
};
if (result.IsPrivate)
{
result.AccessList = CRMSecurity.GetAccessSubjectTo(cases)
.SkipWhile(item => item.Key == Constants.GroupEveryone.ID)
.Select(item => EmployeeWraperHelper.Get(item.Key));
}
return result;
}
}
public static class CasesWrapperHelperExtension
{
public static DIHelper AddCasesWrapperHelperService(this DIHelper services)
{
services.TryAddTransient<CasesWrapperHelper>();
return services.AddApiDateTimeHelper()
.AddEmployeeWraper()
.AddCRMSecurityService();
}
}
}

View File

@ -0,0 +1,200 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.Api.CRM.Wrappers;
using ASC.Common;
using ASC.CRM.Classes;
using ASC.CRM.Core;
using ASC.CRM.Core.Enums;
using ASC.Web.Api.Models;
using Newtonsoft.Json.Linq;
using System;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
/// <summary>
/// Address
/// </summary>
[DataContract(Name = "address", Namespace = "")]
public class Address
{
public Address()
{
}
public Address(ContactInfo contactInfo)
{
if (contactInfo.InfoType != ContactInfoType.Address) throw new ArgumentException();
City = JObject.Parse(contactInfo.Data)["city"].Value<String>();
Country = JObject.Parse(contactInfo.Data)["country"].Value<String>();
State = JObject.Parse(contactInfo.Data)["state"].Value<String>();
Street = JObject.Parse(contactInfo.Data)["street"].Value<String>();
Zip = JObject.Parse(contactInfo.Data)["zip"].Value<String>();
Category = contactInfo.Category;
CategoryName = contactInfo.CategoryToString();
IsPrimary = contactInfo.IsPrimary;
}
public static bool TryParse(ContactInfo contactInfo, out Address res)
{
if (contactInfo.InfoType != ContactInfoType.Address)
{
res = null;
return false;
}
try
{
res = Newtonsoft.Json.JsonConvert.DeserializeObject<Address>(contactInfo.Data);
res.Category = contactInfo.Category;
res.CategoryName = contactInfo.CategoryToString();
res.IsPrimary = contactInfo.IsPrimary;
return true;
}
catch (Exception)
{
res = null;
return false;
}
}
[DataMember(Order = 1, IsRequired = false, EmitDefaultValue = false)]
public String Street { get; set; }
[DataMember(Order = 2, IsRequired = false, EmitDefaultValue = false)]
public String City { get; set; }
[DataMember(Order = 3, IsRequired = false, EmitDefaultValue = false)]
public String State { get; set; }
[DataMember(Order = 4, IsRequired = false, EmitDefaultValue = false)]
public String Zip { get; set; }
[DataMember(Order = 5, IsRequired = false, EmitDefaultValue = false)]
public String Country { get; set; }
[DataMember(Order = 6, IsRequired = false, EmitDefaultValue = false)]
public int Category { get; set; }
[DataMember(Order = 7, IsRequired = false, EmitDefaultValue = false)]
public String CategoryName { get; set; }
[DataMember(Order = 8, IsRequired = false, EmitDefaultValue = false)]
public Boolean IsPrimary { get; set; }
public static Address GetSample()
{
return new Address
{
Country = "Latvia",
Zip = "LV-1021",
Street = "Lubanas st. 125a-25",
State = "",
City = "Riga",
IsPrimary = true,
Category = (int)ContactInfoBaseCategory.Work,
CategoryName = ((AddressCategory)ContactInfoBaseCategory.Work).ToLocalizedString()
};
}
}
/// <summary>
/// Contact information
/// </summary>
[DataContract(Name = "commonDataItem", Namespace = "")]
public class ContactInfoWrapper
{
public ContactInfoWrapper()
{
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(Order = 1)]
public ContactInfoType InfoType { get; set; }
[DataMember(Order = 2)]
public int Category { get; set; }
[DataMember(Order = 3)]
public String Data { get; set; }
[DataMember(Order = 4)]
public String CategoryName { get; set; }
[DataMember(Order = 5)]
public bool IsPrimary { get; set; }
public static ContactInfoWrapper GetSample()
{
return new ContactInfoWrapper
{
IsPrimary = true,
Category = (int)ContactInfoBaseCategory.Home,
CategoryName = ContactInfoBaseCategory.Home.ToLocalizedString(),
Data = "support@onlyoffice.com",
InfoType = ContactInfoType.Email
};
}
}
public class ContactInfoWrapperHelper
{
public ContactInfoWrapperHelper()
{
}
public ContactInfoWrapper Get(ContactInfo contactInfo)
{
return new ContactInfoWrapper
{
InfoType = contactInfo.InfoType,
Category = contactInfo.Category,
CategoryName = contactInfo.CategoryToString(),
Data = contactInfo.Data,
IsPrimary = contactInfo.IsPrimary,
Id = contactInfo.ID
};
}
}
public static class ContactInfoWrapperHelperExtension
{
public static DIHelper AddContactInfoWrapperService(this DIHelper services)
{
services.TryAddTransient<ContactInfoWrapperHelper>();
return services;
}
}
}

View File

@ -0,0 +1,491 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.Web.Api.Models;
using ASC.Web.CRM;
using ASC.Web.CRM.Classes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using Contact = ASC.CRM.Core.Entities.Contact;
namespace ASC.Api.CRM.Wrappers
{
/// <summary>
/// Person
/// </summary>
[DataContract(Name = "person", Namespace = "")]
public class PersonWrapper : ContactWrapper
{
public PersonWrapper(int id) :
base(id)
{
}
public PersonWrapper(Person person)
: base(person)
{
FirstName = person.FirstName;
LastName = person.LastName;
Title = person.JobTitle;
}
public static PersonWrapper ToPersonWrapperQuick(Person person)
{
var result = new PersonWrapper(person.ID);
result.DisplayName = person.GetTitle();
result.IsPrivate = CRMSecurity.IsPrivate(person);
result.IsShared = person.ShareType == ShareType.ReadWrite || person.ShareType == ShareType.Read;
result.ShareType = person.ShareType;
if (result.IsPrivate)
{
result.AccessList = CRMSecurity.GetAccessSubjectTo(person)
.Select(item => EmployeeWraper.Get(item.Key));
}
result.Currency = !String.IsNullOrEmpty(person.Currency) ?
new CurrencyInfoWrapper(CurrencyProvider.Get(person.Currency)) :
null;
result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, person.ID, false).ToLower();
result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, person.ID, false).ToLower();
result.IsCompany = false;
result.CanEdit = CRMSecurity.CanEdit(person);
//result.CanDelete = CRMSecurity.CanDelete(contact);
result.CreateBy = EmployeeWraper.Get(person.CreateBy);
result.Created = (ApiDateTime)person.CreateOn;
result.About = person.About;
result.Industry = person.Industry;
result.FirstName = person.FirstName;
result.LastName = person.LastName;
result.Title = person.JobTitle;
return result;
}
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public String FirstName { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public String LastName { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactBaseWrapper Company { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Title { get; set; }
public new static PersonWrapper GetSample()
{
return new PersonWrapper(0)
{
IsPrivate = true,
IsShared = false,
IsCompany = false,
FirstName = "Tadjeddine",
LastName = "Bachir",
Company = CompanyWrapper.GetSample(),
Title = "Programmer",
About = "",
Created = ApiDateTime.GetSample(),
CreateBy = EmployeeWraper.GetSample(),
ShareType = ShareType.None
};
}
}
/// <summary>
/// Company
/// </summary>
[DataContract(Name = "company", Namespace = "")]
public class CompanyWrapper : ContactWrapper
{
public CompanyWrapper(int id) :
base(id)
{
}
public CompanyWrapper(Company company)
: base(company)
{
CompanyName = company.CompanyName;
// PersonsCount = Global.DaoFactory.ContactDao.GetMembersCount(company.ID);
}
public static CompanyWrapper ToCompanyWrapperQuick(Company company)
{
var result = new CompanyWrapper(company.ID);
result.DisplayName = company.GetTitle();
result.IsPrivate = CRMSecurity.IsPrivate(company);
result.IsShared = company.ShareType == ShareType.ReadWrite || company.ShareType == ShareType.Read;
result.ShareType = company.ShareType;
if (result.IsPrivate)
{
result.AccessList = CRMSecurity.GetAccessSubjectTo(company)
.Select(item => EmployeeWraper.Get(item.Key));
}
result.Currency = !String.IsNullOrEmpty(company.Currency) ?
new CurrencyInfoWrapper(CurrencyProvider.Get(company.Currency)) :
null;
result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, company.ID, true).ToLower();
result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, company.ID, true).ToLower();
result.IsCompany = true;
result.CanEdit = CRMSecurity.CanEdit(company);
//result.CanDelete = CRMSecurity.CanDelete(contact);
result.CompanyName = company.CompanyName;
result.CreateBy = EmployeeWraper.Get(company.CreateBy);
result.Created = (ApiDateTime)company.CreateOn;
result.About = company.About;
result.Industry = company.Industry;
return result;
}
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public String CompanyName { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public IEnumerable<ContactBaseWrapper> Persons { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public int PersonsCount { get; set; }
public new static CompanyWrapper GetSample()
{
return new CompanyWrapper(0)
{
IsPrivate = true,
IsShared = false,
IsCompany = true,
About = "",
CompanyName = "Food and Culture Project",
PersonsCount = 0
};
}
}
[DataContract(Name = "contact", Namespace = "")]
[KnownType(typeof(PersonWrapper))]
[KnownType(typeof(CompanyWrapper))]
public abstract class ContactWrapper : ContactBaseWrapper
{
protected ContactWrapper(int id)
: base(id)
{
}
protected ContactWrapper(Contact contact)
: base(contact)
{
CreateBy = EmployeeWraper.Get(contact.CreateBy);
Created = (ApiDateTime)contact.CreateOn;
About = contact.About;
Industry = contact.Industry;
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<Address> Addresses { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EmployeeWraper CreateBy { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ApiDateTime Created { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String About { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Industry { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactStatusBaseWrapper ContactStatus { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactTypeBaseWrapper ContactType { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<ContactInfoWrapper> CommonData { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<CustomFieldBaseWrapper> CustomFields { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<String> Tags { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int TaskCount { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool HaveLateTasks { get; set; }
public new static ContactWrapper GetSample()
{
return new PersonWrapper(0)
{
IsPrivate = true,
IsShared = false,
IsCompany = false,
FirstName = "Tadjeddine",
LastName = "Bachir",
Company = CompanyWrapper.GetSample(),
Title = "Programmer",
About = "",
Created = ApiDateTime.GetSample(),
CreateBy = EmployeeWraper.GetSample(),
CommonData = new List<ContactInfoWrapper>(){ContactInfoWrapper.GetSample()},
CustomFields = new List<CustomFieldBaseWrapper>(){CustomFieldBaseWrapper.GetSample()},
ShareType = ShareType.None,
CanDelete = true,
CanEdit = true,
TaskCount = 0,
HaveLateTasks = false
};
}
}
[DataContract(Name = "contactBase", Namespace = "")]
public class ContactBaseWithEmailWrapper : ContactBaseWrapper
{
protected ContactBaseWithEmailWrapper(int id)
: base(id)
{
}
public ContactBaseWithEmailWrapper(Contact contact)
: base(contact)
{
}
public ContactBaseWithEmailWrapper(ContactWrapper contactWrapper) : base(contactWrapper.ID)
{
AccessList = contactWrapper.AccessList;
CanEdit = contactWrapper.CanEdit;
DisplayName = contactWrapper.DisplayName;
IsCompany = contactWrapper.IsCompany;
IsPrivate = contactWrapper.IsPrivate;
IsShared = contactWrapper.IsShared;
ShareType = contactWrapper.ShareType;
MediumFotoUrl = contactWrapper.MediumFotoUrl;
SmallFotoUrl = contactWrapper.SmallFotoUrl;
if (contactWrapper.CommonData != null && contactWrapper.CommonData.Count() != 0)
{
Email = contactWrapper.CommonData.FirstOrDefault(item => item.InfoType == ContactInfoType.Email && item.IsPrimary);
}
else
{
Email = null;
}
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactInfoWrapper Email { get; set; }
}
[DataContract(Name = "contactBase", Namespace = "")]
public class ContactBaseWithPhoneWrapper : ContactBaseWrapper
{
protected ContactBaseWithPhoneWrapper(int id)
: base(id)
{
}
public ContactBaseWithPhoneWrapper(Contact contact)
: base(contact)
{
}
public ContactBaseWithPhoneWrapper(ContactWrapper contactWrapper)
: base(contactWrapper.ID)
{
AccessList = contactWrapper.AccessList;
CanEdit = contactWrapper.CanEdit;
DisplayName = contactWrapper.DisplayName;
IsCompany = contactWrapper.IsCompany;
IsPrivate = contactWrapper.IsPrivate;
IsShared = contactWrapper.IsShared;
ShareType = contactWrapper.ShareType;
MediumFotoUrl = contactWrapper.MediumFotoUrl;
SmallFotoUrl = contactWrapper.SmallFotoUrl;
if (contactWrapper.CommonData != null && contactWrapper.CommonData.Count() != 0)
{
Phone = contactWrapper.CommonData.FirstOrDefault(item => item.InfoType == ContactInfoType.Phone && item.IsPrimary);
}
else
{
Phone = null;
}
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactInfoWrapper Phone { get; set; }
}
/// <summary>
/// Contact base information
/// </summary>
[DataContract(Name = "contactBase", Namespace = "")]
public class ContactBaseWrapper
{
public ContactBaseWrapper(Contact contact)
: base(contact.ID)
{
DisplayName = contact.GetTitle();
IsPrivate = CRMSecurity.IsPrivate(contact);
IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read;
ShareType = contact.ShareType;
if (IsPrivate)
{
AccessList = CRMSecurity.GetAccessSubjectTo(contact)
.Select(item => EmployeeWraper.Get(item.Key));
}
Currency = !String.IsNullOrEmpty(contact.Currency) ?
new CurrencyInfoWrapper(CurrencyProvider.Get(contact.Currency)) :
null;
SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower();
MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower();
IsCompany = contact is Company;
CanEdit = CRMSecurity.CanEdit(contact);
CanDelete = CRMSecurity.CanDelete(contact);
}
public static ContactBaseWrapper ToContactBaseWrapperQuick(Contact contact)
{
var result = new ContactBaseWrapper(contact.ID);
result.DisplayName = contact.GetTitle();
result.IsPrivate = CRMSecurity.IsPrivate(contact);
result.IsShared = contact.ShareType == ShareType.ReadWrite || contact.ShareType == ShareType.Read;
result.ShareType = contact.ShareType;
if (result.IsPrivate)
{
result.AccessList = CRMSecurity.GetAccessSubjectTo(contact)
.Select(item => EmployeeWraper.Get(item.Key));
}
result.Currency = !String.IsNullOrEmpty(contact.Currency) ?
new CurrencyInfoWrapper(CurrencyProvider.Get(contact.Currency)) :
null;
result.SmallFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=1", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower();
result.MediumFotoUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=contactphotoulr&cid={1}&isc={2}&ps=2", PathProvider.BaseAbsolutePath, contact.ID, contact is Company).ToLower();
result.IsCompany = contact is Company;
result.CanEdit = CRMSecurity.CanEdit(contact);
//result.CanDelete = CRMSecurity.CanDelete(contact);
return result;
}
protected ContactBaseWrapper(int contactID)
: base(contactID)
{
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String SmallFotoUrl { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String MediumFotoUrl { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public String DisplayName { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool IsCompany { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<EmployeeWraper> AccessList { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool IsPrivate { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool IsShared { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public ShareType ShareType { get; set; }
[DataMember]
public CurrencyInfoWrapper Currency { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanEdit { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanDelete { get; set; }
public static ContactBaseWrapper GetSample()
{
return new ContactBaseWrapper(0)
{
IsPrivate = true,
IsShared = false,
IsCompany = false,
DisplayName = "Tadjeddine Bachir",
SmallFotoUrl = "url to foto"
};
}
}
[DataContract(Name = "contact_task", Namespace = "")]
public class ContactWithTaskWrapper
{
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public TaskBaseWrapper Task { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactWrapper Contact { get; set; }
}
}

View File

@ -0,0 +1,104 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Runtime.Serialization;
using ASC.CRM.Core;
namespace ASC.Api.CRM
{
/// <summary>
/// Currency information
/// </summary>
[DataContract(Name = "currencyInfo", Namespace = "")]
public class CurrencyInfoWrapper
{
public CurrencyInfoWrapper()
{
}
public CurrencyInfoWrapper(CurrencyInfo currencyInfo)
{
Abbreviation = currencyInfo.Abbreviation;
CultureName = currencyInfo.CultureName;
Symbol = currencyInfo.Symbol;
Title = currencyInfo.Title;
IsConvertable = currencyInfo.IsConvertable;
IsBasic = currencyInfo.IsBasic;
}
[DataMember]
public String Title { get; set; }
[DataMember]
public String Symbol { get; set; }
[DataMember]
public String Abbreviation { get; set; }
[DataMember]
public String CultureName { get; set; }
[DataMember]
public bool IsConvertable { get; set; }
[DataMember]
public bool IsBasic { get; set; }
public static CurrencyInfoWrapper GetSample()
{
return new CurrencyInfoWrapper
{
Title = "Chinese Yuan",
Abbreviation = "CNY",
Symbol = "¥",
CultureName = "CN",
IsConvertable = true,
IsBasic = false
};
}
}
/// <summary>
/// Currency rate information
/// </summary>
[DataContract(Name = "currencyRateInfo", Namespace = "")]
public class CurrencyRateInfoWrapper : CurrencyInfoWrapper
{
public CurrencyRateInfoWrapper()
{
}
public CurrencyRateInfoWrapper(CurrencyInfo currencyInfo, Decimal rate) : base(currencyInfo)
{
Rate = rate;
}
[DataMember]
public Decimal Rate { get; set; }
}
}

View File

@ -0,0 +1,73 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Runtime.Serialization;
using ASC.Api.CRM.Wrappers;
using ASC.CRM.Core;
namespace ASC.Api.CRM
{
/// <summary>
/// Currency rate
/// </summary>
[DataContract(Name = "currencyRate", Namespace = "")]
public class CurrencyRateWrapper
{
public CurrencyRateWrapper(int id)
{
}
public CurrencyRateWrapper(CurrencyRate currencyRate)
{
FromCurrency = currencyRate.FromCurrency;
ToCurrency = currencyRate.ToCurrency;
Rate = currencyRate.Rate;
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember]
public String FromCurrency { get; set; }
[DataMember]
public String ToCurrency { get; set; }
[DataMember]
public decimal Rate { get; set; }
public static CurrencyRateWrapper GetSample()
{
return new CurrencyRateWrapper(1)
{
FromCurrency = "EUR",
ToCurrency = "USD",
Rate = (decimal)1.1
};
}
}
}

View File

@ -0,0 +1,122 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using System;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
[DataContract(Name = "customField", Namespace = "")]
public class CustomFieldWrapper : CustomFieldBaseWrapper
{
public CustomFieldWrapper(int id)
: base(id)
{
}
public CustomFieldWrapper(CustomField customField)
: base(customField)
{
}
[DataMember]
public int RelativeItemsCount { get; set; }
public new static CustomFieldWrapper GetSample()
{
return new CustomFieldWrapper(0)
{
Position = 10,
EntityId = 14523423,
FieldType = CustomFieldType.Date,
FieldValue = ApiDateTime.GetSample().ToString(),
Label = "Birthdate",
Mask = "",
RelativeItemsCount = 0
};
}
}
/// <summary>
/// User custom fields
/// </summary>
[DataContract(Name = "customField", Namespace = "")]
public class CustomFieldBaseWrapper
{
public CustomFieldBaseWrapper(int id)
{
}
public CustomFieldBaseWrapper(CustomField customField)
{
EntityId = customField.EntityID;
Label = customField.Label;
FieldValue = customField.Value;
FieldType = customField.FieldType;
Position = customField.Position;
Mask = customField.Mask;
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember]
public int EntityId { get; set; }
[DataMember]
public String Label { get; set; }
[DataMember]
public String FieldValue { get; set; }
[DataMember]
public CustomFieldType FieldType { get; set; }
[DataMember]
public int Position { get; set; }
[DataMember]
public String Mask { get; set; }
public static CustomFieldBaseWrapper GetSample()
{
return new CustomFieldBaseWrapper(0)
{
Position = 10,
EntityId = 14523423,
FieldType = CustomFieldType.Date,
FieldValue = ApiDateTime.GetSample().ToString(),
Label = "Birthdate",
Mask = ""
};
}
}
}

View File

@ -0,0 +1,423 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.CRM.Classes;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.Web.Api.Models;
using ASC.Web.CRM.Classes;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
/// <summary>
/// Invoice
/// </summary>
[DataContract(Name = "invoiceBase", Namespace = "")]
public class InvoiceBaseWrapper
{
public InvoiceBaseWrapper(int id)
{
}
public InvoiceBaseWrapper(Invoice invoice)
{
Status = new InvoiceStatusWrapper(invoice.Status);
Number = invoice.Number;
IssueDate = (ApiDateTime) invoice.IssueDate;
TemplateType = invoice.TemplateType;
DueDate = (ApiDateTime) invoice.DueDate;
Currency = !String.IsNullOrEmpty(invoice.Currency) ?
new CurrencyInfoWrapper(CurrencyProvider.Get(invoice.Currency)) :
new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency);
ExchangeRate = invoice.ExchangeRate;
Language = invoice.Language;
PurchaseOrderNumber = invoice.PurchaseOrderNumber;
Terms = invoice.Terms;
Description = invoice.Description;
FileID = invoice.FileID;
CreateOn = (ApiDateTime)invoice.CreateOn;
CreateBy = EmployeeWraper.Get(invoice.CreateBy);
CanEdit = CRMSecurity.CanEdit(invoice);
CanDelete = CRMSecurity.CanDelete(invoice);
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember]
public InvoiceStatusWrapper Status { get; set; }
[DataMember]
public string Number { get; set; }
[DataMember]
public ApiDateTime IssueDate { get; set; }
[DataMember]
public InvoiceTemplateType TemplateType { get; set; }
[DataMember]
public ContactBaseWithEmailWrapper Contact { get; set; }
[DataMember]
public ContactBaseWithEmailWrapper Consignee { get; set; }
[DataMember]
public EntityWrapper Entity { get; set; }
[DataMember]
public ApiDateTime DueDate { get; set; }
[DataMember]
public string Language { get; set; }
[DataMember]
public CurrencyInfoWrapper Currency { get; set; }
[DataMember]
public decimal ExchangeRate { get; set; }
[DataMember]
public string PurchaseOrderNumber { get; set; }
[DataMember]
public string Terms { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public int FileID { get; set; }
[DataMember]
public ApiDateTime CreateOn { get; set; }
[DataMember]
public EmployeeWraper CreateBy { get; set; }
[DataMember]
public decimal Cost { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanEdit { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanDelete { get; set; }
}
/// <summary>
/// Invoice
/// </summary>
[DataContract(Name = "invoice", Namespace = "")]
public class InvoiceWrapper : InvoiceBaseWrapper
{
public InvoiceWrapper(int id)
: base(id)
{
}
public InvoiceWrapper(Invoice invoice)
: base(invoice.ID)
{
Status = new InvoiceStatusWrapper(invoice.Status);
Number = invoice.Number;
IssueDate = (ApiDateTime) invoice.IssueDate;
TemplateType = invoice.TemplateType;
DueDate = (ApiDateTime) invoice.DueDate;
Currency = !String.IsNullOrEmpty(invoice.Currency) ?
new CurrencyInfoWrapper(CurrencyProvider.Get(invoice.Currency)) :
new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency);
ExchangeRate = invoice.ExchangeRate;
Language = invoice.Language;
PurchaseOrderNumber = invoice.PurchaseOrderNumber;
Terms = invoice.Terms;
Description = invoice.Description;
FileID = invoice.FileID;
CreateOn = (ApiDateTime)invoice.CreateOn;
CreateBy = EmployeeWraper.Get(invoice.CreateBy);
CanEdit = CRMSecurity.CanEdit(invoice);
CanDelete = CRMSecurity.CanDelete(invoice);
}
[DataMember]
public List<InvoiceLineWrapper> InvoiceLines { get; set; }
public static InvoiceWrapper GetSample()
{
return new InvoiceWrapper(0)
{
Status = new InvoiceStatusWrapper(InvoiceStatus.Draft),
Number = string.Empty,
IssueDate = ApiDateTime.GetSample(),
TemplateType = InvoiceTemplateType.Eur,
Language = string.Empty,
DueDate = ApiDateTime.GetSample(),
Currency = CurrencyInfoWrapper.GetSample(),
ExchangeRate = (decimal)1.00,
PurchaseOrderNumber = string.Empty,
Terms = string.Empty,
Description = string.Empty,
FileID = -1,
CreateOn = ApiDateTime.GetSample(),
CreateBy = EmployeeWraper.GetSample(),
CanEdit = true,
CanDelete = true,
Cost = 0,
InvoiceLines = new List<InvoiceLineWrapper>{ InvoiceLineWrapper.GetSample() }
};
}
}
/// <summary>
/// Invoice Item
/// </summary>
[DataContract(Name = "invoiceItem", Namespace = "")]
public class InvoiceItemWrapper
{
public InvoiceItemWrapper(int id)
{
}
public InvoiceItemWrapper(InvoiceItem invoiceItem)
{
Title = invoiceItem.Title;
StockKeepingUnit = invoiceItem.StockKeepingUnit;
Description = invoiceItem.Description;
Price = invoiceItem.Price;
Quantity = invoiceItem.Quantity;
StockQuantity = invoiceItem.StockQuantity;
TrackInvenory = invoiceItem.TrackInventory;
CreateOn = (ApiDateTime)invoiceItem.CreateOn;
CreateBy = EmployeeWraper.Get(invoiceItem.CreateBy);
Currency = !String.IsNullOrEmpty(invoiceItem.Currency) ?
new CurrencyInfoWrapper(CurrencyProvider.Get(invoiceItem.Currency)) :
new CurrencyInfoWrapper(Global.TenantSettings.DefaultCurrency);
CanEdit = CRMSecurity.CanEdit(invoiceItem);
CanDelete = CRMSecurity.CanDelete(invoiceItem);
}
[DataMember]
public string Title { get; set; }
[DataMember]
public string StockKeepingUnit { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public decimal Price { get; set; }
[DataMember]
public CurrencyInfoWrapper Currency { get; set; }
[DataMember]
public int Quantity { get; set; }
[DataMember]
public int StockQuantity { get; set; }
[DataMember]
public bool TrackInvenory { get; set; }
[DataMember]
public InvoiceTaxWrapper InvoiceTax1 { get; set; }
[DataMember]
public InvoiceTaxWrapper InvoiceTax2 { get; set; }
[DataMember]
public ApiDateTime CreateOn { get; set; }
[DataMember]
public EmployeeWraper CreateBy { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanEdit { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanDelete { get; set; }
}
/// <summary>
/// Invoice Tax
/// </summary>
[DataContract(Name = "invoiceTax", Namespace = "")]
public class InvoiceTaxWrapper
{
public InvoiceTaxWrapper()
{
}
public InvoiceTaxWrapper(InvoiceTax invoiceTax)
: base(invoiceTax.ID)
{
Name = invoiceTax.Name;
Description = invoiceTax.Description;
Rate = invoiceTax.Rate;
CreateOn = (ApiDateTime)invoiceTax.CreateOn;
CreateBy = EmployeeWraper.Get(invoiceTax.CreateBy);
CanEdit = CRMSecurity.CanEdit(invoiceTax);
CanDelete = CRMSecurity.CanDelete(invoiceTax);
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember]
public string Name { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public decimal Rate { get; set; }
[DataMember]
public ApiDateTime CreateOn { get; set; }
[DataMember]
public EmployeeWraper CreateBy { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanEdit { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanDelete { get; set; }
}
/// <summary>
/// Invoice Line
/// </summary>
[DataContract(Name = "invoiceLine", Namespace = "")]
public class InvoiceLineWrapper
{
public InvoiceLineWrapper(int id)
: base(id)
{
}
public InvoiceLineWrapper(InvoiceLine invoiceLine)
: base(invoiceLine.ID)
{
InvoiceID = invoiceLine.InvoiceID;
InvoiceItemID = invoiceLine.InvoiceItemID;
InvoiceTax1ID = invoiceLine.InvoiceTax1ID;
InvoiceTax2ID = invoiceLine.InvoiceTax2ID;
SortOrder = invoiceLine.SortOrder;
Description = invoiceLine.Description;
Quantity = invoiceLine.Quantity;
Price = invoiceLine.Price;
Discount = invoiceLine.Discount;
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember]
public int InvoiceID { get; set; }
[DataMember]
public int InvoiceItemID { get; set; }
[DataMember]
public int InvoiceTax1ID { get; set; }
[DataMember]
public int InvoiceTax2ID { get; set; }
[DataMember]
public int SortOrder { get; set; }
[DataMember]
public string Description { get; set; }
[DataMember]
public int Quantity { get; set; }
[DataMember]
public decimal Price { get; set; }
[DataMember]
public decimal Discount { get; set; }
public static InvoiceLineWrapper GetSample()
{
return new InvoiceLineWrapper(0)
{
Description = string.Empty,
Discount = (decimal)0.00,
InvoiceID = 0,
InvoiceItemID = 0,
InvoiceTax1ID = 0,
InvoiceTax2ID = 0,
Price = (decimal)0.00,
Quantity = 0
};
}
}
/// <summary>
/// Invoice Status
/// </summary>
[DataContract(Name = "invoiceStatus", Namespace = "")]
public class InvoiceStatusWrapper
{
public InvoiceStatusWrapper()
{
}
public InvoiceStatusWrapper(int id)
: base(id)
{
Title = ((InvoiceStatus)id).ToLocalizedString();
}
public InvoiceStatusWrapper(InvoiceStatus status)
: base((int)status)
{
Title = status.ToLocalizedString();
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember]
public string Title { get; set; }
}
}

View File

@ -0,0 +1,420 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.CRM.Core.Entities;
using ASC.Web.Core.Utility.Skins;
using ASC.Web.CRM.Configuration;
using System;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
#region History Category
[DataContract(Name = "historyCategoryBase", Namespace = "")]
public class HistoryCategoryBaseWrapper : ListItemWrapper
{
public HistoryCategoryBaseWrapper() : base(0)
{
}
public HistoryCategoryBaseWrapper(ListItem listItem)
: base(listItem)
{
if (!String.IsNullOrEmpty(listItem.AdditionalParams))
ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID);
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember]
public String ImagePath { get; set; }
public static HistoryCategoryBaseWrapper GetSample()
{
return new HistoryCategoryBaseWrapper
{
ID = 30,
Title = "Lunch",
SortOrder = 10,
Color = String.Empty,
Description = "",
ImagePath = "path to image"
};
}
}
[DataContract(Name = "historyCategory", Namespace = "")]
public class HistoryCategoryWrapper : HistoryCategoryBaseWrapper
{
public HistoryCategoryWrapper()
{
}
public HistoryCategoryWrapper(ListItem listItem)
: base(listItem)
{
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int RelativeItemsCount { get; set; }
public new static HistoryCategoryWrapper GetSample()
{
return new HistoryCategoryWrapper
{
ID = 30,
Title = "Lunch",
SortOrder = 10,
Color = String.Empty,
Description = "",
ImagePath = "path to image",
RelativeItemsCount = 1
};
}
}
#endregion
#region Deal Milestone
[DataContract(Name = "opportunityStagesBase", Namespace = "")]
public class DealMilestoneBaseWrapper : ListItemWrapper
{
public DealMilestoneBaseWrapper()
: base(0)
{
}
public DealMilestoneBaseWrapper(DealMilestone dealMilestone)
: base(dealMilestone.ID)
{
SuccessProbability = dealMilestone.Probability;
StageType = dealMilestone.Status;
Color = dealMilestone.Color;
Description = dealMilestone.Description;
Title = dealMilestone.Title;
}
[DataMember]
public int SuccessProbability { get; set; }
[DataMember]
public DealMilestoneStatus StageType { get; set; }
public static DealMilestoneBaseWrapper GetSample()
{
return new DealMilestoneBaseWrapper
{
ID = 30,
Title = "Discussion",
SortOrder = 2,
Color = "#B9AFD3",
Description = "The potential buyer showed his/her interest and sees how your offering meets his/her goal",
StageType = DealMilestoneStatus.Open,
SuccessProbability = 20
};
}
}
[DataContract(Name = "opportunityStages", Namespace = "")]
public class DealMilestoneWrapper : DealMilestoneBaseWrapper
{
public DealMilestoneWrapper()
{
}
public DealMilestoneWrapper(DealMilestone dealMilestone)
: base(dealMilestone)
{
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int RelativeItemsCount { get; set; }
public new static DealMilestoneWrapper GetSample()
{
return new DealMilestoneWrapper
{
ID = 30,
Title = "Discussion",
SortOrder = 2,
Color = "#B9AFD3",
Description = "The potential buyer showed his/her interest and sees how your offering meets his/her goal",
StageType = DealMilestoneStatus.Open,
SuccessProbability = 20,
RelativeItemsCount = 1
};
}
}
#endregion
#region Task Category
[DataContract(Name = "taskCategoryBase", Namespace = "")]
public class TaskCategoryBaseWrapper : ListItemWrapper
{
public TaskCategoryBaseWrapper()
: base(0)
{
}
public TaskCategoryBaseWrapper(ListItem listItem)
: base(listItem)
{
ImagePath = WebImageSupplier.GetAbsoluteWebPath(listItem.AdditionalParams, ProductEntryPoint.ID);
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String ImagePath { get; set; }
public static TaskCategoryBaseWrapper GetSample()
{
return new TaskCategoryBaseWrapper
{
ID = 30,
Title = "Appointment",
SortOrder = 2,
Description = "",
ImagePath = "path to image"
};
}
}
[DataContract(Name = "taskCategory", Namespace = "")]
public class TaskCategoryWrapper : TaskCategoryBaseWrapper
{
public TaskCategoryWrapper()
{
}
public TaskCategoryWrapper(ListItem listItem)
: base(listItem)
{
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int RelativeItemsCount { get; set; }
public new static TaskCategoryWrapper GetSample()
{
return new TaskCategoryWrapper
{
ID = 30,
Title = "Appointment",
SortOrder = 2,
Description = "",
ImagePath = "path to image",
RelativeItemsCount = 1
};
}
}
#endregion
#region Contact Status
[DataContract(Name = "contactStatusBase", Namespace = "")]
public class ContactStatusBaseWrapper : ListItemWrapper
{
public ContactStatusBaseWrapper() :
base(0)
{
}
public ContactStatusBaseWrapper(ListItem listItem)
: base(listItem)
{
}
public static ContactStatusBaseWrapper GetSample()
{
return new ContactStatusBaseWrapper
{
ID = 30,
Title = "Cold",
SortOrder = 2,
Description = ""
};
}
}
[DataContract(Name = "contactStatus", Namespace = "")]
public class ContactStatusWrapper : ContactStatusBaseWrapper
{
public ContactStatusWrapper()
{
}
public ContactStatusWrapper(ListItem listItem)
: base(listItem)
{
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int RelativeItemsCount { get; set; }
public new static ContactStatusWrapper GetSample()
{
return new ContactStatusWrapper
{
ID = 30,
Title = "Cold",
SortOrder = 2,
Description = "",
RelativeItemsCount = 1
};
}
}
#endregion
#region Contact Type
[DataContract(Name = "contactTypeBase", Namespace = "")]
public class ContactTypeBaseWrapper : ListItemWrapper
{
public ContactTypeBaseWrapper() :
base(0)
{
}
public ContactTypeBaseWrapper(ListItem listItem)
: base(listItem)
{
}
public static ContactTypeBaseWrapper GetSample()
{
return new ContactTypeBaseWrapper
{
ID = 30,
Title = "Client",
SortOrder = 2,
Description = ""
};
}
}
[DataContract(Name = "contactType", Namespace = "")]
public class ContactTypeWrapper : ContactTypeBaseWrapper
{
public ContactTypeWrapper()
{
}
public ContactTypeWrapper(ListItem listItem)
: base(listItem)
{
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int RelativeItemsCount { get; set; }
public new static ContactTypeWrapper GetSample()
{
return new ContactTypeWrapper
{
ID = 30,
Title = "Client",
SortOrder = 2,
Description = "",
RelativeItemsCount = 1
};
}
}
#endregion
#region Tags
[DataContract(Name = "tagWrapper", Namespace = "")]
public class TagWrapper
{
public TagWrapper()
{
Title = String.Empty;
RelativeItemsCount = 0;
}
public TagWrapper(String tag, int relativeItemsCount = 0)
{
Title = tag;
RelativeItemsCount = relativeItemsCount;
}
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public String Title { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int RelativeItemsCount { get; set; }
public static TagWrapper GetSample()
{
return new TagWrapper
{
Title = "Tag",
RelativeItemsCount = 1
};
}
}
#endregion
[DataContract(Name = "listItem", Namespace = "")]
public abstract class ListItemWrapper
{
protected ListItemWrapper(int id)
{
}
protected ListItemWrapper(ListItem listItem)
{
Title = listItem.Title;
Description = listItem.Description;
Color = listItem.Color;
SortOrder = listItem.SortOrder;
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Title { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Description { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Color { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int SortOrder { get; set; }
}
}

View File

@ -0,0 +1,178 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.Common;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.Web.Api.Models;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
/// <summary>
/// Opportunity
/// </summary>
[DataContract(Name = "opportunity", Namespace = "")]
public class OpportunityWrapper
{
public OpportunityWrapper()
{
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EmployeeWraper CreateBy { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ApiDateTime Created { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<ContactBaseWrapper> Members { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactBaseWrapper Contact { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public String Title { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Description { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EmployeeWraper Responsible { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public BidType BidType { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public decimal BidValue { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public CurrencyInfoWrapper BidCurrency { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int PerPeriodValue { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public DealMilestoneBaseWrapper Stage { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int SuccessProbability { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ApiDateTime ActualCloseDate { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ApiDateTime ExpectedCloseDate { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool IsPrivate { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<EmployeeWraper> AccessList { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool CanEdit { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<CustomFieldBaseWrapper> CustomFields { get; set; }
public static OpportunityWrapper GetSample()
{
return new OpportunityWrapper
{
CreateBy = EmployeeWraper.GetSample(),
Created = ApiDateTime.GetSample(),
Responsible = EmployeeWraper.GetSample(),
Title = "Hotel catalogue",
Description = "",
ExpectedCloseDate = ApiDateTime.GetSample(),
Contact = ContactBaseWrapper.GetSample(),
IsPrivate = false,
SuccessProbability = 65,
BidType = BidType.FixedBid,
Stage = DealMilestoneBaseWrapper.GetSample()
};
}
}
public class OpportunityWrapperHelper
{
public OpportunityWrapperHelper(ApiDateTimeHelper apiDateTimeHelper,
EmployeeWraperHelper employeeWraperHelper,
CRMSecurity cRMSecurity)
{
ApiDateTimeHelper = apiDateTimeHelper;
EmployeeWraperHelper = employeeWraperHelper;
CRMSecurity = cRMSecurity;
}
public CRMSecurity CRMSecurity { get; }
public ApiDateTimeHelper ApiDateTimeHelper { get; }
public EmployeeWraperHelper EmployeeWraperHelper { get; }
public OpportunityWrapper Get(Deal deal)
{
return new OpportunityWrapper
{
Id = deal.ID,
CreateBy = EmployeeWraperHelper.Get(deal.CreateBy),
Created = ApiDateTimeHelper.Get(deal.CreateOn),
Title = deal.Title,
Description = deal.Description,
Responsible = EmployeeWraperHelper.Get(deal.ResponsibleID),
BidType = deal.BidType,
BidValue = deal.BidValue,
PerPeriodValue = deal.PerPeriodValue,
SuccessProbability = deal.DealMilestoneProbability,
ActualCloseDate = ApiDateTimeHelper.Get(deal.ActualCloseDate),
ExpectedCloseDate = ApiDateTimeHelper.Get(deal.ExpectedCloseDate),
CanEdit = CRMSecurity.CanEdit(deal)
};
}
}
public static class OpportunityWrapperHelperExtension
{
public static DIHelper AddOpportunityWrapperHelperService(this DIHelper services)
{
services.TryAddTransient<OpportunityWrapperHelper>();
return services.AddApiDateTimeHelper()
.AddEmployeeWraper()
.AddCRMSecurityService();
}
}
}

View File

@ -0,0 +1,154 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.Api.Documents;
using ASC.Common;
using ASC.CRM.Core;
using ASC.CRM.Core.Entities;
using ASC.Web.Api.Models;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
[DataContract(Name = "entity", Namespace = "")]
public class EntityWrapper
{
[DataMember]
public String EntityType { get; set; }
[DataMember]
public int EntityId { get; set; }
[DataMember]
public String EntityTitle { get; set; }
public static EntityWrapper GetSample()
{
return new EntityWrapper
{
EntityId = 123445,
EntityType = "opportunity",
EntityTitle = "Household appliances internet shop"
};
}
}
[DataContract(Name = "historyEvent", Namespace = "")]
public class RelationshipEventWrapper
{
public RelationshipEventWrapper()
{
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EmployeeWraper CreateBy { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public ApiDateTime Created { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public String Content { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public HistoryCategoryBaseWrapper Category { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactBaseWrapper Contact { get; set; }
[DataMember]
public EntityWrapper Entity { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public bool CanEdit { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<FileWrapper<int>> Files { get; set; }
public static RelationshipEventWrapper GetSample()
{
return new RelationshipEventWrapper
{
CanEdit = true,
Category = HistoryCategoryBaseWrapper.GetSample(),
Entity = EntityWrapper.GetSample(),
Contact = ContactBaseWrapper.GetSample(),
Created = ApiDateTime.GetSample(),
CreateBy = EmployeeWraper.GetSample(),
Files = new[] { FileWrapper<int>.GetSample() },
Content = @"Agreed to meet at lunch and discuss the client commercial offer"
};
}
}
public class RelationshipEventWrapperHelper
{
public RelationshipEventWrapperHelper(ApiDateTimeHelper apiDateTimeHelper,
EmployeeWraperHelper employeeWraperHelper,
CRMSecurity cRMSecurity)
{
ApiDateTimeHelper = apiDateTimeHelper;
EmployeeWraperHelper = employeeWraperHelper;
CRMSecurity = cRMSecurity;
}
public CRMSecurity CRMSecurity { get; }
public ApiDateTimeHelper ApiDateTimeHelper { get; }
public EmployeeWraperHelper EmployeeWraperHelper { get; }
public RelationshipEventWrapper Get(RelationshipEvent relationshipEvent)
{
return new RelationshipEventWrapper
{
Id = relationshipEvent.ID,
CreateBy = EmployeeWraperHelper.Get(relationshipEvent.CreateBy),
Created = ApiDateTimeHelper.Get(relationshipEvent.CreateOn),
Content = relationshipEvent.Content,
Files = new List<FileWrapper<int>>(),
CanEdit = CRMSecurity.CanEdit(relationshipEvent)
};
}
}
public static class RelationshipEventWrapperHelperExtension
{
public static DIHelper AddRelationshipEventWrapperHelperService(this DIHelper services)
{
services.TryAddTransient<RelationshipEventWrapperHelper>();
return services.AddApiDateTimeHelper()
.AddEmployeeWraper()
.AddCRMSecurityService();
}
}
}

View File

@ -0,0 +1,48 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
[DataContract]
public class ReportWrapper
{
[DataMember]
public String ReportTitle { get; set; }
[DataMember]
public String ReportDescription { get; set; }
[DataMember]
public IEnumerable<String> Lables { get; set; }
[DataMember]
public Object Data { get; set; }
}
}

View File

@ -0,0 +1,37 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
namespace ASC.Api.CRM.Wrappers
{
public enum SubjectEnum
{
Contact,
Person,
Company,
Case,
Opportunity
}
}

View File

@ -0,0 +1,118 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Web.Api.Models;
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
[DataContract(Namespace = "taskTemplateContainer")]
public class TaskTemplateContainerWrapper
{
public TaskTemplateContainerWrapper()
{
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = true)]
public String Title { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = true)]
public String EntityType { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public IEnumerable<TaskTemplateWrapper> Items { get; set; }
public static TaskTemplateContainerWrapper GetSample()
{
return new TaskTemplateContainerWrapper
{
EntityType = "contact",
Title = "Birthday greetings",
Items = new List<TaskTemplateWrapper>
{
TaskTemplateWrapper.GetSample()
}
};
}
}
[DataContract(Namespace = "taskTemplate")]
public class TaskTemplateWrapper
{
public TaskTemplateWrapper()
{
}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public int ContainerID { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public String Title { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Description { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public EmployeeWraper Responsible { get; set; }
[DataMember(IsRequired = true, EmitDefaultValue = false)]
public TaskCategoryWrapper Category { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool isNotify { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public long OffsetTicks { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = true)]
public bool DeadLineIsFixed { get; set; }
public static TaskTemplateWrapper GetSample()
{
return new TaskTemplateWrapper
{
Title = "Send an Email",
Category = TaskCategoryWrapper.GetSample(),
isNotify = true,
Responsible = EmployeeWraper.GetSample(),
ContainerID = 12,
DeadLineIsFixed = false,
OffsetTicks = TimeSpan.FromDays(10).Ticks,
Description = ""
};
}
}
}

View File

@ -0,0 +1,236 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.Common;
using ASC.CRM.Core;
using ASC.CRM.Core.Dao;
using ASC.CRM.Core.Entities;
using ASC.Web.Api.Models;
using System;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
/// <summary>
/// Task
/// </summary>
[DataContract(Name = "task", Namespace = "")]
public class TaskWrapper
{
//public TaskWrapper(Task task)
//{
// CreateBy = EmployeeWraper.Get(task.CreateBy);
// Created = (ApiDateTime)task.CreateOn;
// Title = task.Title;
// Description = task.Description;
// DeadLine = (ApiDateTime)task.DeadLine;
// Responsible = EmployeeWraper.Get(task.ResponsibleID);
// IsClosed = task.IsClosed;
// AlertValue = task.AlertValue;
//}
[DataMember(Name = "id")]
public int Id { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EmployeeWraper CreateBy { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ApiDateTime Created { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ContactBaseWithEmailWrapper Contact { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Title { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Description { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ApiDateTime DeadLine { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int AlertValue { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EmployeeWraper Responsible { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public bool IsClosed { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public TaskCategoryBaseWrapper Category { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EntityWrapper Entity { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public bool CanEdit { get; set; }
public static TaskWrapper GetSample()
{
return new TaskWrapper
{
Created = ApiDateTime.GetSample(),
CreateBy = EmployeeWraper.GetSample(),
DeadLine = ApiDateTime.GetSample(),
IsClosed = false,
Responsible = EmployeeWraper.GetSample(),
// Category = TaskCategoryBaseWrapper.GetSample(),
CanEdit = true,
Title = "Send a commercial offer",
AlertValue = 0
};
}
}
[DataContract(Name = "taskBase", Namespace = "")]
public class TaskBaseWrapper
{
[DataMember(Name = "id")]
public int Id { get; set; }
public TaskBaseWrapper()
{
}
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Title { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public String Description { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public ApiDateTime DeadLine { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public int AlertValue { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EmployeeWraper Responsible { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public bool IsClosed { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public TaskCategoryBaseWrapper Category { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public EntityWrapper Entity { get; set; }
[DataMember(IsRequired = false, EmitDefaultValue = false)]
public bool CanEdit { get; set; }
public static TaskBaseWrapper GetSample()
{
return new TaskBaseWrapper
{
DeadLine = ApiDateTime.GetSample(),
IsClosed = false,
Responsible = EmployeeWraper.GetSample(),
Category = TaskCategoryBaseWrapper.GetSample(),
CanEdit = true,
Title = "Send a commercial offer",
AlertValue = 0
};
}
}
public class TaskWrapperHelper
{
public TaskWrapperHelper(ApiDateTimeHelper apiDateTimeHelper,
EmployeeWraperHelper employeeWraperHelper,
CRMSecurity cRMSecurity,
DaoFactory daoFactory)
{
ApiDateTimeHelper = apiDateTimeHelper;
EmployeeWraperHelper = employeeWraperHelper;
CRMSecurity = cRMSecurity;
DaoFactory = daoFactory;
}
public CRMSecurity CRMSecurity { get; }
public ApiDateTimeHelper ApiDateTimeHelper { get; }
public EmployeeWraperHelper EmployeeWraperHelper { get; }
public DaoFactory DaoFactory { get; }
public TaskWrapper Get(Task task)
{
var result = new TaskWrapper
{
Title = task.Title,
Description = task.Description,
DeadLine = ApiDateTimeHelper.Get(task.DeadLine),
Responsible = EmployeeWraperHelper.Get(task.ResponsibleID),
IsClosed = task.IsClosed,
AlertValue = task.AlertValue
};
if (task.CategoryID > 0)
{
result.Category = GetTaskCategoryByID(task.CategoryID);
}
if (task.ContactID > 0)
{
result.Contact = ToContactBaseWithEmailWrapper(DaoFactory.GetContactDao().GetByID(task.ContactID));
}
if (task.EntityID > 0)
{
result.Entity = ToEntityWrapper(task.EntityType, task.EntityID);
}
result.CanEdit = CRMSecurity.CanEdit(task);
return result;
}
}
public static class TaskWrapperHelperExtension
{
public static DIHelper AddTaskWrapperHelperService(this DIHelper services)
{
services.TryAddTransient<TaskWrapperHelper>();
return services.AddApiDateTimeHelper()
.AddEmployeeWraper()
.AddCRMSecurityService();
}
}
}
//private TaskWrapper ToTaskWrapper(Task task)
//{
// var result = new TaskWrapper(task);
// return result;
//}

View File

@ -0,0 +1,95 @@
/*
*
* (c) Copyright Ascensio System Limited 2010-2018
*
* This program is freeware. You can redistribute it and/or modify it under the terms of the GNU
* General Public License (GPL) version 3 as published by the Free Software Foundation (https://www.gnu.org/copyleft/gpl.html).
* In accordance with Section 7(a) of the GNU GPL its Section 15 shall be amended to the effect that
* Ascensio System SIA expressly excludes the warranty of non-infringement of any third-party rights.
*
* THIS PROGRAM IS DISTRIBUTED WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY OR
* FITNESS FOR A PARTICULAR PURPOSE. For more details, see GNU GPL at https://www.gnu.org/copyleft/gpl.html
*
* You can contact Ascensio System SIA by email at sales@onlyoffice.com
*
* The interactive user interfaces in modified source and object code versions of ONLYOFFICE must display
* Appropriate Legal Notices, as required under Section 5 of the GNU GPL version 3.
*
* Pursuant to Section 7 § 3(b) of the GNU GPL you must retain the original ONLYOFFICE logo which contains
* relevant author attributions when distributing the software. If the display of the logo in its graphic
* form is not reasonably feasible for technical reasons, you must include the words "Powered by ONLYOFFICE"
* in every copy of the program you distribute.
* Pursuant to Section 7 § 3(e) we decline to grant you any rights under trademark law for use of our trademarks.
*
*/
using ASC.Api.Core;
using ASC.VoipService;
using ASC.Web.Api.Models;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
namespace ASC.Api.CRM.Wrappers
{
[DataContract(Name = "voipCall", Namespace = "")]
public class VoipCallWrapper
{
[DataMember(Order = 1)]
public string Id { get; set; }
[DataMember(Order = 2)]
public string From { get; set; }
[DataMember(Order = 3)]
public string To { get; set; }
[DataMember(Order = 4)]
public VoipCallStatus? Status { get; set; }
[DataMember(Order = 5)]
public EmployeeWraper AnsweredBy { get; set; }
[DataMember(Order = 6)]
public ApiDateTime DialDate { get; set; }
[DataMember(Order = 7)]
public int DialDuration { get; set; }
[DataMember(Order = 10)]
public decimal Cost { get; set; }
[DataMember(Order = 11)]
public ContactWrapper Contact { get; set; }
[DataMember(Order = 11, EmitDefaultValue = false)]
public IEnumerable<VoipCallWrapper> Calls { get; set; }
[DataMember(Order = 13)]
public string RecordUrl { get; set; }
[DataMember(Order = 14)]
public int RecordDuration { get; set; }
public VoipCallWrapper(VoipCall call, ContactWrapper contact = null)
{
Id = call.Id;
From = call.From;
To = call.To;
Status = call.Status;
AnsweredBy = EmployeeWraper.Get(call.AnsweredBy);
DialDate = new ApiDateTime(call.DialDate);
DialDuration = call.DialDuration;
Cost = call.Price + call.ChildCalls.Sum(r=> r.Price) + call.VoipRecord.Price;
Contact = contact;
RecordUrl = call.VoipRecord.Uri;
RecordDuration = call.VoipRecord.Duration;
if (call.ChildCalls.Any())
{
Calls = call.ChildCalls.Select(childCall => new VoipCallWrapper(childCall));
}
}
}
}

View File

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
@ -21,6 +22,28 @@ namespace ASC.CRM
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
})
.ConfigureAppConfiguration((hostingContext, config) =>
{
var buided = config.Build();
var path = buided["pathToConf"];
if (!Path.IsPathRooted(path))
{
path = Path.GetFullPath(Path.Combine(hostingContext.HostingEnvironment.ContentRootPath, path));
}
config.SetBasePath(path);
config
.AddInMemoryCollection(new Dictionary<string, string>
{
{"pathToConf", path}
})
.AddJsonFile("appsettings.json")
.AddJsonFile($"appsettings.{hostingContext.HostingEnvironment.EnvironmentName}.json", true)
.AddJsonFile("storage.json")
.AddJsonFile("kafka.json")
.AddJsonFile($"kafka.{hostingContext.HostingEnvironment.EnvironmentName}.json", true)
.AddEnvironmentVariables();
});
}
}

View File

@ -1,5 +1,4 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
@ -8,6 +7,7 @@
"sslPort": 0
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
@ -20,11 +20,11 @@
"Kestrel WebServer": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"applicationUrl": "http://localhost:5000",
"launchUrl": "api/2.0/crm/task/10",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"applicationUrl": "http://localhost:5000"
}
}
}

View File

@ -23,6 +23,7 @@
*
*/
using ASC.Common;
using ASC.Core;
using ASC.Core.Billing;
using ASC.Core.Tenants;
@ -54,11 +55,11 @@ namespace ASC.Web.CRM.Services.NotifyService
{
ServiceProvider = serviceProvider;
}
public IServiceProvider ServiceProvider { get; }
public void SendAboutCreateNewContact(List<Guid> recipientID,
int contactID,
public void SendAboutCreateNewContact(List<Guid> recipientID,
int contactID,
string contactTitle, NameValueCollection fields)
{
if ((recipientID.Count == 0) || String.IsNullOrEmpty(contactTitle)) return;
@ -114,26 +115,26 @@ namespace ASC.Web.CRM.Services.NotifyService
case EntityType.Person:
case EntityType.Company:
case EntityType.Contact:
{
var contact = daoFactory.GetContactDao().GetByID(entityID);
title = contact != null ? contact.GetTitle() : string.Empty;
relativeURL = "default.aspx?id=" + entityID;
break;
}
{
var contact = daoFactory.GetContactDao().GetByID(entityID);
title = contact != null ? contact.GetTitle() : string.Empty;
relativeURL = "default.aspx?id=" + entityID;
break;
}
case EntityType.Opportunity:
{
var deal = daoFactory.GetDealDao().GetByID(entityID);
title = deal != null ? deal.Title : string.Empty;
relativeURL = "deals.aspx?id=" + entityID;
break;
}
{
var deal = daoFactory.GetDealDao().GetByID(entityID);
title = deal != null ? deal.Title : string.Empty;
relativeURL = "deals.aspx?id=" + entityID;
break;
}
case EntityType.Case:
{
var cases = daoFactory.GetCasesDao().GetByID(entityID);
title = cases != null ? cases.Title : string.Empty;
relativeURL = "cases.aspx?id=" + entityID;
break;
}
{
var cases = daoFactory.GetCasesDao().GetByID(entityID);
title = cases != null ? cases.Title : string.Empty;
relativeURL = "cases.aspx?id=" + entityID;
break;
}
default:
throw new ArgumentException();
@ -156,7 +157,7 @@ namespace ASC.Web.CRM.Services.NotifyService
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
NameValueCollection baseEntityData;
if (entity.EntityID != 0)
@ -197,7 +198,7 @@ namespace ASC.Web.CRM.Services.NotifyService
new TagValue(NotifyConstants.Tag_EntityID, baseEntityData["id"]),
new TagValue(NotifyConstants.Tag_EntityRelativeURL, baseEntityData["entityRelativeURL"]),
new TagValue(NotifyConstants.Tag_AdditionalData,
new Hashtable {
new Hashtable {
{ "Files", fileListInfoHashtable },
{"EventContent", entity.Content}}));
@ -220,7 +221,7 @@ namespace ASC.Web.CRM.Services.NotifyService
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var recipient = notifySource.GetRecipientsProvider().GetRecipient(recipientID.ToString());
var recipient = notifySource.GetRecipientsProvider().GetRecipient(recipientID.ToString());
client.SendNoticeToAsync(coreBaseSettings.CustomMode ? NotifyConstants.Event_ExportCompletedCustomMode : NotifyConstants.Event_ExportCompleted,
null,
@ -353,9 +354,9 @@ namespace ASC.Web.CRM.Services.NotifyService
// }
// }
// var listItem = dao.ListItemDao.GetByID(task.CategoryID);
// var listItem = dao.GetListItemDao().GetByID(task.CategoryID);
// NotifyClient.Instance.SendTaskReminder(task,
// NotifyClient.SendTaskReminder(task,
// listItem != null ? listItem.Title : string.Empty,
// taskContact, taskCase, taskDeal);
// }
@ -371,11 +372,11 @@ namespace ASC.Web.CRM.Services.NotifyService
//}
public void SendTaskReminder(Task task, String taskCategoryTitle, Contact taskContact, ASC.CRM.Core.Entities.Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal)
{
{
using var scope = ServiceProvider.CreateScope();
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var recipient = notifySource.GetRecipientsProvider().GetRecipient(task.ResponsibleID.ToString());
if (recipient == null) return;
@ -420,7 +421,7 @@ namespace ASC.Web.CRM.Services.NotifyService
true,
new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
new TagValue(NotifyConstants.Tag_AdditionalData,
new Hashtable {
new Hashtable {
{ "TaskDescription", HttpUtility.HtmlEncode(task.Description) },
{ "TaskCategory", taskCategoryTitle },
@ -439,13 +440,13 @@ namespace ASC.Web.CRM.Services.NotifyService
}
public void SendAboutResponsibleByTask(Task task, String taskCategoryTitle, Contact taskContact, Cases taskCase, ASC.CRM.Core.Entities.Deal taskDeal, Hashtable fileListInfoHashtable)
{
{
using var scope = ServiceProvider.CreateScope();
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var tenantUtil = scope.ServiceProvider.GetService<TenantUtil>();
var recipient = notifySource.GetRecipientsProvider().GetRecipient(task.ResponsibleID.ToString());
var recipient = notifySource.GetRecipientsProvider().GetRecipient(task.ResponsibleID.ToString());
if (recipient == null) return;
@ -482,7 +483,7 @@ namespace ASC.Web.CRM.Services.NotifyService
taskDealRelativeUrl = String.Format("products/crm/deals.aspx?id={0}", taskDeal.ID);
taskDealTitle = taskDeal.Title.HtmlEncode();
}
client.SendNoticeToAsync(
NotifyConstants.Event_ResponsibleForTask,
null,
@ -490,7 +491,7 @@ namespace ASC.Web.CRM.Services.NotifyService
true,
new TagValue(NotifyConstants.Tag_EntityTitle, task.Title),
new TagValue(NotifyConstants.Tag_AdditionalData,
new Hashtable {
new Hashtable {
{ "TaskDescription", HttpUtility.HtmlEncode(task.Description) },
{ "Files", fileListInfoHashtable },
{ "TaskCategory", taskCategoryTitle },
@ -515,7 +516,7 @@ namespace ASC.Web.CRM.Services.NotifyService
var notifySource = scope.ServiceProvider.GetService<NotifySource>();
var securityContext = scope.ServiceProvider.GetService<SecurityContext>();
var client = WorkContext.NotifyContext.NotifyService.RegisterClient(notifySource, scope);
var recipient = notifySource.GetRecipientsProvider().GetRecipient(deal.ResponsibleID.ToString());
if (recipient == null) return;
@ -528,22 +529,22 @@ namespace ASC.Web.CRM.Services.NotifyService
new TagValue(NotifyConstants.Tag_EntityTitle, deal.Title),
new TagValue(NotifyConstants.Tag_EntityID, deal.ID),
new TagValue(NotifyConstants.Tag_AdditionalData,
new Hashtable {
new Hashtable {
{ "OpportunityDescription", HttpUtility.HtmlEncode(deal.Description) }
})
);
}
//public INotifyClient Client
//{
// get { return client; }
//}
//private NotifyClient(INotifyClient client, INotifySource source)
//{
// this.client = client;
// this.source = source;
//}
}
}
public static class NotifyClientExtention
{
public static DIHelper AddNotifyClientService(this DIHelper services)
{
services.TryAddScoped<NotifyClient>();
return services;
}
}
}

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ASC.Api.Core.Auth;
using ASC.Api.Core.Core;
using ASC.Api.Core.Middleware;
using ASC.Common;
using Microsoft.AspNetCore.Builder;
@ -12,26 +13,66 @@ using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using ASC.Common.Logging;
using Autofac.Extensions.DependencyInjection;
using ASC.Common.DependencyInjection;
using ASC.Api.CRM;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc.Authorization;
using Microsoft.AspNetCore.Mvc.Formatters;
using System.Text;
namespace ASC.CRM
{
public class Startup
{
public Startup(IConfiguration configuration)
public Startup(IConfiguration configuration, IHostEnvironment hostEnvironment)
{
Configuration = configuration;
HostEnvironment = hostEnvironment;
}
public IHostEnvironment HostEnvironment { get; }
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
services.AddHttpContextAccessor();
services.AddControllers();
services.AddControllers()
.AddNewtonsoftJson()
.AddXmlSerializerFormatters();
services.AddTransient<IConfigureOptions<MvcNewtonsoftJsonOptions>, CustomJsonOptionsWrapper>();
services.AddMemoryCache();
services.AddAuthentication("cookie")
.AddScheme<AuthenticationSchemeOptions, CookieAuthHandler>("cookie", a => { });
var builder = services.AddMvcCore(config =>
{
//var policy = new AuthorizationPolicyBuilder().RequireAuthenticatedUser().Build();
//config.Filters.Add(new AuthorizeFilter(policy));
//config.Filters.Add(new TypeFilterAttribute(typeof(TenantStatusFilter)));
//config.Filters.Add(new TypeFilterAttribute(typeof(PaymentFilter)));
//config.Filters.Add(new TypeFilterAttribute(typeof(IpSecurityFilter)));
//config.Filters.Add(new TypeFilterAttribute(typeof(ProductSecurityFilter)));
//config.Filters.Add(new CustomResponseFilterAttribute());
//config.Filters.Add(new CustomExceptionFilterAttribute());
//config.Filters.Add(new TypeFilterAttribute(typeof(FormatFilter)));
config.OutputFormatters.RemoveType<XmlSerializerOutputFormatter>();
config.OutputFormatters.Add(new XmlOutputFormatter());
});
var diHelper = new DIHelper(services);
diHelper
.AddCookieAuthHandler()
.AddCultureMiddleware()
@ -40,6 +81,13 @@ namespace ASC.CRM
.AddProductSecurityFilter()
.AddTenantStatusFilter();
diHelper.AddNLogManager("ASC.CRM");
diHelper.AddCRMControllerService();
services.AddAutofac(Configuration, HostEnvironment.ContentRootPath);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
@ -50,8 +98,6 @@ namespace ASC.CRM
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseAuthorization();

View File

@ -61,7 +61,8 @@ namespace ASC.Web.CRM.Classes
Configuration = configuration;
SettingsManager = settingsManager;
var currencies = daoFactory.GetCurrencyInfoDao().GetAll();
var daocur = daoFactory.GetCurrencyInfoDao();
var currencies = daocur.GetAll();
if (currencies == null || currencies.Count == 0)
{
@ -351,10 +352,10 @@ namespace ASC.Web.CRM.Classes
{
public static DIHelper AddCurrencyProviderService(this DIHelper services)
{
services.TryAddScoped<CRMSecurity>();
services.TryAddScoped<CurrencyProvider>();
return services.AddSettingsManagerService()
.AddDaoFactoryService();
return services.AddSettingsManagerService();
// .AddDaoFactoryService();
}
}
}
}

View File

@ -773,7 +773,7 @@ namespace ASC.Web.CRM.Classes
return services.AddPathProviderService()
.AddDocumentServiceConnectorService()
.AddOrganisationLogoManagerService()
.AddDaoFactoryService()
// .AddDaoFactoryService()
.AddInvoiceFormattedDataService();
}
}

View File

@ -1,9 +0,0 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}

View File

@ -1,10 +1,3 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*"
"pathToConf": "..\\..\\..\\config"
}