using Hcs.ClientApi.DataTypes;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using HouseManagement = Hcs.Service.Async.HouseManagement.v15_7_0_1;
namespace Hcs.ClientApi.HouseManagementApi
{
///
/// Метод получения реестра лицевых счетов
///
public class HcsMethodExportAccountData : HcsHouseManagementMethod
{
public HcsMethodExportAccountData(HcsClientConfig config) : base(config)
{
CanBeRestarted = true;
}
///
/// Получает реестр лицевых счетов по зданию с данным ГУИД ФИАС или по списку номеров ЕЛС
///
public async Task Query(
Guid? fiasHouseGuid, IEnumerable unifiedAccountNumbers,
Action<ГисЛицевойСчет> resultHandler, CancellationToken token)
{
int numResults = 0;
var itemNames = new List { };
List items = new List { };
if (fiasHouseGuid != null)
{
itemNames.Add(HouseManagement.ItemsChoiceType26.FIASHouseGuid);
items.Add(FormatGuid(fiasHouseGuid));
}
if (unifiedAccountNumbers != null)
{
if (unifiedAccountNumbers.Count() > 1000)
throw new HcsException($"Слишком много ЕЛС в запросе {unifiedAccountNumbers.Count()} > допустимых 1000");
foreach (var un in unifiedAccountNumbers)
{
itemNames.Add(HouseManagement.ItemsChoiceType26.UnifiedAccountNumber);
items.Add(un);
}
}
try
{
var request = new HouseManagement.exportAccountRequest
{
Id = HcsConstants.SignedXmlElementId,
Items = items.ToArray(),
ItemsElementName = itemNames.ToArray()
};
var stateResult = await SendAndWaitResultAsync(request, async (portClient) =>
{
var ackResponse = await portClient.exportAccountDataAsync(
CreateRequestHeader(), request);
return ackResponse.AckRequest.Ack;
}, token);
stateResult.Items.OfType().ToList().ForEach(
account => { resultHandler(Adopt(account)); numResults += 1; });
}
catch (HcsNoResultsRemoteException)
{
return 0;
}
return numResults;
}
private ГисЛицевойСчет Adopt(HouseManagement.exportAccountResultType source)
{
return new ГисЛицевойСчет()
{
ГуидЛицевогоСчета = ParseGuid(source.AccountGUID),
НомерЕЛС = source.UnifiedAccountNumber,
НомерЛицевогоСчета = source.AccountNumber,
ПолнаяПлощадь = (source.TotalSquareSpecified ? (decimal?)source.TotalSquare : null),
ЖилаяПлощадь = (source.ResidentialSquareSpecified ? (decimal?)source.ResidentialSquare : null),
КодЖКУ = source.ServiceID,
ДатаСоздания = (source.CreationDateSpecified ? (DateTime?)source.CreationDate : null),
ДатаЗакрытия = (source.Closed != null ? (DateTime?)source.Closed.CloseDate : null),
КодНсиПричиныЗакрытия = (source.Closed != null ? source.Closed.CloseReason.Code : null),
ИмяПричиныЗакрытия = (source.Closed != null ? source.Closed.Description : null),
Размещения = Adopt(source.Accommodation),
Основания = Adopt(source.AccountReasons)
};
}
private ГисОснованиеЛС[] Adopt(HouseManagement.exportAccountResultTypeAccountReasons source)
{
if (source == null) throw new ArgumentNullException("HouseManagement.exportAccountResultTypeAccountReasons");
var основания = new List<ГисОснованиеЛС>();
if (source.SupplyResourceContract != null)
{
foreach (var sr in source.SupplyResourceContract)
{
var основание = new ГисОснованиеЛС();
основание.ТипОснованияЛС = ГисТипОснованияЛС.ДоговорРСО;
for (int i = 0; i < sr.Items.Length; i++)
{
switch (sr.ItemsElementName[i])
{
case HouseManagement.ItemsChoiceType17.ContractGUID:
основание.ГуидДоговора = ParseGuid(sr.Items[i]);
break;
}
}
if (основание.ГуидДоговора == default(Guid))
throw new HcsException("Для основания ЛС не указан ГУИД договора РСО");
основания.Add(основание);
}
}
if (source.SocialHireContract != null)
{
var sh = source.SocialHireContract;
var основание = new ГисОснованиеЛС();
основание.ТипОснованияЛС = ГисТипОснованияЛС.Соцнайм;
for (int i = 0; i < sh.Items.Length; i++)
{
object itemValue = sh.Items[i];
switch (sh.ItemsElementName[i])
{
case HouseManagement.ItemsChoiceType18.ContractGUID:
основание.ГуидДоговора = ParseGuid(itemValue);
break;
case HouseManagement.ItemsChoiceType18.ContractNumber:
основание.НомерДоговора = (itemValue != null ? itemValue.ToString() : null);
break;
}
}
if (основание.ГуидДоговора == default(Guid))
throw new HcsException("Для основания ЛС не указан ГУИД договора соцнайма");
основания.Add(основание);
}
if (source.Contract != null)
{
var основание = new ГисОснованиеЛС();
основание.ТипОснованияЛС = ГисТипОснованияЛС.Договор;
основание.ГуидДоговора = ParseGuid(source.Contract.ContractGUID);
основания.Add(основание);
}
// TODO: Проверить комментарий
// Непонятно что делать с остальными типам основания и даже следует ли их
// расшифровывать или считать ошибкой пустого списка оснований
return основания.ToArray();
}
private ГисРазмещениеЛС[] Adopt(HouseManagement.AccountExportTypeAccommodation[] array)
{
if (array == null) throw new ArgumentNullException("HouseManagement.AccountExportTypeAccommodation");
return array.ToList().Select(x => Adopt(x)).ToArray();
}
private ГисРазмещениеЛС Adopt(HouseManagement.AccountExportTypeAccommodation source)
{
var размещение = new ГисРазмещениеЛС();
размещение.ПроцентДоли = (source.SharePercentSpecified ? (decimal?)source.SharePercent : null);
switch (source.ItemElementName)
{
case HouseManagement.ItemChoiceType11.FIASHouseGuid: размещение.ГуидЗдания = ParseGuid(source.Item); break;
case HouseManagement.ItemChoiceType11.PremisesGUID: размещение.ГуидПомещения = ParseGuid(source.Item); break;
case HouseManagement.ItemChoiceType11.LivingRoomGUID: размещение.ГуидЖилойКомнаты = ParseGuid(source.Item); break;
default: throw new HcsException("Неизвестный тип размещения ЛС: " + source.ItemElementName);
}
return размещение;
}
}
}