using Newtonsoft.Json; using SvetoforVKBot.Models.Updates; using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data.SqlClient; using System.Security.Cryptography; using VkNet; using VkNet.Enums.SafetyEnums; using VkNet.Model.Keyboard; using VkNet.Model.RequestParams; using VkNet.Utils; using VkNet.Model.Template; using VkNet.Model.Template.Carousel; using System.Linq; namespace SvetoforVKBot.Models.Commands.LK.Menu { public class ShowPersonalMenuCarusel { private const string PHOTOIDNEXT = "-194717824_457239273_446146426236760985"; //{"id": 457239273, "owner_id": -194717824, "access_key": "446146426236760985"} public void Execute(RootObject update, VkApi client, SvetoforVKBot.Data.SvetoforVKBotEntities db, int curCategory, int curProduct, int curWay, double curDayKkal) //curCategory - id Categories, curProduct - порядковый номер в массиве продуктов, curWay - для showProductCarusel направление навигации { MessagesSendParams @params = new MessagesSendParams(); var chatId = update.@object.message.from_id; int i = 0; int prevCatalog = 0, nextCatalog = 0; int naviState = 0; double sum = 0; string desc = ""; int curDay = (int)DateTime.Now.DayOfWeek; if (curDay == 0) curDay = 7; List categories = new List(); List products = new List(); List allProducts = new List(); List randomFood = new List(); //List personalProducts = new List(); var row = new List(); var listButtons = new List>(); TemplateBuilder templateBuilder = new TemplateBuilder(); CarouselElementAction carouselElementAction = new CarouselElementAction(); carouselElementAction.Type = CarouselElementActionType.OpenPhoto; double belkiLow = 0, zhiryLow = 0, uglevodyLow = 0, belkiHigh = 0, zhiryHigh = 0, uglevodyHigh = 0; double curBelki = 0, curZhiry = 0, curUglevody = 0; double foodPercent = 0; double belkiPercent = 0, zhiryPercent = 0, uglevodyPercent = 0; double dayKkal = 0; string foodTime = ""; try { var user = db.Users.Single(usr => usr.chatId == chatId); var cartObject = JsonConvert.DeserializeObject(user.cart); var choosenProducts = JsonConvert.DeserializeObject>(user.choosenProducts); List sportDays = JsonConvert.DeserializeObject>(user.sportDays); //if (curDay == 8) curDay = (int)DateTime.Now.DayOfWeek; int nextDay = curDay + 1; if (nextDay == 8) nextDay = 1; foreach (var o in cartObject.orders) { sum += o.price * o.number; } categories = db.CategoriesDostavkas.ToList().ConvertAll(c => new CategoriesDostavka() { categoryId = c.categoryId, name = c.name, btnName = c.btnName, kbColor = c.kbColor, }); allProducts = db.ProductsDostavkas.Where(p => p.categoryId != 0 && JsonConvert.DeserializeObject>(p.weekDays).Exists(day => day == curDay)). ToList().ConvertAll(e=>new ProductsDostavka() { id = e.id, article = e.article, colorId = e.colorId, categoryId = e.categoryId, name = e.name, fullName = e.fullName, descriptionCarousel = e.descriptionCarousel, price = Convert.ToDouble(e.price), photo = e.photo, photoCarousel = e.photoCarousel, kkal = e.kkal, foodType = JsonConvert.DeserializeObject>(e.foodType), belki = Convert.ToDouble(e.belki), zhiry = Convert.ToDouble(e.zhiry), uglevody = Convert.ToDouble(e.uglevody), }); ProductsDostavka water = new ProductsDostavka(); water = allProducts.Find(p => p.article.Equals("55")); allProducts.Remove(water); //allProducts.RemoveAll(p => !p.foodType.Contains(curCategory)); if (choosenProducts.Count > 0) allProducts.RemoveAll(p => choosenProducts.Contains(p.id)); switch (user.track) { case 1: belkiLow = 1.4; belkiHigh = 2; zhiryLow = 1; zhiryHigh = 1.1; uglevodyLow = 2.4; uglevodyHigh = 3; break; case 2: belkiLow = 1.2; belkiHigh = 1.7; zhiryLow = 0.9; zhiryHigh = 1; uglevodyLow = 2; uglevodyHigh = 2.6; break; case 3: belkiLow = 1.6; belkiHigh = 2.2; zhiryLow = 1.1; zhiryHigh = 1.2; uglevodyLow = 2.8; uglevodyHigh = 3.4; break; } switch (curCategory) { case 1: allProducts.RemoveAll(p => p.categoryId == 1); foodPercent = 0.3; belkiPercent = 0.3; uglevodyPercent = 0.4; zhiryPercent = 0.2; foodTime = "🥐Завтрак"; randomFood = allProducts.FindAll(ap => (ap.categoryId != 1) && ap.zhiry <= zhiryLow * user.weight * zhiryPercent && ap.uglevody <= uglevodyLow * user.weight * uglevodyPercent); //Углеводы - 0.4 //Белки - 0.3 //Жиры - 0.2 //Кнопка ещё один вариант //web break; case 2: foodPercent = 0.4; belkiPercent = 0.3; uglevodyPercent = 0.3; zhiryPercent = 0.4; foodTime = "🍲Обед"; randomFood = allProducts.FindAll(ap => ap.categoryId == 1 && ap.zhiry <= zhiryLow * user.weight * zhiryPercent && ap.uglevody <= uglevodyLow * user.weight * uglevodyPercent); break; case 3: allProducts.RemoveAll(p => p.categoryId == 1); foodPercent = 0.1; belkiPercent = 0.2; uglevodyPercent = 0.2; zhiryPercent = 0.2; foodTime = "🥪Перекус"; //ap.categoryId == 5 || ap.categoryId == 4 randomFood = allProducts.FindAll(ap => (ap.categoryId != 1) && ap.zhiry <= zhiryLow * user.weight * zhiryPercent && ap.uglevody <= uglevodyLow * user.weight * uglevodyPercent); break; case 4: allProducts.RemoveAll(p => p.categoryId == 1); foodPercent = 0.3; belkiPercent = 0.2; uglevodyPercent = 0.2; zhiryPercent = 0.2; randomFood = allProducts.FindAll(ap => (ap.categoryId != 1) && ap.zhiry <= zhiryLow * user.weight * zhiryPercent && ap.uglevody <= uglevodyLow * user.weight * uglevodyPercent); foodTime = "🥗Ужин"; break; } double maxKkal = Math.Round(curDayKkal * 1.2 * foodPercent); double minKkal = Math.Round(curDayKkal * 0.9 * foodPercent); Random rand = new Random(); if (choosenProducts.Count > 0) randomFood.RemoveAll(p => choosenProducts.Contains(p.id)); int randomBludo = rand.Next(0, randomFood.Count); if (curCategory == 3) { products.Add(randomFood.Find(rf => rf.kkal <= maxKkal)); } else { products.Add(randomFood[randomBludo]); } curBelki = products[0].belki; curZhiry = products[0].zhiry; curUglevody = products[0].uglevody; dayKkal = products[0].kkal; choosenProducts.Add(products[0].id); ProductsDostavka tmp = new ProductsDostavka(); for (i = 0; i < allProducts.Count; i++) { tmp = allProducts[i]; allProducts.RemoveAt(i); allProducts.Insert(rand.Next(allProducts.Count), tmp); } foreach (var ap in allProducts) { //if (dayKkal + ap.kkal <= maxKkal) //curBelki <= belkiLow * weight * foodPercent && curUglevody + ap.uglevody < uglevodyHigh * weight * foodPercent) if (curBelki + ap.belki <= belkiHigh * user.weight * belkiPercent && curUglevody + ap.uglevody <= uglevodyHigh * user.weight * uglevodyPercent)// && //curZhiry + ap.zhiry <= zhiryHigh * weight * zhiryPercent) { if (!products.Exists(p => p.categoryId == ap.categoryId)) { if (true)//curUglevody + ap.uglevody < uglevodyHigh * weight * foodPercent curBelki < belkiHigh * weight * foodPercent && curZhiry < zhiryHigh * weight * foodPercent && curUglevody < uglevodyHigh * weight * foodPercent) { curBelki += ap.belki; curZhiry += ap.zhiry; curUglevody += ap.uglevody; dayKkal += ap.kkal; products.Add(ap); choosenProducts.Add(ap.id); } } } //else break; } //if (dayKkal < minKkal) //{ // if (curCategory != 3) // { // products.Add(allProducts.Find(ap => !choosenProducts.Contains(ap.id) && ap.zhiry <= zhiryLow * weight * zhiryPercent && ap.uglevody <= uglevodyLow * weight * uglevodyPercent && ap.categoryId != 7)); // curBelki += products[products.Count - 1].belki; // curZhiry += products[products.Count - 1].zhiry; // curUglevody += products[products.Count - 1].uglevody; // dayKkal += products[products.Count - 1].kkal; // choosenProducts.Add(products[products.Count - 1].id); // } // //else // // products.Add(allProducts.Find(ap => !choosenProducts.Contains(ap.id) && ap.kkal <= maxKkal - minKkal)); // //choosenProducts.Add(products[products.Count - 1].id); //} if (!products.Exists(p => p.categoryId == 7)) products.Add(water); //(p => p.article.Equals("55"))) //if (curCategory != 4) //{ // SqlCommand updCart = new SqlCommand("UPDATE Users SET choosenProducts = @choosenProducts WHERE chatId = @chatId;", Con); // updCart.Parameters.AddWithValue("@chatId", chatId); // updCart.Parameters.AddWithValue("@choosenProducts", JsonConvert.SerializeObject(choosenProducts)); // updCart.ExecuteNonQuery(); //} //else //{ // SqlCommand updCart = new SqlCommand("UPDATE Users SET choosenProducts = @choosenProducts WHERE chatId = @chatId;", Con); // updCart.Parameters.AddWithValue("@chatId", chatId); // updCart.Parameters.AddWithValue("@choosenProducts", "[]"); // updCart.ExecuteNonQuery(); //} nextCatalog = curProduct + 9; prevCatalog = curProduct - 9; if (curProduct > 0 && products.Count > 6) { if (nextCatalog > products.Count) nextCatalog = products.Count - (products.Count - curProduct); if (prevCatalog < 0) prevCatalog = 0; } for (i = curProduct; i < products.Count; i++) { var jsPhoto = JsonConvert.DeserializeObject(products[i].photoCarousel); desc = products[i].descriptionCarousel; //+ " " + products[i].weight; if (desc.Length > 80) desc = desc.Substring(0, 77) + "..."; //desc.Substring(0, 77) templateBuilder.AddTemplateElement(new CarouselElement() { Title = products[i].fullName, Description = desc + " | " + products[i].kkal + " ккал\n" + $"Б\\Ж\\У: {products[i].belki}г\\{products[i].zhiry}г\\{products[i].uglevody}г", PhotoId = jsPhoto.owner_id + "_" + jsPhoto.id + "_" + jsPhoto.access_key, Buttons = new List() { new MessageKeyboardButton(){ Action = new MessageKeyboardButtonAction(){ Label = "Добавить в корзину " + products[i].price + "р", Payload = "{\"button\":\"selectAddToCart-" + products[i].categoryId + "-" + products[i].id + "-" + curDayKkal + "\"}", Type = KeyboardButtonActionType.Text }, Color = KeyboardButtonColor.Positive }, //new MessageKeyboardButton(){ // Action = new MessageKeyboardButtonAction(){ Label = "Подробнее", // Payload = "{\"button\":\"selectAddToCart-" + curCategory + "-" + i + "\"}", // Type = KeyboardButtonActionType.Text }, // Color = KeyboardButtonColor.Default //}, }, Action = carouselElementAction, }); if (templateBuilder.Elements.Count == 9 && products.Count > 10) break; } if (products.Count > 10) { switch (curWay) { case 1: if (curProduct < (products.Count - 9)) naviState = 1; else naviState = 2; break; case 2: if (curProduct == 0) naviState = 1; else naviState = 2; break; default: naviState = 2; break; } switch (naviState) { case 1: templateBuilder.AddTemplateElement(new CarouselElement() { Title = ".", Description = ".", PhotoId = PHOTOIDNEXT, Buttons = new List() { new MessageKeyboardButton() { Action = new MessageKeyboardButtonAction(){ Label = ">> Следующие " + (products.Count - nextCatalog).ToString(), Payload = "{\"button\":\"selectProduct-" + products[nextCatalog].categoryId + "-" + nextCatalog + "-1\"}", Type = KeyboardButtonActionType.Text }, Color = KeyboardButtonColor.Primary }, }, Action = carouselElementAction, }); break; case 2: templateBuilder.AddTemplateElement(new CarouselElement() { Title = ".", Description = ".", PhotoId = PHOTOIDNEXT, Buttons = new List() { new MessageKeyboardButton() { Action = new MessageKeyboardButtonAction(){ Label = "<< Предыдущие " + curProduct, Payload = "{\"button\":\"selectProduct-" + products[prevCatalog].categoryId + "-" + prevCatalog + "-2\"}", Type = KeyboardButtonActionType.Text }, Color = KeyboardButtonColor.Primary }, }, Action = carouselElementAction, }); break; } } @params.Message = foodTime + "\n" + "Калории: " + dayKkal + " ккал \n" + $"Б\\Ж\\У: {curBelki}г\\{curZhiry}г\\{curUglevody}г \n\n" + $"Если хотите подобрать блюда ещё раз, нажмите кнопку повторно😉"; @params.Template = templateBuilder.Build(); @params.UserId = chatId; @params.RandomId = GetRandomId(); client.Messages.SendAsync(@params); } catch (Exception ee) { @params.Message = "‼Ошибка в ShowProductCaruselMain: " + ee.Message; @params.Attachments = null; @params.Keyboard = null; @params.UserId = 59111081; @params.RandomId = GetRandomId(); client.Messages.SendAsync(@params); } } private static readonly RandomNumberGenerator Rng = RandomNumberGenerator.Create(); private int GetRandomId() { var intBytes = new byte[4]; Rng.GetBytes(intBytes); return BitConverter.ToInt32(intBytes, 0); } } }