public JObject setLoanAcquired(JObject request) { // Get arguments request.TryGetValue("loanItemID", out JToken requestLoanItemId); request.TryGetValue("value", out JToken requestAcquiredValue); // Verify presence of arguments var failedVerifications = new List <string>(); if (requestLoanItemId == null) { failedVerifications.Add("loanItemID"); } if (requestAcquiredValue == null) { failedVerifications.Add("value"); } if (failedVerifications.Any()) { return(Templates.MissingArguments(failedVerifications.ToArray())); } // Verify arguments if (requestLoanItemId.Type != JTokenType.Integer) { failedVerifications.Add("loanItemID"); } if (requestAcquiredValue.Type != JTokenType.Boolean) { failedVerifications.Add("value"); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } // Get loanItem var condition = new MySqlConditionBuilder("id", MySqlDbType.Int32, (object)requestLoanItemId.ToObject <int>()); var loanItem = Connection.Select <LoanItem>(condition).FirstOrDefault(); if (loanItem == null) { return(Templates.NoSuchLoan(requestLoanItemId.ToString())); } // Update the IsAcquired value if it isn't equal to the 'value' argument if ((bool)requestAcquiredValue != loanItem.IsAcquired) { loanItem.IsAcquired = (bool)requestAcquiredValue; Connection.Update(loanItem); } //Create base response return(new JObject() { { "reason", null } }); }
public JObject resizeLoan(JObject request) { //Get arguments request.TryGetValue("loanId", out JToken loanItemID); request.TryGetValue("start", out JToken requestStart); request.TryGetValue("end", out JToken requestEnd); // Verify the arguments List <string> failedVerifications = new List <string>(); if (loanItemID == null || loanItemID.Type != JTokenType.Integer) { failedVerifications.Add("loanId"); } if (requestStart == null || !(requestStart.Type == JTokenType.String || requestStart.Type == JTokenType.Date)) { failedVerifications.Add("start"); } if (requestEnd == null || !(requestEnd.Type == JTokenType.String || requestEnd.Type == JTokenType.Date)) { failedVerifications.Add("end"); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } // Parse arguments DateTime start; DateTime end; string loanID = loanItemID.ToString(); try { start = DateTime.Parse(requestStart.ToString()); } catch (Exception) { return(Templates.InvalidArgument("Unable to parse 'start'")); } try { end = DateTime.Parse(requestEnd.ToString()); } catch (Exception) { return(Templates.InvalidArgument("Unable to parse 'end'")); } if (end < start) { return(Templates.InvalidArguments("'end' must come after 'start'")); } DateTimeSpan newLoanSpan = new DateTimeSpan(start, end); if (newLoanSpan.Start < DateTime.Now.Date) { return(Templates.InvalidArgument("'start' may not be set earlier than today.")); } if (newLoanSpan.Duration > MaxLoanDuration) { return(Templates.InvalidArgument($"Duration of the loan may not exceed {MaxLoanDuration.Days} days.")); } // Build a condition to get the specific loan var condition = new MySqlConditionBuilder(); // Automatically limit results to current user only if their permission is User if (CurrentUser.Permission <= UserPermission.User) { condition.And().Column("user").Equals(CurrentUser.Username, MySqlDbType.String); } condition.And().Column("id").Equals(loanID, MySqlDbType.Int32); //Get the specified loanItem if it exists. If it doesn't, throw an error. LoanItem oldLoan = Connection.Select <LoanItem>(condition).FirstOrDefault(); if (oldLoan == null) { return(Templates.NoSuchLoan(loanID)); } // Return a loanExpired template if the loan has already ended if (oldLoan.End < DateTime.Now) { return(Templates.LoanExpired()); } if (oldLoan.Start < DateTime.Now && oldLoan.Start != start) { return(Templates.LoanAlreadyStarted()); } // Build condition condition = new MySqlConditionBuilder() .Column("product_item") .Equals(oldLoan.ProductItem, MySqlDbType.Int32); // Select only relevant loans condition.And().Column("end").GreaterThanOrEqual().Operand(start, MySqlDbType.DateTime); condition.And().Column("start").LessThanOrEqual().Operand(end, MySqlDbType.DateTime); //Get all loanItems for this loan's product_item. var loans = Connection.Select <LoanItem>(condition).ToList(); //Check for conflicting loanItems bool canResize = true; foreach (var loan in loans) { var loanSpan = new DateTimeSpan(loan.Start, loan.End); if (newLoanSpan.Overlaps(loanSpan)) { canResize = false; break; } } //Create response var responseData = new JObject(); JObject response = new JObject() { { "reason", null }, { "responseData", responseData } }; if (canResize) { // Update loan oldLoan.Start = start; oldLoan.End = end; Connection.Update(oldLoan); } else if (oldLoan.IsAcquired && !canResize) // If loan is not eligible for a item reassignment { return(Templates.LoanResizeFailed()); } else // If the loan is eligible for an item reassignment { // Try to retrieve a list of unreserved equivalent products var unreservedAlts = Core_GetUnreservedItems(oldLoan.GetProductItem(Connection).ProductId, newLoanSpan); if (unreservedAlts == null) // Normally this value should not be able to be null. This block is just a failsafe that adds context. { throw new InvalidOperationException("Expected type of 'unreservedAlts' is List, but nullreference was found."); } if (!unreservedAlts.Any()) { Log.Error("Failed at line 107"); return(Templates.LoanResizeFailed()); } // Update loan oldLoan.ProductItem = unreservedAlts.First().Id.Value; oldLoan.Start = start; oldLoan.End = end; Connection.Update(oldLoan); // Return new data in response and add message for context responseData["product_item"] = oldLoan.ProductItem; response["message"] = "Loan has been reassigned."; } return(response); }
public JObject getLoans(JObject request) { // Get arguments request.TryGetValue("columns", out JToken requestColumns); request.TryGetValue("productItemIds", out JToken requestProductItems); request.TryGetValue("userId", out JToken requestUserId); request.TryGetValue("loanItemID", out JToken requestLoanId); request.TryGetValue("start", out JToken requestStart); request.TryGetValue("end", out JToken requestEnd); // Verify arguments List <string> failedVerifications = new List <string>(); if (requestColumns != null && (requestColumns.Type != JTokenType.Array || requestColumns.Any(x => x.Type != JTokenType.String))) { failedVerifications.Add("columns"); } if (requestProductItems != null && (requestProductItems.Type != JTokenType.Array || requestProductItems.Any(x => x.Type != JTokenType.String))) { failedVerifications.Add("productItemIds"); } if (requestUserId != null && requestUserId.Type != JTokenType.String) { failedVerifications.Add("userId"); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } // Parse arguments DateTime start; DateTime end; try { start = requestStart == null ? new DateTime() : DateTime.Parse(requestStart.ToString()); } catch (Exception) { return(Templates.InvalidArgument("Unable to parse 'start'")); } try { end = requestEnd == null ? new DateTime() : DateTime.Parse(requestEnd.ToString()); } catch (Exception) { return(Templates.InvalidArgument("Unable to parse 'end'")); } // Prepare values if (requestColumns == null || requestColumns.Count() == 0) { requestColumns = new JArray(LoanItem.metadata.Select(x => x.Column)); } // Build condition var condition = new MySqlConditionBuilder(); if (requestProductItems != null && requestProductItems.Any()) { condition.NewGroup(); foreach (var productItem in requestProductItems) { condition.Or() .Column("product_item") .Equals(productItem, MySqlDbType.String); } condition.EndGroup(); } // Filter by specific loan id if (requestLoanId != null) { condition.And().Column("id").Equals(requestLoanId, MySqlDbType.Int32); } // Filter by user if (requestUserId != null) { condition.And().Column("user").Equals(requestUserId, MySqlDbType.String); } // Automatically limit results to current user only if their permission is User if (CurrentUser.Permission <= UserPermission.User) { condition.And().Column("user").Equals(CurrentUser.Username, MySqlDbType.String); } // Select only relevant loans if (requestStart != null) { condition.And().Column("end").GreaterThanOrEqual().Operand(start, MySqlDbType.DateTime); } if (requestEnd != null) { condition.And().Column("start").LessThanOrEqual().Operand(end, MySqlDbType.DateTime); } // Get loans var loans = Connection.Select <LoanItem>(requestColumns.ToObject <string[]>(), condition); // Build base response var responseData = new JArray(); JObject response = new JObject() { { "reason", null }, { "responseData", responseData } }; // Populate responseData foreach (var loanData in loans) { var item = new JObject(); for (int i = 0; i < requestColumns.Count(); i++) { if (loanData[i] is DateTime) { item[(string)requestColumns[i]] = new JValue(((DateTime)loanData[i]).ToUniversalTime().Subtract(Epoch).TotalMilliseconds); } else { item[(string)requestColumns[i]] = new JValue(loanData[i]); } } responseData.Add(item); } return(response); }
public JObject getImages(JObject request) { //Get arguments request.TryGetValue("columns", out JToken requestColumns); request.TryGetValue("images", out JToken requestImageIds); if (requestImageIds == null) { return(Templates.MissingArguments("imageIds")); } // Verify arguments List <string> failedVerifications = new List <string>(); if (requestColumns != null && (requestColumns.Type != JTokenType.Array || ((JArray)requestColumns).Count == 0)) { failedVerifications.Add("columns"); } if (requestImageIds.Type != JTokenType.Array) { failedVerifications.Add("images"); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } // Build condition var condition = new MySqlConditionBuilder(); bool first = true; foreach (string id in requestImageIds) { if (!first) { condition.Or(); } condition.Column(Image.indexes.First(x => x.Type == Index.IndexType.PRIMARY).Columns[0].Column); condition.Equals(id, MySqlDbType.String); first = false; } // If condition is blank, add a condition that is false if (first) { condition.Not().Null().Is().Null(); } // Prepare query values if (requestColumns == null || !requestColumns.Any()) { requestColumns = new JArray(Image.metadata.Select(x => x.Column)); } // Add primary key column name ((JArray)requestColumns).Insert(0, Image.indexes.First(x => x.Type == Index.IndexType.PRIMARY).Columns[0].Column); // Get images List <object[]> imageData = Connection.Select <Image>(requestColumns.ToObject <string[]>(), condition).ToList(); //Create base response var responseData = new JObject(); var response = new JObject() { { "reason", null }, { "responseData", responseData } }; foreach (var data in imageData) { var item = new JObject(); for (int i = 1; i < requestColumns.Count(); i++) { item.Add((string)requestColumns[i], new JValue(data[i])); } responseData.Add((string)data[0], item); } return(response); }
public JObject addLoan(JObject request) { //Get arguments request.TryGetValue("productId", out JToken requestProductId); request.TryGetValue("start", out JToken requestStart); request.TryGetValue("end", out JToken requestEnd); // Verify the arguments List <string> failedVerifications = new List <string>(); if (requestProductId == null || requestProductId.Type != JTokenType.String) { failedVerifications.Add("productID"); } if (requestStart == null || !(requestStart.Type == JTokenType.String || requestStart.Type == JTokenType.Date)) { failedVerifications.Add("start"); } if (requestEnd == null || !(requestEnd.Type == JTokenType.String || requestEnd.Type == JTokenType.Date)) { failedVerifications.Add("end"); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } // Parse arguments DateTime start; DateTime end; string productId = requestProductId.ToString(); try { start = DateTime.Parse(requestStart.ToString()); } catch (Exception) { return(Templates.InvalidArgument("Unable to parse 'start'")); } try { end = DateTime.Parse(requestEnd.ToString()); } catch (Exception) { return(Templates.InvalidArgument("Unable to parse 'end'")); } if (end < start) { return(Templates.InvalidArguments("'end' must come after 'start'")); } var newLoanSpan = new DateTimeSpan(start, end); if (newLoanSpan.Start < DateTime.Now.Date) { return(Templates.InvalidArgument("'start' may not be set earlier than today.")); } if (newLoanSpan.Duration > MaxLoanDuration) { return(Templates.InvalidArgument($"Duration of the loan may not exceed {MaxLoanDuration.Days} days.")); } // Get an unreserved product item ProductItem item; try { item = Core_GetUnreservedItems(productId, newLoanSpan).FirstOrDefault(); } catch (Exception) { return(Templates.NoItemsForProduct(productId)); } if (item == null) { return(Templates.NoItemsForProduct($"Product '{productId}' has no items available during this time.")); } var loan = new LoanItem(null, CurrentUser.Username, item.Id.Value, start, end); Connection.Upload(loan); //Create response JObject response = new JObject() { { "reason", null }, { "responseData", new JObject() { { "loanId", loan.Id }, { "productItem", item.Id } } } }; return(response); }
public JObject getUsers(JObject request) { request.TryGetValue("permission", out JToken permValue); request.TryGetValue("username", out JToken usernameValue); // Verify arguments int permission; string username; if (permValue != null && permValue.Type == JTokenType.Integer) { permission = permValue.ToObject <int>(); if (permission <= -1 || permission >= 4) { return(Templates.InvalidArguments("Permission out of range: " + permission)); } } else { permission = -1; } if (usernameValue != null && usernameValue.Type == JTokenType.String) { username = usernameValue.ToObject <string>(); } else { username = null; } username += "%"; //Construct query MySqlConditionBuilder query = new MySqlConditionBuilder(); if (username != null) { query.Column("username") .Like(username); } if (permission != -1) { query.And() .Column("permissions") .Equals(permission, MySql.Data.MySqlClient.MySqlDbType.Int32); } //Get users List <User> userdata = Connection.Select <User>(query).ToList(); //Create response list JArray users = new JArray(); foreach (User user in userdata) { users.Add(new JObject() { { "username", user.Username }, { "permission", (int)user.Permission } }); } //Create response return(new JObject() { { "reason", null }, { "responseData", users } }); }
public JObject getProducts(JObject request) { // Get request arguments request.TryGetValue("columns", out JToken requestColumns); request.TryGetValue("criteria", out JToken requestCriteria); request.TryGetValue("language", out JToken requestLanguages); request.TryGetValue("start", out JToken requestRangeStart); request.TryGetValue("amount", out JToken requestRangeAmount); MySqlConditionBuilder condition = new MySqlConditionBuilder(); // Verify the types of the arguments List <string> failedVerifications = new List <string>(); if (requestColumns != null && (requestColumns.Type != JTokenType.Array || requestColumns.Any(x => x.Type != JTokenType.String))) { failedVerifications.Add("colums"); } if (requestCriteria != null) { try { condition = Misc.CreateCondition((JObject)requestCriteria, condition); } catch (Exception) { failedVerifications.Add("criteria"); } } if (requestLanguages != null && (requestLanguages.Type != JTokenType.Array || requestLanguages.Any(x => x.Type != JTokenType.String))) { failedVerifications.Add("language"); } if (requestRangeStart != null && (requestRangeStart.Type != JTokenType.Integer)) { failedVerifications.Add("start"); } if (requestRangeAmount != null && (requestRangeAmount.Type != JTokenType.Integer)) { failedVerifications.Add("amount"); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } //Create base response var responseData = new JArray(); JObject response = new JObject() { { "reason", null }, { "responseData", responseData } }; // Prepare values for database call var productPrimary = Product.indexes.First(x => x.Type == Index.IndexType.PRIMARY).Columns[0]; condition.And() .Column(productPrimary.Column) .NotEquals(0, productPrimary.Type); (ulong, ulong)range = (requestRangeStart?.ToObject <ulong>() ?? 0, requestRangeAmount?.ToObject <ulong>() ?? ulong.MaxValue); if (requestColumns == null || requestColumns.Count() == 0) { requestColumns = new JArray(Product.metadata.Select(x => x.Column)); } else if (requestLanguages != null && !requestColumns.Contains("name")) { ((JArray)requestColumns).Add("name"); } // Remove unknown language columns requestLanguages = new JArray(requestLanguages.Where(x => LanguageItem.metadata.Select(y => y.Column).Contains(x.ToString()))); // Request category data from database List <object[]> categoryData = Connection.Select <Product>(requestColumns.ToObject <string[]>(), condition, range).ToList(); // Add all categories as dictionaries to responseData foreach (var data in categoryData) { var item = new JObject(); for (int i = 0; i < requestColumns.Count(); i++) { item[(string)requestColumns[i]] = new JValue(data[i]); } responseData.Add(item); } // Add translations if specified in the arguments if (requestLanguages != null) { List <string> nameIds = responseData.Select(x => x["name"].ToString()).ToList(); // Build a condition to get all language items in one query var nameCondition = new MySqlConditionBuilder(); foreach (var name in nameIds) { nameCondition.Or(); nameCondition.Column("id"); nameCondition.Equals(name, MySqlDbType.String); } // Get the specified translations var languageColumns = requestLanguages.ToObject <List <string> >(); if (languageColumns.Count == 0) { languageColumns.AddRange(LanguageItem.metadata.Select(x => x.Column)); } else { languageColumns.Insert(0, "id"); } List <object[]> names = Connection.Select <LanguageItem>(languageColumns.ToArray(), nameCondition).ToList(); for (int i = 0; i < responseData.Count; i++) { var nameData = names.First(x => x[0].Equals(nameIds[i])); var translations = new JObject(); for (int j = 1; j < languageColumns.Count; j++) { if (nameData[j] != null) { translations[languageColumns[j]] = new JValue(nameData[j]); } } responseData[i]["name"] = translations; } } if (requestLanguages != null) { List <string> descIds = responseData.Select(x => x["description"].ToString()).ToList(); // Build a condition to get all language items in one query var descCondition = new MySqlConditionBuilder(); foreach (var desc in descIds) { descCondition.Or(); descCondition.Column("id"); descCondition.Equals(desc, MySqlDbType.String); } // Get the specified translations var languageColumns = requestLanguages.ToObject <List <string> >(); if (languageColumns.Count == 0) { languageColumns.AddRange(LanguageItem.metadata.Select(x => x.Column)); } else { languageColumns.Insert(0, "id"); } List <object[]> names = Connection.Select <LanguageItem>(languageColumns.ToArray(), descCondition).ToList(); for (int i = 0; i < responseData.Count; i++) { var nameData = names.First(x => x[0].Equals(descIds[i])); var translations = new JObject(); for (int j = 1; j < languageColumns.Count; j++) { if (nameData[j] != null) { translations[languageColumns[j]] = new JValue(nameData[j]); } } responseData[i]["description"] = translations; } } return(response); }
public JObject addProduct(JObject request) { //Get arguments string productID; string manufacturer; string categoryID; request.TryGetValue("productID", out JToken productIDValue); request.TryGetValue("categoryID", out JToken categoryIDValue); request.TryGetValue("manufacturer", out JToken manufacturerValue); request.TryGetValue("description", out JToken descriptionValue); request.TryGetValue("name", out JToken nameValue); // Verify presence of arguments List <string> failedVerifications = new List <string>(); if (productIDValue == null) { failedVerifications.Add("productID"); } if (categoryIDValue == null) { failedVerifications.Add("categoryID"); } if (manufacturerValue == null) { failedVerifications.Add("manufacturer"); } if (nameValue == null) { failedVerifications.Add("name"); } if (failedVerifications.Any()) { return(Templates.MissingArguments(failedVerifications.ToArray())); } // Verify arguments if (productIDValue.Type != JTokenType.String) { failedVerifications.Add("productID"); } if (categoryIDValue.Type != JTokenType.String) { failedVerifications.Add("categoryID"); } if (manufacturerValue.Type != JTokenType.String) { failedVerifications.Add("manufacturer"); } if (nameValue.Type != JTokenType.Object) { failedVerifications.Add("name"); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } // Prepare values productID = productIDValue.ToObject <string>(); manufacturer = manufacturerValue.ToObject <string>(); categoryID = categoryIDValue.ToObject <string>(); // Get image request.TryGetValue("image", out JToken imageValue); string extension = null; byte[] imageData = null; if (imageValue != null && imageValue.Type == JTokenType.Object) { JObject image = imageValue.ToObject <JObject>(); image.TryGetValue("data", out JToken dataValue); image.TryGetValue("extension", out JToken extensionValue); if (extensionValue != null && extensionValue.Type == JTokenType.String && dataValue != null && dataValue.Type == JTokenType.String) { extension = extensionValue.ToObject <string>(); imageData = (byte[])dataValue; if (!Image.ImageFormats.Contains(extension)) { return(Templates.InvalidArgument("extension")); } } else { return(Templates.MissingArguments("data, extension")); } } // Get languages string en; string nl = null; string ar = null; JObject names = nameValue.ToObject <JObject>(); names.TryGetValue("en", out JToken nameEnValue); names.TryGetValue("nl", out JToken nameNlValue); names.TryGetValue("ar", out JToken nameArValue); if (nameEnValue != null && nameEnValue.Type == JTokenType.String) { en = names["en"].ToObject <string>(); } else { return(Templates.MissingArguments("name: en")); } if (nameNlValue != null && nameNlValue.Type == JTokenType.String) { nl = names["nl"].ToObject <string>(); } if (nameArValue != null && nameArValue.Type == JTokenType.String) { ar = names["ar"].ToObject <string>(); } LanguageItem name = new LanguageItem(productID + "_name", en, nl, ar); LanguageItem description; if (descriptionValue != null && descriptionValue.Type == JTokenType.Object) { //Get description JObject desc = descriptionValue.ToObject <JObject>(); desc.TryGetValue("en", out JToken descEnValue); desc.TryGetValue("nl", out JToken descNlValue); desc.TryGetValue("ar", out JToken descArValue); if (descEnValue != null && descEnValue.Type == JTokenType.String) { en = desc["en"].ToObject <string>(); } else { return(Templates.MissingArguments("description: en")); } if (descNlValue != null && descNlValue.Type == JTokenType.String) { nl = desc["nl"].ToObject <string>(); } if (descArValue != null && descArValue.Type == JTokenType.String) { ar = desc["ar"].ToObject <string>(); } description = new LanguageItem(productID + "_description", en, nl, ar); } else { description = new LanguageItem(productID + "_description", null); } //Check if product already exists Product product = GetObject <Product>(productID); if (product != null) { return(Templates.AlreadyExists(productID)); } //Check if category exists ProductCategory category = GetObject <ProductCategory>(categoryID); if (category == null) { return(Templates.NoSuchProductCategory(categoryID)); } //Create product, languageItem, image name.Upload(Connection); description.Upload(Connection); if (imageData != null) { Image image = new Image(productID + "_image", imageData, extension); image.Upload(Connection); product = new Product(productID, manufacturer, categoryID, productID + "_name", productID + "_description", image.Id); } else { product = new Product(productID, manufacturer, categoryID, productID + "_name", productID + "_description"); } product.Upload(Connection); //Create response return(new JObject() { { "reason", null }, }); }
public JObject getUnavailableDates(JObject request) { // Get arguments request.TryGetValue("productId", out JToken requestProductId); request.TryGetValue("start", out JToken requestStart); request.TryGetValue("end", out JToken requestEnd); // Verify arguments List <string> failedVerifications = new List <string>(); if (requestProductId == null || requestProductId.Type != JTokenType.String) { return(Templates.InvalidArgument("productId")); } if (requestStart == null) { return(Templates.InvalidArgument("start")); } if (requestEnd == null) { return(Templates.InvalidArgument("end")); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } // Parse arguments DateTime start; DateTime end; try { start = requestStart == null ? new DateTime() : DateTime.Parse(requestStart.ToString()); } catch (Exception) { return(Templates.InvalidArgument("Unable to parse 'start'")); } try { end = requestEnd == null ? new DateTime() : DateTime.Parse(requestEnd.ToString()); } catch (Exception) { return(Templates.InvalidArgument("Unable to parse 'end'")); } var range = new DateTimeSpan(start, end); if (range.Duration.Days > 122) { return(Templates.InvalidArgument("start and end may not be more than 122 days apart.")); } // Get all items var condition = new MySqlConditionBuilder("product", MySqlDbType.String, requestProductId.ToString()); var productItems = Connection.Select <ProductItem>(condition).ToArray(); // Return empty response if no items were found if (!productItems.Any()) { return new JObject() { { "reason", null }, { "responseData", new JArray() } } } ; // Get all loans within the specified range condition = new MySqlConditionBuilder("product_item", MySqlDbType.Int32, productItems.Select(x => x.Id).Cast <object>().ToArray()); condition.And() .Column("end") .GreaterThanOrEqual() .Operand(range.Start, MySqlDbType.DateTime); condition.And() .Column("start") .LessThanOrEqual() .Operand(range.End, MySqlDbType.DateTime); var loanItems = Connection.Select <LoanItem>(condition).ToArray(); // No idea if this is the most efficient way, but it basically iterates // through all dates of a loan and slaps them in a cache. If the cache // already contains the date, it increases the counter. // If the counter is larger or equal to the total amount of items, we // consider that date unavailable. var dateCache = new Dictionary <DateTime, int>(); foreach (var loan in loanItems) { while (loan.Start < loan.End) { if (loan.Start < range.Start) { loan.Start = loan.Start.AddDays(1); continue; } if (loan.End > range.End) { break; } if (dateCache.ContainsKey(loan.Start)) { dateCache[loan.Start]++; } else { dateCache[loan.Start] = 1; } loan.Start = loan.Start.AddDays(1); } } // Build base response var responseData = new JArray(); JObject response = new JObject() { { "reason", null }, { "responseData", responseData } }; // Add all dates with an amount of loans greater or equal to the max available items foreach ((DateTime date, int count) in dateCache) { if (count >= productItems.Length) { responseData.Add((long)(date.ToUniversalTime() - Epoch).TotalMilliseconds); } } return(response); } }
public JObject deleteProductItems(JObject request) { //Get arguments request.TryGetValue("productID", out JToken requestProductId); request.TryGetValue("count", out JToken requestCount); // Verify presence of arguments var failedVerifications = new List <string>(); if (requestProductId == null) { failedVerifications.Add("productID"); } if (requestCount == null) { failedVerifications.Add("count"); } if (failedVerifications.Any()) { return(Templates.MissingArguments(failedVerifications.ToArray())); } // Verify arguments if (requestProductId.Type != JTokenType.String) { failedVerifications.Add("productId"); } if (requestCount.Type != JTokenType.Integer || ((int)requestCount) < 0) { failedVerifications.Add("count"); } if (failedVerifications.Any()) { return(Templates.InvalidArguments(failedVerifications.ToArray())); } // Get all productItems var condition = new MySqlConditionBuilder("product", MySqlDbType.String, requestProductId.ToString()); var productItems = Connection.Select <ProductItem>(condition).ToArray(); // Return bare response if no items exist if (!productItems.Any()) { return(new JObject() { { "reason", null }, { "responseData", new JObject() { { "deleted", 0 }, { "ignored", 0 } } } }); } // Get all aquired loans that have yet to end condition = new MySqlConditionBuilder("product_item", MySqlDbType.Int32, productItems.Select(x => x.Id).Cast <object>().ToArray()); condition.And() .Column("end") .GreaterThanOrEqual() .Operand(DateTime.Now, MySqlDbType.DateTime); condition.And() .Column("is_item_acquired") .Equals().True(); var loans = Connection.Select <LoanItem>(condition).ToArray(); // Create function to track how many product items were ignored and how many weren't int ignored = 0; int notIgnored = 0; bool shouldIgnoreLoanedItem(ProductItem item) { bool b = loans.FirstOrDefault(x => x.ProductItem == item.Id) != null; if (notIgnored != (int)requestCount) { if (b) { ignored++; } else { notIgnored++; } } return(b); } // Filter out items that are loaned out var deletableItems = productItems.Where(x => !shouldIgnoreLoanedItem(x)).Take((int)requestCount).ToArray(); // Delete all items foreach (var item in deletableItems) { Connection.Delete(item); } //Create base response return(new JObject() { { "reason", null }, { "responseData", new JObject() { { "deleted", notIgnored }, { "ignored", ignored } } } }); }