103 lines
42 KiB
PL/PgSQL
103 lines
42 KiB
PL/PgSQL
-- Generated by ops/demo/build-trial-banquet.mjs. Additive demo upgrade only.
|
||
begin;
|
||
create or replace function public.caterium_trial_banquet_seed_v1()
|
||
returns jsonb language sql immutable security definer set search_path=public,pg_temp
|
||
as $fn$ select $demo${"version":1,"banquet":[{"id":"demo-banquet-v1-caprese","name":"Капрезе с моцареллой и базиликом","category":6,"catalogSection":"Холодные закуски","price":290,"weight":"120 г","pieces":1,"photo":"","demo":true,"composition":["Моцарелла мини, Томаты, Базилик, Масло оливковое"],"ingredients":[["Моцарелла мини",0.05,"кг"],["Томаты",0.07,"кг"],["Базилик",0.006,"кг"],["Масло оливковое",0.005,"кг"]],"ttk":{"number":"ДЕМО-Б01","basis":"На 1 порцию / 1 гостя","outputGrams":120,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-mozzarella","name":"Моцарелла мини","unit":"кг","gross":0.05,"net":0.05,"unitCost":950},{"productId":"demo-v1-stock-tomato","name":"Томаты","unit":"кг","gross":0.07,"net":0.06,"unitCost":260},{"productId":"demo-v1-stock-basil","name":"Базилик","unit":"кг","gross":0.006,"net":0.005,"unitCost":1500},{"productId":"demo-v1-stock-oil","name":"Масло оливковое","unit":"кг","gross":0.005,"net":0.005,"unitCost":1100}],"steps":["Нарезать томаты и моцареллу.","Выложить слоями, добавить базилик и масло."],"allergens":["Молоко"],"ingredientCost":80.2,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-roastbeef","name":"Ростбиф с корнишонами и горчичным соусом","category":6,"catalogSection":"Холодные закуски","price":390,"weight":"100 г","pieces":1,"photo":"","demo":true,"composition":["Ростбиф готовый, Корнишоны, Горчица, Сливки"],"ingredients":[["Ростбиф готовый",0.065,"кг"],["Корнишоны",0.022,"кг"],["Горчица",0.005,"кг"],["Сливки",0.01,"кг"]],"ttk":{"number":"ДЕМО-Б02","basis":"На 1 порцию / 1 гостя","outputGrams":100,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-beef","name":"Ростбиф готовый","unit":"кг","gross":0.065,"net":0.065,"unitCost":2000},{"productId":"demo-v1-stock-pickle","name":"Корнишоны","unit":"кг","gross":0.022,"net":0.02,"unitCost":400},{"productId":"demo-v1-stock-mustard","name":"Горчица","unit":"кг","gross":0.005,"net":0.005,"unitCost":350},{"productId":"demo-v1-stock-cooking-cream","name":"Сливки","unit":"кг","gross":0.01,"net":0.01,"unitCost":500}],"steps":["Нарезать готовый ростбиф тонкими ломтиками.","Смешать сливки с горчицей, подать с корнишонами."],"allergens":["Молоко","Горчица"],"ingredientCost":145.55,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-salmon-roll","name":"Рулетики из лосося со сливочным сыром","category":6,"catalogSection":"Холодные закуски","price":350,"weight":"90 г","pieces":1,"photo":"","demo":true,"composition":["Лосось слабосолёный, Сыр сливочный, Огурцы, Укроп"],"ingredients":[["Лосось слабосолёный",0.045,"кг"],["Сыр сливочный",0.025,"кг"],["Огурцы",0.022,"кг"],["Укроп",0.003,"кг"]],"ttk":{"number":"ДЕМО-Б03","basis":"На 1 порцию / 1 гостя","outputGrams":90,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-salmon","name":"Лосось слабосолёный","unit":"кг","gross":0.045,"net":0.045,"unitCost":2400},{"productId":"demo-v1-stock-cream","name":"Сыр сливочный","unit":"кг","gross":0.025,"net":0.025,"unitCost":850},{"productId":"demo-v1-stock-cucumber","name":"Огурцы","unit":"кг","gross":0.022,"net":0.018,"unitCost":220},{"productId":"demo-v1-stock-dill","name":"Укроп","unit":"кг","gross":0.003,"net":0.002,"unitCost":700}],"steps":["Нарезать лосось и огурец тонкими ломтиками.","Распределить сыр, свернуть рулетики, украсить укропом."],"allergens":["Рыба","Молоко"],"ingredientCost":136.19,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-hummus","name":"Овощные палочки с хумусом","category":6,"catalogSection":"Холодные закуски","price":230,"weight":"160 г","pieces":1,"photo":"","demo":true,"composition":["Морковь, Огурцы, Перец сладкий, Хумус готовый"],"ingredients":[["Морковь",0.048,"кг"],["Огурцы",0.044,"кг"],["Перец сладкий",0.04,"кг"],["Хумус готовый",0.05,"кг"]],"ttk":{"number":"ДЕМО-Б04","basis":"На 1 порцию / 1 гостя","outputGrams":160,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-carrot","name":"Морковь","unit":"кг","gross":0.048,"net":0.04,"unitCost":90},{"productId":"demo-v1-stock-cucumber","name":"Огурцы","unit":"кг","gross":0.044,"net":0.04,"unitCost":220},{"productId":"demo-v1-stock-pepper","name":"Перец сладкий","unit":"кг","gross":0.04,"net":0.03,"unitCost":380},{"productId":"demo-v1-stock-hummus","name":"Хумус готовый","unit":"кг","gross":0.05,"net":0.05,"unitCost":600}],"steps":["Очистить овощи и нарезать палочками.","Подать с порцией готового хумуса."],"allergens":["Кунжут в составе хумуса"],"ingredientCost":59.2,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-caesar","name":"Салат с курицей, сухариками и сыром","category":6,"catalogSection":"Салаты","price":340,"weight":"180 г","pieces":1,"photo":"","demo":true,"composition":["Филе курицы готовое, Салат листовой, Томаты черри, Хлеб тостовый, Сыр гауда, Сливки, Горчица"],"ingredients":[["Филе курицы готовое",0.06,"кг"],["Салат листовой",0.042,"кг"],["Томаты черри",0.035,"кг"],["Хлеб тостовый",0.023,"кг"],["Сыр гауда",0.015,"кг"],["Сливки",0.015,"кг"],["Горчица",0.005,"кг"]],"ttk":{"number":"ДЕМО-Б05","basis":"На 1 порцию / 1 гостя","outputGrams":180,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-chicken","name":"Филе курицы готовое","unit":"кг","gross":0.06,"net":0.06,"unitCost":850},{"productId":"demo-v1-stock-lettuce","name":"Салат листовой","unit":"кг","gross":0.042,"net":0.035,"unitCost":700},{"productId":"demo-v1-stock-cherry","name":"Томаты черри","unit":"кг","gross":0.035,"net":0.03,"unitCost":450},{"productId":"demo-v1-stock-toast","name":"Хлеб тостовый","unit":"кг","gross":0.023,"net":0.02,"unitCost":240},{"productId":"demo-v1-stock-gouda","name":"Сыр гауда","unit":"кг","gross":0.015,"net":0.015,"unitCost":900},{"productId":"demo-v1-stock-cooking-cream","name":"Сливки","unit":"кг","gross":0.015,"net":0.015,"unitCost":500},{"productId":"demo-v1-stock-mustard","name":"Горчица","unit":"кг","gross":0.005,"net":0.005,"unitCost":350}],"steps":["Подсушить кубики хлеба, подготовить салат и томаты.","Нарезать готовую курицу, соединить с овощами и сыром.","Заправить сливками с горчицей, сверху добавить сухарики."],"allergens":["Глютен","Молоко","Горчица"],"ingredientCost":124.42,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-olivier","name":"Оливье с индейкой","category":6,"catalogSection":"Салаты","price":280,"weight":"180 г","pieces":1,"photo":"","demo":true,"composition":["Картофель, Морковь, Ветчина из индейки, Яйцо куриное без скорлупы, Горошек зелёный консервированный, Корнишоны, Сливки, Горчица"],"ingredients":[["Картофель",0.065,"кг"],["Морковь",0.026,"кг"],["Ветчина из индейки",0.035,"кг"],["Яйцо куриное без скорлупы",0.022,"кг"],["Горошек зелёный консервированный",0.02,"кг"],["Корнишоны",0.022,"кг"],["Сливки",0.012,"кг"],["Горчица",0.003,"кг"]],"ttk":{"number":"ДЕМО-Б06","basis":"На 1 порцию / 1 гостя","outputGrams":180,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-banquet-v1-stock-potato","name":"Картофель","unit":"кг","gross":0.065,"net":0.05,"unitCost":80},{"productId":"demo-v1-stock-carrot","name":"Морковь","unit":"кг","gross":0.026,"net":0.02,"unitCost":90},{"productId":"demo-v1-stock-turkey","name":"Ветчина из индейки","unit":"кг","gross":0.035,"net":0.035,"unitCost":1000},{"productId":"demo-banquet-v1-stock-egg","name":"Яйцо куриное без скорлупы","unit":"кг","gross":0.022,"net":0.02,"unitCost":260},{"productId":"demo-banquet-v1-stock-peas","name":"Горошек зелёный консервированный","unit":"кг","gross":0.02,"net":0.02,"unitCost":300},{"productId":"demo-v1-stock-pickle","name":"Корнишоны","unit":"кг","gross":0.022,"net":0.02,"unitCost":400},{"productId":"demo-v1-stock-cooking-cream","name":"Сливки","unit":"кг","gross":0.012,"net":0.012,"unitCost":500},{"productId":"demo-v1-stock-mustard","name":"Горчица","unit":"кг","gross":0.003,"net":0.003,"unitCost":350}],"steps":["Отварить картофель, морковь и яйцо; остудить.","Нарезать овощи, яйцо, ветчину и корнишоны кубиком.","Добавить горошек и заправить сливками с горчицей."],"allergens":["Яйцо","Молоко","Горчица"],"ingredientCost":70.11,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-greek","name":"Овощной салат с моцареллой и маслинами","category":6,"catalogSection":"Салаты","price":290,"weight":"180 г","pieces":1,"photo":"","demo":true,"composition":["Томаты, Огурцы, Перец сладкий, Моцарелла мини, Маслины без косточек, Масло оливковое"],"ingredients":[["Томаты",0.055,"кг"],["Огурцы",0.044,"кг"],["Перец сладкий",0.032,"кг"],["Моцарелла мини",0.04,"кг"],["Маслины без косточек",0.017,"кг"],["Масло оливковое",0.01,"кг"]],"ttk":{"number":"ДЕМО-Б07","basis":"На 1 порцию / 1 гостя","outputGrams":180,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-tomato","name":"Томаты","unit":"кг","gross":0.055,"net":0.05,"unitCost":260},{"productId":"demo-v1-stock-cucumber","name":"Огурцы","unit":"кг","gross":0.044,"net":0.04,"unitCost":220},{"productId":"demo-v1-stock-pepper","name":"Перец сладкий","unit":"кг","gross":0.032,"net":0.025,"unitCost":380},{"productId":"demo-v1-stock-mozzarella","name":"Моцарелла мини","unit":"кг","gross":0.04,"net":0.04,"unitCost":950},{"productId":"demo-v1-stock-olive","name":"Маслины без косточек","unit":"кг","gross":0.017,"net":0.015,"unitCost":650},{"productId":"demo-v1-stock-oil","name":"Масло оливковое","unit":"кг","gross":0.01,"net":0.01,"unitCost":1100}],"steps":["Подготовить и крупно нарезать овощи.","Добавить моцареллу и маслины, заправить маслом."],"allergens":["Молоко"],"ingredientCost":96.19,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-julienne","name":"Жюльен с курицей и грибами","category":6,"catalogSection":"Горячие закуски","price":310,"weight":"130 г","pieces":1,"photo":"","demo":true,"composition":["Филе курицы готовое, Шампиньоны, Лук репчатый, Сливки, Сыр гауда, Масло оливковое"],"ingredients":[["Филе курицы готовое",0.04,"кг"],["Шампиньоны",0.06,"кг"],["Лук репчатый",0.015,"кг"],["Сливки",0.025,"кг"],["Сыр гауда",0.015,"кг"],["Масло оливковое",0.005,"кг"]],"ttk":{"number":"ДЕМО-Б08","basis":"На 1 порцию / 1 гостя","outputGrams":130,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-chicken","name":"Филе курицы готовое","unit":"кг","gross":0.04,"net":0.04,"unitCost":850},{"productId":"demo-v1-stock-mushroom","name":"Шампиньоны","unit":"кг","gross":0.06,"net":0.04,"unitCost":340},{"productId":"demo-v1-stock-onion","name":"Лук репчатый","unit":"кг","gross":0.015,"net":0.01,"unitCost":80},{"productId":"demo-v1-stock-cooking-cream","name":"Сливки","unit":"кг","gross":0.025,"net":0.02,"unitCost":500},{"productId":"demo-v1-stock-gouda","name":"Сыр гауда","unit":"кг","gross":0.015,"net":0.015,"unitCost":900},{"productId":"demo-v1-stock-oil","name":"Масло оливковое","unit":"кг","gross":0.005,"net":0.005,"unitCost":1100}],"steps":["Обжарить нарезанные грибы и лук на масле.","Добавить готовую курицу и сливки, распределить по формам.","Посыпать сыром и запечь до расплавления."],"allergens":["Молоко"],"ingredientCost":87.1,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-stuffed-mushrooms","name":"Шампиньоны, запечённые с сыром","category":6,"catalogSection":"Горячие закуски","price":270,"weight":"120 г","pieces":1,"photo":"","demo":true,"composition":["Шампиньоны, Сыр сливочный, Сыр гауда, Укроп, Масло оливковое"],"ingredients":[["Шампиньоны",0.125,"кг"],["Сыр сливочный",0.02,"кг"],["Сыр гауда",0.01,"кг"],["Укроп",0.003,"кг"],["Масло оливковое",0.003,"кг"]],"ttk":{"number":"ДЕМО-Б09","basis":"На 1 порцию / 1 гостя","outputGrams":120,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-mushroom","name":"Шампиньоны","unit":"кг","gross":0.125,"net":0.085,"unitCost":340},{"productId":"demo-v1-stock-cream","name":"Сыр сливочный","unit":"кг","gross":0.02,"net":0.02,"unitCost":850},{"productId":"demo-v1-stock-gouda","name":"Сыр гауда","unit":"кг","gross":0.01,"net":0.01,"unitCost":900},{"productId":"demo-v1-stock-dill","name":"Укроп","unit":"кг","gross":0.003,"net":0.002,"unitCost":700},{"productId":"demo-v1-stock-oil","name":"Масло оливковое","unit":"кг","gross":0.003,"net":0.003,"unitCost":1100}],"steps":["Подготовить шляпки грибов, ножки мелко нарезать.","Смешать ножки со сливочным сыром и укропом, наполнить шляпки.","Добавить гауду и запечь."],"allergens":["Молоко"],"ingredientCost":73.9,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-chicken","name":"Куриное филе с овощами и сливочным соусом","category":6,"catalogSection":"Горячие блюда","price":490,"weight":"220 г","pieces":1,"photo":"","demo":true,"composition":["Филе куриное сырое, Перец сладкий, Морковь, Сливки, Масло оливковое"],"ingredients":[["Филе куриное сырое",0.18,"кг"],["Перец сладкий",0.045,"кг"],["Морковь",0.032,"кг"],["Сливки",0.03,"кг"],["Масло оливковое",0.005,"кг"]],"ttk":{"number":"ДЕМО-Б10","basis":"На 1 порцию / 1 гостя","outputGrams":220,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-banquet-v1-stock-chicken-raw","name":"Филе куриное сырое","unit":"кг","gross":0.18,"net":0.135,"unitCost":480},{"productId":"demo-v1-stock-pepper","name":"Перец сладкий","unit":"кг","gross":0.045,"net":0.03,"unitCost":380},{"productId":"demo-v1-stock-carrot","name":"Морковь","unit":"кг","gross":0.032,"net":0.025,"unitCost":90},{"productId":"demo-v1-stock-cooking-cream","name":"Сливки","unit":"кг","gross":0.03,"net":0.025,"unitCost":500},{"productId":"demo-v1-stock-oil","name":"Масло оливковое","unit":"кг","gross":0.005,"net":0.005,"unitCost":1100}],"steps":["Обжарить куриное филе и довести до готовности.","Отдельно приготовить перец и морковь.","Добавить сливочный соус, подать с овощами; учесть потери при приготовлении."],"allergens":["Молоко"],"ingredientCost":126.88,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-cod","name":"Треска с лимоном и овощами","category":6,"catalogSection":"Горячие блюда","price":590,"weight":"200 г","pieces":1,"photo":"","demo":true,"composition":["Филе трески, Томаты, Перец сладкий, Лимон, Масло оливковое"],"ingredients":[["Филе трески",0.17,"кг"],["Томаты",0.045,"кг"],["Перец сладкий",0.03,"кг"],["Лимон",0.015,"кг"],["Масло оливковое",0.005,"кг"]],"ttk":{"number":"ДЕМО-Б11","basis":"На 1 порцию / 1 гостя","outputGrams":200,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-banquet-v1-stock-whitefish","name":"Филе трески","unit":"кг","gross":0.17,"net":0.13,"unitCost":950},{"productId":"demo-v1-stock-tomato","name":"Томаты","unit":"кг","gross":0.045,"net":0.035,"unitCost":260},{"productId":"demo-v1-stock-pepper","name":"Перец сладкий","unit":"кг","gross":0.03,"net":0.02,"unitCost":380},{"productId":"demo-banquet-v1-stock-lemon","name":"Лимон","unit":"кг","gross":0.015,"net":0.01,"unitCost":300},{"productId":"demo-v1-stock-oil","name":"Масло оливковое","unit":"кг","gross":0.005,"net":0.005,"unitCost":1100}],"steps":["Подготовить филе и нарезать овощи.","Запечь рыбу с овощами, лимоном и маслом до готовности."],"allergens":["Рыба"],"ingredientCost":194.6,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-beef-hot","name":"Ростбиф с грибами в сливочном соусе","category":6,"catalogSection":"Горячие блюда","price":690,"weight":"220 г","pieces":1,"photo":"","demo":true,"composition":["Ростбиф готовый, Шампиньоны, Лук репчатый, Сливки, Масло оливковое"],"ingredients":[["Ростбиф готовый",0.125,"кг"],["Шампиньоны",0.08,"кг"],["Лук репчатый",0.024,"кг"],["Сливки",0.03,"кг"],["Масло оливковое",0.005,"кг"]],"ttk":{"number":"ДЕМО-Б12","basis":"На 1 порцию / 1 гостя","outputGrams":220,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-beef","name":"Ростбиф готовый","unit":"кг","gross":0.125,"net":0.12,"unitCost":2000},{"productId":"demo-v1-stock-mushroom","name":"Шампиньоны","unit":"кг","gross":0.08,"net":0.055,"unitCost":340},{"productId":"demo-v1-stock-onion","name":"Лук репчатый","unit":"кг","gross":0.024,"net":0.015,"unitCost":80},{"productId":"demo-v1-stock-cooking-cream","name":"Сливки","unit":"кг","gross":0.03,"net":0.025,"unitCost":500},{"productId":"demo-v1-stock-oil","name":"Масло оливковое","unit":"кг","gross":0.005,"net":0.005,"unitCost":1100}],"steps":["Обжарить грибы и лук, добавить сливки.","Прогреть готовый ростбиф и подать с грибным соусом."],"allergens":["Молоко"],"ingredientCost":299.62,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-mash","name":"Картофельное пюре","category":6,"catalogSection":"Гарниры","price":160,"weight":"150 г","pieces":1,"photo":"","demo":true,"composition":["Картофель, Молоко, Масло сливочное"],"ingredients":[["Картофель",0.17,"кг"],["Молоко",0.025,"кг"],["Масло сливочное",0.01,"кг"]],"ttk":{"number":"ДЕМО-Б13","basis":"На 1 порцию / 1 гостя","outputGrams":150,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-banquet-v1-stock-potato","name":"Картофель","unit":"кг","gross":0.17,"net":0.12,"unitCost":80},{"productId":"demo-banquet-v1-stock-milk","name":"Молоко","unit":"кг","gross":0.025,"net":0.02,"unitCost":110},{"productId":"demo-banquet-v1-stock-butter","name":"Масло сливочное","unit":"кг","gross":0.01,"net":0.01,"unitCost":1100}],"steps":["Очистить и отварить картофель, слить воду.","Размять с тёплым молоком и сливочным маслом."],"allergens":["Молоко"],"ingredientCost":27.35,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-rice","name":"Рис с овощами","category":6,"catalogSection":"Гарниры","price":170,"weight":"150 г","pieces":1,"photo":"","demo":true,"composition":["Рис сухой, Морковь, Перец сладкий, Горошек зелёный консервированный, Масло оливковое"],"ingredients":[["Рис сухой",0.04,"кг"],["Морковь",0.025,"кг"],["Перец сладкий",0.025,"кг"],["Горошек зелёный консервированный",0.015,"кг"],["Масло оливковое",0.005,"кг"]],"ttk":{"number":"ДЕМО-Б14","basis":"На 1 порцию / 1 гостя","outputGrams":150,"waterGrams":50,"pieces":1,"rows":[{"productId":"demo-banquet-v1-stock-rice","name":"Рис сухой","unit":"кг","gross":0.04,"net":0.04,"unitCost":180},{"productId":"demo-v1-stock-carrot","name":"Морковь","unit":"кг","gross":0.025,"net":0.02,"unitCost":90},{"productId":"demo-v1-stock-pepper","name":"Перец сладкий","unit":"кг","gross":0.025,"net":0.02,"unitCost":380},{"productId":"demo-banquet-v1-stock-peas","name":"Горошек зелёный консервированный","unit":"кг","gross":0.015,"net":0.015,"unitCost":300},{"productId":"demo-v1-stock-oil","name":"Масло оливковое","unit":"кг","gross":0.005,"net":0.005,"unitCost":1100}],"steps":["Отварить рис; учебный расчёт учитывает 50 г поглощённой воды на порцию.","Приготовить овощи, добавить горошек и смешать с рисом."],"allergens":[],"ingredientCost":28.95,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-berry-cream","name":"Ягодный десерт со сливочным кремом","category":6,"catalogSection":"Десерты","price":240,"weight":"110 г","pieces":1,"photo":"","demo":true,"composition":["Сыр сливочный, Сливки, Крошка бисквитная, Клубника, Голубика, Пудра сахарная"],"ingredients":[["Сыр сливочный",0.035,"кг"],["Сливки",0.02,"кг"],["Крошка бисквитная",0.015,"кг"],["Клубника",0.028,"кг"],["Голубика",0.011,"кг"],["Пудра сахарная",0.005,"кг"]],"ttk":{"number":"ДЕМО-Б15","basis":"На 1 порцию / 1 гостя","outputGrams":110,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-cream","name":"Сыр сливочный","unit":"кг","gross":0.035,"net":0.035,"unitCost":850},{"productId":"demo-v1-stock-cooking-cream","name":"Сливки","unit":"кг","gross":0.02,"net":0.02,"unitCost":500},{"productId":"demo-v1-stock-biscuit","name":"Крошка бисквитная","unit":"кг","gross":0.015,"net":0.015,"unitCost":500},{"productId":"demo-v1-stock-strawberry","name":"Клубника","unit":"кг","gross":0.028,"net":0.025,"unitCost":750},{"productId":"demo-v1-stock-blueberry","name":"Голубика","unit":"кг","gross":0.011,"net":0.01,"unitCost":1300},{"productId":"demo-v1-stock-sugar","name":"Пудра сахарная","unit":"кг","gross":0.005,"net":0.005,"unitCost":160}],"steps":["Смешать сыр, сливки и сахарную пудру.","Выложить в креманку бисквит, крем и подготовленные ягоды."],"allergens":["Молоко","Глютен","Яйцо в составе бисквита"],"ingredientCost":83.35,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-cheese-honey","name":"Бри с виноградом, мёдом и орехами","category":6,"catalogSection":"Десерты","price":310,"weight":"100 г","pieces":1,"photo":"","demo":true,"composition":["Сыр бри, Виноград, Орех грецкий очищенный, Мёд"],"ingredients":[["Сыр бри",0.045,"кг"],["Виноград",0.039,"кг"],["Орех грецкий очищенный",0.01,"кг"],["Мёд",0.01,"кг"]],"ttk":{"number":"ДЕМО-Б16","basis":"На 1 порцию / 1 гостя","outputGrams":100,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-brie","name":"Сыр бри","unit":"кг","gross":0.045,"net":0.045,"unitCost":1600},{"productId":"demo-v1-stock-grape","name":"Виноград","unit":"кг","gross":0.039,"net":0.035,"unitCost":420},{"productId":"demo-v1-stock-walnut","name":"Орех грецкий очищенный","unit":"кг","gross":0.01,"net":0.01,"unitCost":1000},{"productId":"demo-v1-stock-honey","name":"Мёд","unit":"кг","gross":0.01,"net":0.01,"unitCost":800}],"steps":["Нарезать бри и подготовить виноград.","Подать с грецким орехом и мёдом."],"allergens":["Молоко","Орехи"],"ingredientCost":106.38,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-fruit","name":"Фруктово-ягодное ассорти","category":6,"catalogSection":"Фрукты и ягоды","price":290,"weight":"180 г","pieces":1,"photo":"","demo":true,"composition":["Виноград, Клубника, Голубика"],"ingredients":[["Виноград",0.088,"кг"],["Клубника",0.077,"кг"],["Голубика",0.032,"кг"]],"ttk":{"number":"ДЕМО-Б17","basis":"На 1 порцию / 1 гостя","outputGrams":180,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-grape","name":"Виноград","unit":"кг","gross":0.088,"net":0.08,"unitCost":420},{"productId":"demo-v1-stock-strawberry","name":"Клубника","unit":"кг","gross":0.077,"net":0.07,"unitCost":750},{"productId":"demo-v1-stock-blueberry","name":"Голубика","unit":"кг","gross":0.032,"net":0.03,"unitCost":1300}],"steps":["Подготовить ягоды и виноград, удалить плодоножки.","Выложить порционное ассорти."],"allergens":[],"ingredientCost":136.31,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}},{"id":"demo-banquet-v1-bread","name":"Хлебная корзинка с зелёным маслом","category":6,"catalogSection":"Хлеб и масло","price":120,"weight":"60 г","pieces":1,"photo":"","demo":true,"composition":["Багет, Хлеб ржаной, Масло сливочное, Укроп"],"ingredients":[["Багет",0.03,"кг"],["Хлеб ржаной",0.02,"кг"],["Масло сливочное",0.008,"кг"],["Укроп",0.003,"кг"]],"ttk":{"number":"ДЕМО-Б18","basis":"На 1 порцию / 1 гостя","outputGrams":60,"waterGrams":0,"pieces":1,"rows":[{"productId":"demo-v1-stock-baguette","name":"Багет","unit":"кг","gross":0.03,"net":0.03,"unitCost":240},{"productId":"demo-v1-stock-rye","name":"Хлеб ржаной","unit":"кг","gross":0.02,"net":0.02,"unitCost":220},{"productId":"demo-banquet-v1-stock-butter","name":"Масло сливочное","unit":"кг","gross":0.008,"net":0.008,"unitCost":1100},{"productId":"demo-v1-stock-dill","name":"Укроп","unit":"кг","gross":0.003,"net":0.002,"unitCost":700}],"steps":["Нарезать хлеб, при желании подсушить.","Смешать масло с укропом, подать отдельно."],"allergens":["Глютен","Молоко"],"ingredientCost":22.5,"note":"Учебная рецептура и примерные цены. Выход указан после приготовления. Перед использованием в работе уточните нормы, стоимость и аллергены."}}],"stock":[{"id":"demo-banquet-v1-stock-potato","name":"Картофель","cost":80,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-fresh","lastPurchaseDate":"","lastPurchasePrice":0},{"id":"demo-banquet-v1-stock-butter","name":"Масло сливочное","cost":1100,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-fresh","lastPurchaseDate":"","lastPurchasePrice":0},{"id":"demo-banquet-v1-stock-milk","name":"Молоко","cost":110,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-fresh","lastPurchaseDate":"","lastPurchasePrice":0},{"id":"demo-banquet-v1-stock-egg","name":"Яйцо куриное без скорлупы","cost":260,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-fresh","lastPurchaseDate":"","lastPurchasePrice":0},{"id":"demo-banquet-v1-stock-peas","name":"Горошек зелёный консервированный","cost":300,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-grocery","lastPurchaseDate":"","lastPurchasePrice":0},{"id":"demo-banquet-v1-stock-chicken-raw","name":"Филе куриное сырое","cost":480,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-protein","lastPurchaseDate":"","lastPurchasePrice":0},{"id":"demo-banquet-v1-stock-whitefish","name":"Филе трески","cost":950,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-protein","lastPurchaseDate":"","lastPurchasePrice":0},{"id":"demo-banquet-v1-stock-lemon","name":"Лимон","cost":300,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-fresh","lastPurchaseDate":"","lastPurchasePrice":0},{"id":"demo-banquet-v1-stock-rice","name":"Рис сухой","cost":180,"unit":"кг","qty":0,"min":0.1,"supplierId":"demo-v1-supplier-grocery","lastPurchaseDate":"","lastPurchasePrice":0}]}$demo$::jsonb $fn$;
|
||
revoke all on function public.caterium_trial_banquet_seed_v1() from public,anon,authenticated;
|
||
|
||
create or replace function public.caterium_trial_demo_status(p_workspace uuid)
|
||
returns jsonb language plpgsql stable security definer set search_path=public,pg_temp
|
||
as $fn$
|
||
declare
|
||
v_storage jsonb; v_empty boolean:=true; v_key text; v_value jsonb;
|
||
v_allowed boolean; v_installed boolean;
|
||
begin
|
||
if auth.uid() is null or public.sun_member_role(p_workspace) is null then raise exception 'Access denied'; end if;
|
||
select coalesce(payload->'storage','{}'::jsonb) into v_storage from public.sun_app_state where workspace_id=p_workspace;
|
||
v_installed:=coalesce(v_storage#>>'{sunTrialDemoV1,v,version}','')='1';
|
||
foreach v_key in array array['sunBoxes','sunStock','sunSuppliers','sunStockMoves'] loop
|
||
v_value:=v_storage#>array[v_key,'v'];
|
||
if v_value is not null and v_value<>'[]'::jsonb then v_empty:=false; end if;
|
||
if v_storage ? v_key and (jsonb_typeof(v_storage->v_key)<>'object' or v_value is null) then v_empty:=false; end if;
|
||
end loop;
|
||
v_allowed:=public.sun_member_role(p_workspace)='admin'
|
||
and public.sun_subscription_access_mode(p_workspace)='full'
|
||
and (exists(select 1 from public.sun_workspace_subscriptions where workspace_id=p_workspace and status='trialing') or public.sun_is_platform_admin())
|
||
and public.sun_workspace_has_feature(p_workspace,'catalog_edit')
|
||
and public.sun_workspace_has_feature(p_workspace,'stock')
|
||
and public.sun_workspace_has_feature(p_workspace,'suppliers')
|
||
and not exists(select 1 from public.sun_workspace_members m join public.caterium_sidebar_brand_assignment a on a.user_id=m.user_id where m.workspace_id=p_workspace);
|
||
return jsonb_build_object('eligible',coalesce(v_allowed,false),'installed',v_installed,'empty',v_empty,'canInstall',coalesce(v_allowed,false) and v_empty and not v_installed,'canUpgrade',coalesce(v_allowed,false) and v_installed and coalesce(v_storage#>>'{sunTrialDemoV1,v,banquetVersion}','')<>'1');
|
||
end $fn$;
|
||
|
||
|
||
create or replace function public.caterium_install_trial_banquet(p_workspace uuid)
|
||
returns jsonb language plpgsql security definer set search_path=public,pg_temp
|
||
as $fn$
|
||
declare
|
||
v_state public.sun_app_state%rowtype; v_status jsonb; v_storage jsonb;
|
||
v_seed jsonb; v_key text; v_items jsonb; v_added jsonb; v_marker jsonb;
|
||
begin
|
||
if auth.uid() is null or public.sun_member_role(p_workspace) is distinct from 'admin' then raise exception 'Administrator membership required'; end if;
|
||
perform 1 from public.sun_workspaces where id=p_workspace for update;
|
||
v_status:=public.caterium_trial_demo_status(p_workspace);
|
||
if not (v_status->>'eligible')::boolean then raise exception 'Демонстрационная база доступна в пробной или собственной тестовой компании разработчика'; end if;
|
||
if not (v_status->>'installed')::boolean then raise exception 'Сначала установите демонстрационную базу'; end if;
|
||
if not (v_status->>'canUpgrade')::boolean then return v_status; end if;
|
||
select * into v_state from public.sun_app_state where workspace_id=p_workspace for update;
|
||
v_storage:=v_state.payload->'storage'; v_seed:=public.caterium_trial_banquet_seed_v1();
|
||
foreach v_key in array array['sunBoxes','sunStock'] loop
|
||
v_items:=coalesce(v_storage#>array[v_key,'v'],'[]'::jsonb);
|
||
if jsonb_typeof(v_items)<>'array' then raise exception 'Неверный формат каталога или склада. Данные сохранены без изменений'; end if;
|
||
-- Keep every existing row byte-for-byte, including edited demo prices and balances.
|
||
select coalesce(jsonb_agg(n),'[]'::jsonb) into v_added
|
||
from jsonb_array_elements(v_seed->case when v_key='sunBoxes' then 'banquet' else 'stock' end) n
|
||
where not exists(select 1 from jsonb_array_elements(v_items) old where old->>'id'=n->>'id');
|
||
v_storage:=v_storage||jsonb_build_object(v_key,jsonb_build_object('t','j','v',v_items||v_added));
|
||
end loop;
|
||
v_marker:=(v_storage#>'{sunTrialDemoV1,v}')||jsonb_build_object('banquetVersion',1,'banquetInstalledAt',now());
|
||
v_storage:=jsonb_set(v_storage,'{sunTrialDemoV1,v}',v_marker);
|
||
perform public.sun_save_app_state_v17(p_workspace,jsonb_set(v_state.payload,'{storage}',v_storage),'trial-banquet-v1',v_state.revision);
|
||
insert into public.sun_platform_audit_events(actor_user_id,action,target_workspace_id,details)
|
||
values(auth.uid(),'trial_demo.banquet_install',p_workspace,jsonb_build_object('version',1,'dishes',18));
|
||
return public.caterium_trial_demo_status(p_workspace);
|
||
end $fn$;
|
||
revoke all on function public.caterium_install_trial_banquet(uuid) from public,anon;
|
||
grant execute on function public.caterium_install_trial_banquet(uuid) to authenticated;
|
||
|
||
-- Both onboarding's existing trigger and the install button use this entry point.
|
||
create or replace function public.caterium_install_trial_demo(p_workspace uuid)
|
||
returns jsonb language plpgsql security definer set search_path=public,pg_temp
|
||
as $fn$
|
||
declare
|
||
v_state public.sun_app_state%rowtype; v_status jsonb; v_seed jsonb; v_storage jsonb; v_moves jsonb; v_marker jsonb;
|
||
begin
|
||
if auth.uid() is null or public.sun_member_role(p_workspace) is distinct from 'admin' then raise exception 'Administrator membership required'; end if;
|
||
perform 1 from public.sun_workspaces where id=p_workspace for update;
|
||
v_status:=public.caterium_trial_demo_status(p_workspace);
|
||
if not (v_status->>'eligible')::boolean then raise exception 'Демонстрационная база доступна в пробной или собственной тестовой компании разработчика'; end if;
|
||
if (v_status->>'installed')::boolean then return public.caterium_install_trial_banquet(p_workspace); end if;
|
||
if not (v_status->>'empty')::boolean then raise exception 'Каталог, склад или поставщики уже заполнены. Данные сохранены без изменений'; end if;
|
||
select * into v_state from public.sun_app_state where workspace_id=p_workspace for update;
|
||
if not found then raise exception 'Рабочая база не найдена'; end if;
|
||
v_seed:=public.caterium_trial_demo_seed_v1();
|
||
select coalesce(jsonb_agg(jsonb_build_object('id','demo-v1-opening-'||(p->>'id'),'productId',p->>'id','productName',p->>'name','unit',p->>'unit',
|
||
'type','set','qty',p->'qty','setTo',p->'qty','cost',p->'cost','date',current_date::text,'createdAt',now(),
|
||
'supplierId',p->>'supplierId','note','Учебный начальный остаток')),'[]'::jsonb) into v_moves
|
||
from jsonb_array_elements(v_seed->'stock') p where (p->>'qty')::numeric>0;
|
||
v_marker:=jsonb_build_object('version',1,'batch','trial-demo-v1','installedAt',now(),'scenario',v_seed->'scenario');
|
||
v_storage:=coalesce(v_state.payload->'storage','{}'::jsonb)||jsonb_build_object(
|
||
'sunBoxes',jsonb_build_object('t','j','v',v_seed->'boxes'),
|
||
'sunStock',jsonb_build_object('t','j','v',v_seed->'stock'),
|
||
'sunSuppliers',jsonb_build_object('t','j','v',v_seed->'suppliers'),
|
||
'sunStockMoves',jsonb_build_object('t','j','v',v_moves),
|
||
'sunTrialDemoV1',jsonb_build_object('t','j','v',v_marker));
|
||
perform public.sun_save_app_state_v17(p_workspace,jsonb_set(v_state.payload,'{storage}',v_storage),'trial-demo-v1',v_state.revision);
|
||
insert into public.sun_platform_audit_events(actor_user_id,action,target_workspace_id,details)
|
||
values(auth.uid(),'trial_demo.install',p_workspace,jsonb_build_object('version',1,'boxes',10));
|
||
return public.caterium_install_trial_banquet(p_workspace);
|
||
end $fn$;
|
||
|
||
notify pgrst,'reload schema';
|
||
commit;
|