public ImportModelEmployee(
     DataParserEmployee dataParser,
     SettingsMatchEmployeesViewModel matchSettingsViewModel) : base(dataParser, typeof(CountersEmployee), matchSettingsViewModel)
 {
     this.matchSettingsViewModel = matchSettingsViewModel ?? throw new ArgumentNullException(nameof(matchSettingsViewModel));
     this.dataParser             = dataParser ?? throw new ArgumentNullException(nameof(dataParser));
 }
        public void EmployeesLoad_StolenskyGok()
        {
            var navigation          = Substitute.For <INavigationManager>();
            var interactive         = Substitute.For <IInteractiveMessage>();
            var progressStep        = Substitute.For <IProgressBarDisplayable>();
            var progressInterceptor = Substitute.For <ProgressInterceptor>();
            var dataparser          = new DataParserEmployee(new PersonNames(), new SizeService(), new PhoneFormatter(PhoneFormat.RussiaOnlyHyphenated));
            var setting             = new SettingsMatchEmployeesViewModel();
            var model = new ImportModelEmployee(dataparser, setting);

            using (var employeesLoad = new ExcelImportViewModel(model, UnitOfWorkFactory, navigation, interactive, progressInterceptor)) {
                employeesLoad.ProgressStep = progressStep;
                employeesLoad.FileName     = "Samples/Excel/cardkey_list.xlsx";
                Assert.That(employeesLoad.Sheets.Count, Is.GreaterThan(0));
                employeesLoad.SelectedSheet = employeesLoad.Sheets.First();
                Assert.That(employeesLoad.SensitiveSecondStepButton, Is.True, "Кнопка второго шага должна быть доступна");
                employeesLoad.SecondStep();
                Assert.That(employeesLoad.SensitiveThirdStepButton, Is.True, "Кнопка третьего шага должна быть доступна");
                employeesLoad.ThirdStep();
                Assert.That(employeesLoad.SensitiveSaveButton, Is.True, "Кнопка сохранить должна быть доступна");
                employeesLoad.Save();

                var uow       = employeesLoad.UoW;
                var employees = uow.GetAll <EmployeeCard>().ToList();
                Assert.That(employees.Count, Is.EqualTo(9));
                var sergey = employees.First(x => x.PersonnelNumber == "58391");
                Assert.That(sergey.CardKey, Is.EqualTo("80313E3A538A04"));
                Assert.That(sergey.LastName, Is.EqualTo("Волчихин"));
                Assert.That(sergey.FirstName, Is.EqualTo("Сергей"));
                Assert.That(sergey.Patronymic, Is.EqualTo("Владимирович"));
                Assert.That(sergey.Sex, Is.EqualTo(Sex.M));
            }
        }
        public string GetPersonalNumber(SettingsMatchEmployeesViewModel settings, SheetRowEmployee row, int columnIndex)
        {
            var original = settings.ConvertPersonnelNumber ?
                           EmployeeParse.ConvertPersonnelNumber(row.CellStringValue(columnIndex)) : row.CellStringValue(columnIndex);

            return(original?.Trim());
        }
        public void EmployeesLoad_osmbtDepartments()
        {
            NewSessionWithSameDB();
            var navigation          = Substitute.For <INavigationManager>();
            var interactive         = Substitute.For <IInteractiveMessage>();
            var progressStep        = Substitute.For <IProgressBarDisplayable>();
            var progressInterceptor = Substitute.For <ProgressInterceptor>();
            var dataparser          = new DataParserEmployee(new PersonNames(), new SizeService(), new PhoneFormatter(PhoneFormat.RussiaOnlyHyphenated));
            var setting             = new SettingsMatchEmployeesViewModel();

            //Так же проверяем что табельные номера вида 00002 превратятся в "2"
            setting.ConvertPersonnelNumber = true;
            var model = new ImportModelEmployee(dataparser, setting);

            using (var rootUow = UnitOfWorkFactory.CreateWithoutRoot())
            {
                var existEmployee = new EmployeeCard
                {
                    PersonnelNumber = "5213",
                    LastName        = "Старая фамилия",
                    FirstName       = "Старое имя",
                    Comment         = "Старый комментарий"
                };
                rootUow.Save(existEmployee);
                rootUow.Commit();

                using (var employeesLoad = new ExcelImportViewModel(model, UnitOfWorkFactory, navigation, interactive, progressInterceptor)) {
                    var uow          = employeesLoad.UoW;
                    var employeesold = uow.GetAll <EmployeeCard>().ToList();
                    Assert.That(employeesold.Count, Is.EqualTo(1));

                    employeesLoad.ProgressStep = progressStep;
                    employeesLoad.FileName     = "Samples/Excel/osmbt.xls";
                    Assert.That(employeesLoad.Sheets.Count, Is.GreaterThan(0));
                    employeesLoad.SelectedSheet = employeesLoad.Sheets.First();
                    Assert.That(employeesLoad.SensitiveSecondStepButton, Is.True, "Кнопка второго шага должна быть доступна");
                    employeesLoad.SecondStep();
                    Assert.That(employeesLoad.SensitiveThirdStepButton, Is.True, "Кнопка третьего шага должна быть доступна");
                    employeesLoad.ThirdStep();
                    Assert.That(employeesLoad.SensitiveSaveButton, Is.True, "Кнопка сохранить должна быть доступна");
                    employeesLoad.Save();

                    var employees = uow.GetAll <EmployeeCard>().ToList();
                    Assert.That(employees.Count, Is.EqualTo(2));
                    var artem = employees.First(x => x.PersonnelNumber == "5213");
                    Assert.That(artem.FirstName, Is.EqualTo("Артем"));
                    Assert.That(artem.LastName, Is.EqualTo("Беляев"));
                    Assert.That(artem.Comment, Is.EqualTo("Старый комментарий"));                     //Фамилия и имя заменились, комментарий остался старым.
                    Assert.That(artem.Subdivision.Name, Is.EqualTo("500100 Цех керамического кирпича"));
                    Assert.That(artem.Department.Name, Is.EqualTo("Участок Е1 Бригада 7  (Е1)"));

                    //Проверяем что не дублируем должности и подразделения.
                    var igor = employees.First(x => x.PersonnelNumber == "4103");
                    Assert.That(igor.Subdivision.Name, Is.EqualTo("500100 Цех керамического кирпича"));
                    Assert.That(igor.Post.Name, Is.EqualTo("Заведующий хозяйством"));
                    Assert.That(igor.Department.Name, Is.EqualTo("Участок 500100"));
                }
            }
        }
        public void EmployeesLoad_Vostok1c()
        {
            //В файле дата хранится в виде строки, поэтому для прохождения теста, нужна русская культура
            Thread.CurrentThread.CurrentCulture = CultureInfo.CreateSpecificCulture("ru-RU");
            var navigation          = Substitute.For <INavigationManager>();
            var interactive         = Substitute.For <IInteractiveMessage>();
            var progressStep        = Substitute.For <IProgressBarDisplayable>();
            var progressInterceptor = Substitute.For <ProgressInterceptor>();
            var dataparser          = new DataParserEmployee(new PersonNames(), new SizeService(), new PhoneFormatter(PhoneFormat.RussiaOnlyHyphenated));
            var setting             = new SettingsMatchEmployeesViewModel();

            //Так же проверяем что табельные номера вида 00002 превратятся в "2"
            setting.ConvertPersonnelNumber = true;
            var model = new ImportModelEmployee(dataparser, setting);

            using (var employeesLoad = new ExcelImportViewModel(model, UnitOfWorkFactory, navigation, interactive, progressInterceptor)) {
                employeesLoad.ProgressStep = progressStep;
                employeesLoad.FileName     = "Samples/Excel/vostok_1c_employee.xls";
                Assert.That(employeesLoad.Sheets.Count, Is.GreaterThan(0));
                employeesLoad.SelectedSheet = employeesLoad.Sheets.First();
                Assert.That(employeesLoad.SensitiveSecondStepButton, Is.True, "Кнопка второго шага должна быть доступна");
                employeesLoad.SecondStep();
                Assert.That(employeesLoad.SensitiveThirdStepButton, Is.True, "Кнопка третьего шага должна быть доступна");
                employeesLoad.ThirdStep();
                Assert.That(employeesLoad.SensitiveSaveButton, Is.True, "Кнопка сохранить должна быть доступна");
                employeesLoad.Save();

                var uow       = employeesLoad.UoW;
                var employees = uow.GetAll <EmployeeCard>().ToList();
                Assert.That(employees.Count, Is.EqualTo(4));
                var olga = employees.First(x => x.PersonnelNumber == "1");
                Assert.That(olga.LastName, Is.EqualTo("Гриднева"));
                Assert.That(olga.FirstName, Is.EqualTo("Ольга"));
                Assert.That(olga.Patronymic, Is.EqualTo("Николаевна"));
                Assert.That(olga.HireDate, Is.EqualTo(new DateTime(2020, 3, 10)));
                Assert.That(olga.Sex, Is.EqualTo(Sex.F));
                Assert.That(olga.Subdivision.Name, Is.EqualTo("500006 Отдел главного энергетика"));
                Assert.That(olga.Post.Name, Is.EqualTo("Ведущий инженер"));
                Assert.That(olga.Post.Subdivision.Name, Is.EqualTo("500006 Отдел главного энергетика"));

                //Проверяем что должности из разных подразделений не сливаются.
                var natalia = employees.First(x => x.PersonnelNumber == "2");
                Assert.That(natalia.Subdivision.Name, Is.EqualTo("500007 Отдел главного механика"));
                Assert.That(natalia.Post.Name, Is.EqualTo("Ведущий инженер"));
                Assert.That(natalia.Post.Subdivision.Name, Is.EqualTo("500007 Отдел главного механика"));

                //Проверяем что не дублируем должности и подразделения.
                var igor = employees.First(x => x.PersonnelNumber == "3");
                var ury  = employees.First(x => x.PersonnelNumber == "5");
                Assert.That(igor.Subdivision.Name, Is.EqualTo("500300 Цех санитарных керамических изделий"));
                Assert.That(igor.Post.Name, Is.EqualTo("Изготовитель капов (из эпоксидной смолы)."));
                Assert.That(igor.Post.Subdivision.Name, Is.EqualTo("500300 Цех санитарных керамических изделий"));
                Assert.That(igor.Subdivision.Id, Is.EqualTo(ury.Subdivision.Id));
                Assert.That(igor.Post.Id, Is.EqualTo(ury.Post.Id));
                Assert.That(igor.Post.Subdivision.Id, Is.EqualTo(ury.Post.Subdivision.Id));
            }
        }
        public IEnumerable <object> PrepareToSave(IUnitOfWork uow, SettingsMatchEmployeesViewModel settings, SheetRowEmployee row)
        {
            var employee = row.Employees.FirstOrDefault() ?? new EmployeeCard();

            //Здесь колонки сортируются чтобы процесс обработки данных был в порядке следования описания типов в Enum
            //Это надо для того чтобы наличие 2 полей с похожими данными заполнялись правильно. Например чтобы отдельное поле с фамилией могло перезаписать значение фамилии поученной из общего поля ФИО.
            foreach (var column in row.ChangedColumns.Keys.OrderBy(x => x.DataType))
            {
                if (row.ChangedColumns[column].ChangeType == ChangeType.NewEntity || row.ChangedColumns[column].ChangeType == ChangeType.ChangeValue)
                {
                    SetValue(settings, uow, employee, row, column);
                }
            }
            yield return(employee);
        }
        public void MatchByNumber(
            IUnitOfWork uow,
            IEnumerable <SheetRowEmployee> list,
            List <ImportedColumn <DataTypeEmployee> > columns,
            SettingsMatchEmployeesViewModel settings,
            IProgressBarDisplayable progress)
        {
            progress.Start(2, text: "Сопоставление с существующими сотрудниками");
            var numberColumn =
                columns.FirstOrDefault(x => x.DataType == DataTypeEmployee.PersonnelNumber);
            var numbers = list.Select(x => GetPersonalNumber(settings, x, numberColumn.Index))
                          .Where(x => !String.IsNullOrWhiteSpace(x))
                          .Distinct().ToArray();
            var exists = uow.Session.QueryOver <EmployeeCard>()
                         .Where(x => x.PersonnelNumber.IsIn(numbers))
                         .List();

            progress.Add();
            foreach (var employee in exists)
            {
                var found = list.Where(x =>
                                       GetPersonalNumber(settings, x, numberColumn.Index) == employee.PersonnelNumber).ToArray();
                found.First().Employees.Add(employee);
            }

            //Пропускаем дубликаты Табельных номеров в файле
            progress.Add();
            var groups = list.GroupBy(x => GetPersonalNumber(settings, x, numberColumn.Index));

            foreach (var group in groups)
            {
                if (String.IsNullOrWhiteSpace(group.Key))
                {
                    //Если табельного номера нет проверяем по FIO
                    MatchByName(uow, group, columns, progress);
                }

                foreach (var item in group.Skip(1))
                {
                    item.ProgramSkipped = true;
                }
            }
            progress.Close();
        }
        public void EmployeesLoad_DateWorks()
        {
            var navigation          = Substitute.For <INavigationManager>();
            var interactive         = Substitute.For <IInteractiveMessage>();
            var progressStep        = Substitute.For <IProgressBarDisplayable>();
            var progressInterceptor = Substitute.For <ProgressInterceptor>();
            var dataparser          = new DataParserEmployee(new PersonNames(), new SizeService(), new PhoneFormatter(PhoneFormat.RussiaOnlyHyphenated));
            var setting             = new SettingsMatchEmployeesViewModel();
            var model = new ImportModelEmployee(dataparser, setting);

            using (var employeesLoad = new ExcelImportViewModel(model, UnitOfWorkFactory, navigation, interactive, progressInterceptor)) {
                var importModel = employeesLoad.ImportModel as ImportModelEmployee;
                employeesLoad.ProgressStep = progressStep;
                employeesLoad.FileName     = "Samples/Excel/dismissed_employees.xls";
                Assert.That(employeesLoad.Sheets.Count, Is.GreaterThan(0));
                employeesLoad.SelectedSheet = employeesLoad.Sheets.First();
                Assert.That(employeesLoad.SensitiveSecondStepButton, Is.True, "Кнопка второго шага должна быть доступна");
                employeesLoad.SecondStep();
                importModel.Columns[1].DataType = DataTypeEmployee.DismissDate;                 //Вторая колонка дата увольнения.
                Assert.That(employeesLoad.SensitiveThirdStepButton, Is.True, "Кнопка третьего шага должна быть доступна");
                employeesLoad.ThirdStep();
                Assert.That(employeesLoad.SensitiveSaveButton, Is.True, "Кнопка сохранить должна быть доступна");
                employeesLoad.Save();

                var uow       = employeesLoad.UoW;
                var employees = uow.GetAll <EmployeeCard>().ToList();

                Assert.That(employees.Count, Is.EqualTo(2));
                var anastasia = employees.First(x => x.FirstName == "Анастасия");
                Assert.That(anastasia.LastName, Is.EqualTo("Устинова"));
                Assert.That(anastasia.Patronymic, Is.EqualTo("Владимировна"));
                Assert.That(anastasia.HireDate, Is.EqualTo(new DateTime(2006, 4, 4)));
                Assert.That(anastasia.Sex, Is.EqualTo(Sex.F));
                Assert.That(anastasia.DismissDate, Is.EqualTo(new DateTime(2021, 3, 31)));

                var natalia = employees.First(x => x.FirstName == "Наталья");
                Assert.That(natalia.HireDate, Is.EqualTo(new DateTime(2020, 12, 11)));
                Assert.That(natalia.Sex, Is.EqualTo(Sex.F));
                Assert.That(natalia.DismissDate, Is.EqualTo(new DateTime(2021, 1, 13)));
            }
        }
        public void FindChanges(
            IUnitOfWork uow,
            IEnumerable <SheetRowEmployee> list,
            ImportedColumn <DataTypeEmployee>[] meaningfulColumns,
            IProgressBarDisplayable progress,
            SettingsMatchEmployeesViewModel settings)
        {
            progress.Start(list.Count(), text: "Поиск изменений");
            foreach (var row in list)
            {
                progress.Add();
                if (row.Skipped)
                {
                    continue;
                }

                var employee  = row.Employees.FirstOrDefault();
                var rowChange = ChangeType.ChangeValue;

                if (employee == null)
                {
                    employee = new EmployeeCard {
                        Comment       = "Импортирован из Excel",
                        CreatedbyUser = userService?.GetCurrentUser(uow)
                    };
                    row.Employees.Add(employee);
                    rowChange = ChangeType.NewEntity;
                }

                foreach (var column in meaningfulColumns)
                {
                    MakeChange(settings, employee, row, column, rowChange, uow);
                }
            }
            progress.Close();
        }
        private void SetValue(
            SettingsMatchEmployeesViewModel settings,
            IUnitOfWork uow,
            EmployeeCard employee,
            SheetRowEmployee row,
            ImportedColumn <DataTypeEmployee> column)
        {
            var value    = row.CellStringValue(column.Index);
            var dataType = column.DataType;

            if (String.IsNullOrWhiteSpace(value))
            {
                return;
            }

            switch (dataType)
            {
            case DataTypeEmployee.CardKey:
                employee.CardKey = value;
                break;

            case DataTypeEmployee.PersonnelNumber:
                employee.PersonnelNumber = (settings.ConvertPersonnelNumber ?
                                            EmployeeParse.ConvertPersonnelNumber(value) : value)?.Trim();
                break;

            case DataTypeEmployee.Phone:
                employee.PhoneNumber = phoneFormatter.FormatString(value);
                break;

            case DataTypeEmployee.LastName:
                employee.LastName = value;
                break;

            case DataTypeEmployee.FirstName:
                employee.FirstName = value;
                if (employee.Sex == Sex.None)
                {
                    employee.Sex = personNames.GetSexByName(employee.FirstName);
                }
                break;

            case DataTypeEmployee.Patronymic:
                employee.Patronymic = value;
                break;

            case DataTypeEmployee.Sex:
                //Первая М английская, вторая русская.
                if (value.StartsWith("M", StringComparison.CurrentCultureIgnoreCase) ||
                    value.StartsWith("М", StringComparison.CurrentCultureIgnoreCase))
                {
                    employee.Sex = Sex.M;
                }
                if (value.StartsWith("F", StringComparison.CurrentCultureIgnoreCase) ||
                    value.StartsWith("Ж", StringComparison.CurrentCultureIgnoreCase))
                {
                    employee.Sex = Sex.F;
                }
                break;

            case DataTypeEmployee.Fio:
                value.SplitFullName(out var lastName, out var firstName, out var patronymic);
                if (!String.IsNullOrEmpty(lastName) && !String.Equals(employee.LastName, value, StringComparison.CurrentCultureIgnoreCase))
                {
                    employee.LastName = lastName;
                }
                if (!String.IsNullOrEmpty(firstName) && !String.Equals(employee.FirstName, value, StringComparison.CurrentCultureIgnoreCase))
                {
                    employee.FirstName = firstName;
                }
                if (!String.IsNullOrEmpty(patronymic) && !String.Equals(employee.Patronymic, value, StringComparison.CurrentCultureIgnoreCase))
                {
                    employee.Patronymic = patronymic;
                }
                if (employee.Sex == Sex.None && !String.IsNullOrWhiteSpace(employee.FirstName))
                {
                    employee.Sex = personNames.GetSexByName(employee.FirstName);
                }
                break;

            case DataTypeEmployee.HireDate:
                var hireDate = row.CellDateTimeValue(column.Index);
                if (hireDate != null)
                {
                    employee.HireDate = hireDate;
                }
                break;

            case DataTypeEmployee.DismissDate:
                var dismissDate = row.CellDateTimeValue(column.Index);
                if (dismissDate != null)
                {
                    employee.DismissDate = dismissDate;
                }
                break;

            case DataTypeEmployee.BirthDate:
                var birthDate = row.CellDateTimeValue(column.Index);
                if (birthDate != null)
                {
                    employee.BirthDate = birthDate;
                }
                break;

            case DataTypeEmployee.Subdivision:
            case DataTypeEmployee.Department:
            case DataTypeEmployee.Post:
                //Устанавливаем в MakeChange;
                break;

            case DataTypeEmployee.Growth:
                var height = SizeParser.ParseSize(uow, value, sizeService, CategorySizeType.Height);
                if (height is null)
                {
                    break;
                }
                var employeeHeight = employee.Sizes.FirstOrDefault(x => x.SizeType == height.SizeType);
                if (employeeHeight is null)
                {
                    employeeHeight = new EmployeeSize
                    {
                        Size = height, SizeType = height.SizeType, Employee = employee
                    };
                    employee.Sizes.Add(employeeHeight);
                }
                else
                {
                    employeeHeight.Size = height;
                }
                break;

            case DataTypeEmployee.WearSize:
                var size = SizeParser.ParseSize(uow, value, sizeService, CategorySizeType.Size);
                if (size is null)
                {
                    break;
                }
                var employeeSize = employee.Sizes.FirstOrDefault(x => x.SizeType == size.SizeType);
                if (employeeSize is null)
                {
                    employeeSize = new EmployeeSize
                    {
                        Size = size, SizeType = size.SizeType, Employee = employee
                    };
                    employee.Sizes.Add(employeeSize);
                }
                else
                {
                    employeeSize.Size = size;
                }
                break;

            case DataTypeEmployee.ShoesSize:
            {
                var shoesSize = SizeParser.ParseSize(uow, value, sizeService, CategorySizeType.Size);
                if (shoesSize is null)
                {
                    break;
                }
                var employeeShoesSize = employee.Sizes.FirstOrDefault(x => x.SizeType == shoesSize.SizeType);
                if (employeeShoesSize is null)
                {
                    employeeShoesSize = new EmployeeSize
                    {
                        Size = shoesSize, SizeType = shoesSize.SizeType, Employee = employee
                    };
                    employee.Sizes.Add(employeeShoesSize);
                }
                else
                {
                    employeeShoesSize.Size = shoesSize;
                }
            }
            break;

            default:
                throw new NotSupportedException($"Тип данных {dataType} не поддерживается.");
            }
        }
        public void MakeChange(
            SettingsMatchEmployeesViewModel settings,
            EmployeeCard employee,
            SheetRowEmployee row,
            ImportedColumn <DataTypeEmployee> column,
            ChangeType rowChange,
            IUnitOfWork uow)
        {
            var value    = row.CellStringValue(column.Index);
            var dataType = column.DataType;

            if (String.IsNullOrWhiteSpace(value))
            {
                row.AddColumnChange(column, ChangeType.NotChanged);
                return;
            }

            switch (dataType)
            {
            case DataTypeEmployee.CardKey:
                row.ChangedColumns.Add(column, CompareString(employee.CardKey, value, rowChange));
                break;

            case DataTypeEmployee.PersonnelNumber:
                row.ChangedColumns.Add(column, CompareString(employee.PersonnelNumber,
                                                             (settings.ConvertPersonnelNumber ? EmployeeParse.ConvertPersonnelNumber(value) : value)?.Trim(), rowChange));
                break;

            case DataTypeEmployee.Phone:
                row.ChangedColumns.Add(column, ComparePhone(employee.PhoneNumber, value, rowChange));
                break;

            case DataTypeEmployee.LastName:
                row.ChangedColumns.Add(column, CompareString(employee.LastName, value, rowChange));
                break;

            case DataTypeEmployee.FirstName:
                row.ChangedColumns.Add(column, CompareString(employee.FirstName, value, rowChange));
                break;

            case DataTypeEmployee.Patronymic:
                row.ChangedColumns.Add(column, CompareString(employee.Patronymic, value, rowChange));
                break;

            case DataTypeEmployee.Sex:
                //Первая М английская, вторая русская.
                if (value.StartsWith("M", StringComparison.CurrentCultureIgnoreCase) ||
                    value.StartsWith("М", StringComparison.CurrentCultureIgnoreCase))
                {
                    row.AddColumnChange(column, employee.Sex == Sex.M ? ChangeType.NotChanged : rowChange);
                    break;
                }
                if (value.StartsWith("F", StringComparison.CurrentCultureIgnoreCase) ||
                    value.StartsWith("Ж", StringComparison.CurrentCultureIgnoreCase))
                {
                    row.AddColumnChange(column, employee.Sex == Sex.F ? ChangeType.NotChanged : rowChange);
                    break;
                }
                row.AddColumnChange(column, ChangeType.ParseError);
                break;

            case DataTypeEmployee.Fio:
                value.SplitFullName(out var lastName, out var firstName, out var patronymic);
                var lastDiff = !String.IsNullOrEmpty(lastName) &&
                               !String.Equals(employee.LastName, lastName, StringComparison.CurrentCultureIgnoreCase);
                var firstDiff = !String.IsNullOrEmpty(firstName) &&
                                !String.Equals(employee.FirstName, firstName, StringComparison.CurrentCultureIgnoreCase);
                var patronymicDiff = !String.IsNullOrEmpty(patronymic) &&
                                     !String.Equals(employee.Patronymic, patronymic, StringComparison.CurrentCultureIgnoreCase);
                string oldValue = (lastDiff || firstDiff || patronymicDiff) ? employee.FullName : null;
                row.AddColumnChange(column, (lastDiff || firstDiff || patronymicDiff) ? rowChange : ChangeType.NotChanged, oldValue);
                break;

            case DataTypeEmployee.HireDate:
                row.ChangedColumns.Add(column, CompareDate(employee.HireDate, row.CellDateTimeValue(column.Index), rowChange));
                break;

            case DataTypeEmployee.DismissDate:
                row.ChangedColumns.Add(column, CompareDate(employee.DismissDate, row.CellDateTimeValue(column.Index), rowChange));
                break;

            case DataTypeEmployee.BirthDate:
                row.ChangedColumns.Add(column, CompareDate(employee.BirthDate, row.CellDateTimeValue(column.Index), rowChange));
                break;

            case DataTypeEmployee.Subdivision:
                if (String.Equals(employee.Subdivision?.Name, value, StringComparison.CurrentCultureIgnoreCase))
                {
                    row.AddColumnChange(column, ChangeType.NotChanged);
                    break;
                }

                var subdivision = UsedSubdivisions.FirstOrDefault(x =>
                                                                  String.Equals(x.Name, value, StringComparison.CurrentCultureIgnoreCase));
                if (subdivision == null)
                {
                    subdivision = new Subdivision {
                        Name = value
                    };
                    UsedSubdivisions.Add(subdivision);
                }
                row.AddColumnChange(column, subdivision.Id == 0 ? ChangeType.NewEntity : rowChange, employee.Subdivision?.Name);
                employee.Subdivision = subdivision;
                break;

            case DataTypeEmployee.Department:
                if (String.Equals(employee.Department?.Name, value, StringComparison.CurrentCultureIgnoreCase))
                {
                    row.AddColumnChange(column, ChangeType.NotChanged);
                    break;
                }
                var department = UsedDepartment.FirstOrDefault(x =>
                                                               String.Equals(x.Name, value, StringComparison.CurrentCultureIgnoreCase) &&
                                                               (employee.Subdivision == null && x.Subdivision == null ||
                                                                DomainHelper.EqualDomainObjects(x.Subdivision, employee.Subdivision)));
                if (department == null)
                {
                    department = new Department {
                        Name        = value,
                        Subdivision = employee.Subdivision,
                        Comments    = "Создан при импорте сотрудников из Excel"
                    };
                    UsedDepartment.Add(department);
                }
                row.AddColumnChange(column, department.Id == 0 ? ChangeType.NewEntity : rowChange, employee.Department?.Name);
                employee.Department = department;
                break;

            case DataTypeEmployee.Post:
                if (String.Equals(employee.Post?.Name, value, StringComparison.CurrentCultureIgnoreCase))
                {
                    row.AddColumnChange(column, ChangeType.NotChanged);
                    break;
                }
                var post = UsedPosts.FirstOrDefault(x =>
                                                    String.Equals(x.Name, value, StringComparison.CurrentCultureIgnoreCase) &&
                                                    (employee.Subdivision == null && x.Subdivision == null ||
                                                     DomainHelper.EqualDomainObjects(x.Subdivision, employee.Subdivision)));
                if (post == null)
                {
                    post = new Post {
                        Name        = value,
                        Subdivision = employee.Subdivision,
                        Comments    = "Создана при импорте сотрудников из Excel"
                    };
                    UsedPosts.Add(post);
                }
                row.AddColumnChange(column, post.Id == 0 ? ChangeType.NewEntity : rowChange, employee.Post?.Name);
                employee.Post = post;
                break;

            case DataTypeEmployee.Growth: {
                var height         = SizeParser.ParseSize(uow, row.CellStringValue(column.Index), sizeService, CategorySizeType.Height);
                var employeeHeight = employee.Sizes.FirstOrDefault(x => x.SizeType == height.SizeType)?.Size;
                row.ChangedColumns.Add(column, CompareSize(employeeHeight, height, rowChange, uow));
            }
            break;

            case DataTypeEmployee.WearSize: {
                var size         = SizeParser.ParseSize(uow, row.CellStringValue(column.Index), sizeService, CategorySizeType.Size);
                var employeeSize = employee.Sizes.FirstOrDefault(x => x.SizeType == size.SizeType)?.Size;
                row.ChangedColumns.Add(column, CompareSize(employeeSize, size, rowChange, uow));
            }
            break;

            case DataTypeEmployee.ShoesSize: {
                var size         = SizeParser.ParseSize(uow, row.CellStringValue(column.Index), sizeService, CategorySizeType.Size);
                var employeeSize = employee.Sizes.FirstOrDefault(x => x.SizeType == size.SizeType)?.Size;
                row.ChangedColumns.Add(column, CompareSize(employeeSize, size, rowChange, uow));
            }
            break;

            default:
                throw new NotSupportedException($"Тип данных {dataType} не поддерживается.");
            }
        }
        public void EmployeesLoad_EmptyRows_Sizes_A2Case()
        {
            var navigation          = Substitute.For <INavigationManager>();
            var interactive         = Substitute.For <IInteractiveMessage>();
            var progressStep        = Substitute.For <IProgressBarDisplayable>();
            var progressInterceptor = Substitute.For <ProgressInterceptor>();
            var dataParser          = new DataParserEmployee(new PersonNames(), new SizeService(), new PhoneFormatter(PhoneFormat.RussiaOnlyHyphenated));
            var setting             = new SettingsMatchEmployeesViewModel();
            var model = new ImportModelEmployee(dataParser, setting);

            using (var employeesLoad = new ExcelImportViewModel(model, UnitOfWorkFactory, navigation, interactive, progressInterceptor))
            {
                var uow        = employeesLoad.UoW;
                var heightType = new SizeType
                {
                    Name = "РостТип", Position = 1, UseInEmployee = true, CategorySizeType = CategorySizeType.Height
                };
                uow.Save(heightType);
                var sizeType = new SizeType
                {
                    Name = "РазмерТип", Position = 2, CategorySizeType = CategorySizeType.Size, UseInEmployee = true
                };
                uow.Save(sizeType);
                var shoesType = new SizeType
                {
                    Name = "ОбувьТип", Position = 3, CategorySizeType = CategorySizeType.Size, UseInEmployee = true
                };
                uow.Save(shoesType);
                var height = new Size {
                    Name = "170-176", SizeType = heightType, UseInEmployee = true
                };
                uow.Save(height);
                var size = new Size {
                    Name = "48-50", SizeType = sizeType, UseInEmployee = true
                };
                uow.Save(size);
                var shoes = new Size {
                    Name = "38", SizeType = shoesType, UseInEmployee = true
                };
                uow.Save(shoes);
                uow.Commit();

                employeesLoad.ProgressStep = progressStep;
                employeesLoad.FileName     = "Samples/Excel/empty_first_row_a2.xls";
                Assert.That(employeesLoad.Sheets.Count, Is.GreaterThan(0));
                employeesLoad.SelectedSheet = employeesLoad.Sheets.First();
                Assert.That(employeesLoad.SensitiveSecondStepButton, Is.True, "Кнопка второго шага должна быть доступна");
                employeesLoad.SecondStep();
                Assert.That(employeesLoad.SensitiveThirdStepButton, Is.True, "Кнопка третьего шага должна быть доступна");
                employeesLoad.ThirdStep();
                Assert.That(employeesLoad.SensitiveSaveButton, Is.True, "Кнопка сохранить должна быть доступна");
                employeesLoad.Save();
                uow.Commit();

                var employees = uow.GetAll <EmployeeCard>().ToList();

                Assert.That(employees.Count, Is.EqualTo(5));
                var nikolay = employees.First(x => x.FirstName == "Николай");
                Assert.That(nikolay.Sizes.FirstOrDefault(x => x.SizeType == heightType)?.Size?.Id, Is.EqualTo(height.Id));
                Assert.That(nikolay.Sizes.FirstOrDefault(x => x.SizeType == sizeType)?.Size?.Id, Is.EqualTo(size.Id));
                Assert.That(nikolay.Sizes.FirstOrDefault(x => x.SizeType == shoesType)?.Size?.Id, Is.EqualTo(shoes.Id));

                //Проверяем что должности не задублировались
                var posts = uow.GetAll <Post>();
                Assert.That(posts.Count, Is.EqualTo(3));
            }
        }