crm: migrate DAO to EF Core

This commit is contained in:
Alexey Bannov 2020-04-07 23:48:40 +03:00
parent bbb4997f20
commit 47a2c521f3
12 changed files with 593 additions and 467 deletions

View File

@ -489,7 +489,7 @@ namespace ASC.CRM.Core.Dao
{
foreach (var k in keywords)
{
result = result.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k));
result = result.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%"));
}
}
else if (!ids.Any())

View File

@ -202,12 +202,11 @@ namespace ASC.CRM.Core.Dao
var idsFromAcl = CoreDbContext.Acl.Where(x => x.Tenant == TenantID &&
x.Action == CRMSecurity._actionRead.ID &&
x.Subject == SecurityContext.CurrentAccount.ID &&
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Company).FullName. ))
(Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Company).FullName + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Object, typeof(Person).FullName + "%")))
.Select(x => Convert.ToInt32(x.Object.Split('|', StringSplitOptions.None)[1]))
.ToList();
objectId.ObjectType.FullName
// oldContacts || publicContact || contact is private, but user is ManagerContact
sqlQuery = sqlQuery.Where(x => x.IsShared == null || x.IsShared > 0 || idsFromAcl.Contains(x.Id));
}
@ -700,7 +699,7 @@ namespace ASC.CRM.Core.Dao
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.DisplayName, k));
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.DisplayName, k + "%"));
}
}
else
@ -1639,11 +1638,11 @@ namespace ASC.CRM.Core.Dao
}
var contactID = newContactID.ToArray();
var filesIDs = new object[0];
int[] filesIDs = new int[0];
var tx = CRMDbContext.Database.BeginTransaction();
var tagdao = FilesIntegration.TagDao();
var tagdao = FilesIntegration.DaoFactory.GetTagDao<int>();
var tagNames = Query(CRMDbContext.RelationshipEvent).Where(x => contactID.Contains(x.ContactId) && x.HaveFiles)
.Select(x => String.Format("RelationshipEvent_{0}", x.Id)).ToArray();
@ -1652,7 +1651,7 @@ namespace ASC.CRM.Core.Dao
{
filesIDs = tagdao.GetTags(tagNames, TagType.System)
.Where(t => t.EntryType == FileEntryType.File)
.Select(t => t.EntryId)
.Select(t => Convert.ToInt32(t.EntryId))
.ToArray();
}
@ -1705,7 +1704,7 @@ namespace ASC.CRM.Core.Dao
contacts.ForEach(contact => AuthorizationManager.RemoveAllAces(contact));
var filedao = FilesIntegration.GetFileDao();
var filedao = FilesIntegration.DaoFactory.GetFileDao<int>();
foreach (var filesID in filesIDs)
{

View File

@ -327,7 +327,7 @@ namespace ASC.CRM.Core.Dao
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k) || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k));
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") || Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%"));
}
}
else if (ids.Count == 0) return null;
@ -819,7 +819,7 @@ namespace ASC.CRM.Core.Dao
var dealID = deals.Select(x => x.ID).ToArray();
object[] filesIDs;
var tagdao = FilesIntegration.TagDao();
var tagdao = FilesIntegration.DaoFactory.GetTagDao<int>();
var tagNames = Query(CRMDbContext.RelationshipEvent)
.Where(x => x.HaveFiles && dealID.Contains(x.EntityId) && x.EntityType == EntityType.Opportunity)
@ -849,11 +849,11 @@ namespace ASC.CRM.Core.Dao
deals.ForEach(deal => AuthorizationManager.RemoveAllAces(deal));
var filedao = FilesIntegration.GetFileDao();
var filedao = FilesIntegration.DaoFactory.GetFileDao<int>();
foreach (var filesID in filesIDs)
{
filedao.DeleteFile(filesID);
filedao.DeleteFile(Convert.ToInt32(filesID));
}
}

View File

@ -873,8 +873,8 @@ namespace ASC.CRM.Core.Dao
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Number, k) ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k));
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Number, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%"));
}
}
else

View File

@ -24,6 +24,7 @@
*/
using ASC.Collections;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Core.Common.EF;
using ASC.CRM.Classes;
@ -31,7 +32,9 @@ using ASC.CRM.Core.EF;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.CRM.Resources;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
@ -42,18 +45,20 @@ namespace ASC.CRM.Core.Dao
public class CachedListItem : ListItemDao
{
private readonly HttpRequestDictionary<ListItem> _listItemCache = new HttpRequestDictionary<ListItem>("crm_list_item");
private readonly HttpRequestDictionary<ListItem> _listItemCache;
public CachedListItem(
DbContextManager<CRMDbContext> dbContextManager,
TenantManager tenantManager,
SecurityContext securityContext)
SecurityContext securityContext,
IHttpContextAccessor httpContextAccessor,
IOptionsMonitor<ILog> logger)
: base(dbContextManager,
tenantManager,
securityContext)
securityContext,
logger)
{
_listItemCache = new HttpRequestDictionary<ListItem>(httpContextAccessor?.HttpContext, "crm_list_item");
}
public override void ChangeColor(int id, string newColor)
@ -112,10 +117,12 @@ namespace ASC.CRM.Core.Dao
public ListItemDao(
DbContextManager<CRMDbContext> dbContextManager,
TenantManager tenantManager,
SecurityContext securityContext)
SecurityContext securityContext,
IOptionsMonitor<ILog> logger)
: base(dbContextManager,
tenantManager,
securityContext)
securityContext,
logger)
{
@ -274,7 +281,7 @@ namespace ASC.CRM.Core.Dao
public int GetRelativeItemsCount(ListType listType, int id)
{
int result;
switch (listType)
{
case ListType.ContactStatus:
@ -300,48 +307,66 @@ namespace ASC.CRM.Core.Dao
public Dictionary<int, int> GetRelativeItemsCount(ListType listType)
{
var sqlQuery = Query("crm_list_item tbl_list_item")
.Where(Exp.Eq("tbl_list_item.list_type", (int)listType))
.Select("tbl_list_item.id")
.OrderBy("tbl_list_item.sort_order", true)
.GroupBy("tbl_list_item.id");
Dictionary<int, int> result;
switch (listType)
{
case ListType.ContactStatus:
sqlQuery.LeftOuterJoin("crm_contact tbl_crm_contact",
Exp.EqColumns("tbl_list_item.id", "tbl_crm_contact.status_id")
& Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_contact.tenant_id"))
.Select("count(tbl_crm_contact.status_id)");
break;
case ListType.ContactType:
sqlQuery.LeftOuterJoin("crm_contact tbl_crm_contact",
Exp.EqColumns("tbl_list_item.id", "tbl_crm_contact.contact_type_id")
& Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_contact.tenant_id"))
.Select("count(tbl_crm_contact.contact_type_id)");
break;
case ListType.TaskCategory:
sqlQuery.LeftOuterJoin("crm_task tbl_crm_task",
Exp.EqColumns("tbl_list_item.id", "tbl_crm_task.category_id")
& Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_task.tenant_id"))
.Select("count(tbl_crm_task.category_id)");
break;
case ListType.HistoryCategory:
sqlQuery.LeftOuterJoin("crm_relationship_event tbl_crm_relationship_event",
Exp.EqColumns("tbl_list_item.id", "tbl_crm_relationship_event.category_id")
& Exp.EqColumns("tbl_list_item.tenant_id", "tbl_crm_relationship_event.tenant_id"))
.Select("count(tbl_crm_relationship_event.category_id)");
{
result = Query(CRMDbContext.ListItem)
.GroupJoin(Query(CRMDbContext.Contacts),
x => x.Id,
y => y.StatusId,
(x, y) => new { Column1 = x, Column2 = y.Count() })
.Where(x => x.Column1.ListType == listType)
.OrderBy(x => x.Column1.SortOrder)
.ToDictionary(x => x.Column1.Id, x => x.Column2);
break;
break;
}
case ListType.ContactType:
{
result = Query(CRMDbContext.ListItem)
.GroupJoin(Query(CRMDbContext.Contacts),
x => x.Id,
y => y.ContactTypeId,
(x, y) => new { Column1 = x, Column2 = y.Count() })
.Where(x => x.Column1.ListType == listType)
.OrderBy(x => x.Column1.SortOrder)
.ToDictionary(x => x.Column1.Id, x => x.Column2);
break;
}
case ListType.TaskCategory:
{
result = Query(CRMDbContext.ListItem)
.GroupJoin(Query(CRMDbContext.Tasks),
x => x.Id,
y => y.CategoryId,
(x, y) => new { Column1 = x, Column2 = y.Count() })
.Where(x => x.Column1.ListType == listType)
.OrderBy(x => x.Column1.SortOrder)
.ToDictionary(x => x.Column1.Id, x => x.Column2);
break;
}
case ListType.HistoryCategory:
{
result = Query(CRMDbContext.ListItem)
.GroupJoin(Query(CRMDbContext.RelationshipEvent),
x => x.Id,
y => y.CategoryId,
(x, y) => new { Column1 = x, Column2 = y.Count() })
.Where(x => x.Column1.ListType == listType)
.OrderBy(x => x.Column1.SortOrder)
.ToDictionary(x => x.Column1.Id, x => x.Column2);
break;
}
default:
throw new ArgumentException();
}
var queryResult = Db.ExecuteList(sqlQuery);
return queryResult.ToDictionary(x => Convert.ToInt32(x[0]), y => Convert.ToInt32(y[1]));
return result;
}
public virtual int CreateItem(ListType listType, ListItem enumItem)
@ -412,7 +437,7 @@ namespace ASC.CRM.Core.Dao
itemToUpdate.Title = enumItem.Title;
itemToUpdate.AdditionalParams = enumItem.AdditionalParams;
itemToUpdate.Color = enumItem.Color;
CRMDbContext.SaveChanges();
}
@ -476,18 +501,18 @@ namespace ASC.CRM.Core.Dao
case ListType.ContactType:
{
var itemToUpdate = Query(CRMDbContext.Contacts).Single(x => x.ContactTypeId == fromItemID);
itemToUpdate.ContactTypeId = toItemID;
CRMDbContext.Update(itemToUpdate);
}
break;
case ListType.TaskCategory:
{
{
var itemToUpdate = Query(CRMDbContext.Tasks).Single(x => x.CategoryId == fromItemID);
itemToUpdate.CategoryId = toItemID;
CRMDbContext.Update(itemToUpdate);
CRMDbContext.Update(itemToUpdate);
}
break;
case ListType.HistoryCategory:

View File

@ -24,39 +24,32 @@
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using ASC.Collections;
using ASC.Common.Logging;
using ASC.Core;
using ASC.Core.Common.EF;
using ASC.Core.Tenants;
using ASC.CRM.Classes;
using ASC.CRM.Core.EF;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.ElasticSearch;
using ASC.Files.Core;
using ASC.Web.CRM;
using ASC.Web.CRM.Classes;
using ASC.Web.CRM.Core.Search;
using ASC.Web.Files.Api;
using ASC.Web.Studio.Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OrderBy = ASC.CRM.Core.Entities.OrderBy;
using File = ASC.Files.Core.File;
using ASC.CRM.Core.Enums;
using ASC.Core.Common.EF;
using ASC.CRM.Core.EF;
using ASC.Core;
using ASC.CRM.Classes;
using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;
using System.Text;
using OrderBy = ASC.CRM.Core.Entities.OrderBy;
namespace ASC.CRM.Core.Dao
{
@ -73,7 +66,9 @@ namespace ASC.CRM.Core.Dao
TenantUtil tenantUtil,
SetupInfo setupInfo,
PathProvider pathProvider,
IHttpContextAccessor httpContextAccessor
IHttpContextAccessor httpContextAccessor,
IOptionsMonitor<ILog> logger
) :
base(dbContextManager,
tenantManager,
@ -82,7 +77,8 @@ namespace ASC.CRM.Core.Dao
cRMSecurity,
tenantUtil,
setupInfo,
pathProvider)
pathProvider,
logger)
{
_contactCache = new HttpRequestDictionary<RelationshipEvent>(httpContextAccessor?.HttpContext, "crm_relationshipEvent");
}
@ -113,11 +109,13 @@ namespace ASC.CRM.Core.Dao
CRMSecurity cRMSecurity,
TenantUtil tenantUtil,
SetupInfo setupInfo,
PathProvider pathProvider
PathProvider pathProvider,
IOptionsMonitor<ILog> logger
) :
base(dbContextManager,
tenantManager,
securityContext)
securityContext,
logger)
{
FilesIntegration = filesIntegration;
TenantUtil = tenantUtil;
@ -164,7 +162,7 @@ namespace ASC.CRM.Core.Dao
{
if (fileIDs.Length == 0) return;
var dao = FilesIntegration.TagDao();
var dao = FilesIntegration.DaoFactory.GetTagDao<int>();
var tags = fileIDs.ToList().ConvertAll(fileID => new Tag("RelationshipEvent_" + eventID, TagType.System, Guid.Empty) { EntryType = FileEntryType.File, EntryId = fileID });
@ -190,7 +188,7 @@ namespace ASC.CRM.Core.Dao
return GetFilesIDs(contactID, entityType, entityID).Length;
}
private object[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID)
private int[] GetFilesIDs(int[] contactID, EntityType entityType, int entityID)
{
if (entityID > 0 && entityType != EntityType.Opportunity && entityType != EntityType.Case)
throw new ArgumentException();
@ -206,42 +204,42 @@ namespace ASC.CRM.Core.Dao
sqlQuery = sqlQuery.Where(x => x.HaveFiles);
var tagNames = sqlQuery.Select(x => String.Format("RelationshipEvent_{0}", x.Id));
var tagdao = FilesIntegration.TagDao();
var tagdao = FilesIntegration.DaoFactory.GetTagDao<int>();
return tagdao.GetTags(tagNames.ToArray(), TagType.System)
.Where(t => t.EntryType == FileEntryType.File)
.Select(t => t.EntryId).ToArray();
.Select(t => Convert.ToInt32(t.EntryId)).ToArray();
}
public List<File> GetAllFiles(int[] contactID, EntityType entityType, int entityID)
public List<File<int>> GetAllFiles(int[] contactID, EntityType entityType, int entityID)
{
var filedao = FilesIntegration.GetFileDao();
var filedao = FilesIntegration.DaoFactory.GetFileDao<int>();
var ids = GetFilesIDs(contactID, entityType, entityID);
var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List<File>();
var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List<File<int>>();
files.ForEach(CRMSecurity.SetAccessTo);
return files.ToList();
}
public Dictionary<int, List<File>> GetFiles(int[] eventID)
public Dictionary<int, List<File<int>>> GetFiles(int[] eventID)
{
if (eventID == null || eventID.Length == 0)
throw new ArgumentException("eventID");
var tagdao = FilesIntegration.TagDao();
var filedao = FilesIntegration.GetFileDao();
var tagdao = FilesIntegration.DaoFactory.GetTagDao<int>();
var filedao = FilesIntegration.DaoFactory.GetFileDao<int>();
var findedTags = tagdao.GetTags(eventID.Select(item => String.Concat("RelationshipEvent_", item)).ToArray(),
TagType.System).Where(t => t.EntryType == FileEntryType.File);
var filesID = findedTags.Select(t => t.EntryId).ToArray();
var filesID = findedTags.Select(t => Convert.ToInt32(t.EntryId)).ToArray();
var files = 0 < filesID.Length ? filedao.GetFiles(filesID) : new List<File>();
var files = 0 < filesID.Length ? filedao.GetFiles(filesID) : new List<File<int>>();
var filesTemp = new Dictionary<object, File>();
var filesTemp = new Dictionary<object, File<int>>();
files.ForEach(item =>
{
@ -253,16 +251,16 @@ namespace ASC.CRM.Core.Dao
x => x.Select(item => filesTemp[item.EntryId]).ToList());
}
public List<File> GetFiles(int eventID)
public List<File<int>> GetFiles(int eventID)
{
if (eventID == 0)
throw new ArgumentException("eventID");
var tagdao = FilesIntegration.TagDao();
var filedao = FilesIntegration.GetFileDao();
var tagdao = FilesIntegration.DaoFactory.GetTagDao<int>();
var filedao = FilesIntegration.DaoFactory.GetFileDao<int>();
var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => t.EntryId).ToArray();
var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List<File>();
var ids = tagdao.GetTags(String.Concat("RelationshipEvent_", eventID), TagType.System).Where(t => t.EntryType == FileEntryType.File).Select(t => Convert.ToInt32(t.EntryId)).ToArray();
var files = 0 < ids.Length ? filedao.GetFiles(ids) : new List<File<int>>();
files.ForEach(CRMSecurity.SetAccessTo);
@ -278,7 +276,7 @@ namespace ASC.CRM.Core.Dao
var files = GetAllFiles(contactID, entityType, entityID);
var dao = FilesIntegration.GetFileDao();
var dao = FilesIntegration.DaoFactory.GetFileDao<int>();
foreach (var file in files)
{
@ -286,19 +284,19 @@ namespace ASC.CRM.Core.Dao
}
}
public List<int> RemoveFile(File file)
public List<int> RemoveFile(File<int> file)
{
CRMSecurity.DemandDelete(file);
List<int> eventIDs;
var tagdao = FilesIntegration.TagDao();
var tagdao = FilesIntegration.DaoFactory.GetTagDao<int>();
var tags = tagdao.GetTags(file.ID, FileEntryType.File, TagType.System).ToList().FindAll(tag => tag.TagName.StartsWith("RelationshipEvent_"));
eventIDs = tags.Select(item => Convert.ToInt32(item.TagName.Split(new[] { '_' })[1])).ToList();
var dao = FilesIntegration.GetFileDao();
var dao = FilesIntegration.DaoFactory.GetFileDao<int>();
dao.DeleteFile(file.ID);
@ -372,51 +370,51 @@ namespace ASC.CRM.Core.Dao
// if (msg == null)
throw new ArgumentException("Mail message cannot be found");
var msgResponseWrapper = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg)));
var msgRequestObj = msgResponseWrapper.Value<JObject>("response");
string messageUrl;
//var msgResponseWrapper = JObject.Parse(Encoding.UTF8.GetString(Convert.FromBase64String(msg)));
//var msgRequestObj = msgResponseWrapper.Value<JObject>("response");
//string messageUrl;
htmlBody = msgRequestObj.Value<String>("htmlBody");
//htmlBody = msgRequestObj.Value<String>("htmlBody");
using (var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(htmlBody)))
{
var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId);
//using (var fileStream = new MemoryStream(Encoding.UTF8.GetBytes(htmlBody)))
//{
// var filePath = String.Format("folder_{0}/message_{1}.html", (messageId / 1000 + 1) * 1000, messageId);
Global.GetStore().Save("mail_messages", filePath, fileStream);
// Global.GetStore().Save("mail_messages", filePath, fileStream);
messageUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=mailmessage&message_id={1}", PathProvider.BaseAbsolutePath, messageId).ToLower();
// messageUrl = String.Format("{0}HttpHandlers/filehandler.ashx?action=mailmessage&message_id={1}", PathProvider.BaseAbsolutePath, messageId).ToLower();
}
//}
var msg_date_created = msgRequestObj.Value<String>("date");
var message_id = msgRequestObj.Value<Int32>("id");
item.Content = JsonConvert.SerializeObject(new
{
@from = msgRequestObj.Value<String>("from"),
to = msgRequestObj.Value<String>("to"),
cc = msgRequestObj.Value<String>("cc"),
bcc = msgRequestObj.Value<String>("bcc"),
subject = msgRequestObj.Value<String>("subject"),
important = msgRequestObj.Value<Boolean>("important"),
chain_id = msgRequestObj.Value<String>("chainId"),
is_sended = msgRequestObj.Value<Int32>("folder") != 1,
date_created = msg_date_created,
introduction = msgRequestObj.Value<String>("introduction"),
message_id = message_id,
message_url = messageUrl
});
//var msg_date_created = msgRequestObj.Value<String>("date");
//var message_id = msgRequestObj.Value<Int32>("id");
//item.Content = JsonConvert.SerializeObject(new
//{
// @from = msgRequestObj.Value<String>("from"),
// to = msgRequestObj.Value<String>("to"),
// cc = msgRequestObj.Value<String>("cc"),
// bcc = msgRequestObj.Value<String>("bcc"),
// subject = msgRequestObj.Value<String>("subject"),
// important = msgRequestObj.Value<Boolean>("important"),
// chain_id = msgRequestObj.Value<String>("chainId"),
// is_sended = msgRequestObj.Value<Int32>("folder") != 1,
// date_created = msg_date_created,
// introduction = msgRequestObj.Value<String>("introduction"),
// message_id = message_id,
// message_url = messageUrl
//});
item.CreateOn = DateTime.Parse(msg_date_created, CultureInfo.InvariantCulture);
//item.CreateOn = DateTime.Parse(msg_date_created, CultureInfo.InvariantCulture);
var sqlQueryFindMailsAlready = Query(CRMDbContext.RelationshipEvent)
.Where(x => x.ContactId == item.ContactID)
.Where(x => x.EntityType == item.EntityType)
.Where(x => x.EntityId == item.EntityID)
.Where(x => x.CategoryId == item.CategoryID)
.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, String.Format("\"message_id\":{0},", message_id)));
//var sqlQueryFindMailsAlready = Query(CRMDbContext.RelationshipEvent)
// .Where(x => x.ContactId == item.ContactID)
// .Where(x => x.EntityType == item.EntityType)
// .Where(x => x.EntityId == item.EntityID)
// .Where(x => x.CategoryId == item.CategoryID)
// .Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, String.Format("\"message_id\":{0},", message_id)));
if (sqlQueryFindMailsAlready.Count() > 0)
throw new Exception("Already exists");
//if (sqlQueryFindMailsAlready.Count() > 0)
// throw new Exception("Already exists");
}
var itemToInsert = new DbRelationshipEvent
@ -560,7 +558,7 @@ namespace ASC.CRM.Core.Dao
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, k));
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, k + "%"));
}
}
}
@ -710,7 +708,7 @@ namespace ASC.CRM.Core.Dao
var serializer = new DataContractJsonSerializer(typeof(CrmHistoryContent));
using (var stream = new MemoryStream())
using (var stream = new System.IO.MemoryStream())
{
serializer.WriteObject(stream, content_struct);
return Encoding.UTF8.GetString(stream.ToArray());

View File

@ -24,38 +24,72 @@
*/
using System;
using System.Collections.Generic;
using System.Linq;
using ASC.Common.Data.Sql;
using ASC.Common.Data.Sql.Expressions;
using ASC.Common.Logging;
using ASC.Common.Utils;
using ASC.Core;
using ASC.Core.Common.EF;
using ASC.Core.Tenants;
using ASC.CRM.Classes;
using ASC.CRM.Core.EF;
using ASC.CRM.Core.Entities;
using ASC.CRM.Core.Enums;
using ASC.ElasticSearch;
using ASC.Web.Core.ModuleManagement.Common;
using ASC.Web.Core.Utility.Skins;
using ASC.Web.CRM;
using ASC.Web.CRM.Classes;
using ASC.Web.CRM.Configuration;
using ASC.Web.CRM.Core.Search;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.Linq;
namespace ASC.CRM.Core.Dao
{
public class SearchDao : AbstractDao
{
{
private Dictionary<EntityType, IEnumerable<int>> _findedIDs;
private bool _fullTextSearchEnable;
private DaoFactory DaoFactory { get; set; }
public SearchDao(int tenantID, DaoFactory daoFactory)
: base(tenantID)
public SearchDao(DbContextManager<CRMDbContext> dbContextManager,
TenantManager tenantManager,
SecurityContext securityContext,
CRMSecurity cRMSecurity,
TenantUtil tenantUtil,
PathProvider pathProvider,
FactoryIndexer<TasksWrapper> tasksWrapperIndexer,
FactoryIndexer<InvoicesWrapper> invoicesWrapperIndexer,
IOptionsMonitor<ILog> logger,
WebImageSupplier webImageSupplier,
BundleSearch bundleSearch
) :
base(dbContextManager,
tenantManager,
securityContext,
logger)
{
DaoFactory = daoFactory;
TasksWrapperIndexer = tasksWrapperIndexer;
InvoicesWrapperIndexer = invoicesWrapperIndexer;
CRMSecurity = cRMSecurity;
TenantUtil = tenantUtil;
PathProvider = pathProvider;
WebImageSupplier = webImageSupplier;
BundleSearch = bundleSearch;
}
public BundleSearch BundleSearch { get; }
public WebImageSupplier WebImageSupplier { get; }
public TenantUtil TenantUtil { get; }
public PathProvider PathProvider { get; }
public FactoryIndexer<TasksWrapper> TasksWrapperIndexer { get; }
public FactoryIndexer<InvoicesWrapper> InvoicesWrapperIndexer { get; }
public CRMSecurity CRMSecurity { get; }
public SearchResultItem[] Search(String searchText)
{
var keywords = searchText.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
@ -68,7 +102,7 @@ namespace ASC.CRM.Core.Dao
&& BundleSearch.Support(EntityType.Opportunity)
&& BundleSearch.Support(EntityType.Task)
&& BundleSearch.Support(EntityType.Invoice);
if (_fullTextSearchEnable)
{
_findedIDs = new Dictionary<EntityType, IEnumerable<int>>();
@ -92,13 +126,15 @@ namespace ASC.CRM.Core.Dao
}
List<int> tasksId;
if (FactoryIndexer<TasksWrapper>.TrySelectIds(r => r.MatchAll(searchText), out tasksId))
if (TasksWrapperIndexer.TrySelectIds(r => r.MatchAll(searchText), out tasksId))
{
_findedIDs.Add(EntityType.Task, tasksId);
}
List<int> invoicesId;
if (FactoryIndexer<InvoicesWrapper>.TrySelectIds(r => r.MatchAll(searchText), out invoicesId))
if (InvoicesWrapperIndexer.TrySelectIds(r => r.MatchAll(searchText), out invoicesId))
{
_findedIDs.Add(EntityType.Invoice, invoicesId);
}
@ -112,285 +148,293 @@ namespace ASC.CRM.Core.Dao
.ToDictionary(group => group.Key, group => group.First());
}
var searchQuery = GetSearchQuery(keywords);
if (searchQuery == null) return new SearchResultItem[0];
return ToSearchResultItem(Db.ExecuteList(searchQuery));
return GetSearchResultItems(keywords);
}
private Dictionary<EntityType, IEnumerable<int>> SearchByRelationshipEvent(String[] keywords)
{
var historyQuery = Query("crm_relationship_event")
.Select(
"contact_id",
"entity_id",
"entity_type")
.Distinct()
.Where(BuildLike(new[] { "content" }, keywords));
var sqlQuery = Query(CRMDbContext.RelationshipEvent);
return Db.ExecuteList(historyQuery).ConvertAll(row =>
if (keywords.Length > 0)
{
foreach (var k in keywords)
{
var entityID = Convert.ToInt32(row[1]);
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Content, k + "%"));
}
}
if (entityID > 0)
return new[] { row[1], row[2] };
return new[] { row[0], (int)EntityType.Contact };
}).GroupBy(row => row[1])
.ToDictionary(x => (EntityType)x.Key, x => x.SelectMany(item => item).Select(Convert.ToInt32));
return sqlQuery.GroupBy(x => x.EntityType)
.ToDictionary(x => x.Key, x => x.Select(y => y.EntityId > 0 ? y.EntityId : y.ContactId));
}
private Dictionary<EntityType, IEnumerable<int>> SearchByCustomFields(String[] keywords)
{
var sqlQuery = Query(CRMDbContext.FieldValue);
var customFieldQuery = Query("crm_field_value")
.Select("entity_id",
"entity_type")
.Distinct()
.Where(BuildLike(new[] { "value" }, keywords));
if (keywords.Length > 0)
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Value, k + "%"));
}
}
return Db.ExecuteList(customFieldQuery)
.GroupBy(row => row[1])
.ToDictionary(x => (EntityType)x.Key, x => x.SelectMany(item => item).Select(Convert.ToInt32));
return sqlQuery.GroupBy(x => x.EntityType)
.ToDictionary(x => x.Key, x => x.Select(x => x.EntityId));
}
private Dictionary<EntityType, IEnumerable<int>> SearchByContactInfos(String[] keywords)
{
var sqlResult = Db.ExecuteList(Query("crm_contact_info").Distinct()
.Select("contact_id")
.Where(BuildLike(new[] { "data" }, keywords))).Select(item => Convert.ToInt32(item[0]));
var sqlQuery = Query(CRMDbContext.ContactsInfo);
return new Dictionary<EntityType, IEnumerable<int>> { { EntityType.Contact, sqlResult } };
}
private String ToColumn(EntityType entityType)
{
return String.Format("{0} as container_type", (int)entityType);
}
private Exp BuildWhereExp(EntityType entityType, String[] keywords)
{
Exp where = Exp.Empty;
if (_findedIDs.ContainsKey(entityType))
where = Exp.In("id", _findedIDs[entityType].ToArray());
if (BundleSearch.Support(entityType)) return where;
Exp byField;
switch (entityType)
if (keywords.Length > 0)
{
case EntityType.Contact:
byField = BuildLike(new[]
{
"first_name",
"last_name",
"company_name",
"title",
"notes"
}, keywords);
break;
case EntityType.Opportunity:
byField = BuildLike(new[]
{
"title",
"description"
}, keywords);
break;
case EntityType.Task:
byField = BuildLike(new[]
{
"title",
"description"
}, keywords);
break;
case EntityType.Case:
byField = BuildLike(new[]
{
"title"
}, keywords);
break;
case EntityType.Invoice:
byField = BuildLike(new[]
{
"number",
"description"
}, keywords);
break;
default:
throw new ArgumentException();
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Data, k + "%"));
}
}
if (where != Exp.Empty)
where &= byField;
else
where = byField;
return where;
return new Dictionary<EntityType, IEnumerable<int>> { { EntityType.Contact, sqlQuery.Select(x => x.ContactId).Distinct() } };
}
private bool IncludeToSearch(EntityType entityType)
{
return !BundleSearch.Support(entityType) || _findedIDs.ContainsKey(entityType);
return !BundleSearch.Support(entityType) || _findedIDs.ContainsKey(entityType);
}
private SqlQuery GetSearchQuery(String[] keywords)
{
var queries = new List<SqlQuery>();
if (IncludeToSearch(EntityType.Task))
queries.Add(Query("crm_task")
.Select(ToColumn(EntityType.Task), "id", "title", "description", "contact_id", "entity_id",
"entity_type", "create_on")
.Where(BuildWhereExp(EntityType.Task, keywords)));
if (IncludeToSearch(EntityType.Opportunity))
queries.Add(Query("crm_deal")
.Select(ToColumn(EntityType.Opportunity), "id", "title", "description", "contact_id", "0 as entity_id", "0 as entity_type", "create_on")
.Where(BuildWhereExp(EntityType.Opportunity, keywords)));
if (IncludeToSearch(EntityType.Contact))
queries.Add(Query("crm_contact")
.Select(ToColumn(EntityType.Contact),
"id",
String.Format(@"case is_company
when 0 then
concat(first_name, ' ', last_name)
else
company_name
end as title"),
"notes as description", "0 as contact_id", "0 as entity_id", "0 as entity_type", "create_on")
.Where(BuildWhereExp(EntityType.Contact, keywords)));
if (IncludeToSearch(EntityType.Case))
queries.Add(Query("crm_case")
.Select(ToColumn(EntityType.Case), "id", "title", "'' as description", "0 as contact_id", "0 as entity_id", "0 as entity_type", "create_on")
.Where(BuildWhereExp(EntityType.Case, keywords)));
if (IncludeToSearch(EntityType.Invoice))
queries.Add(Query("crm_invoice")
.Select(ToColumn(EntityType.Invoice), "id", "number as title", "description", "contact_id", "entity_id", "entity_type", "create_on")
.Where(BuildWhereExp(EntityType.Invoice, keywords)));
if (queries.Count == 0) return null;
if (queries.Count == 1) return queries[0];
return queries[0].UnionAll(queries.Skip(1).ToArray());
}
private SearchResultItem[] ToSearchResultItem(IEnumerable<object[]> rows)
private SearchResultItem[] GetSearchResultItems(String[] keywords)
{
var result = new List<SearchResultItem>();
foreach (var row in rows)
if (IncludeToSearch(EntityType.Task))
{
var containerType = ((EntityType)Convert.ToInt32(row[0]));
var id = row[1];
string imageRef;
String url;
var sqlQuery = Query(CRMDbContext.Tasks);
switch (containerType)
if (_findedIDs.ContainsKey(EntityType.Task))
{
case EntityType.Contact:
sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Task].Contains(x.Id));
}
else
{
if (keywords.Length > 0)
{
foreach (var k in keywords)
{
var contact = DaoFactory.ContactDao.GetByID(Convert.ToInt32(id));
if (contact == null || !CRMSecurity.CanAccessTo(contact)) continue;
url = String.Format("default.aspx?id={0}", id);
if (contact is Company)
imageRef = WebImageSupplier.GetAbsoluteWebPath("companies_widget.png",
ProductEntryPoint.ID);
else
imageRef = WebImageSupplier.GetAbsoluteWebPath("people_widget.png",
ProductEntryPoint.ID);
break;
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%"));
}
case EntityType.Opportunity:
{
var deal = DaoFactory.DealDao.GetByID(Convert.ToInt32(id));
if (deal == null || !CRMSecurity.CanAccessTo(deal)) continue;
url = String.Format("deals.aspx?id={0}", id);
imageRef = WebImageSupplier.GetAbsoluteWebPath("deal_widget.png",
ProductEntryPoint.ID);
break;
}
case EntityType.Case:
{
var cases = DaoFactory.CasesDao.GetByID(Convert.ToInt32(id));
if (cases == null || !CRMSecurity.CanAccessTo(cases)) continue;
url = String.Format("cases.aspx?id={0}", id);
imageRef = WebImageSupplier.GetAbsoluteWebPath("cases_widget.png",
ProductEntryPoint.ID);
break;
}
case EntityType.Task:
{
var task = DaoFactory.TaskDao.GetByID(Convert.ToInt32(id));
if (task == null || !CRMSecurity.CanAccessTo(task)) continue;
url = "";
imageRef = WebImageSupplier.GetAbsoluteWebPath("tasks_widget.png",
ProductEntryPoint.ID);
break;
}
case EntityType.Invoice:
{
var invoice = DaoFactory.InvoiceDao.GetByID(Convert.ToInt32(id));
if (invoice == null || !CRMSecurity.CanAccessTo(invoice)) continue;
url = String.Format("invoices.aspx?id={0}", id);
imageRef = WebImageSupplier.GetAbsoluteWebPath("invoices_widget.png",
ProductEntryPoint.ID);
break;
}
default:
throw new ArgumentException();
}
}
result.Add(new SearchResultItem
sqlQuery.ToList().ForEach(x =>
{
Name = Convert.ToString(row[2]),
Description = HtmlUtil.GetText(Convert.ToString(row[3]), 120),
URL = !string.IsNullOrEmpty(url) ? String.Concat(PathProvider.BaseAbsolutePath, url) : string.Empty,
Date = TenantUtil.DateTimeFromUtc(DateTime.Parse(Convert.ToString(row[7]))),
Additional = new Dictionary<String, Object>
{ { "imageRef", imageRef },
{"relativeInfo", GetPath(
Convert.ToInt32(row[4]),
Convert.ToInt32(row[5]),
(EntityType)Convert.ToInt32(row[6]))},
{"typeInfo", containerType.ToLocalizedString()}
}
if (!CRMSecurity.CanAccessTo(new Task { ID = x.Id })) return;
result.Add(new SearchResultItem
{
Name = x.Title,
Description = HtmlUtil.GetText(x.Description, 120),
URL = PathProvider.BaseAbsolutePath,
Date = TenantUtil.DateTimeFromUtc(x.CreateOn),
Additional = new Dictionary<String, Object>
{ { "imageRef", WebImageSupplier.GetAbsoluteWebPath("tasks_widget.png", ProductEntryPoint.ID) },
{"relativeInfo", GetPath(
x.ContactId,
x.EntityId,
x.EntityType)},
{"typeInfo", EntityType.Task.ToLocalizedString()}
}
});
});
}
if (IncludeToSearch(EntityType.Opportunity))
{
var sqlQuery = Query(CRMDbContext.Deals);
if (_findedIDs.ContainsKey(EntityType.Opportunity))
{
sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Opportunity].Contains(x.Id));
}
else
{
if (keywords.Length > 0)
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%"));
}
}
}
sqlQuery.ToList().ForEach(x =>
{
if (!CRMSecurity.CanAccessTo(new Deal { ID = x.Id })) return;
result.Add(new SearchResultItem
{
Name = x.Title,
Description = HtmlUtil.GetText(x.Description, 120),
URL = string.Concat(PathProvider.BaseAbsolutePath, string.Format("deals.aspx?id={0}", x.Id)),
Date = TenantUtil.DateTimeFromUtc(x.CreateOn),
Additional = new Dictionary<string, object>
{ { "imageRef", WebImageSupplier.GetAbsoluteWebPath("deal_widget.png", ProductEntryPoint.ID) },
{"relativeInfo", GetPath(
x.ContactId,
0,
0)},
{"typeInfo", EntityType.Opportunity.ToLocalizedString()}
}
});
});
}
if (IncludeToSearch(EntityType.Contact))
{
var sqlQuery = Query(CRMDbContext.Contacts);
if (_findedIDs.ContainsKey(EntityType.Contact))
{
sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Contact].Contains(x.Id));
}
else
{
if (keywords.Length > 0)
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.FirstName, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.LastName, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.CompanyName, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Notes, k + "%")
);
}
}
}
sqlQuery.ToList().ForEach(x =>
{
if (x.IsCompany)
{
if (!CRMSecurity.CanAccessTo(new Company { ID = x.Id })) return;
}
else
{
if (!CRMSecurity.CanAccessTo(new Person { ID = x.Id })) return;
}
result.Add(new SearchResultItem
{
Name = x.IsCompany ? x.CompanyName : String.Format("{0} {1}", x.FirstName, x.LastName),
Description = HtmlUtil.GetText(x.Notes, 120),
URL = String.Concat(PathProvider.BaseAbsolutePath, String.Format("default.aspx?id={0}", x.Id)),
Date = TenantUtil.DateTimeFromUtc(x.CreateOn),
Additional = new Dictionary<String, Object>
{ { "imageRef", WebImageSupplier.GetAbsoluteWebPath(x.IsCompany ? "companies_widget.png" : "people_widget.png", ProductEntryPoint.ID) },
{"relativeInfo", GetPath(
0,
0,
0)},
{"typeInfo", EntityType.Contact.ToLocalizedString()}
}
});
});
}
if (IncludeToSearch(EntityType.Case))
{
var sqlQuery = Query(CRMDbContext.Cases);
if (_findedIDs.ContainsKey(EntityType.Case))
{
sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Case].Contains(x.Id));
}
else
{
if (keywords.Length > 0)
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%"));
}
}
}
sqlQuery.ToList().ForEach(x =>
{
if (!CRMSecurity.CanAccessTo(new Cases { ID = x.Id })) return;
result.Add(new SearchResultItem
{
Name = x.Title,
Description = String.Empty,
URL = String.Concat(PathProvider.BaseAbsolutePath, String.Format("cases.aspx?id={0}", x.Id)),
Date = TenantUtil.DateTimeFromUtc(x.CreateOn),
Additional = new Dictionary<String, Object>
{ { "imageRef", WebImageSupplier.GetAbsoluteWebPath("cases_widget.png", ProductEntryPoint.ID) },
{"relativeInfo", GetPath(
0,
0,
0)},
{"typeInfo", EntityType.Case.ToLocalizedString()}
}
});
});
}
if (IncludeToSearch(EntityType.Invoice))
{
var sqlQuery = Query(CRMDbContext.Invoices);
if (_findedIDs.ContainsKey(EntityType.Invoice))
{
sqlQuery = sqlQuery.Where(x => _findedIDs[EntityType.Invoice].Contains(x.Id));
}
else
{
if (keywords.Length > 0)
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Number, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%"));
}
}
}
sqlQuery.ToList().ForEach(x =>
{
if (!CRMSecurity.CanAccessTo(new Invoice { ID = x.Id })) return;
result.Add(new SearchResultItem
{
Name = x.Number,
Description = String.Empty,
URL = String.Concat(PathProvider.BaseAbsolutePath, String.Format("invoices.aspx?id={0}", x.Id)),
Date = TenantUtil.DateTimeFromUtc(x.CreateOn),
Additional = new Dictionary<String, Object>
{ { "imageRef", WebImageSupplier.GetAbsoluteWebPath("invoices_widget.png", ProductEntryPoint.ID) },
{"relativeInfo", GetPath(
x.ContactId,
x.EntityId,
x.EntityType)},
{"typeInfo", EntityType.Invoice.ToLocalizedString()}
}
});
});
}
return result.ToArray();
}
private String GetPath(int contactID, int entityID, EntityType entityType)

View File

@ -24,12 +24,14 @@
*/
using ASC.Common.Logging;
using ASC.Core;
using ASC.Core.Common.EF;
using ASC.CRM.Core.EF;
using ASC.CRM.Core.Enums;
using ASC.CRM.Resources;
using Microsoft.EntityFrameworkCore.Internal;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -41,10 +43,12 @@ namespace ASC.CRM.Core.Dao
{
public TagDao(DbContextManager<CRMDbContext> dbContextManager,
TenantManager tenantManager,
SecurityContext securityContext) :
SecurityContext securityContext,
IOptionsMonitor<ILog> logger) :
base(dbContextManager,
tenantManager,
securityContext)
securityContext,
logger)
{
}

View File

@ -115,8 +115,7 @@ namespace ASC.CRM.Core.Dao
CRMSecurity cRMSecurity,
TenantUtil tenantUtil,
FactoryIndexer<TasksWrapper> factoryIndexer,
IOptionsMonitor<ILog> logger,
DbContextManager<CoreDbContext> coreDbContext
IOptionsMonitor<ILog> logger
) :
base(dbContextManager,
tenantManager,
@ -126,12 +125,9 @@ namespace ASC.CRM.Core.Dao
CRMSecurity = cRMSecurity;
TenantUtil = tenantUtil;
FactoryIndexer = factoryIndexer;
CoreDbContext = coreDbContext.Value;
}
public CoreDbContext CoreDbContext { get; }
public FactoryIndexer<TasksWrapper> FactoryIndexer { get; }
public TenantUtil TenantUtil { get; }
@ -339,8 +335,8 @@ namespace ASC.CRM.Core.Dao
{
foreach (var k in keywords)
{
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k) ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k));
sqlQuery = sqlQuery.Where(x => Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Title, k + "%") ||
Microsoft.EntityFrameworkCore.EF.Functions.Like(x.Description, k + "%"));
}
}
else

View File

@ -24,13 +24,10 @@
*/
#region Usings
using System;
using System.Runtime.Serialization;
using ASC.Common.Security;
#endregion
using ASC.CRM.Core.Enums;
namespace ASC.CRM.Core.Entities
{
@ -80,30 +77,30 @@ namespace ASC.CRM.Core.Entities
public DateTime ActualCloseDate { get; set; }
[DataMember(Name = "actual_close_date")]
private String ActualCloseDateStr
{
get
{
return ActualCloseDate.Date == DateTime.MinValue.Date
? string.Empty : ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern);
}
set { ; }
}
//[DataMember(Name = "actual_close_date")]
//private String ActualCloseDateStr
//{
// get
// {
// return ActualCloseDate.Date == DateTime.MinValue.Date
// ? string.Empty : ActualCloseDate.ToString(DateTimeExtension.DateFormatPattern);
// }
// set { ; }
//}
public DateTime ExpectedCloseDate { get; set; }
[DataMember(Name = "expected_close_date")]
private String ExpectedCloseDateStr
{
get
{
return ExpectedCloseDate.Date == DateTime.MinValue.Date
? string.Empty : ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern);
}
set { ; }
}
//private String ExpectedCloseDateStr
//{
// get
// {
// return ExpectedCloseDate.Date == DateTime.MinValue.Date
// ? string.Empty : ExpectedCloseDate.ToString(DateTimeExtension.DateFormatPattern);
// }
// set { ; }
//}
public object SecurityId
{

View File

@ -27,63 +27,122 @@
using System.Collections.Generic;
using System.Linq;
using ASC.CRM.Core;
using ASC.CRM.Core.Enums;
using ASC.ElasticSearch;
namespace ASC.Web.CRM.Core.Search
{
public class BundleSearch
{
public static bool Support(EntityType entityType)
public BundleSearch(FactoryIndexer<ContactsWrapper> contactsWrapperFactoryIndexer,
FactoryIndexer<InfoWrapper> infoWrapperFactoryIndexer,
FactoryIndexer<FieldsWrapper> fieldsWrapperFactoryIndexer,
FactoryIndexer<EventsWrapper> eventsWrapperFactoryIndexer,
FactoryIndexer<DealsWrapper> dealsWrapperFactoryIndexer,
FactoryIndexer<TasksWrapper> tasksWrapperFactoryIndexer,
FactoryIndexer<CasesWrapper> casesWrapperFactoryIndexer,
FactoryIndexer<InvoicesWrapper> invoicesWrapperFactoryIndexer,
FactoryIndexerHelper factoryIndexerHelper,
ContactsWrapper contactsWrapper,
InfoWrapper infoWrapper,
FieldsWrapper fieldsWrapper,
EventsWrapper eventsWrapper,
DealsWrapper dealsWrapper,
TasksWrapper tasksWrapper,
CasesWrapper casesWrapper,
InvoicesWrapper invoicesWrapper)
{
ContactsWrapperFactoryIndexer = contactsWrapperFactoryIndexer;
InfoWrapperFactoryIndexer = infoWrapperFactoryIndexer;
FieldsWrapperFactoryIndexer = fieldsWrapperFactoryIndexer;
EventsWrapperFactoryIndexer = eventsWrapperFactoryIndexer;
DealsWrapperFactoryIndexer = dealsWrapperFactoryIndexer;
TasksWrapperFactoryIndexer = tasksWrapperFactoryIndexer;
CasesWrapperFactoryIndexer = casesWrapperFactoryIndexer;
InvoicesWrapperFactoryIndexer = invoicesWrapperFactoryIndexer;
FactoryIndexerHelper = factoryIndexerHelper;
ContactsWrapper = contactsWrapper;
InfoWrapper = infoWrapper;
FieldsWrapper = fieldsWrapper;
EventsWrapper = eventsWrapper;
DealsWrapper = dealsWrapper;
TasksWrapper = tasksWrapper;
CasesWrapper = casesWrapper;
InvoicesWrapper = invoicesWrapper;
}
public ContactsWrapper ContactsWrapper { get; }
public InfoWrapper InfoWrapper { get; }
public FieldsWrapper FieldsWrapper { get; }
public EventsWrapper EventsWrapper { get; }
public DealsWrapper DealsWrapper { get; }
public TasksWrapper TasksWrapper { get; }
public CasesWrapper CasesWrapper { get; }
public InvoicesWrapper InvoicesWrapper { get; }
public FactoryIndexerHelper FactoryIndexerHelper { get; }
public FactoryIndexer<ContactsWrapper> ContactsWrapperFactoryIndexer { get; }
public FactoryIndexer<InfoWrapper> InfoWrapperFactoryIndexer { get; }
public FactoryIndexer<FieldsWrapper> FieldsWrapperFactoryIndexer { get; }
public FactoryIndexer<EventsWrapper> EventsWrapperFactoryIndexer { get; }
public FactoryIndexer<DealsWrapper> DealsWrapperFactoryIndexer { get; }
public FactoryIndexer<TasksWrapper> TasksWrapperFactoryIndexer { get; }
public FactoryIndexer<CasesWrapper> CasesWrapperFactoryIndexer { get; }
public FactoryIndexer<InvoicesWrapper> InvoicesWrapperFactoryIndexer { get; }
public bool Support(EntityType entityType)
{
switch (entityType)
{
case EntityType.Person:
case EntityType.Contact:
case EntityType.Company:
return FactoryIndexer<ContactsWrapper>.Support &&
FactoryIndexer<InfoWrapper>.Support &&
FactoryIndexer<FieldsWrapper>.Support &&
FactoryIndexer<EventsWrapper>.Support;
return FactoryIndexerHelper.Support(ContactsWrapper) &&
FactoryIndexerHelper.Support(InfoWrapper) &&
FactoryIndexerHelper.Support(FieldsWrapper) &&
FactoryIndexerHelper.Support(EventsWrapper);
case EntityType.Opportunity:
return FactoryIndexer<DealsWrapper>.Support &&
FactoryIndexer<FieldsWrapper>.Support &&
FactoryIndexer<EventsWrapper>.Support;
return FactoryIndexerHelper.Support(DealsWrapper) &&
FactoryIndexerHelper.Support(FieldsWrapper) &&
FactoryIndexerHelper.Support(EventsWrapper);
case EntityType.RelationshipEvent:
return FactoryIndexer<EventsWrapper>.Support;
return FactoryIndexerHelper.Support(EventsWrapper);
case EntityType.Task:
return FactoryIndexer<TasksWrapper>.Support;
return FactoryIndexerHelper.Support(TasksWrapper);
case EntityType.Case:
return FactoryIndexer<CasesWrapper>.Support &&
FactoryIndexer<FieldsWrapper>.Support &&
FactoryIndexer<EventsWrapper>.Support;
return FactoryIndexerHelper.Support(CasesWrapper) &&
FactoryIndexerHelper.Support(FieldsWrapper) &&
FactoryIndexerHelper.Support(EventsWrapper);
case EntityType.Invoice:
return FactoryIndexer<InvoicesWrapper>.Support;
return FactoryIndexerHelper.Support(InvoicesWrapper);
}
return false;
}
public static bool TrySelectCase(string text, out List<int> result)
public bool TrySelectCase(string text, out List<int> result)
{
var success = false;
result = new List<int>();
List<int> casesId;
if (FactoryIndexer<CasesWrapper>.TrySelectIds(s => s.MatchAll(text), out casesId))
if (CasesWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out casesId))
{
result.AddRange(casesId);
success = true;
}
IReadOnlyCollection<FieldsWrapper> casesCustom;
if (FactoryIndexer<FieldsWrapper>.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7), out casesCustom))
if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7), out casesCustom))
{
result.AddRange(casesCustom.Select(r => r.EntityId).ToList());
success = true;
}
IReadOnlyCollection<EventsWrapper> events;
if (!FactoryIndexer<EventsWrapper>.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7).Gt(r => r.EntityId, 0), out events))
if (!EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 7).Gt(r => r.EntityId, 0), out events))
{
result.AddRange(events.Select(r => r.EntityId).ToList());
success = true;
@ -92,34 +151,38 @@ namespace ASC.Web.CRM.Core.Search
return success;
}
public static bool TrySelectContact(string text, out List<int> result)
public bool TrySelectContact(string text, out List<int> result)
{
var success = false;
result = new List<int>();
List<int> contactsId;
if (FactoryIndexer<ContactsWrapper>.TrySelectIds(s => s.MatchAll(text), out contactsId))
if (ContactsWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out contactsId))
{
result.AddRange(contactsId);
success = true;
}
IReadOnlyCollection<InfoWrapper> infos;
if (FactoryIndexer<InfoWrapper>.TrySelect(s => s.MatchAll(text), out infos))
if (InfoWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text), out infos))
{
result.AddRange(infos.Select(r => r.ContactId).ToList());
success = true;
}
IReadOnlyCollection<FieldsWrapper> personCustom;
if (FactoryIndexer<FieldsWrapper>.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] {0, 4, 5}), out personCustom))
if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).In(r => r.EntityType, new[] {0, 4, 5}), out personCustom))
{
result.AddRange(personCustom.Select(r => r.EntityId).ToList());
success = true;
}
IReadOnlyCollection<EventsWrapper> events;
if (FactoryIndexer<EventsWrapper>.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events))
if (EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Gt(r => r.ContactId, 0), out events))
{
result.AddRange(events.Select(r => r.ContactId).ToList());
success = true;
@ -128,27 +191,27 @@ namespace ASC.Web.CRM.Core.Search
return success;
}
public static bool TrySelectOpportunity(string text, out List<int> result)
public bool TrySelectOpportunity(string text, out List<int> result)
{
var success = false;
result = new List<int>();
List<int> dealsId;
if (FactoryIndexer<DealsWrapper>.TrySelectIds(s => s.MatchAll(text), out dealsId))
if (DealsWrapperFactoryIndexer.TrySelectIds(s => s.MatchAll(text), out dealsId))
{
result.AddRange(dealsId);
success = true;
}
IReadOnlyCollection<FieldsWrapper> casesCustom;
if (FactoryIndexer<FieldsWrapper>.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1), out casesCustom))
if (FieldsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1), out casesCustom))
{
result.AddRange(casesCustom.Select(r => r.EntityId).ToList());
success = true;
}
IReadOnlyCollection<EventsWrapper> events;
if (!FactoryIndexer<EventsWrapper>.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1).Gt(r => r.EntityId, 0), out events))
if (!EventsWrapperFactoryIndexer.TrySelect(s => s.MatchAll(text).Where(r => r.EntityType, 1).Gt(r => r.EntityId, 0), out events))
{
result.AddRange(events.Select(r => r.EntityId).ToList());
success = true;

View File

@ -226,7 +226,7 @@ namespace ASC.CRM.Core
AuthorizationManager.AddAce(new AzRecord(Constants.GroupEveryone.ID, _actionRead.ID, AceType.Deny, entity));
}
public void SetAccessTo(File file)
public void SetAccessTo(File<int> file)
{
if (IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID)
file.Access = FileShare.None;
@ -387,7 +387,7 @@ namespace ASC.CRM.Core
return false;
}
public bool CanEdit(File file)
public bool CanEdit(File<int> file)
{
if (!(IsAdmin || file.CreateBy == SecurityContext.CurrentAccount.ID || file.ModifiedBy == SecurityContext.CurrentAccount.ID))
return false;
@ -532,7 +532,7 @@ namespace ASC.CRM.Core
return contact.ShareType == ShareType.None;
}
public void DemandAccessTo(File file)
public void DemandAccessTo(File<int> file)
{
// if (!CanAccessTo((File)file)) CreateSecurityException();
}
@ -572,7 +572,7 @@ namespace ASC.CRM.Core
if (!CanAccessTo(invoiceTax)) throw CreateSecurityException();
}
public void DemandEdit(File file)
public void DemandEdit(File<int> file)
{
if (!CanEdit(file)) throw CreateSecurityException();
}
@ -617,7 +617,7 @@ namespace ASC.CRM.Core
if (!CanEdit(invoiceItem)) throw CreateSecurityException();
}
public void DemandDelete(File file)
public void DemandDelete(File<int> file)
{
if (!CanEdit(file)) throw CreateSecurityException();
}