Alv-no / alvtime

Ett timeføringssystem som gjør at konsulenter fører timene sine.
https://alv-no.github.io/alvtime/
9 stars 4 forks source link

Error when trying to write hours #606

Open klyngen opened 1 year ago

klyngen commented 1 year ago

Steps to reproduce: Try to add hours to the following field image

Theories The issue appears when writing hours quickly or when mixing vacation with normal hours

Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details. ---> Microsoft.Data.SqlClient.SqlException (0x80131904): Violation of UNIQUE KEY constraint 'UC_EarnedOvertime'. Cannot insert duplicate key in object 'dbo.EarnedOvertime'. The duplicate key value is (11, 2022-11-30 00:00:00.0000000, 1.00).The statement has been terminated.   at Microsoft.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__188_0(Task`1 result)   at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)--- End of stack trace from previous location ---   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)--- End of stack trace from previous location ---   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)ClientConnectionId:040c4602-3c05-446c-bfa0-811feb142f2dError Number:2627,State:1,Class:14ClientConnectionId before routing:47a17e13-c487-4cf5-8719-fcfdc48c1164Routing Destination:eec693118e17.HS1.tr21769.westeurope1-a.worker.database.windows.net,11010   --- End of inner exception stack trace ---   at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(IEnumerable`1 commandBatches, IRelationalConnection connection, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IList`1 entriesToSave, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(StateManager stateManager, Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)   at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)   at AlvTime.Persistence.Repositories.TimeRegistrationStorage.StoreOvertime(List`1 overtimeEntries, Int32 userId) in /app/AlvTime.Persistence/Repositories/TimeRegistrationStorage.cs:line 206   at AlvTime.Business.TimeRegistration.TimeRegistrationService.StoreNewOvertime(List`1 timeEntriesOnDay) in /app/AlvTime.Business/TimeRegistration/TimeRegistrationService.cs:line 546   at AlvTime.Business.TimeRegistration.TimeRegistrationService.UpdateEarnedOvertime(List`1 timeEntriesOnDay, Int32 userId) in /app/AlvTime.Business/TimeRegistration/TimeRegistrationService.cs:line 488   at AlvTime.Business.TimeRegistration.TimeRegistrationService.<>c__DisplayClass10_1.<<UpsertTimeEntry>b__0>d.MoveNext() in /app/AlvTime.Business/TimeRegistration/TimeRegistrationService.cs:line 74--- End of stack trace from previous location ---   at AlvTime.Persistence.Repositories.DbContextScope.AsAtomic(Func`1 atomicAction) in /app/AlvTime.Persistence/Repositories/DbContextScope.cs:line 20   at AlvTime.Persistence.Repositories.DbContextScope.AsAtomic(Func`1 atomicAction) in /app/AlvTime.Persistence/Repositories/DbContextScope.cs:line 21   at AlvTime.Business.TimeRegistration.TimeRegistrationService.UpsertTimeEntry(IEnumerable`1 timeEntries) in /app/AlvTime.Business/TimeRegistration/TimeRegistrationService.cs:line 69   at AlvTimeWebApi.Controllers.TimeEntriesController.UpsertTimeEntry(List`1 requests) in /app/AlvTimeWebApi/Controllers/TimeEntriesController.cs:line 78   at lambda_method345(Closure , Object )   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeNextResourceFilter>g__Awaited|25_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)   at Microsoft.AspNetCore.Authorization.Policy.AuthorizationMiddlewareResultHandler.HandleAsync(RequestDelegate next, HttpContext context, AuthorizationPolicy policy, PolicyAuthorizationResult authorizeResult)   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)   at AlvTimeWebApi.ErrorHandling.ErrorHandlingMiddleware.Invoke(HttpContext context) in /app/AlvTimeWebApi/ErrorHandling/ErrorHandlingMiddleware.cs:line 25
palbock commented 1 year ago

Several tasks had previously been registered on the relevant date then changed back to 0. The tasks registered with a 0 value were 23 - Pålagt overtid, 17 - Alvtime, 18 - Avspasering, 13 - Ferie, 2 - Funksjonell Arkitekt. After deleting all the hour entries with a 0 value, I was able to register the new hour entry again. Bug must have something to do with the previously registered tasks when trying to calculate overtime for the date.