added pagesixe to userlist object. added total user count to enable PageCount to work correctly. added GET_TOTAL_USER_COUNT and GET_ALL_USERS_PAGINATE sqlite procedures to support pagination. updated methods in SQLiteRepository to support pagination procedures and pagination properties of UserList. updated UsersController to support pagination parameters. tidied html script tags. added pagination buttons at the bottom of user page. including drop down to select PageSize added setPageSize, goToUserPage and setPagination methods to the viewmodel. updated other methods for sammy etc to work with pagesize and PageNumber params. #11
421 lines
15 KiB
C#
421 lines
15 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Runtime.InteropServices.WindowsRuntime;
|
|
using Interfaces;
|
|
using SQLite.Net;
|
|
using SQLite.Net.Platform.Win32;
|
|
|
|
namespace SQLiteRepository
|
|
{
|
|
public class SQLiteRepository : IRepository
|
|
{
|
|
private readonly SQLiteConnection _connection;
|
|
private string _path = "flexitimedb.db";
|
|
|
|
public SQLiteRepository()
|
|
{
|
|
_connection = new SQLiteConnection(new SQLitePlatformWin32(), _path);
|
|
|
|
_connection.CreateTable<CardUniqueId>();
|
|
_connection.CreateTable<UserIdentity>();
|
|
_connection.CreateTable<TimeLogDb>();
|
|
}
|
|
|
|
public UserList GetUsers(int pageNumber=-1, int pageSize=-1)
|
|
{
|
|
var ret = new UserList();
|
|
List<UserIdentity> users;
|
|
int userCount = -1;
|
|
if (pageNumber == -1 && pageSize == -1)
|
|
{
|
|
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS);
|
|
userCount = users.Count;
|
|
}
|
|
else
|
|
{
|
|
users = _connection.Query<UserIdentity>(SQLiteProcedures.GET_ALL_USERS_PAGINATE,
|
|
pageSize, (pageNumber-1)*pageSize);
|
|
userCount = _connection.ExecuteScalar<int>(SQLiteProcedures.GET_TOTAL_USER_COUNT);
|
|
}
|
|
|
|
if (!users.Any())
|
|
{
|
|
if (pageNumber == -1 && pageSize == -1)
|
|
{
|
|
ret.PageNumber = 1;
|
|
ret.PageSize = 20;
|
|
}
|
|
else
|
|
{
|
|
ret.PageNumber = pageNumber;
|
|
ret.PageSize = pageSize;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
foreach (var user in users)
|
|
{
|
|
var userObj = ChangeToUserObject(user);
|
|
var cards = _connection.Query<CardUniqueId>(
|
|
SQLiteProcedures.GET_CARDS_BY_USER_ID,
|
|
user.Id);
|
|
|
|
foreach (var card in cards)
|
|
{
|
|
userObj.AssociatedIdentifiers.Add(new Identifier()
|
|
{
|
|
UniqueId = card.CardUId,
|
|
IsAssociatedToUser = true,
|
|
Id = card.Id
|
|
});
|
|
}
|
|
ret.Users.Add(userObj);
|
|
}
|
|
if (pageNumber == -1 && pageSize == -1)
|
|
{
|
|
ret.PageSize = 1; //TODO: switch to ret.UserCount
|
|
ret.PageNumber = 1;
|
|
}
|
|
else
|
|
{
|
|
ret.PageSize = pageSize;
|
|
ret.PageNumber = pageNumber;
|
|
}
|
|
ret.TotalUserCount = userCount;
|
|
return ret;
|
|
}
|
|
|
|
public UserList Search(string searchParam)
|
|
{
|
|
var ret = new UserList();
|
|
searchParam = string.Format("%{0}%", searchParam);
|
|
var users = _connection.Query<UserIdentity>(
|
|
SQLiteProcedures.SEARCH_USER_LIST,
|
|
searchParam, searchParam);
|
|
|
|
if (!users.Any())
|
|
{
|
|
ret.PageNumber = 1;
|
|
ret.PageSize = 20;
|
|
return ret;
|
|
}
|
|
|
|
foreach (var user in users)
|
|
{
|
|
var userObj = ChangeToUserObject(user);
|
|
var cards = _connection.Query<CardUniqueId>(
|
|
SQLiteProcedures.GET_CARDS_BY_USER_ID,
|
|
user.Id);
|
|
|
|
foreach (var card in cards)
|
|
{
|
|
userObj.AssociatedIdentifiers.Add(new Identifier()
|
|
{
|
|
UniqueId = card.CardUId,
|
|
IsAssociatedToUser = true,
|
|
Id = card.Id
|
|
});
|
|
}
|
|
ret.Users.Add(userObj);
|
|
}
|
|
ret.PageSize = 20;
|
|
ret.PageNumber = 1;
|
|
|
|
return ret;
|
|
}
|
|
|
|
public User GetUser(int id)
|
|
{
|
|
var ret = new User();
|
|
|
|
var users = _connection.Query<UserIdentity>(
|
|
SQLiteProcedures.GET_USER_BY_ID,
|
|
id);
|
|
|
|
if (!users.Any()) return ret;
|
|
|
|
var user = users.First();
|
|
ret = ChangeToUserObject(user);
|
|
var cards = _connection.Query<CardUniqueId>(
|
|
SQLiteProcedures.GET_CARDS_BY_USER_ID,
|
|
user.Id);
|
|
|
|
foreach (var card in cards)
|
|
{
|
|
ret.AssociatedIdentifiers.Add(new Identifier { UniqueId = card.CardUId, IsAssociatedToUser = true, Id = card.Id});
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
public TimeLogList GetTimeLogs(int userId)
|
|
{
|
|
var ret = new TimeLogList();
|
|
//get this calendar week;
|
|
var now = DateTime.UtcNow;
|
|
var calendarWeek = GetIso8601CalendarWeek(now);
|
|
ret.CalendarWeek = calendarWeek;
|
|
ret.SelectedDate = now.Date;
|
|
ret.TimeLogs = GetTimeLogList(userId, calendarWeek, now.Year);
|
|
|
|
return ret;
|
|
}
|
|
|
|
public TimeLogList GetTimeLogs(int userId, DateTime selectedDate)
|
|
{
|
|
var ret = new TimeLogList {SelectedDate = selectedDate.Date};
|
|
var calendarWeek = GetIso8601CalendarWeek(selectedDate);
|
|
ret.CalendarWeek = calendarWeek;
|
|
|
|
ret.TimeLogs = GetTimeLogList(userId, calendarWeek, selectedDate.Year);
|
|
|
|
return ret;
|
|
}
|
|
|
|
public IdentifierList GetUnassignedIdentifierList()
|
|
{
|
|
var ret = new IdentifierList();
|
|
var cardQuery = _connection.Query<CardUniqueId>(
|
|
SQLiteProcedures.GET_UNASSIGNED_CARD_LIST,
|
|
Constants.UNASSIGNED_CARD_USER_ID);
|
|
|
|
foreach (var card in cardQuery)
|
|
{
|
|
ret.data.Add(new Identifier
|
|
{
|
|
Id = card.Id,
|
|
IsAssociatedToUser = card.UserId_FK != Constants.UNASSIGNED_CARD_USER_ID,
|
|
UniqueId = card.CardUId
|
|
});
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
//TODO: Check time logs table on update to ensure associated cards/unique identifiers are removed/added as appropriate.
|
|
public OperationResponse UpdateUser(User user, out int userIdResult)
|
|
{
|
|
//if(user.UserId <=0) return OperationResponse.FAILED;
|
|
|
|
var ret = OperationResponse.NONE;
|
|
var cardIds = new List<int>();
|
|
|
|
//Get a list of current associated identifiers, convert into a list of Identifier Objects..
|
|
var currentCards =
|
|
_connection.Query<CardUniqueId>(SQLiteProcedures.GET_CARDS_BY_USER_ID, user.UserId)
|
|
.Select(x => new Identifier {Id = x.Id, IsAssociatedToUser = true, UniqueId = x.CardUId});
|
|
var cardsToRemove = currentCards.Except(user.AssociatedIdentifiers).Select(x=>x.Id).ToList();
|
|
|
|
#region GetUnique Identifiers
|
|
foreach (var card in user.AssociatedIdentifiers)
|
|
{
|
|
var existingCard = _connection.Query<CardUniqueId>(
|
|
SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID, card.UniqueId);
|
|
|
|
if (!existingCard.Any())
|
|
{
|
|
var cardInsert = new CardUniqueId { CardUId = card.UniqueId, UserId_FK = -1 };
|
|
_connection.Insert(cardInsert);
|
|
cardIds.Add(cardInsert.Id);
|
|
if (ret < OperationResponse.CREATED)
|
|
ret = OperationResponse.CREATED; //only change it if my status supercedes.
|
|
}
|
|
else
|
|
{
|
|
cardIds.Add(existingCard.First().Id);
|
|
if (ret < OperationResponse.UPDATED)
|
|
ret = OperationResponse.UPDATED;
|
|
}
|
|
}
|
|
#endregion
|
|
|
|
#region Update/Create User
|
|
int userId;
|
|
|
|
if (user.UserId != -1)
|
|
{
|
|
//edit..
|
|
_connection.Query<UserIdentity>(
|
|
"update UserIdentity set FirstName=?, LastName=?, HoursPerWeek=?,IsContractor=? where Id=?",
|
|
user.FirstName,
|
|
user.LastName,
|
|
user.HoursPerWeek,
|
|
user.IsContractor,
|
|
user.UserId
|
|
);
|
|
userId = user.UserId;
|
|
}
|
|
else
|
|
{
|
|
var userInsert = new UserIdentity
|
|
{
|
|
FirstName = user.FirstName,
|
|
LastName = user.LastName,
|
|
HoursPerWeek = user.HoursPerWeek,
|
|
IsContractor = user.IsContractor
|
|
};
|
|
_connection.Insert(userInsert);
|
|
userId = userInsert.Id;
|
|
if (ret < OperationResponse.CREATED)
|
|
ret = OperationResponse.CREATED;
|
|
}
|
|
#endregion
|
|
|
|
#region Update Card/Unique Id entries.
|
|
foreach (var cardId in cardIds)
|
|
{
|
|
_connection.Query<CardUniqueId>(
|
|
SQLiteProcedures.UPDATE_CARD_USER_ID,
|
|
userId, cardId);
|
|
}
|
|
foreach (var card in cardsToRemove)
|
|
{
|
|
_connection.Query<CardUniqueId>(
|
|
SQLiteProcedures.UPDATE_CARD_USER_ID,
|
|
-1, card);
|
|
}
|
|
#endregion
|
|
|
|
userIdResult = userId;
|
|
return ret;
|
|
}
|
|
|
|
public OperationResponse LogEventTime(Identifier identifier, out int logId)
|
|
{
|
|
var cardIdQuery = _connection.Query<CardUniqueId>(
|
|
SQLiteProcedures.GET_CARDS_BY_UNIQUE_ID,
|
|
identifier.UniqueId);
|
|
|
|
#region Get/Insert the PK Id Identifier to associate the time log to.
|
|
var ident = new CardUniqueId();
|
|
if (!cardIdQuery.Any())
|
|
{
|
|
//new card, create it!
|
|
ident.UserId_FK = -1;
|
|
ident.CardUId = identifier.UniqueId;
|
|
_connection.Insert(ident);
|
|
}
|
|
else
|
|
{
|
|
//TODO: log when more than one comes back. should NEVER happen but....
|
|
ident = cardIdQuery.First();
|
|
}
|
|
#endregion
|
|
|
|
// Get The User Direction (are they going in or out)?
|
|
var logDirection = GetLogDirection(ident.UserId_FK);
|
|
|
|
#region Get the current time (for swiping). and calendar week/year to help recall the data.
|
|
var logTime = DateTime.UtcNow;
|
|
var calendarWeek = GetIso8601CalendarWeek(logTime);
|
|
var year = logTime.Year;
|
|
#endregion
|
|
|
|
//TODO: Handle When the identifier is assigned to a user (identifier has -1)
|
|
//when identifier not assigned to user, just store it anyway and carry on, can update later.
|
|
|
|
var timeLog = new TimeLogDb
|
|
{
|
|
SwipeEventDateTime = DateTime.UtcNow,
|
|
UserId_FK = ident.UserId_FK,
|
|
IdentifierId = ident.Id,
|
|
Direction = logDirection,
|
|
Year = year,
|
|
CalendarWeek=calendarWeek
|
|
};
|
|
|
|
_connection.Insert(timeLog);
|
|
logId = timeLog.Id;
|
|
|
|
return OperationResponse.SUCCESS;
|
|
}
|
|
|
|
private List<TimeLog> GetTimeLogList(int userId, int calendarWeek, int year)
|
|
{
|
|
var timeLogList = _connection.Query<TimeLogDb>(
|
|
SQLiteProcedures.GET_TIMELOGS,
|
|
userId, calendarWeek, year);
|
|
|
|
var ret = timeLogList.Select(x => new TimeLog
|
|
{
|
|
Id = x.Id,
|
|
CalendarWeek = x.CalendarWeek,
|
|
Direction = (LogDirection)x.Direction,
|
|
IdentifierId = x.IdentifierId,
|
|
EventTime = x.SwipeEventDateTime,
|
|
UserId = x.UserId_FK,
|
|
Year = x.Year
|
|
}).ToList();
|
|
return ret;
|
|
}
|
|
|
|
private LogDirectionDb GetLogDirection(int userId)
|
|
{
|
|
var logDirection = LogDirectionDb.UNKNOWN;
|
|
if (userId != -1)
|
|
{
|
|
var lastEntry = _connection.Query<TimeLogDb>(
|
|
SQLiteProcedures.GET_LAST_TIMELOG_DIRECTION,
|
|
userId);
|
|
if (lastEntry.Any())
|
|
{
|
|
var lastLog = lastEntry.First();
|
|
// See if the datetime retrieved is yesterday. If yesterday, logDirection = true (in)
|
|
if (IsLogDateTimeYesterdayOrOlder(lastLog.SwipeEventDateTime.DateTime))
|
|
{
|
|
logDirection = LogDirectionDb.IN;
|
|
}
|
|
else
|
|
{
|
|
// we have a time log from today already, so just do the opposite of what we last did!
|
|
if (lastLog.Direction == LogDirectionDb.IN)
|
|
logDirection = LogDirectionDb.OUT;
|
|
else if (lastLog.Direction == LogDirectionDb.OUT)
|
|
logDirection = LogDirectionDb.IN;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//assume its the first then!
|
|
logDirection = LogDirectionDb.IN;
|
|
}
|
|
}
|
|
return logDirection;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get the calendar week of the year according to the ISO8601 standard (starts monday).
|
|
/// </summary>
|
|
/// <param name="date">the date to get the calendar week of.</param>
|
|
/// <returns>the calendar week of the year in integer form (1-52)</returns>
|
|
private int GetIso8601CalendarWeek(DateTime date)
|
|
{
|
|
var day = CultureInfo.InvariantCulture.Calendar.GetDayOfWeek(date);
|
|
if (day >= DayOfWeek.Monday && day <= DayOfWeek.Wednesday)
|
|
{
|
|
date = date.AddDays(3);
|
|
}
|
|
return CultureInfo.InvariantCulture.Calendar.GetWeekOfYear(date, CalendarWeekRule.FirstFourDayWeek,
|
|
DayOfWeek.Monday);
|
|
}
|
|
|
|
private bool IsLogDateTimeYesterdayOrOlder(DateTime dt)
|
|
{
|
|
return dt.Date.CompareTo(DateTime.Today.Date) < 0;
|
|
}
|
|
|
|
private User ChangeToUserObject(UserIdentity user)
|
|
{
|
|
return new User
|
|
{
|
|
UserId = user.Id,
|
|
FirstName = user.FirstName,
|
|
LastName = user.LastName,
|
|
HoursPerWeek = user.HoursPerWeek,
|
|
IsContractor = user.IsContractor
|
|
};
|
|
}
|
|
}
|
|
}
|