Exemplo n.º 1
0
        public async Task <ScheduleModel> SaveAsync([FromBody] ScheduleCreateModel model)
        {
            var entity = await _service.CreateScheduleAsync(model.Title, model.StartDate);

            return(_mapper.Map <ScheduleModel>(entity));
        }
        public IActionResult Create(ScheduleCreateModel model)
        {
            if (model == null || !ModelState.IsValid)
            {
                return(View(model));
            }

            var students = new List <Schedule_Student>();
            var tempFile = System.IO.Path.GetTempFileName();
            var when     = model.When.Value.Date;

            var whenAsString = when.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);

            var schedule = new Schedule
            {
                CreatedBy          = User.Identity.Name,
                Description        = model.Description,
                Location           = model.Location,
                MaxStudentsPerSlot = model.MaxStudentsPerSlot.Value,
                Name     = model.Name,
                When     = when,
                Students = students,
                Slots    = model.Slots
                           .OrderBy(s => s.StartsAt)
                           .Select(s => new ScheduleSlot
                {
                    IsAvailable = s.Available,
                    StartsAt    = DateTime.ParseExact($"{whenAsString} {s.StartsAt}", "yyyy-MM-dd HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal),
                    EndsAt      = DateTime.ParseExact($"{whenAsString} {s.EndsAt}", "yyyy-MM-dd HH:mm", CultureInfo.CurrentCulture, DateTimeStyles.AssumeLocal),
                    Description = s.Description,
                })
                           .ToList()
            };

            // Read students.
            using (var reader = ExcelReaderFactory.CreateReader(model.StudentsUpload.OpenReadStream()))
            {
                // https://github.com/ExcelDataReader/ExcelDataReader#asdataset-configuration-options
                var dataSet = reader.AsDataSet(new ExcelDataSetConfiguration
                {
                    FilterSheet        = (tableReader, sheetIndex) => sheetIndex == 0,
                    ConfigureDataTable = (tableReader) => new ExcelDataTableConfiguration
                    {
                        UseHeaderRow  = true,
                        FilterRow     = (rowReader) => !string.IsNullOrWhiteSpace(rowReader.GetValue(0)?.ToString()),
                        FilterColumn  = (rowReader, columnIndex) => columnIndex <= 12,
                        ReadHeaderRow = (rowReader) =>
                        {
                            // Only try to read the first 100 columns; bail otherwise as the file may be bad.
                            var rowIndex = 0;

                            while (rowIndex < 100 && string.IsNullOrWhiteSpace(rowReader.GetValue(0)?.ToString()))
                            {
                                rowReader.Read();
                                rowIndex += 1;
                            }
                        }
                    }
                });

                var table = dataSet.Tables[0];

                if (!table.Columns.Contains("Aluno") || !table.Columns.Contains("Nome"))
                {
                    ModelState.AddModelError(nameof(model.StudentsUpload), "O ficheiro Excel tem que conter uma coluna 'Aluno' e outra 'Nome'.");
                    return(View(model));
                }

                var studentsInExcel = table.Rows
                                      .OfType <DataRow>()
                                      .Select(row =>
                {
                    var studentNumber = row["Aluno"].ToString().Trim();
                    var studentName   = row["Nome"].ToString().Trim();

                    return(new Student {
                        StudentNumber = studentNumber, Name = studentName
                    });
                })
                                      // Remove empty rows
                                      .Where(s => !string.IsNullOrWhiteSpace(s.Name) && !string.IsNullOrWhiteSpace(s.StudentNumber))
                                      // Remove duplicates
                                      .Distinct(new LambdaEqualityComparer <Student, string>(s => s.StudentNumber))
                                      .ToList();

                // Get the student numbers that are both in the db and the Excel spreadsheet.
                // For those that aren't in the db (i.e., not in this variable), add them to the db.
                var studentsInExcelAndDb = db.Students
                                           .Where(s => studentsInExcel.Select(e => e.StudentNumber).ToList().Contains(s.StudentNumber))
                                           .Select(s => s.StudentNumber)
                                           .ToHashSet();

                foreach (var inExcel in studentsInExcel)
                {
                    var studentNumber = inExcel.StudentNumber;

                    if (!studentsInExcelAndDb.Contains(studentNumber))
                    {
                        db.Students.Add(new Student {
                            StudentNumber = studentNumber, Name = inExcel.Name
                        });
                    }

                    students.Add(new Schedule_Student
                    {
                        Student_Id = studentNumber,
                        Schedule   = schedule
                    });
                }
            }

            db.Schedules.Add(schedule);

            db.SaveChanges();

            return(RedirectToAction(nameof(Index)));
        }