Compare commits

..

No commits in common. "8eeed983f094509036bc319f24a28b8018ea1cbd" and "f9be519e03c17ec64b514a51f524b88e5c7365c0" have entirely different histories.

5 changed files with 352 additions and 739 deletions

View file

@ -41,50 +41,4 @@ let mys_recipe_model = common::create_recipe_model_from_file(common::create_reci
... ...
``` ```
### Get list of material settings ...WIP
```rust
// get current material settings including empty (0)
let mut used_in_mys = mys_recipe_model.list_material_settings();
used_in_mys.push("0".to_string());
```
### Get all recipe of expected material id
```rust
let aus_latest = common::create_recipe_model_from_file(common::create_recipe_path(
"aus",
*aus_version.unwrap(),
));
let prod_list = aus_latest.find_recipe_by_material_path_id("511214");
```
### Generate google sheet style table of recipe from file
```rust
// Experimental: expect current execution path to have `./test_result` folder first, and `config.RECIPE_DIR/{country}/{version_file_format}` must exist.
import::generate_recipe_sheet_table("mys", 626);
```
### Notes
Simple Snippet Patterns
```rust
// =============================================
// Get current material and convert to thai id
// =============================================
let curr_rpl_mat_id = rpl.materialPathId.as_i64().unwrap_or(0);
// strip off first 2
let pure_mat_id = if curr_rpl_mat_id > 300000 {
//
curr_rpl_mat_id.to_string()[2..]
.parse::<i64>()
.expect("not a number")
} else {
curr_rpl_mat_id
};
```

View file

@ -1,8 +1,4 @@
use std::{ use std::{collections::HashMap, fs::File, io};
collections::{BTreeMap, HashMap},
fs::File,
io,
};
use chrono::{DateTime, NaiveDateTime}; use chrono::{DateTime, NaiveDateTime};
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator};
@ -15,11 +11,6 @@ pub trait CommonRecipeTrait {
fn compare(&self, another_setting: &Self) -> Vec<String>; fn compare(&self, another_setting: &Self) -> Vec<String>;
} }
pub trait CommonCompressTrait {
fn flatten(&mut self) -> BTreeMap<String, Value>;
fn unflatten(&mut self, flatted: BTreeMap<String, Value>) -> BTreeMap<String, Value>;
}
macro_rules! compare_field { macro_rules! compare_field {
($self: ident, $another_setting: ident, $list: ident, $field: ident) => { ($self: ident, $another_setting: ident, $list: ident, $field: ident) => {
if $self.$field != $another_setting.$field { if $self.$field != $another_setting.$field {
@ -609,116 +600,13 @@ impl Recipe {
res_map res_map
} }
/// Get all data in this recipe as summary, this does not contain all the field but only id or name.
///
pub fn get_recipe_data_summary(&mut self) -> RecipeSummary {
// mapping Recipe01, MaterialSetting, Topping, MaterialCode
let recipe01_summary = self
.Recipe01
.clone()
.iter()
.map(|r01| Recipe01Summary {
productCode: r01.productCode.clone(),
name: r01.name.clone().unwrap_or("".to_string()),
})
.collect::<Vec<Recipe01Summary>>();
let matset_summary = self
.MaterialSetting
.clone()
.iter()
.map(|ms| MaterialSettingSummary {
id: ms.id.clone(),
materialName: ms
.materialName
.clone()
.unwrap_or(ms.materialOtherName.clone().unwrap_or("".to_string())),
})
.collect::<Vec<MaterialSettingSummary>>();
let topping_group_summary = self
.Topping
.ToppingGroup
.clone()
.iter()
.map(|tg| {
if !tg.name.is_empty() {
ToppingGroupSummary {
groupID: tg.groupID.clone(),
name: tg.name.clone(),
}
} else {
ToppingGroupSummary {
groupID: tg.groupID.clone(),
name: tg.otherName.clone(),
}
}
})
.collect::<Vec<ToppingGroupSummary>>();
let topping_list_summary = self
.Topping
.ToppingList
.clone()
.iter()
.map(|tpl| {
if tpl.name.is_some() {
ToppingListSummary {
id: tpl.id.clone(),
name: tpl.name.clone().unwrap(),
}
} else {
ToppingListSummary {
id: tpl.id.clone(),
name: tpl.otherName.clone().unwrap_or("".to_string()),
}
}
})
.collect::<Vec<ToppingListSummary>>();
RecipeSummary {
Timestamp: self.Timestamp.clone(),
MachineSetting: self.MachineSetting.clone(),
Recipe01: recipe01_summary,
MaterialSetting: matset_summary,
Topping: ToppingSummary {
ToppingGroup: topping_group_summary,
ToppingList: topping_list_summary,
},
MaterialCode: self.MaterialCode.clone(),
extra: self.extra.clone(),
}
}
// zone import recipe // zone import recipe
// //
// //
#[deprecated]
pub fn add_prefix_country_code(&mut self) {} pub fn add_prefix_country_code(&mut self) {}
pub fn get_prefix_country_code(&mut self) -> String {
// get by first recipe as sample
let rp_clone = self.Recipe01.clone();
let first_recipe = rp_clone.first().unwrap();
let product_code_split = first_recipe.productCode.split("-").collect::<Vec<&str>>();
product_code_split.first().unwrap().to_string()
}
} }
// impl CommonCompressTrait for Recipe {
// fn flatten(&mut self) -> BTreeMap<String, Value> {
// let mut result = BTreeMap::new();
// let mut map = serde_json::json!(*self);
// result
// }
// fn unflatten(&mut self, flatted: BTreeMap<String, Value>) -> BTreeMap<String, Value> {}
// }
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn StrShowTextErrorDefault() -> Option<Vec<Value>> { fn StrShowTextErrorDefault() -> Option<Vec<Value>> {
Some(vec![ Some(vec![
@ -1624,7 +1512,6 @@ pub struct RecipeList {
pub enum MaterialType { pub enum MaterialType {
Bean, Bean,
Brew,
Syrup, Syrup,
Soda, Soda,
Powder, Powder,
@ -1637,54 +1524,11 @@ pub enum MaterialType {
Leaves, Leaves,
Clean, Clean,
CleanV2, CleanV2,
IceScreamBingsu,
FreshSyrup,
FrozenFruit,
// esp module
// check
ToppingSlot,
Unknown, Unknown,
} }
impl RecipeList { impl RecipeList {
pub fn get_material_type(&mut self, country_code: Option<String>) -> MaterialType { pub fn get_material_type(&mut self) {}
let pure_mat_id = if country_code.is_some() {
let cc = country_code.unwrap().parse::<i64>().expect("not a number");
let mat_num = self.materialPathId.clone().as_i64().unwrap();
let check_if_start_with_cc = mat_num.to_string().starts_with(&format!("{cc}"));
if check_if_start_with_cc {
mat_num - (cc * 10000)
} else {
mat_num
}
} else {
self.materialPathId.clone().as_i64().expect("not a number")
};
return match pure_mat_id {
8000 => MaterialType::Brew,
8001 => MaterialType::Clean,
8002 => MaterialType::CleanV2,
8110..8131 => MaterialType::ToppingSlot,
1031 => MaterialType::Soda,
1 => MaterialType::Water,
9100 => MaterialType::Ice,
8102..8104 => MaterialType::Whipper,
1001..1009 | 1100..1200 => MaterialType::Bean,
1600..1800 => MaterialType::Leaves,
1032..1040 | 1020..1031 | 1200..1300 | 1400..1500 => MaterialType::Syrup,
1040..1081 | 1300..1400 => MaterialType::Powder,
9500..9550 => MaterialType::Cup,
9600..9650 => MaterialType::Lid,
9700..9750 => MaterialType::Straw,
2100..2201 => MaterialType::IceScreamBingsu,
2201..2301 => MaterialType::FreshSyrup,
2301..2501 => MaterialType::FrozenFruit,
_ => MaterialType::Unknown,
};
}
// grep data fn // grep data fn
pub fn get_data_used_in_brew(&mut self) -> Value { pub fn get_data_used_in_brew(&mut self) -> Value {
@ -1844,43 +1688,26 @@ impl CommonRecipeTrait for MaterialSetting {
} }
impl MaterialSetting { impl MaterialSetting {
pub fn get_definition_type(&mut self, country_code: Option<String>) -> MaterialType { pub fn get_definition_type(&mut self) -> MaterialType {
let pure_mat_id = if country_code.is_some() { match self.id.as_i64().unwrap() {
let cc = country_code.unwrap().parse::<i64>().expect("not a number"); 8102..8103 => MaterialType::Whipper,
let mat_num = self.id.clone().as_i64().unwrap(); 9100 => MaterialType::Ice,
let check_if_start_with_cc = mat_num.to_string().starts_with(&format!("{cc}"));
if check_if_start_with_cc {
mat_num - (cc * 10000)
} else {
mat_num
}
} else {
self.id.clone().as_i64().expect("not a number")
};
return match pure_mat_id {
8000 => MaterialType::Brew,
8001 => MaterialType::Clean, 8001 => MaterialType::Clean,
8002 => MaterialType::CleanV2, 8002 => MaterialType::CleanV2,
8110..8131 => MaterialType::ToppingSlot, _ => {
1031 => MaterialType::Soda, if self.BeanChannel {
1 => MaterialType::Water, MaterialType::Bean
9100 => MaterialType::Ice, } else if self.PowderChannel {
8102..8104 => MaterialType::Whipper, MaterialType::Powder
1001..1009 | 1100..1200 => MaterialType::Bean, } else if self.SyrupChannel {
1600..1800 => MaterialType::Leaves, MaterialType::Syrup
1032..1040 | 1020..1031 | 1200..1300 | 1400..1500 => MaterialType::Syrup, } else if self.SodaChannel {
1040..1081 | 1300..1400 => MaterialType::Powder, MaterialType::Soda
9500..9550 => MaterialType::Cup, } else {
9600..9650 => MaterialType::Lid, MaterialType::Unknown
9700..9750 => MaterialType::Straw, }
2100..2201 => MaterialType::IceScreamBingsu, }
2201..2301 => MaterialType::FreshSyrup, }
2301..2501 => MaterialType::FrozenFruit,
_ => MaterialType::Unknown,
};
} }
} }
@ -1896,10 +1723,10 @@ impl MachineSetting {
#[allow(non_snake_case)] #[allow(non_snake_case)]
fn BlankListGroupID() -> Option<Vec<Value>> { fn BlankListGroupID() -> Option<Vec<Value>> {
Some(vec![ Some(vec![
Value::Number(0.into()), Value::String("0".into()),
Value::Number(0.into()), Value::String("0".into()),
Value::Number(0.into()), Value::String("0".into()),
Value::Number(0.into()), Value::String("0".into()),
]) ])
} }
@ -1932,28 +1759,6 @@ pub struct MenuToppingList {
// pub extra: std::collections::HashMap<String, Value>, // pub extra: std::collections::HashMap<String, Value>,
} }
impl MenuToppingList {
pub fn to_single_line(&mut self) -> String {
format!(
"#__ListGroupID={:?},defaultIDSelect={},groupID={},isUse={}",
self.ListGroupID
.clone()
.unwrap_or_default()
.iter()
.map(|gid| gid.as_i64().unwrap().to_string())
.collect::<Vec<String>>(),
self.defaultIDSelect.as_i64().unwrap(),
self.groupID
.clone()
.unwrap_or_default()
.as_str()
.unwrap()
.to_string(),
self.isUse
)
}
}
/// The `Topping` struct represents a collection of topping groups and topping lists. /// The `Topping` struct represents a collection of topping groups and topping lists.
/// ///
/// Properties: /// Properties:
@ -2241,109 +2046,3 @@ impl Recipe01 {
.collect() .collect()
} }
} }
// --------------------------------------
#[allow(non_snake_case)]
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct RecipeSummary {
pub Timestamp: String,
pub MachineSetting: MachineSetting,
pub Recipe01: Vec<Recipe01Summary>,
pub MaterialSetting: Vec<MaterialSettingSummary>,
pub Topping: ToppingSummary,
pub MaterialCode: Vec<MaterialCode>,
#[serde(flatten)]
pub extra: std::collections::HashMap<String, serde_json::Value>,
}
impl RecipeSummary {
pub fn recipe01_contains(&mut self, pd: String) -> bool {
let filtered = self
.Recipe01
.iter()
.filter(|r01| r01.productCode.eq(&pd))
.collect::<Vec<&Recipe01Summary>>();
!filtered.is_empty()
}
#[allow(non_snake_case)]
pub fn materialSetting_contains(&mut self, id: Value) -> bool {
let filtered = self
.MaterialSetting
.iter()
.filter(|ms| ms.id.eq(&id))
.collect::<Vec<&MaterialSettingSummary>>();
!filtered.is_empty()
}
#[allow(non_snake_case)]
pub fn materialCode_contains(&mut self, mat_id: Value) -> bool {
let filtered = self
.MaterialCode
.iter()
.filter(|mc| mc.materialID.eq(&mat_id))
.collect::<Vec<&MaterialCode>>();
!filtered.is_empty()
}
#[allow(non_snake_case)]
pub fn toppingList_contains(&mut self, id: Value) -> bool {
let filtered = self
.Topping
.ToppingList
.iter()
.filter(|tpl| tpl.id.eq(&id))
.collect::<Vec<&ToppingListSummary>>();
!filtered.is_empty()
}
#[allow(non_snake_case)]
pub fn toppingGroup_contains(&mut self, gid: Value) -> bool {
let filtered = self
.Topping
.ToppingGroup
.iter()
.filter(|tg| tg.groupID.eq(&gid))
.collect::<Vec<&ToppingGroupSummary>>();
!filtered.is_empty()
}
}
#[allow(non_snake_case)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct Recipe01Summary {
pub productCode: String,
pub name: String,
}
#[allow(non_snake_case)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct MaterialSettingSummary {
pub id: Value,
pub materialName: String,
}
#[allow(non_snake_case)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct ToppingSummary {
pub ToppingGroup: Vec<ToppingGroupSummary>,
pub ToppingList: Vec<ToppingListSummary>,
}
#[allow(non_snake_case)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct ToppingGroupSummary {
pub groupID: Value,
pub name: String,
}
#[allow(non_snake_case)]
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct ToppingListSummary {
pub id: Value,
pub name: String,
}

View file

@ -3,7 +3,6 @@ pub struct Headers {}
impl Headers { impl Headers {
// will be deprecated by next version // will be deprecated by next version
#[deprecated]
pub fn get_recipe_table_sgp_24022025() -> Vec<&'static str> { pub fn get_recipe_table_sgp_24022025() -> Vec<&'static str> {
[ [
"Name", "Name",
@ -129,7 +128,6 @@ impl Headers {
.to_vec() .to_vec()
} }
#[deprecated]
pub fn get_recipe_table_dubai_16052025() -> Vec<&'static str> { pub fn get_recipe_table_dubai_16052025() -> Vec<&'static str> {
[ [
"Name", "Name",

View file

@ -151,22 +151,7 @@ pub fn change_prefix_by_country(
for ele in x.clone().recipes { for ele in x.clone().recipes {
let mut eled = ele.clone(); let mut eled = ele.clone();
if check_allowed_change_mat_prefix(eled.clone().materialPathId) { if check_allowed_change_mat_prefix(eled.clone().materialPathId) {
let curr_id = eled.clone().materialPathId.as_i64().unwrap_or(0); let new_f = format!("{}{}", mat_prefix, eled.clone().materialPathId);
let new_f = if curr_id > 300000 {
// is from inter
// TODO: reset first
let back_to_default_id = curr_id.to_string()[2..]
.parse::<i64>()
.expect("not a number");
format!("{}{}", mat_prefix, back_to_default_id)
} else {
// is from thai
format!("{}{}", mat_prefix, eled.clone().materialPathId)
};
eled.materialPathId = Value::Number(new_f.parse::<i64>().unwrap().into()); eled.materialPathId = Value::Number(new_f.parse::<i64>().unwrap().into());
} }
new_recipes_format.push(eled); new_recipes_format.push(eled);
@ -185,21 +170,8 @@ pub fn change_prefix_by_country(
for ele in sl.recipes { for ele in sl.recipes {
let mut eled = ele.clone(); let mut eled = ele.clone();
if check_allowed_change_mat_prefix(eled.clone().materialPathId) { if check_allowed_change_mat_prefix(eled.clone().materialPathId) {
let curr_id = eled.clone().materialPathId.as_i64().unwrap_or(0); let new_f =
format!("{}{}", mat_prefix, eled.clone().materialPathId);
let new_f = if curr_id > 300000 {
// is from inter
// TODO: reset first
let back_to_default_id = curr_id.to_string()[2..]
.parse::<i64>()
.expect("not a number");
format!("{}{}", mat_prefix, back_to_default_id)
} else {
// is from thai
format!("{}{}", mat_prefix, eled.clone().materialPathId)
};
eled.materialPathId = eled.materialPathId =
Value::Number(new_f.parse::<i64>().unwrap().into()); Value::Number(new_f.parse::<i64>().unwrap().into());
} }

View file

@ -1,7 +1,6 @@
use std::str::FromStr; use std::str::FromStr;
use log::{debug, info}; use log::{debug, info};
use rayon::iter::{IntoParallelRefMutIterator, ParallelIterator};
use serde_json::{Number, Value}; use serde_json::{Number, Value};
use super::common::*; use super::common::*;
@ -10,338 +9,337 @@ use crate::{
previews::{csvf::*, header::Headers}, previews::{csvf::*, header::Headers},
}; };
// #[deprecated] pub fn import_menu(main_version: usize, country_name: &str, into_version: usize) {
// pub fn import_menu(main_version: usize, country_name: &str, into_version: usize) { let latest_recipe_thai = create_recipe_model_from_file(create_recipe_path("tha", main_version));
// let latest_recipe_thai = create_recipe_model_from_file(create_recipe_path("tha", main_version));
// // let mut latest_recipe_mys = // let mut latest_recipe_mys =
// // create_recipe_model_from_file(create_recipe_path("mys", *mys_version.unwrap())); // create_recipe_model_from_file(create_recipe_path("mys", *mys_version.unwrap()));
// let mut latest_recipe_sgp = let mut latest_recipe_sgp =
// create_recipe_model_from_file(create_recipe_path(country_name, into_version)); create_recipe_model_from_file(create_recipe_path(country_name, into_version));
// let diff_list = latest_recipe_thai.list_diff_pd_ignore_country_code(&latest_recipe_sgp); let diff_list = latest_recipe_thai.list_diff_pd_ignore_country_code(&latest_recipe_sgp);
// let mut menu_no_sugar_table = Table::new(); let mut menu_no_sugar_table = Table::new();
// let insert_later_config = TableConfig { let insert_later_config = TableConfig {
// allow_row_length_exceeds_header: false, allow_row_length_exceeds_header: false,
// auto_fix_size: true, auto_fix_size: true,
// auto_fix_size_strategy: AutoFixSizeStrategy::FillRowToMatchHeader { auto_fix_size_strategy: AutoFixSizeStrategy::FillRowToMatchHeader {
// default_value: "".to_string(), default_value: "".to_string(),
// }, },
// }; };
// let mut sg_price_table = menu_no_sugar_table.clone(); let mut sg_price_table = menu_no_sugar_table.clone();
// let mut recipe_table = menu_no_sugar_table.clone(); let mut recipe_table = menu_no_sugar_table.clone();
// menu_no_sugar_table.set_config(insert_later_config.clone()); menu_no_sugar_table.set_config(insert_later_config.clone());
// sg_price_table.set_config(insert_later_config.clone()); sg_price_table.set_config(insert_later_config.clone());
// recipe_table.set_config(insert_later_config.clone()); recipe_table.set_config(insert_later_config.clone());
// menu_no_sugar_table.set_header(["Product Code", "Name"].to_vec()); menu_no_sugar_table.set_header(["Product Code", "Name"].to_vec());
// sg_price_table.set_header(["SKU", "English Name", "Thai Name"].to_vec()); sg_price_table.set_header(["SKU", "English Name", "Thai Name"].to_vec());
// recipe_table.set_header(Headers::get_recipe_table_sgp_24022025()); recipe_table.set_header(Headers::get_recipe_table_sgp_24022025());
// let modified_recipes = change_prefix_by_country( let modified_recipes = change_prefix_by_country(
// country_name, country_name,
// latest_recipe_thai.search_multi_in_parallel(diff_list), latest_recipe_thai.search_multi_in_parallel(diff_list),
// ); );
// // also clone mat setting // also clone mat setting
// // ** Will removed this // ** Will removed this
// let from_tha_mat_settings = [ let from_tha_mat_settings = [
// latest_recipe_thai.search_material_settings("2201".to_string()), latest_recipe_thai.search_material_settings("2201".to_string()),
// latest_recipe_thai.search_material_settings("1217".to_string()), latest_recipe_thai.search_material_settings("1217".to_string()),
// latest_recipe_thai.search_material_settings("1038".to_string()), latest_recipe_thai.search_material_settings("1038".to_string()),
// latest_recipe_thai.search_material_settings("1037".to_string()), latest_recipe_thai.search_material_settings("1037".to_string()),
// ]; ];
// let mut formatted_mat_settings = Vec::new(); let mut formatted_mat_settings = Vec::new();
// from_tha_mat_settings.iter().for_each(|mat_smth| { from_tha_mat_settings.iter().for_each(|mat_smth| {
// let new_mat_smth = *mat_smth; let new_mat_smth = *mat_smth;
// if let Some(x) = new_mat_smth { if let Some(x) = new_mat_smth {
// let mut cl_x = x.clone(); let mut cl_x = x.clone();
// let mut new_mat_id = cl_x.id.clone().as_i64().unwrap().to_string(); let mut new_mat_id = cl_x.id.clone().as_i64().unwrap().to_string();
// // new_product_code = format!("{}-{}", "sgp", new_product_code.split_once('-').unwrap().1); // new_product_code = format!("{}-{}", "sgp", new_product_code.split_once('-').unwrap().1);
// new_mat_id = format!("{}{}", get_mat_prefix(country_name), new_mat_id); new_mat_id = format!("{}{}", get_mat_prefix(country_name), new_mat_id);
// cl_x.id = Value::Number(Number::from_str(&new_mat_id).unwrap()).clone(); cl_x.id = Value::Number(Number::from_str(&new_mat_id).unwrap()).clone();
// // debug!("new formatted mat settings [SGP] -> {:?}", cl_x); // debug!("new formatted mat settings [SGP] -> {:?}", cl_x);
// formatted_mat_settings.push(cl_x); formatted_mat_settings.push(cl_x);
// } }
// }); });
// latest_recipe_sgp latest_recipe_sgp
// .MaterialSetting .MaterialSetting
// .extend(formatted_mat_settings.clone()); .extend(formatted_mat_settings.clone());
// // debug!("modified recipes: {:#?}", modified_recipes); // debug!("modified recipes: {:#?}", modified_recipes);
// // process: generate table // process: generate table
// modified_recipes.iter().enumerate().for_each(|mr| { modified_recipes.iter().enumerate().for_each(|mr| {
// menu_no_sugar_table.add_row(vec![ menu_no_sugar_table.add_row(vec![
// mr.1.productCode.clone(), mr.1.productCode.clone(),
// mr.1.name.clone().unwrap().to_string().replace("\n", "\\n"), mr.1.name.clone().unwrap().to_string().replace("\n", "\\n"),
// ]); ]);
// sg_price_table.add_row(vec![ sg_price_table.add_row(vec![
// mr.1.productCode.clone(), mr.1.productCode.clone(),
// mr.1.otherName mr.1.otherName
// .clone() .clone()
// .unwrap() .unwrap()
// .to_string() .to_string()
// .replace("\n", "\\n"), .replace("\n", "\\n"),
// mr.1.name.clone().unwrap().to_string().replace("\n", "\\n"), mr.1.name.clone().unwrap().to_string().replace("\n", "\\n"),
// ]); ]);
// // Pre process for recipe table // Pre process for recipe table
// // let mut missing_support_mats = Vec::new(); // let mut missing_support_mats = Vec::new();
// let binding = mr.1.clone(); let binding = mr.1.clone();
// let mat_list = binding let mat_list = binding
// .recipes .recipes
// .iter() .iter()
// .filter(|r| r.isUse) .filter(|r| r.isUse)
// .map(|r| { .map(|r| {
// // debug!( // debug!(
// // "r->{:?}", // "r->{:?}",
// // r.materialPathId // r.materialPathId
// // .clone() // .clone()
// // .as_number() // .as_number()
// // .unwrap() // .unwrap()
// // .as_i64() // .as_i64()
// // .unwrap() // .unwrap()
// // .to_string() // .to_string()
// // ); // );
// r.materialPathId r.materialPathId
// .as_number() .as_number()
// .unwrap() .unwrap()
// .as_i64() .as_i64()
// .unwrap() .unwrap()
// .to_string() .to_string()
// }) })
// .collect::<Vec<String>>(); .collect::<Vec<String>>();
// let mut mapping_mats = Vec::new(); let mut mapping_mats = Vec::new();
// // let mut missing_header = Vec::new(); // let mut missing_header = Vec::new();
// mat_list.iter().enumerate().for_each(|(idx, mat)| { mat_list.iter().enumerate().for_each(|(idx, mat)| {
// // if (!mat.parse::<i64>().unwrap().eq(&0i64) // if (!mat.parse::<i64>().unwrap().eq(&0i64)
// // && !recipe_table // && !recipe_table
// // .clone() // .clone()
// // .get_current_header() // .get_current_header()
// // .contains(&mat.to_string())) // .contains(&mat.to_string()))
// // { // {
// // // missing_support_mats.push((idx, mat.to_string())); // // missing_support_mats.push((idx, mat.to_string()));
// // // add to header // // add to header
// // // recipe_table.add_header(mat); // // recipe_table.add_header(mat);
// // missing_header.push(mat); // missing_header.push(mat);
// // } // }
// // skip zero // skip zero
// if !mat.eq("0") { if !mat.eq("0") {
// mapping_mats.push((idx, mat)); mapping_mats.push((idx, mat));
// } }
// }); });
// // if (!missing_header.is_empty()) { // if (!missing_header.is_empty()) {
// // missing_header.iter().for_each(|mh| { // missing_header.iter().for_each(|mh| {
// // if (!recipe_table // if (!recipe_table
// // .clone() // .clone()
// // .get_current_header() // .get_current_header()
// // .contains(mh.clone())) // .contains(mh.clone()))
// // { // {
// // recipe_table.add_header(mh); // recipe_table.add_header(mh);
// // } // }
// // }); // });
// // } // }
// let inter_name_empty = mr.1.otherName.clone().unwrap().is_empty(); let inter_name_empty = mr.1.otherName.clone().unwrap().is_empty();
// let used_name = if inter_name_empty { let used_name = if inter_name_empty {
// mr.1.name.clone().unwrap().to_string().replace("\n", "\\n") mr.1.name.clone().unwrap().to_string().replace("\n", "\\n")
// } else { } else {
// mr.1.otherName mr.1.otherName
// .clone() .clone()
// .unwrap() .unwrap()
// .to_string() .to_string()
// .replace("\n", "\\n") .replace("\n", "\\n")
// }; };
// let mut used_mats = vec![used_name, mr.1.productCode.clone()]; let mut used_mats = vec![used_name, mr.1.productCode.clone()];
// // add by using mat // add by using mat
// // let mut reorder1 = Vec::new(); // let mut reorder1 = Vec::new();
// // let mut add_last = Vec::new(); // let mut add_last = Vec::new();
// // reorder by header // reorder by header
// // recipe_table.clone().get_current_header().iter().for_each(|h| { // recipe_table.clone().get_current_header().iter().for_each(|h| {
// // let mut found = false; // let mut found = false;
// // mapping_mats.iter().for_each(|(idx, mat)| { // mapping_mats.iter().for_each(|(idx, mat)| {
// // if (h.eq(mat)) { // if (h.eq(mat)) {
// // found = true; // found = true;
// // reorder1.push((idx, mat)); // reorder1.push((idx, mat));
// // } // }
// // }); // });
// // }); // });
// // recipe // recipe
// let mut recipe_brew_values_only = vec![0; recipe_table.clone().get_current_header().len()]; let mut recipe_brew_values_only = vec![0; recipe_table.clone().get_current_header().len()];
// let recipe_list = mr.1.clone().recipes; let recipe_list = mr.1.clone().recipes;
// let mut add_more_to_blender = 0i64; let mut add_more_to_blender = 0i64;
// for repl in recipe_list.iter() { for repl in recipe_list.iter() {
// let current_mat = repl.materialPathId.as_number().unwrap().as_i64().unwrap(); let current_mat = repl.materialPathId.as_number().unwrap().as_i64().unwrap();
// if repl.isUse { if repl.isUse {
// recipe_table recipe_table
// .clone() .clone()
// .get_current_header() .get_current_header()
// .iter() .iter()
// .enumerate() .enumerate()
// .for_each(|(header_idx, header)| { .for_each(|(header_idx, header)| {
// if header_idx > 1 && header.eq(&current_mat.to_string()) { if header_idx > 1 && header.eq(&current_mat.to_string()) {
// // search mat settings for further info // search mat settings for further info
// let mat_setting = let mat_setting =
// latest_recipe_sgp.search_material_settings(current_mat.to_string()); latest_recipe_sgp.search_material_settings(current_mat.to_string());
// if let Some(mat_s) = mat_setting { if let Some(mat_s) = mat_setting {
// match mat_s.clone().get_definition_type() { match mat_s.clone().get_definition_type() {
// recipe::MaterialType::Bean => { recipe::MaterialType::Bean => {
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// repl.powderGram.as_i64().unwrap(); repl.powderGram.as_i64().unwrap();
// // check if there is mix order // check if there is mix order
// if repl if repl
// .MixOrder .MixOrder
// .as_number() .as_number()
// .unwrap() .unwrap()
// .as_i64() .as_i64()
// .unwrap() .unwrap()
// .eq(&0i64) .eq(&0i64)
// { {
// // add to blender index // add to blender index
// add_more_to_blender = repl.waterYield.as_i64().unwrap(); add_more_to_blender = repl.waterYield.as_i64().unwrap();
// } }
// } }
// recipe::MaterialType::Syrup => { recipe::MaterialType::Syrup => {
// // debug // debug
// println!( println!(
// "SYRUP [{}]: {} --> {} = {:?}", "SYRUP [{}]: {} --> {} = {:?}",
// mr.1.productCode.clone(), mr.1.productCode.clone(),
// header_idx, header_idx,
// repl.materialPathId.clone(), repl.materialPathId.clone(),
// repl.syrupGram repl.syrupGram
// ); );
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// repl.syrupGram.as_i64().unwrap(); repl.syrupGram.as_i64().unwrap();
// } }
// recipe::MaterialType::Soda => { recipe::MaterialType::Soda => {
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// repl.syrupGram.as_i64().unwrap(); repl.syrupGram.as_i64().unwrap();
// } }
// recipe::MaterialType::Powder => { recipe::MaterialType::Powder => {
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// repl.powderGram.as_i64().unwrap(); repl.powderGram.as_i64().unwrap();
// } }
// recipe::MaterialType::Water => todo!(), recipe::MaterialType::Water => todo!(),
// recipe::MaterialType::Ice => { recipe::MaterialType::Ice => {
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// repl.waterCold.as_i64().unwrap(); repl.waterCold.as_i64().unwrap();
// } }
// recipe::MaterialType::Cup => { recipe::MaterialType::Cup => {
// recipe_brew_values_only[header_idx] += 1; recipe_brew_values_only[header_idx] += 1;
// } }
// recipe::MaterialType::Lid => {} recipe::MaterialType::Lid => {}
// recipe::MaterialType::Straw => {} recipe::MaterialType::Straw => {}
// recipe::MaterialType::Whipper => { recipe::MaterialType::Whipper => {
// let water_yield = repl.waterYield.as_i64().unwrap(); let water_yield = repl.waterYield.as_i64().unwrap();
// let water_cold = repl.waterCold.as_i64().unwrap(); let water_cold = repl.waterCold.as_i64().unwrap();
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// water_yield + water_cold; water_yield + water_cold;
// if add_more_to_blender > 0i64 { if add_more_to_blender > 0i64 {
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// add_more_to_blender; add_more_to_blender;
// add_more_to_blender = 0i64; add_more_to_blender = 0i64;
// } }
// } }
// recipe::MaterialType::Leaves => {} recipe::MaterialType::Leaves => {}
// recipe::MaterialType::Clean => { recipe::MaterialType::Clean => {
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// repl.waterYield.as_i64().unwrap(); repl.waterYield.as_i64().unwrap();
// } }
// recipe::MaterialType::CleanV2 => { recipe::MaterialType::CleanV2 => {
// recipe_brew_values_only[header_idx] += recipe_brew_values_only[header_idx] +=
// repl.waterYield.as_i64().unwrap(); repl.waterYield.as_i64().unwrap();
// } }
// _ => { recipe::MaterialType::Unknown => {
// recipe_brew_values_only[header_idx] += 0i64; recipe_brew_values_only[header_idx] += 0i64;
// } }
// } }
// } else { } else {
// // suspect new mat or not found // suspect new mat or not found
// debug!("mat error [NotFound/Unknown] ==> {}", repl.materialPathId); debug!("mat error [NotFound/Unknown] ==> {}", repl.materialPathId);
// } }
// } }
// }); });
// } }
// } }
// for (vidx, val) in recipe_brew_values_only.iter().enumerate() { for (vidx, val) in recipe_brew_values_only.iter().enumerate() {
// // skip first 2 // skip first 2
// if vidx <= 1 { if vidx <= 1 {
// continue; continue;
// } }
// if val > &0i64 { if val > &0i64 {
// used_mats.push(val.to_string()); used_mats.push(val.to_string());
// } else { } else {
// used_mats.push(String::from("")); used_mats.push(String::from(""));
// } }
// } }
// // debug!("Used Materials: \n{:?}", used_mats); // debug!("Used Materials: \n{:?}", used_mats);
// recipe_table.add_row(used_mats); recipe_table.add_row(used_mats);
// }); });
// // Exclusive only for SGP // Exclusive only for SGP
// if country_name.eq_ignore_ascii_case("sgp") { if country_name.eq_ignore_ascii_case("sgp") {
// menu_no_sugar_table.generate_save_file("./test_result/menu_no_sugar.csv"); menu_no_sugar_table.generate_save_file("./test_result/menu_no_sugar.csv");
// // process: generate table for price // process: generate table for price
// sg_price_table.generate_save_file("./test_result/sg_price.csv"); sg_price_table.generate_save_file("./test_result/sg_price.csv");
// // process: generate table for recipe // process: generate table for recipe
// recipe_table.generate_save_file("./test_result/sg_recipe.csv"); recipe_table.generate_save_file("./test_result/sg_recipe.csv");
// // final process // final process
// let mut pr = PartialRecipe::default(); let mut pr = PartialRecipe::default();
// pr.sync_new(modified_recipes, formatted_mat_settings.clone()); pr.sync_new(modified_recipes, formatted_mat_settings.clone());
// // export file for recipe json // export file for recipe json
// pr.export("./test_result/grep_into_modified_new_recipe_for_sgp.json"); pr.export("./test_result/grep_into_modified_new_recipe_for_sgp.json");
// } else { } else {
// sg_price_table.generate_save_file("./test_result/o1_price.csv"); sg_price_table.generate_save_file("./test_result/o1_price.csv");
// // process: generate table for recipe // process: generate table for recipe
// recipe_table.generate_save_file("./test_result/o1_recipe.csv"); recipe_table.generate_save_file("./test_result/o1_recipe.csv");
// // final process // final process
// let mut pr = PartialRecipe::default(); let mut pr = PartialRecipe::default();
// pr.sync_new(modified_recipes, formatted_mat_settings.clone()); pr.sync_new(modified_recipes, formatted_mat_settings.clone());
// // export file for recipe json // export file for recipe json
// pr.export("./test_result/grep_into_modified_new_recipe_for_o1.json"); pr.export("./test_result/grep_into_modified_new_recipe_for_o1.json");
// } }
// // WIP other countries // WIP other countries
// } }
pub fn generate_recipe_sheet_table(country_name: &str, into_version: usize) { pub fn generate_recipe_sheet_table(country_name: &str, into_version: usize) {
let latest_recipe = let mut latest_recipe =
create_recipe_model_from_file(create_recipe_path(country_name, into_version)); create_recipe_model_from_file(create_recipe_path(country_name, into_version));
let mut recipe_table = Table::new(); let mut recipe_table = Table::new();
@ -402,26 +400,7 @@ pub fn generate_recipe_sheet_table(country_name: &str, into_version: usize) {
} }
} }
// FIX: case sub menu is ignored latest_recipe.clone().Recipe01.iter_mut().for_each(|rpl| {
let sub_menu_fetched: Vec<Vec<crate::models::recipe::Recipe01>> = latest_recipe
.Recipe01
.clone()
.par_iter_mut()
.filter_map(|x| {
if x.SubMenu.clone().is_some_and(|xs| !xs.is_empty()) {
Some(x.SubMenu.clone().unwrap())
} else {
None
}
})
.collect();
let mut submenus = sub_menu_fetched.concat();
let mut recipe_iter = latest_recipe.clone().Recipe01;
let prefix_cc = latest_recipe.clone().get_prefix_country_code();
recipe_iter.append(&mut submenus);
recipe_iter.iter_mut().for_each(|rpl| {
let binding = rpl.clone(); let binding = rpl.clone();
let mat_list = binding let mat_list = binding
.recipes .recipes
@ -473,11 +452,24 @@ pub fn generate_recipe_sheet_table(country_name: &str, into_version: usize) {
.enumerate() .enumerate()
.for_each(|(header_idx, header)| { .for_each(|(header_idx, header)| {
if header_idx > 1 && header.eq(&current_material.to_string()) { if header_idx > 1 && header.eq(&current_material.to_string()) {
// search mat settings for further info
// if rpl.productCode.clone().ends_with("0090") {
// debug!(
// "MAT [{}]: {} --> {} = pow:{:?},sy:{:?}",
// rpl.productCode.clone(),
// header_idx,
// repl.materialPathId.clone(),
// repl.powderGram,
// repl.syrupGram
// );
// }
let mat_setting = latest_recipe let mat_setting = latest_recipe
.search_material_settings(current_material.to_string()); .search_material_settings(current_material.to_string());
if let Some(mat_s) = mat_setting { if let Some(mat_s) = mat_setting {
match mat_s.clone().get_definition_type(Some(prefix_cc.clone())) { match mat_s.clone().get_definition_type() {
recipe::MaterialType::Bean => { recipe::MaterialType::Bean => {
recipe_brewing_values_only[header_idx] += recipe_brewing_values_only[header_idx] +=
repl.powderGram.as_i64().unwrap(); repl.powderGram.as_i64().unwrap();
@ -496,10 +488,29 @@ pub fn generate_recipe_sheet_table(country_name: &str, into_version: usize) {
} }
} }
recipe::MaterialType::Syrup => { recipe::MaterialType::Syrup => {
// debug
// if rpl.productCode.clone().ends_with("0090") {
// println!(
// "SYRUP [{}]: {} --> {} = {:?}",
// rpl.productCode.clone(),
// header_idx,
// repl.materialPathId.clone(),
// repl.syrupGram
// );
// }
recipe_brewing_values_only[header_idx] += recipe_brewing_values_only[header_idx] +=
repl.syrupGram.as_i64().unwrap(); repl.syrupGram.as_i64().unwrap();
} }
recipe::MaterialType::Soda => { recipe::MaterialType::Soda => {
// println!(
// "SODA [{}]: {} --> {} = {:?}",
// rpl.productCode.clone(),
// header_idx,
// repl.materialPathId.clone(),
// repl.syrupGram
// );
recipe_brewing_values_only[header_idx] += recipe_brewing_values_only[header_idx] +=
repl.syrupGram.as_i64().unwrap(); repl.syrupGram.as_i64().unwrap();
} }
@ -539,7 +550,7 @@ pub fn generate_recipe_sheet_table(country_name: &str, into_version: usize) {
recipe_brewing_values_only[header_idx] += recipe_brewing_values_only[header_idx] +=
repl.waterYield.as_i64().unwrap(); repl.waterYield.as_i64().unwrap();
} }
_ => { recipe::MaterialType::Unknown => {
if rpl.productCode.clone().ends_with("0090") { if rpl.productCode.clone().ends_with("0090") {
println!( println!(
"UNK [{}]: {} --> {} = {:?}", "UNK [{}]: {} --> {} = {:?}",
@ -592,57 +603,36 @@ pub fn generate_recipe_sheet_table(country_name: &str, into_version: usize) {
/// - MaterialCode /// - MaterialCode
/// - Topping /// - Topping
/// ///
pub fn full_import_data(source: Recipe, mut import_target: Recipe) -> Recipe { pub fn full_import_data(source: Recipe, mut import_target: Recipe) {
let mut target_summary = import_target.get_recipe_data_summary();
// import menus // import menus
source.Recipe01.iter().for_each(|r01| { source.Recipe01.iter().for_each(|r01| {
if !target_summary.recipe01_contains(r01.clone().productCode) { if !import_target.Recipe01.contains(r01) {
import_target.Recipe01.push(r01.clone()); import_target.Recipe01.push(r01.clone());
println!(
"recipe >> {} {}",
r01.productCode,
r01.name.clone().unwrap_or("".to_string())
);
} }
}); });
// import materials // import materials
source.MaterialSetting.iter().for_each(|ms| { source.MaterialSetting.iter().for_each(|ms| {
if !target_summary.materialSetting_contains(ms.id.clone()) { if !import_target.MaterialSetting.contains(ms) {
import_target.MaterialSetting.push(ms.clone()); import_target.MaterialSetting.push(ms.clone());
println!(
"mat_set >> {:?} {}",
ms.id,
ms.materialName.clone().unwrap_or("".to_string())
);
} }
}); });
source.MaterialCode.iter().for_each(|mc| { source.MaterialCode.iter().for_each(|mc| {
if !target_summary.materialCode_contains(mc.materialID.clone()) { if !import_target.MaterialCode.contains(mc) {
import_target.MaterialCode.push(mc.clone()); import_target.MaterialCode.push(mc.clone());
println!("mat_code >> {:?}", mc.materialID);
} }
}); });
// import new toppings // import new toppings
source.Topping.ToppingList.iter().for_each(|tpl| { source.Topping.ToppingList.iter().for_each(|tpl| {
if !target_summary.toppingList_contains(tpl.id.clone()) { if !import_target.Topping.ToppingList.contains(tpl) {
import_target.Topping.ToppingList.push(tpl.clone()); import_target.Topping.ToppingList.push(tpl.clone());
println!(
"topping_list >> {:?} {}",
tpl.id,
tpl.name.clone().unwrap_or("".to_string())
);
} }
}); });
source.Topping.ToppingGroup.iter().for_each(|tg| { source.Topping.ToppingGroup.iter().for_each(|tg| {
if !target_summary.toppingGroup_contains(tg.groupID.clone()) { if !import_target.Topping.ToppingGroup.contains(tg) {
import_target.Topping.ToppingGroup.push(tg.clone()); import_target.Topping.ToppingGroup.push(tg.clone());
println!("topping_group >> {:?} {}", tg.groupID, tg.name);
} }
}); });
import_target
} }