430 lines
20 KiB
C#
430 lines
20 KiB
C#
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<CategoriesDostavka> categories = new List<CategoriesDostavka>();
|
||
List<ProductsDostavka> products = new List<ProductsDostavka>();
|
||
List<ProductsDostavka> allProducts = new List<ProductsDostavka>();
|
||
List<ProductsDostavka> randomFood = new List<ProductsDostavka>();
|
||
//List<ProductsDostavka> personalProducts = new List<ProductsDostavka>();
|
||
var row = new List<MessageKeyboardButton>();
|
||
var listButtons = new List<ReadOnlyCollection<MessageKeyboardButton>>();
|
||
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<CartObject>(user.cart);
|
||
var choosenProducts = JsonConvert.DeserializeObject<List<int>>(user.choosenProducts);
|
||
List<int> sportDays = JsonConvert.DeserializeObject<List<int>>(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<CategoriesDostavka>(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<List<int>>(p.weekDays).Exists(day => day == curDay)).
|
||
ToList().ConvertAll<ProductsDostavka>(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<List<int>>(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<CatalogPhotoObject>(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<MessageKeyboardButton>()
|
||
{
|
||
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<MessageKeyboardButton>()
|
||
{
|
||
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<MessageKeyboardButton>()
|
||
{
|
||
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);
|
||
}
|
||
}
|
||
} |