2021-03-15 11:36:22 +00:00
|
|
|
/*
|
|
|
|
*
|
|
|
|
* (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 System.IO;
|
|
|
|
using System.Linq;
|
|
|
|
using System.Security;
|
|
|
|
|
|
|
|
using ASC.Api.Core;
|
|
|
|
using ASC.Api.CRM;
|
|
|
|
using ASC.Api.Utils;
|
|
|
|
using ASC.Common.Web;
|
|
|
|
using ASC.Core.Notify.Signalr;
|
|
|
|
using ASC.Core.Tenants;
|
|
|
|
using ASC.CRM.ApiModels;
|
|
|
|
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.Data.Storage;
|
|
|
|
using ASC.VoipService;
|
|
|
|
using ASC.VoipService.Dao;
|
|
|
|
using ASC.VoipService.Twilio;
|
|
|
|
using ASC.Web.Api.Routing;
|
|
|
|
using ASC.Web.CRM.Classes;
|
|
|
|
using ASC.Web.Studio.Utility;
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
using AutoMapper;
|
|
|
|
|
2021-03-24 15:55:47 +00:00
|
|
|
using Microsoft.AspNetCore.Mvc;
|
|
|
|
|
2021-03-15 11:36:22 +00:00
|
|
|
using SecurityContext = ASC.Core.SecurityContext;
|
|
|
|
|
|
|
|
namespace ASC.CRM.Api
|
|
|
|
{
|
|
|
|
public class VoIPController : BaseApiController
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
private readonly SignalrServiceClient _signalrServiceClient;
|
|
|
|
private readonly ApiContext _apiContext;
|
|
|
|
private readonly VoipEngine _voipEngine;
|
|
|
|
private readonly TenantUtil _tenantUtil;
|
|
|
|
private readonly SecurityContext _securityContext;
|
|
|
|
private readonly CommonLinkUtility _commonLinkUtility;
|
|
|
|
private readonly StorageFactory _storageFactory;
|
|
|
|
private readonly ContactPhotoManager _contactPhotoManager;
|
|
|
|
private readonly Global _global;
|
|
|
|
|
2021-05-05 14:09:05 +00:00
|
|
|
public VoIPController(CrmSecurity crmSecurity,
|
2021-03-15 11:36:22 +00:00
|
|
|
DaoFactory daoFactory,
|
|
|
|
Global global,
|
|
|
|
ContactPhotoManager contactPhotoManager,
|
|
|
|
StorageFactory storageFactory,
|
|
|
|
CommonLinkUtility commonLinkUtility,
|
|
|
|
SecurityContext securityContext,
|
|
|
|
TenantUtil tenantUtil,
|
|
|
|
VoipEngine voipEngine,
|
|
|
|
ApiContext apiContext,
|
2021-03-19 16:56:26 +00:00
|
|
|
SignalrServiceClient signalrServiceClient,
|
|
|
|
IMapper mapper)
|
2021-04-06 17:33:28 +00:00
|
|
|
: base(daoFactory, crmSecurity, mapper)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
_global = global;
|
|
|
|
_contactPhotoManager = contactPhotoManager;
|
|
|
|
_storageFactory = storageFactory;
|
|
|
|
_commonLinkUtility = commonLinkUtility;
|
|
|
|
_securityContext = securityContext;
|
|
|
|
_tenantUtil = tenantUtil;
|
|
|
|
_voipEngine = voipEngine;
|
|
|
|
_apiContext = apiContext;
|
|
|
|
_signalrServiceClient = signalrServiceClient;
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <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)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(isoCountryCode)) throw new ArgumentException();
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
return _daoFactory.GetVoipDao().GetProvider().GetAvailablePhoneNumbers(numberType, isoCountryCode);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
[Read(@"voip/numbers/unlinked")]
|
|
|
|
public IEnumerable<VoipPhone> GetUnlinkedPhoneNumbers()
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var listPhones = _daoFactory.GetVoipDao().GetProvider().GetExistingPhoneNumbers();
|
|
|
|
var buyedPhones = _daoFactory.GetVoipDao().GetNumbers();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
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()
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
return _daoFactory.GetVoipDao().GetNumbers();
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
[Create(@"voip/numbers")]
|
2021-06-23 19:32:56 +00:00
|
|
|
public VoipPhone BuyNumber([FromBody] string number)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var newPhone = _daoFactory.GetVoipDao().GetProvider().BuyNumber(number);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
_daoFactory.GetVoipDao().GetProvider().CreateQueue(newPhone);
|
2021-03-15 11:36:22 +00:00
|
|
|
SetDefaultAudio(newPhone);
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
_daoFactory.GetVoipDao().GetProvider().UpdateSettings(newPhone);
|
|
|
|
return _daoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
[Create(@"voip/numbers/link")]
|
2021-06-23 19:32:56 +00:00
|
|
|
public VoipPhone LinkNumber([FromBody] string id)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var newPhone = _daoFactory.GetVoipDao().GetProvider().GetPhone(id);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
_daoFactory.GetVoipDao().GetProvider().CreateQueue(newPhone);
|
2021-03-15 11:36:22 +00:00
|
|
|
SetDefaultAudio(newPhone);
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
_daoFactory.GetVoipDao().GetProvider().UpdateSettings(newPhone);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
return _daoFactory.GetVoipDao().SaveOrUpdateNumber(newPhone);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public void SetDefaultAudio(VoipPhone newPhone)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
var storage = _storageFactory.GetStorage("", "crm");
|
2021-03-15 11:36:22 +00:00
|
|
|
const string path = "default/";
|
|
|
|
var files = storage.ListFilesRelative("voip", path, "*.*", true)
|
|
|
|
.Select(filePath => new
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
path = _commonLinkUtility.GetFullAbsolutePath(storage.GetUri("voip", Path.Combine(path, filePath)).ToString()),
|
2021-03-15 11:36:22 +00:00
|
|
|
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:regex(\w+)}")]
|
|
|
|
public VoipPhone DeleteNumber(string numberId)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
var phone = dao.GetNumber(numberId).NotFoundIfNull();
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
_daoFactory.GetVoipDao().GetProvider().DisablePhone(phone);
|
2021-03-15 11:36:22 +00:00
|
|
|
dao.DeleteNumber(numberId);
|
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
new SignalRHelper(phone.Number, _signalrServiceClient).Reload();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
return phone;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
[Read(@"voip/numbers/{numberId:regex(\w+)}")]
|
|
|
|
public VoipPhone GetNumber(string numberId)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
return _daoFactory.GetVoipDao().GetNumber(numberId).NotFoundIfNull();
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Read(@"voip/numbers/current")]
|
|
|
|
public VoipPhone GetCurrentNumber()
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
return _daoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull();
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Read(@"voip/token")]
|
|
|
|
public string GetToken()
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
return _daoFactory.GetVoipDao().GetProvider().GetToken(GetCurrentNumber().Caller);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
[Update(@"voip/numbers/{numberId:regex(\w+)}/settings")]
|
|
|
|
public VoipPhone UpdateSettings(string numberId, string greeting, string holdUp, string wait, string voiceMail, WorkingHours workingHours, bool? allowOutgoingCalls, bool? record, string alias)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
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)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
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()
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
var number = dao.GetNumbers().FirstOrDefault(r => r.Settings.Queue != null);
|
|
|
|
if (number != null)
|
|
|
|
{
|
|
|
|
return new { queue = number.Settings.Queue, pause = number.Settings.Pause };
|
|
|
|
}
|
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
var files = _storageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + AudioType.Queue.ToString().ToLower(), "*.*", true);
|
2021-03-15 11:36:22 +00:00
|
|
|
var file = files.FirstOrDefault();
|
2021-03-23 15:41:56 +00:00
|
|
|
return new { queue = new Queue(null, "Default", 5, file != null ? _commonLinkUtility.GetFullAbsolutePath(file.ToString()) : "", 5), pause = false };
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
[Read(@"voip/uploads")]
|
|
|
|
public IEnumerable<VoipUpload> GetUploadedFilesUri()
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
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();
|
2021-03-23 15:41:56 +00:00
|
|
|
var store = _global.GetStore();
|
2021-03-15 11:36:22 +00:00
|
|
|
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();
|
2021-03-23 15:41:56 +00:00
|
|
|
store = _storageFactory.GetStorage("", "crm");
|
2021-03-15 11:36:22 +00:00
|
|
|
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 VoipUpload GetVoipUpload(Uri link, string fileName, AudioType audioType, bool isDefault = false)
|
|
|
|
{
|
|
|
|
return new VoipUpload
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
Path = _commonLinkUtility.GetFullAbsolutePath(link.ToString()),
|
2021-03-15 11:36:22 +00:00
|
|
|
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)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
var store = _global.GetStore();
|
2021-03-15 11:36:22 +00:00
|
|
|
var path = Path.Combine(audioType.ToString().ToLower(), fileName);
|
|
|
|
var result = new VoipUpload
|
|
|
|
{
|
|
|
|
AudioType = audioType,
|
|
|
|
Name = fileName,
|
2021-03-23 15:41:56 +00:00
|
|
|
Path = _commonLinkUtility.GetFullAbsolutePath(store.GetUri(path).ToString())
|
2021-03-15 11:36:22 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
if (!store.IsFile("voip", path)) throw new ItemNotFoundException();
|
|
|
|
store.Delete("voip", path);
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
var numbers = dao.GetNumbers();
|
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
var defAudio = _storageFactory.GetStorage("", "crm").ListFiles("voip", "default/" + audioType.ToString().ToLower(), "*.*", true).FirstOrDefault();
|
2021-03-15 11:36:22 +00:00
|
|
|
if (defAudio == null) return result;
|
|
|
|
|
|
|
|
foreach (var number in numbers)
|
|
|
|
{
|
|
|
|
switch (audioType)
|
|
|
|
{
|
|
|
|
case AudioType.Greeting:
|
|
|
|
if (number.Settings.GreetingAudio == result.Path)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
number.Settings.GreetingAudio = _commonLinkUtility.GetFullAbsolutePath(defAudio.ToString());
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case AudioType.HoldUp:
|
|
|
|
if (number.Settings.HoldAudio == result.Path)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
number.Settings.HoldAudio = _commonLinkUtility.GetFullAbsolutePath(defAudio.ToString());
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case AudioType.Queue:
|
|
|
|
var queue = number.Settings.Queue;
|
|
|
|
if (queue != null && queue.WaitUrl == result.Path)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
queue.WaitUrl = _commonLinkUtility.GetFullAbsolutePath(defAudio.ToString());
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case AudioType.VoiceMail:
|
|
|
|
if (number.Settings.VoiceMail == result.Path)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
number.Settings.VoiceMail = _commonLinkUtility.GetFullAbsolutePath(defAudio.ToString());
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
dao.SaveOrUpdateNumber(number);
|
|
|
|
}
|
|
|
|
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
[Read(@"voip/numbers/{numberId:regex(\w+)}/oper")]
|
|
|
|
public IEnumerable<Guid> GetOperators(string numberId)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
return _daoFactory.GetVoipDao().GetNumber(numberId).Settings.Operators.Select(r => r.Id);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
/// <exception cref="ArgumentException"></exception>
|
|
|
|
[Update(@"voip/numbers/{numberId:regex(\w+)}/oper")]
|
|
|
|
public IEnumerable<Agent> AddOperators(string numberId, IEnumerable<Guid> operators)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
if (_daoFactory.GetVoipDao().GetNumbers().SelectMany(r => r.Settings.Operators).Any(r => operators.Contains(r.Id)))
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
|
|
|
throw new ArgumentException("Duplicate", "operators");
|
|
|
|
}
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
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:regex(\w+)}/oper")]
|
|
|
|
public Guid DeleteOperator(string numberId, Guid oper)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
if (!_crmSecurity.IsAdmin) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
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)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
if (!_crmSecurity.IsAdmin && !operatorId.Equals(_securityContext.CurrentAccount.ID)) throw _crmSecurity.CreateSecurityException();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
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)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
new SignalRHelper(phone.Number, _signalrServiceClient).Reload(operatorId.ToString());
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return oper;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
/// <exception cref="SecurityException"></exception>
|
|
|
|
[Create(@"voip/call")]
|
2021-06-28 09:42:42 +00:00
|
|
|
public VoipCallDto MakeCall([FromBody] CreateMakeCallRequestDto inDto)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-06-28 09:42:42 +00:00
|
|
|
var to = inDto.To;
|
|
|
|
var contactId = inDto.ContactId;
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var number = _daoFactory.GetVoipDao().GetCurrentNumber().NotFoundIfNull();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
if (!number.Settings.Caller.AllowOutgoingCalls) throw new SecurityException(CRMErrorsResource.AccessDenied);
|
|
|
|
|
|
|
|
var contactPhone = to.TrimStart('+');
|
|
|
|
|
|
|
|
ContactDto contact;
|
|
|
|
|
|
|
|
if (String.IsNullOrEmpty(contactId))
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
var ids = _daoFactory.GetContactDao().GetContactIDsByContactInfo(ContactInfoType.Phone, contactPhone, null, null);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
contact = _daoFactory.GetContactDao().GetContacts(ids.ToArray()).ConvertAll(x => _mapper.Map<ContactDto>(x)).FirstOrDefault();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
contact = _mapper.Map<ContactDto>(_daoFactory.GetContactDao().GetByID(Convert.ToInt32(contactId)));
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (contact == null)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
contact = _mapper.Map<ContactDto>(_voipEngine.CreateContact(contactPhone));
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
contact = GetContactWithFotos(contact);
|
|
|
|
|
|
|
|
var call = number.Call(to, contact.Id.ToString(CultureInfo.InvariantCulture));
|
|
|
|
|
2021-06-04 16:27:44 +00:00
|
|
|
return _mapper.Map<VoipCallDto>(call);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Create(@"voip/call/{callId:regex(\w+)}/answer")]
|
2021-03-24 15:55:47 +00:00
|
|
|
public VoipCallDto AnswerCall([FromRoute] string callId)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
var call = dao.GetCall(callId).NotFoundIfNull();
|
|
|
|
var number = dao.GetCurrentNumber().NotFoundIfNull();
|
|
|
|
|
|
|
|
number.AnswerQueueCall(call.Id);
|
|
|
|
|
2021-06-04 16:27:44 +00:00
|
|
|
return _mapper.Map<VoipCallDto>(call);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Create(@"voip/call/{callId:regex(\w+)}/reject")]
|
2021-03-24 15:55:47 +00:00
|
|
|
public VoipCallDto RejectCall([FromRoute] string callId)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
var call = dao.GetCall(callId).NotFoundIfNull();
|
|
|
|
var number = dao.GetCurrentNumber().NotFoundIfNull();
|
|
|
|
|
|
|
|
number.RejectQueueCall(call.Id);
|
|
|
|
|
2021-06-04 16:27:44 +00:00
|
|
|
return _mapper.Map<VoipCallDto>(call);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Create(@"voip/call/{callId:regex(\w+)}/redirect")]
|
2021-06-28 09:42:42 +00:00
|
|
|
public VoipCallDto ReditectCall([FromRoute] string callId, [FromBody] string to)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
var call = dao.GetCall(callId).NotFoundIfNull();
|
|
|
|
var number = dao.GetCurrentNumber().NotFoundIfNull();
|
|
|
|
|
|
|
|
if (call.ContactId != 0)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
var contact = _daoFactory.GetContactDao().GetByID(call.ContactId);
|
|
|
|
var managers = _crmSecurity.GetAccessSubjectGuidsTo(contact);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
if (!managers.Contains(Guid.Parse(to)))
|
|
|
|
{
|
|
|
|
managers.Add(Guid.Parse(to));
|
2021-03-19 16:56:26 +00:00
|
|
|
_crmSecurity.SetAccessTo(contact, managers);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
number.RedirectCall(call.Id, to);
|
2021-06-04 16:27:44 +00:00
|
|
|
|
|
|
|
return _mapper.Map<VoipCallDto>(call);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Create(@"voip/call/{callId:regex(\w+)}")]
|
2021-03-24 15:55:47 +00:00
|
|
|
public VoipCallDto SaveCall(
|
2021-06-04 14:38:42 +00:00
|
|
|
[FromRoute] string callId,
|
2021-06-28 09:42:42 +00:00
|
|
|
[FromBody] CreateVoipCallRequestDto inDto)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-06-28 09:42:42 +00:00
|
|
|
|
|
|
|
var from = inDto.From;
|
|
|
|
var to = inDto.To;
|
|
|
|
var answeredBy = inDto.AnsweredBy;
|
|
|
|
var contactId = inDto.ContactId;
|
|
|
|
var status = inDto.Status;
|
|
|
|
var price = inDto.Price;
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var dao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
_voipEngine.GetContact(call);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (call.ContactId == 0)
|
|
|
|
{
|
|
|
|
contactPhone = contactPhone.TrimStart('+');
|
|
|
|
|
|
|
|
var peopleInst = new Person
|
|
|
|
{
|
|
|
|
FirstName = contactPhone,
|
2021-03-23 15:41:56 +00:00
|
|
|
LastName = _tenantUtil.DateTimeFromUtc(DateTime.UtcNow).ToString("yyyy-MM-dd hh:mm"),
|
2021-03-15 11:36:22 +00:00
|
|
|
ShareType = ShareType.None
|
|
|
|
};
|
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
peopleInst.ID = _daoFactory.GetContactDao().SaveContact(peopleInst);
|
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
_crmSecurity.SetAccessTo(peopleInst, new List<Guid> { _securityContext.CurrentAccount.ID });
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
var person = (PersonDto)_mapper.Map<ContactDto>(peopleInst);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-19 16:56:26 +00:00
|
|
|
_daoFactory.GetContactInfoDao().Save(new ContactInfo { ContactID = person.Id, IsPrimary = true, InfoType = ContactInfoType.Phone, Data = contactPhone });
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2021-06-04 16:27:44 +00:00
|
|
|
return _mapper.Map<VoipCallDto>(call);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Create(@"voip/price/{callId:regex(\w+)}")]
|
2021-03-24 15:55:47 +00:00
|
|
|
public void SavePrice([FromRoute] string callId)
|
2021-03-15 11:36:22 +00:00
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
_voipEngine.SaveAdditionalInfo(callId);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Read(@"voip/call")]
|
|
|
|
public IEnumerable<VoipCallDto> GetCalls(string callType, ApiDateTime from, ApiDateTime to, Guid? agent, int? client, int? contactID)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
var voipDao = _daoFactory.GetVoipDao();
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
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,
|
2021-03-23 15:41:56 +00:00
|
|
|
SortBy = _apiContext.SortBy,
|
|
|
|
SortOrder = !_apiContext.SortDescending,
|
|
|
|
SearchText = _apiContext.FilterValue,
|
|
|
|
Offset = _apiContext.StartIndex,
|
|
|
|
Max = _apiContext.Count,
|
2021-03-15 11:36:22 +00:00
|
|
|
};
|
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
_apiContext.SetDataPaginated();
|
|
|
|
_apiContext.SetDataFiltered();
|
|
|
|
_apiContext.SetDataSorted();
|
|
|
|
_apiContext.TotalCount = voipDao.GetCallsCount(filter);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
var defaultSmallPhoto = _contactPhotoManager.GetSmallSizePhoto(-1, false);
|
2021-03-15 11:36:22 +00:00
|
|
|
var calls = voipDao.GetCalls(filter).Select(
|
|
|
|
r =>
|
|
|
|
{
|
|
|
|
ContactDto contact;
|
|
|
|
|
|
|
|
if (r.ContactId != 0)
|
|
|
|
{
|
|
|
|
contact = r.ContactIsCompany
|
|
|
|
? (ContactDto)new CompanyDto() { DisplayName = r.ContactTitle, Id = r.ContactId }
|
|
|
|
: new PersonDto()
|
|
|
|
{
|
|
|
|
DisplayName = r.ContactTitle,
|
|
|
|
Id = r.ContactId
|
|
|
|
};
|
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
contact.SmallFotoUrl = _contactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 };
|
|
|
|
}
|
|
|
|
|
2021-06-04 16:27:44 +00:00
|
|
|
var item = _mapper.Map<VoipCallDto>(r);
|
|
|
|
|
|
|
|
item.Contact = contact;
|
|
|
|
|
|
|
|
return item;
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
|
|
|
return calls;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Read(@"voip/call/missed")]
|
|
|
|
public IEnumerable<VoipCallDto> GetMissedCalls()
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
var voipDao = _daoFactory.GetVoipDao();
|
2021-03-23 15:41:56 +00:00
|
|
|
var defaultSmallPhoto = _contactPhotoManager.GetSmallSizePhoto(-1, false);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
var calls = voipDao.GetMissedCalls(_securityContext.CurrentAccount.ID, 10, DateTime.UtcNow.AddDays(-7)).Select(
|
2021-03-15 11:36:22 +00:00
|
|
|
r =>
|
|
|
|
{
|
|
|
|
ContactDto contact;
|
|
|
|
|
|
|
|
if (r.ContactId != 0)
|
|
|
|
{
|
|
|
|
contact = r.ContactIsCompany
|
|
|
|
? (ContactDto)new CompanyDto() { DisplayName = r.ContactTitle, Id = r.ContactId }
|
|
|
|
: new PersonDto() { DisplayName = r.ContactTitle, Id = r.ContactId };
|
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
contact.SmallFotoUrl = _contactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
contact = new PersonDto() { SmallFotoUrl = defaultSmallPhoto, Id = -1 };
|
|
|
|
}
|
|
|
|
|
2021-06-04 16:27:44 +00:00
|
|
|
var item = _mapper.Map<VoipCallDto>(r);
|
|
|
|
|
|
|
|
item.Contact = contact;
|
|
|
|
|
|
|
|
return item;
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
}).ToList();
|
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
_apiContext.SetDataPaginated();
|
|
|
|
_apiContext.SetDataFiltered();
|
|
|
|
_apiContext.SetDataSorted();
|
|
|
|
_apiContext.TotalCount = calls.Count;
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
return calls;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
///
|
|
|
|
/// </summary>
|
|
|
|
/// <short></short>
|
|
|
|
/// <category>Voip</category>
|
|
|
|
/// <returns></returns>
|
|
|
|
[Read(@"voip/call/{callId:regex(\w+)}")]
|
|
|
|
public VoipCallDto GetCall(string callId)
|
|
|
|
{
|
2021-03-19 16:56:26 +00:00
|
|
|
var call = _daoFactory.GetVoipDao().GetCall(callId);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-03-23 15:41:56 +00:00
|
|
|
_voipEngine.GetContact(call);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
2021-06-04 16:27:44 +00:00
|
|
|
return _mapper.Map<VoipCallDto>(call);
|
2021-03-15 11:36:22 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private ContactDto GetContactWithFotos(ContactDto contact)
|
|
|
|
{
|
2021-03-23 15:41:56 +00:00
|
|
|
contact.SmallFotoUrl = _contactPhotoManager.GetSmallSizePhoto(contact.Id, contact.IsCompany);
|
|
|
|
contact.MediumFotoUrl = _contactPhotoManager.GetMediumSizePhoto(contact.Id, contact.IsCompany);
|
2021-03-15 11:36:22 +00:00
|
|
|
|
|
|
|
return contact;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|