Цель данной статьи - поделиться опытом модификации утилиты импорта. Задача - создание записей в справочнике, который содержит свойство-коллекцию.
В качестве примера возьмем справочник "Продолжительности отпусков" (VacationDuration) из модуля HRPro. Данный справочник используется при планировании отпусков в организации. Справочник содержит свойства: сотрудник, год отпуска и свойство-коллекцию AvailableDuration со свойствами вид отпуска и доступное количество дней.
Чтобы по сотруднику можно было запланировать отпуск, по нему должны быть созданы записи в этом справочнике с перечислением доступных дней по видам отпуска. Утилита импорта в своем коробочном варианте не работает с данным справочником и, главное, не имеет примеров реализации кейса с импортом в свойство-коллекцию.
Для решения данной задачи взята за основу реализация работы с версиями в коробке утилиты.
Для работы со свойством-коллекцией AvailableDuration необходимо определить класс в папке models IAvailableDurations, содержащий свойства справочника:
using System;
using System.Collections.Generic;
using System.Text;
namespace ImportData.IntegrationServicesClient.Models
{
public class IAvailableDurations
{
public int Id { get; set; }
public IVacationKinds VacationKind { get; set; }
public int DaysCount { get; set; }
}
}
Далее, создаем класс в папке models для нашего справочника IVacationDurations:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace ImportData.IntegrationServicesClient.Models
{
[EntityName("Продолжительности отпусков")]
public class IVacationDurations
{
public int Id { get; set; }
public string Status { get; set; }
public string Name { get; set; }
public IEmployees Employee { get; set; }
public DateTime Year { get; set; }
public string Details { get; set; }
public IEnumerable<IAvailableDurations> AvailableDuration { get; set; }
public string TotalDaysInfo { get; set; }
public int TotalDays { get; set; }
Свойство коллекцию объявляем с типом IEnumerable
public IEnumerable<IAvailableDurations> AvailableDuration { get; set; }
Далее необходимо в классе справочника IVacationDurations объявить метод CreateAvailableDuration(), который будет добавлять элементы в свойство коллекцию AvailableDuration:
public IAvailableDurations CreateAvailableDuration(IVacationKinds VacationKind, int DaysCount)
{
var availableDuration = Client.Instance().For<IVacationDurations>()
.Key(this.Id)
.NavigateTo(x => x.AvailableDuration)
.Set(new IAvailableDurations() { VacationKind = VacationKind, DaysCount = DaysCount })
.InsertEntryAsync()
.Result;
if (availableDuration == null)
return null;
return availableDuration;
}
Далее, в папке Databooks создаем класс VacationDuration для считывания данных из шаблона.
В конце метода SaveToRX(), когда полученные из шаблона данные отправляются в BusinessLogic, вызываем метод CreateAvailableDuration()
try
{
var vacationDurations = BusinessLogic.GetEntityWithFilter<IVacationDurations>(x =>
x.Employee.Id == employee.Id && x.Year.Year == year.Year, exceptionList, logger, true);
if (vacationDurations != null)
{
vacationDurations.CreateAvailableDuration(vacationKind, daysCount);
var updateEntity = BusinessLogic.UpdateEntity<IVacationDurations>(vacationDurations, exceptionList, logger);
return exceptionList;
}
var vacationDuration = new IVacationDurations();
vacationDuration.Employee = employee;
vacationDuration.Year = year;
vacationDuration.Status = BusinessLogic.GetPropertyVacationDurationStatus("Active");
var vacationDurationEntity = BusinessLogic.CreateEntity<IVacationDurations>(vacationDuration, exceptionList, logger);
vacationDurationEntity.CreateAvailableDuration(vacationKind, daysCount);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
exceptionList.Add(new Structures.ExceptionsStruct { ErrorType = Constants.ErrorTypes.Error, Message = ex.Message });
return exceptionList;
}
В самом шаблоне записываем каждую продолжительность отпуска в новой строке, повторяя того же сотрудника. Примерно так это будет выглядеть:
В качестве заключения хотел бы сказать, что это один из способов решения данной задачи и имеет и свои ограничения. Например в данной реализации не получится обновлять записи в справочнике, так как записи либо добавляются для нового сотрудника, либо, если совпадает год и сотрудник, добавляются данные в коллекцию. Однако данный способ идеально подходит для разовой передачи данных справочников, содержащих коллекции в свойствах.
Я бы еще упомянул, что если коллекция является обязательным свойством, то такую запись придется импортировать с помощью пакетного запроса (ODataBatch)
Алексей, Есть какой то пример как это сделать в утилите импорта?
Нашел ли кто способ получать уже существующую коллекцию внутри карточки? а то прилетают по одате только внутренние ID записей.
Станислав, я сделал. написал внутренний Expand. теперь табличную часть он мне возвращает и я могу перед добавлением проверить есть ли там это или нет.
Авторизуйтесь, чтобы написать комментарий