/// <summary>
        /// Heart of the getProductItems function.
        /// </summary>
        /// <param name="productIds"></param>
        /// <returns></returns>
        private ILookup <string, ProductItem> Core_getProductItems(string[] productIds, int[] itemIds = null)
        {
            productIds = productIds ?? new string[0];
            itemIds    = itemIds ?? new int[0];

            // Build condition
            MySqlConditionBuilder condition = new MySqlConditionBuilder("product", MySqlDbType.String, productIds);

            condition.And();
            condition.NewGroup();
            foreach (var id in itemIds)
            {
                condition.Or()
                .Column("id")
                .Equals(id, MySqlDbType.Int32);
            }
            condition.EndGroup();

            var itemPrimary = ProductItem.indexes.First(x => x.Type == Index.IndexType.PRIMARY).Columns[0];

            // Ignore default item
            condition.And()
            .Column(itemPrimary.Column)
            .NotEquals(0, itemPrimary.Type);

            return(Connection.Select <ProductItem>(condition).ToLookup(x => x.ProductId));
        }
예제 #2
0
        /// <summary>
        /// Tries to find and return all items of a product type during a timespan that aren't reserved.
        /// </summary>
        /// <param name="productId">The product type whose items to return.</param>
        /// <param name="span">The time period to test for unreserved items.</param>
        /// <returns>A subset of all items of the given product type, or null if the product type has no items.</returns>
        private List <ProductItem> Core_GetUnreservedItems(string productId, DateTimeSpan span)
        {
            List <ProductItem> items = Core_getProductItems(new string[] { productId })[productId].ToList();

            if (!items.Any())
            {
                return(null);
            }

            var condition = new MySqlConditionBuilder();

            condition.NewGroup();
            foreach (var item in items)
            {
                condition.Or()
                .Column("product_item")
                .Equals(item.Id, item.GetIndex("PRIMARY").Columns[0].Type);
            }
            condition.EndGroup();
            condition.And()
            .Column("end")
            .GreaterThanOrEqual()
            .Operand(span.Start, MySqlDbType.DateTime);
            condition.And()
            .Column("start")
            .LessThanOrEqual()
            .Operand(span.End, MySqlDbType.DateTime);

            List <LoanItem> loans = Connection.Select <LoanItem>(condition).ToList();

            foreach (var loan in loans)
            {
                if (!items.Any(x => x.Id == loan.ProductItem))
                {
                    continue;
                }
                var loanSpan = new DateTimeSpan(loan.Start, loan.End);
                if (span.Overlaps(loanSpan))
                {
                    items.Remove(items.First(x => x.Id == loan.ProductItem));
                }
            }
            return(items);
        }
        public JObject deleteLoan(JObject request)
        {
            // Get arguments
            request.TryGetValue("loanId", out JToken loanId);

            // Verify arguments
            if (loanId == null || loanId.Type != JTokenType.Integer)
            {
                return(Templates.InvalidArgument("loanId"));
            }

            // Build condition
            var condition = new MySqlConditionBuilder();

            if (CurrentUser.Permission <= UserPermission.User)
            {
                condition.Column("user").Equals(CurrentUser.Username, MySqlDbType.String);
            }
            condition.And().Column("id").Equals(loanId, MySqlDbType.String);

            // Get and delete loan, or return error if no such loan exists
            var loan = Connection.Select <LoanItem>(condition, range: (0, 1)).FirstOrDefault();

            if (loan == null)
            {
                return(Templates.NoSuchLoan(loanId.ToString()));
            }
            if (loan.Start < DateTime.Now)
            {
                return(Templates.LoanAlreadyStarted());
            }
            Connection.Delete(loan);

            // Create response
            JObject response = new JObject()
            {
                { "reason", null }
            };

            return(response);
        }
예제 #4
0
        public static MySqlConditionBuilder CreateCondition(JObject criteria, MySqlConditionBuilder condition = null)
        {
            condition = condition ?? new MySqlConditionBuilder();
            condition.NewGroup();
            int i = 0;

            foreach (KeyValuePair <string, JToken> pair in criteria)
            {
                if (i > 0)
                {
                    condition.And();
                }

                condition.Column(pair.Key);
                string   value    = (string)pair.Value;
                string[] operands = value.Split("OR");
                foreach (string operand in operands)
                {
                    string[] split = operand.Split(" ");
                    if (split[0] == "LIKE")
                    {
                        condition.Like(split[1]);
                    }
                    else
                    {
                        condition.Equals(operand, MySql.Data.MySqlClient.MySqlDbType.String);
                    }
                    if (operands.Last() != operand)
                    {
                        condition.Or();
                    }
                }
                i++;
            }
            return(condition.EndGroup());
        }
예제 #5
0
        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);
        }
예제 #6
0
        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 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 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 }
                  } }
            });
        }
예제 #11
0
        public JObject deleteProduct(JObject request)
        {
            //Get arguments
            request.TryGetValue("productID", out JToken idValue);
            if (idValue == null || idValue.Type != JTokenType.String)
            {
                return(Templates.MissingArguments("productID"));
            }

            // Prepare values
            string productID = idValue.ToString();


            //Check if product exists
            Product product = GetObject <Product>(productID);

            if (product == null)
            {
                return(Templates.NoSuchProduct(productID));
            }

            // Check if items or acquired loans exist
            var condition = new MySqlConditionBuilder("product", MySqlDbType.String, productID);
            var items     = Connection.Select <ProductItem>(condition).ToList();

            // Check for associated loans if any items exist
            if (items.Any())
            {
                // Get associated loans that are acquired and end after today
                condition = new MySqlConditionBuilder("product_item", MySqlDbType.Int32, items.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();
                List <bool> loans_isAcquired = Connection.Select <LoanItem>(new string[] { "is_item_acquired" }, condition).Select(x => (bool)x[0]).ToList();

                // If any active loans are aquired, respond with CannotDelete
                if (loans_isAcquired.Any())
                {
                    return(Templates.CannotDelete("This product still has active loans."));
                }
            }

            // Delete image if it isnt the default image
            product.Delete(Connection);
            if (product.Image != "default")
            {
                product.GetImage(Connection)?.Delete(Connection);
            }
            // Delete name languageItem if it isnt the default languageItem
            if (product.Name != "0")
            {
                product.GetName(Connection)?.Delete(Connection);
            }
            // Delete description languageItem if it isnt the default languageItem
            if (product.Description != "0")
            {
                product.GetDescription(Connection)?.Delete(Connection);
            }

            //Create base response
            return(new JObject()
            {
                { "reason", null },
            });
        }