public async Task <ActionResult <TimesheetDTO> > PostTimesheet(TimesheetDTO timesheet)
        {
            var user = await _userManager.FindByNameAsync(User?.Identity?.Name);

            if (user != null)
            {
                timesheet.UserId = user.Id;
            }

            var isTimesheetForValidMonth = !_context.Timesheet.Any(t => t.Date.Year.Equals(timesheet.Date.Year) && t.Date.Month.Equals(timesheet.Date.Month) && t.UserId.Equals(user.Id));

            if (!isTimesheetForValidMonth)
            {
                return(BadRequest(new { Message = "Timesheet for selected month already exists!" }));
            }

            var timesheetObj = DtoToModel.DtoToTimesheet(timesheet);

            var validStates = States.GetStatesValues();

            if (!validStates.Contains(timesheet.State))
            {
                return(BadRequest("Provided status does not exist!"));
            }

            await _context.Timesheet.AddAsync(timesheetObj);

            await _context.SaveChangesAsync();

            var dto = ModelToDto.TimesheetToDto(timesheetObj);

            return(CreatedAtAction("GetTimesheet", new { id = timesheet.Id }, dto));
        }
        public void DtoToInvoice_Should_ReturnValidInvoiceObject()
        {
            var invoiceDto = CreateMockInvoiceDTO();

            var sut = DtoToModel.DtoToInvoice(invoiceDto);

            Assert.AreEqual(0, sut.Id);
            Assert.AreEqual(1, sut.TimesheetId);
            Assert.AreEqual(DateTime.Today, sut.GeneratedDate);
            Assert.AreEqual(Array.Empty <byte>(), sut.FileArray);
        }
        public void DtoToTimesheet_Should_ReturnValidTimesheetObject()
        {
            var timesheetDto = CreateMockTimesheetDTO();

            var sut = DtoToModel.DtoToTimesheet(timesheetDto);

            Assert.AreEqual(1, sut.Id);
            Assert.AreEqual(_sampleDate, sut.Date);
            Assert.AreEqual(_sampleUserId, sut.UserId);
            Assert.AreEqual(States.Open, sut.State);
            Assert.AreEqual(1, sut.Rows.ElementAt(0).Id);
            Assert.AreEqual(1, sut.Rows.ElementAt(0).RateTypeId);
            Assert.AreEqual(1, sut.Rows.ElementAt(0).TimesheetId);
            Assert.AreEqual(1, sut.Rows.ElementAt(1).Id);
            Assert.AreEqual(2, sut.Rows.ElementAt(1).RateTypeId);
            Assert.AreEqual(1, sut.Rows.ElementAt(1).TimesheetId);
            Assert.AreEqual(sut.Rows.ElementAt(0).Days, "[{\"Date\":\"2020-05-15T00:00:00\",\"ReportedHours\":8},{\"Date\":\"2020-05-15T00:00:00\",\"ReportedHours\":7}]");
        }
        public async Task <ActionResult <InvoiceDataDTO> > PostInvoice(InvoiceDTO invoice)
        {
            var user = await _userManager.FindByNameAsync(User?.Identity?.Name);

            if (user == null)
            {
                return(Forbid());
            }

            var isInvoiceValid = !_context.Invoice.Any(i => i.TimesheetId.Equals(invoice.TimesheetId)) &&
                                 _context.Timesheet.Any(t =>
                                                        t.Id.Equals(invoice.TimesheetId) && t.State.Equals(Const.States.Closed));

            if (!isInvoiceValid)
            {
                return(BadRequest(new { Message = "Cannot create new invoice for provided timesheet!" }));
            }

            var invoiceTimesheet = await _context.Timesheet.FindAsync(invoice.TimesheetId);

            var invoiceObj = DtoToModel.DtoToInvoice(invoice);

            invoiceObj.InvoiceNumber = $"1/{invoiceTimesheet.Date.Month}/{invoiceTimesheet.Date.Year}";
            invoiceObj.UserId        = user.Id;

            await _context.Invoice.AddAsync(invoiceObj);

            await _context.SaveChangesAsync();

            var obj = _context.Invoice.Include(i => i.Timesheet).Include(i => i.Timesheet.Rows)
                      .First(i => i.Id.Equals(invoiceObj.Id));

            var invoiceSettings = await _context.UserInvoiceSettings.FirstAsync(settings => settings.UserId.Equals(user.Id));

            var invoiceSettingsDto = ModelToDto.InvoiceSettingsToDTO(invoiceSettings);

            var rateTypes = _context.RateTypes.ToList();

            var userRateAmounts = _context.UserRateAmount.Where(amount => amount.UserId.Equals(user.Id)).ToList();

            var dto = ModelToDto.InvoiceToDto(obj, invoiceSettingsDto, rateTypes, userRateAmounts);

            return(dto);
        }
        public async Task <IActionResult> PutTimesheet(int id, TimesheetDTO timesheet)
        {
            if (id != timesheet.Id)
            {
                return(BadRequest());
            }

            var currentUser = await _userManager.FindByNameAsync(User?.Identity?.Name);

            var isCorrectUser = _context.Timesheet.AsNoTracking().Any(t => t.Id == id && t.UserId == currentUser.Id);

            if (!isCorrectUser)
            {
                return(Forbid());
            }

            var timesheetObj = DtoToModel.DtoToTimesheet(timesheet);

            var validStates = States.GetStatesValues();

            if (!validStates.Contains(timesheet.State))
            {
                return(BadRequest());
            }

            var isModificationAllowed = _context.Timesheet.AsNoTracking().First(t => t.Id.Equals(id)).State != States.Closed;

            if (!isModificationAllowed)
            {
                return(BadRequest());
            }

            // new Rows
            var newRows = timesheetObj.Rows.Where(row => row.Id.Equals(0));

            foreach (var newRow in newRows)
            {
                await _context.Row.AddAsync(newRow);
            }

            // edited Rows
            var oldRows = timesheetObj.Rows.Where(row => row.Id > 0);

            foreach (var oldRow in oldRows)
            {
                _context.Entry(oldRow).State = EntityState.Modified;
            }


            // main entity
            _context.Entry(timesheetObj).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!TimesheetExists(id))
                {
                    return(NotFound());
                }
                else
                {
                    throw;
                }
            }

            return(NoContent());
        }