- Modified SelectRecipe to use PUB.SelectModelV for actual recipe activation - Added system state check (cannot change model while running/waiting) - Recipe selection now performs complete process: - Loads model data into PUB.Result.vModel - Saves to SETTING.User.LastModelV - Loads barcode patterns (BCDPattern, BCDIgnorePattern) - Updates customer code from model - Clears saved barcode data - Updates barcode configuration - Sets ZPL filename for custom ZPL models - Returns full recipe data after successful selection - Follows Model_Operation.cs toolStripButton10_Click pattern 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
710 lines
26 KiB
C#
710 lines
26 KiB
C#
using System;
|
||
using System.Runtime.InteropServices;
|
||
using System.Windows.Forms;
|
||
using Newtonsoft.Json;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Collections.Generic;
|
||
using AR;
|
||
|
||
namespace Project.WebUI
|
||
{
|
||
// Important: Allows JavaScript to see this class
|
||
[ClassInterface(ClassInterfaceType.AutoDual)]
|
||
[ComVisible(true)]
|
||
public class MachineBridge
|
||
{
|
||
// Reference to the main form to update logic
|
||
private Project.Dialog.fWebView _host;
|
||
|
||
// Data folder paths
|
||
private readonly string _dataFolder;
|
||
private readonly string _settingsPath;
|
||
private readonly string _recipeFolder;
|
||
|
||
public MachineBridge(Project.Dialog.fWebView host)
|
||
{
|
||
_host = host;
|
||
|
||
// Initialize data folder paths - use existing Data folder
|
||
_dataFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Data");
|
||
_settingsPath = Path.Combine(_dataFolder, "Setting.json");
|
||
_recipeFolder = Path.Combine(_dataFolder, "recipe");
|
||
|
||
// Ensure folders exist
|
||
EnsureDataFoldersExist();
|
||
}
|
||
|
||
private void EnsureDataFoldersExist()
|
||
{
|
||
try
|
||
{
|
||
if (!Directory.Exists(_dataFolder))
|
||
Directory.CreateDirectory(_dataFolder);
|
||
|
||
if (!Directory.Exists(_recipeFolder))
|
||
Directory.CreateDirectory(_recipeFolder);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to create data folders: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
// --- Methods called from React ---
|
||
|
||
public void MoveAxis(string axis, double value)
|
||
{
|
||
Console.WriteLine($"[C#] Moving {axis} to {value}");
|
||
_host.SetTargetPosition(axis, value);
|
||
}
|
||
|
||
public void SetIO(int id, bool isInput, bool state)
|
||
{
|
||
Console.WriteLine($"[C#] Set IO {id} to {state}");
|
||
_host.SetOutput(id, state);
|
||
}
|
||
|
||
public void SystemControl(string command)
|
||
{
|
||
Console.WriteLine($"[C#] CMD: {command}");
|
||
_host.HandleCommand(command);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 마이그레이션완료
|
||
/// </summary>
|
||
/// <param name="recipeTitle"></param>
|
||
/// <returns></returns>
|
||
public string SelectRecipe(string recipeTitle)
|
||
{
|
||
Console.WriteLine($"[C#] Selecting Recipe: {recipeTitle}");
|
||
|
||
try
|
||
{
|
||
// Check if system is running
|
||
if (PUB.sm.Step == eSMStep.RUN || PUB.sm.Step == eSMStep.WAITSTART || PUB.sm.Step == eSMStep.PAUSE)
|
||
{
|
||
var response = new { success = false, message = "Cannot change model while system is currently running (waiting)" };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
|
||
// Select model using PUB.SelectModelV
|
||
bool result = AR.PUB.SelectModelV(recipeTitle, true);
|
||
|
||
if (result)
|
||
{
|
||
Console.WriteLine($"[INFO] Recipe {recipeTitle} selected successfully");
|
||
|
||
// Get the selected model data
|
||
var dr = PUB.mdm.GetDataV(recipeTitle);
|
||
if (dr == null)
|
||
{
|
||
var response = new { success = false, message = "Recipe data not found" };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
|
||
// Convert DataRow to Dictionary
|
||
var recipeData = new Dictionary<string, object>();
|
||
foreach (System.Data.DataColumn col in dr.Table.Columns)
|
||
{
|
||
string colName = col.ColumnName;
|
||
object value = dr[colName];
|
||
|
||
// DBNull을 null로 변환
|
||
if (value == DBNull.Value)
|
||
value = null;
|
||
|
||
recipeData[colName] = value;
|
||
}
|
||
|
||
var response2 = new { success = true, message = "Recipe selected successfully", recipeId = recipeTitle, recipe = recipeData };
|
||
return JsonConvert.SerializeObject(response2);
|
||
}
|
||
else
|
||
{
|
||
var response = new { success = false, message = "Failed to select recipe" };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to select recipe: {ex.Message}");
|
||
var response = new { success = false, message = ex.Message };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// <20><><EFBFBD>̱<CCB1><D7B7>̼<EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string GetConfig()
|
||
{
|
||
try
|
||
{
|
||
// Use SETTING.Data (CommonSetting) from the project
|
||
if (AR.SETTING.Data == null)
|
||
{
|
||
Console.WriteLine($"[WARN] SETTING.Data is not initialized");
|
||
return "[]";
|
||
}
|
||
|
||
var settingsArray = new List<object>();
|
||
var properties = AR.SETTING.Data.GetType().GetProperties();
|
||
|
||
foreach (var prop in properties)
|
||
{
|
||
// Skip non-browsable properties
|
||
var browsable = prop.GetCustomAttributes(typeof(System.ComponentModel.BrowsableAttribute), false)
|
||
.FirstOrDefault() as System.ComponentModel.BrowsableAttribute;
|
||
if (browsable != null && !browsable.Browsable)
|
||
continue;
|
||
|
||
// Skip filename property
|
||
if (prop.Name == "filename")
|
||
continue;
|
||
|
||
// Get property info
|
||
string key = prop.Name;
|
||
object value = prop.GetValue(AR.SETTING.Data, null);
|
||
string type = "String";
|
||
string group = "General";
|
||
string description = key.Replace("_", " ");
|
||
|
||
// Get Category attribute
|
||
var categoryAttr = prop.GetCustomAttributes(typeof(System.ComponentModel.CategoryAttribute), false)
|
||
.FirstOrDefault() as System.ComponentModel.CategoryAttribute;
|
||
if (categoryAttr != null)
|
||
group = categoryAttr.Category;
|
||
|
||
// Get DisplayName attribute
|
||
var displayNameAttr = prop.GetCustomAttributes(typeof(System.ComponentModel.DisplayNameAttribute), false)
|
||
.FirstOrDefault() as System.ComponentModel.DisplayNameAttribute;
|
||
if (displayNameAttr != null)
|
||
description = displayNameAttr.DisplayName;
|
||
|
||
// Get Description attribute
|
||
var descAttr = prop.GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false)
|
||
.FirstOrDefault() as System.ComponentModel.DescriptionAttribute;
|
||
if (descAttr != null)
|
||
description = descAttr.Description;
|
||
|
||
// Determine type based on property type
|
||
if (prop.PropertyType == typeof(bool))
|
||
{
|
||
type = "Boolean";
|
||
value = value?.ToString().ToLower() ?? "false";
|
||
}
|
||
else if (prop.PropertyType == typeof(int) || prop.PropertyType == typeof(long) ||
|
||
prop.PropertyType == typeof(double) || prop.PropertyType == typeof(float))
|
||
{
|
||
type = "Number";
|
||
value = value?.ToString() ?? "0";
|
||
}
|
||
else
|
||
{
|
||
value = value?.ToString() ?? "";
|
||
}
|
||
|
||
settingsArray.Add(new
|
||
{
|
||
Key = key,
|
||
Value = value,
|
||
Group = group,
|
||
Type = type,
|
||
Description = description
|
||
});
|
||
}
|
||
|
||
Console.WriteLine($"[INFO] Loaded {settingsArray.Count} settings from SETTING.Data");
|
||
return JsonConvert.SerializeObject(settingsArray);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to load settings: {ex.Message}");
|
||
return "[]";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// <20><><EFBFBD>̱<CCB1><D7B7>̼Ǽ<CCBC><C7BC><EFBFBD>
|
||
/// </summary>
|
||
/// <param name="configJson"></param>
|
||
public void SaveConfig(string configJson)
|
||
{
|
||
try
|
||
{
|
||
Console.WriteLine($"[Backend] SAVE CONFIG REQUEST RECEIVED");
|
||
|
||
// Parse array format from React
|
||
var settingsArray = JsonConvert.DeserializeObject<List<Dictionary<string, object>>>(configJson);
|
||
|
||
// Update SETTING.Data properties
|
||
var properties = AR.SETTING.Data.GetType().GetProperties();
|
||
|
||
foreach (var item in settingsArray)
|
||
{
|
||
string key = item["Key"].ToString();
|
||
string value = item["Value"].ToString();
|
||
string type = item["Type"].ToString();
|
||
|
||
var prop = properties.FirstOrDefault(p => p.Name == key);
|
||
if (prop == null || !prop.CanWrite)
|
||
continue;
|
||
|
||
// Convert value based on type
|
||
try
|
||
{
|
||
if (type == "Boolean")
|
||
{
|
||
prop.SetValue(AR.SETTING.Data, bool.Parse(value), null);
|
||
}
|
||
else if (type == "Number")
|
||
{
|
||
if (prop.PropertyType == typeof(int))
|
||
prop.SetValue(AR.SETTING.Data, int.Parse(value), null);
|
||
else if (prop.PropertyType == typeof(long))
|
||
prop.SetValue(AR.SETTING.Data, long.Parse(value), null);
|
||
else if (prop.PropertyType == typeof(double))
|
||
prop.SetValue(AR.SETTING.Data, double.Parse(value), null);
|
||
else if (prop.PropertyType == typeof(float))
|
||
prop.SetValue(AR.SETTING.Data, float.Parse(value), null);
|
||
}
|
||
else
|
||
{
|
||
prop.SetValue(AR.SETTING.Data, value, null);
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[WARN] Failed to set property {key}: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
// Save to file
|
||
AR.SETTING.Data.Save();
|
||
|
||
Console.WriteLine($"[INFO] Settings saved successfully");
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to save settings: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 마이그레이션완료
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string GetIOList()
|
||
{
|
||
try
|
||
{
|
||
var result = new
|
||
{
|
||
inputs = GetDigitalInputs(),
|
||
outputs = GetDigitalOutputs(),
|
||
interlocks = GetInterlocks()
|
||
};
|
||
|
||
return JsonConvert.SerializeObject(result);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to get IO list: {ex.Message}");
|
||
return JsonConvert.SerializeObject(new { inputs = new List<object>(), outputs = new List<object>(), interlocks = new List<object>() });
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 마이그레이션완료
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private List<object> GetDigitalInputs()
|
||
{
|
||
var inputs = new List<object>();
|
||
|
||
try
|
||
{
|
||
var diNames = DIO.Pin.GetDIName;
|
||
var diPinNames = DIO.Pin.GetDIPinName;
|
||
int diCount = PUB.dio.GetDICount;
|
||
|
||
for (int i = 0; i < diCount; i++)
|
||
{
|
||
bool state = PUB.dio.GetDIValue(i);
|
||
string name = i < diNames.Length ? diNames[i] : $"DIN_{i:D2}";
|
||
string pinName = i < diPinNames.Length ? diPinNames[i] : $"X{i:D2}";
|
||
|
||
inputs.Add(new
|
||
{
|
||
id = i,
|
||
name = name,
|
||
pinName = pinName,
|
||
type = "input",
|
||
state = state
|
||
});
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to get digital inputs: {ex.Message}");
|
||
}
|
||
|
||
return inputs;
|
||
}
|
||
/// <summary>
|
||
/// 마이그레이션완료
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private List<object> GetDigitalOutputs()
|
||
{
|
||
var outputs = new List<object>();
|
||
|
||
try
|
||
{
|
||
var doNames = DIO.Pin.GetDOName;
|
||
var doPinNames = DIO.Pin.GetDOPinName;
|
||
int doCount = PUB.dio.GetDOCount;
|
||
|
||
for (int i = 0; i < doCount; i++)
|
||
{
|
||
bool state = PUB.dio.GetDOValue(i);
|
||
string name = i < doNames.Length ? doNames[i] : $"DOUT_{i:D2}";
|
||
string pinName = i < doPinNames.Length ? doPinNames[i] : $"Y{i:D2}";
|
||
|
||
outputs.Add(new
|
||
{
|
||
id = i,
|
||
name = name,
|
||
pinName = pinName,
|
||
type = "output",
|
||
state = state
|
||
});
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to get digital outputs: {ex.Message}");
|
||
}
|
||
|
||
return outputs;
|
||
}
|
||
/// <summary>
|
||
/// 마이그레이션완료
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
private List<object> GetInterlocks()
|
||
{
|
||
var interlocks = new List<object>();
|
||
|
||
try
|
||
{
|
||
for (int i = 0; i < PUB.iLock.Length; i++)
|
||
{
|
||
var axisName = ((AR.eAxis)i).ToString();
|
||
var nonAxis = false;
|
||
|
||
// Check if this is a non-axis interlock (i >= 7)
|
||
if (i >= 7)
|
||
{
|
||
axisName = PUB.iLock[i].Tag.ToString();
|
||
nonAxis = true;
|
||
}
|
||
|
||
// Get enum names based on axis index
|
||
string[] ilockNames;
|
||
if (i == 7) ilockNames = Enum.GetNames(typeof(eILockPRL));
|
||
else if (i == 8) ilockNames = Enum.GetNames(typeof(eILockPRR));
|
||
else if (i == 9) ilockNames = Enum.GetNames(typeof(eILockVS0));
|
||
else if (i == 10) ilockNames = Enum.GetNames(typeof(eILockVS1));
|
||
else if (i == 11) ilockNames = Enum.GetNames(typeof(eILockVS2));
|
||
else if (i == 12 || i == 13) ilockNames = Enum.GetNames(typeof(eILockCV));
|
||
else ilockNames = Enum.GetNames(typeof(eILock));
|
||
|
||
// Get interlock values (up to 64 bits)
|
||
var lockValues = new List<object>();
|
||
for (int j = 0; j < ilockNames.Length && j < 64; j++)
|
||
{
|
||
bool state = PUB.iLock[i].get(j);
|
||
lockValues.Add(new
|
||
{
|
||
id = j,
|
||
name = ilockNames[j],
|
||
state = state
|
||
});
|
||
}
|
||
|
||
interlocks.Add(new
|
||
{
|
||
axisIndex = i,
|
||
axisName = axisName,
|
||
nonAxis = nonAxis,
|
||
locks = lockValues,
|
||
hexValue = PUB.iLock[i].Value().HexString()
|
||
});
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to get interlocks: {ex.Message}");
|
||
}
|
||
|
||
return interlocks;
|
||
}
|
||
|
||
|
||
/// <summary>
|
||
/// 마이그레이션완료
|
||
/// </summary>
|
||
/// <returns></returns>
|
||
public string GetRecipeList()
|
||
{
|
||
//PUB.mdm.dataSet.OPModel에 등록된 데이터가 모델 목록이다
|
||
|
||
try
|
||
{
|
||
var recipes = new List<object>();
|
||
|
||
if (PUB.mdm == null || PUB.mdm.dataSet == null || PUB.mdm.dataSet.OPModel == null)
|
||
{
|
||
Console.WriteLine($"[WARN] OPModel is not initialized");
|
||
return JsonConvert.SerializeObject(recipes);
|
||
}
|
||
|
||
// OPModel 테이블에서 Title이 비어있지 않은 항목만 가져오기
|
||
foreach (var row in PUB.mdm.dataSet.OPModel)
|
||
{
|
||
var modelRow = row as DataSet1.OPModelRow;
|
||
if (modelRow == null) continue;
|
||
|
||
// Title이 비어있으면 스킵
|
||
if (string.IsNullOrEmpty(modelRow.Title))
|
||
continue;
|
||
|
||
recipes.Add(new
|
||
{
|
||
id = modelRow.idx.ToString(),
|
||
name = modelRow.Title,
|
||
lastModified = DateTime.Now.ToString("yyyy-MM-dd")
|
||
});
|
||
}
|
||
|
||
Console.WriteLine($"[INFO] Loaded {recipes.Count} recipes from OPModel");
|
||
return JsonConvert.SerializeObject(recipes);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to get recipe list: {ex.Message}");
|
||
return "[]";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 마이그레이션완료
|
||
/// </summary>
|
||
/// <param name="recipeTitle"></param>
|
||
/// <returns></returns>
|
||
public string GetRecipe(string recipeTitle)
|
||
{
|
||
try
|
||
{
|
||
var dr = PUB.mdm.GetDataV(recipeTitle);
|
||
|
||
if (dr == null)
|
||
{
|
||
var response = new { success = false, message = "Recipe not found" };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
|
||
// DataRow의 모든 컬럼을 Dictionary로 변환
|
||
var recipeData = new Dictionary<string, object>();
|
||
foreach (System.Data.DataColumn col in dr.Table.Columns)
|
||
{
|
||
string colName = col.ColumnName;
|
||
object value = dr[colName];
|
||
|
||
// DBNull을 null로 변환
|
||
if (value == DBNull.Value)
|
||
value = null;
|
||
|
||
recipeData[colName] = value;
|
||
}
|
||
|
||
Console.WriteLine($"[INFO] Loaded recipe {recipeTitle}");
|
||
return JsonConvert.SerializeObject(recipeData);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to get recipe {recipeTitle}: {ex.Message}");
|
||
var response = new { success = false, message = ex.Message };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 마이그레이션완료
|
||
/// </summary>
|
||
/// <param name="recipeTitle"></param>
|
||
/// <param name="recipeData"></param>
|
||
/// <returns></returns>
|
||
public string SaveRecipe(string recipeTitle, string recipeData)
|
||
{
|
||
try
|
||
{
|
||
var dr = PUB.mdm.GetDataV(recipeTitle);
|
||
|
||
if (dr == null)
|
||
{
|
||
var response = new { success = false, message = "Recipe not found" };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
|
||
// JSON 데이터를 Dictionary로 변환
|
||
var recipeDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(recipeData);
|
||
|
||
// DataRow의 각 컬럼 업데이트
|
||
foreach (var kvp in recipeDict)
|
||
{
|
||
string colName = kvp.Key;
|
||
|
||
// 컬럼이 테이블에 존재하는지 확인
|
||
if (!dr.Table.Columns.Contains(colName))
|
||
continue;
|
||
|
||
// idx나 Midx 같은 자동 생성 컬럼은 스킵
|
||
if (colName == "idx" || colName == "Midx")
|
||
continue;
|
||
|
||
try
|
||
{
|
||
var col = dr.Table.Columns[colName];
|
||
object value = kvp.Value;
|
||
|
||
// null 처리
|
||
if (value == null)
|
||
{
|
||
dr[colName] = DBNull.Value;
|
||
}
|
||
else
|
||
{
|
||
// 타입 변환
|
||
if (col.DataType == typeof(bool))
|
||
dr[colName] = Convert.ToBoolean(value);
|
||
else if (col.DataType == typeof(int))
|
||
dr[colName] = Convert.ToInt32(value);
|
||
else if (col.DataType == typeof(double))
|
||
dr[colName] = Convert.ToDouble(value);
|
||
else if (col.DataType == typeof(float))
|
||
dr[colName] = Convert.ToSingle(value);
|
||
else
|
||
dr[colName] = value.ToString();
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[WARN] Failed to set column {colName}: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
// 변경사항 저장
|
||
PUB.mdm.dataSet.OPModel.AcceptChanges();
|
||
PUB.mdm.SaveModelV();
|
||
|
||
Console.WriteLine($"[INFO] Recipe {recipeTitle} saved successfully to OPModel");
|
||
|
||
var response2 = new { success = true, message = "Recipe saved successfully", recipeId = recipeTitle };
|
||
return JsonConvert.SerializeObject(response2);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to save recipe {recipeTitle}: {ex.Message}");
|
||
var response = new { success = false, message = ex.Message };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
}
|
||
|
||
public string CopyRecipe(string recipeId, string newName)
|
||
{
|
||
Console.WriteLine($"[C#] Copying Recipe: {recipeId} as {newName}");
|
||
|
||
try
|
||
{
|
||
string sourcePath = Path.Combine(_recipeFolder, $"{recipeId}.json");
|
||
|
||
if (!File.Exists(sourcePath))
|
||
{
|
||
var response = new { success = false, message = "Source recipe not found" };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
|
||
string newId = Guid.NewGuid().ToString().Substring(0, 8);
|
||
string destPath = Path.Combine(_recipeFolder, $"{newId}.json");
|
||
|
||
string json = File.ReadAllText(sourcePath);
|
||
var recipeData = JsonConvert.DeserializeObject<dynamic>(json);
|
||
|
||
recipeData.name = newName;
|
||
|
||
File.WriteAllText(destPath, JsonConvert.SerializeObject(recipeData, Formatting.Indented));
|
||
|
||
string timestamp = DateTime.Now.ToString("yyyy-MM-dd");
|
||
|
||
Console.WriteLine($"[INFO] Recipe copied from {recipeId} to {newId}");
|
||
|
||
var response2 = new {
|
||
success = true,
|
||
message = "Recipe copied successfully",
|
||
newRecipe = new {
|
||
id = newId,
|
||
name = newName,
|
||
lastModified = timestamp
|
||
}
|
||
};
|
||
return JsonConvert.SerializeObject(response2);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to copy recipe: {ex.Message}");
|
||
var response = new { success = false, message = ex.Message };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
}
|
||
|
||
public string DeleteRecipe(string recipeId)
|
||
{
|
||
Console.WriteLine($"[C#] Deleting Recipe: {recipeId}");
|
||
|
||
try
|
||
{
|
||
if (recipeId == _host.GetCurrentRecipe())
|
||
{
|
||
var response1 = new { success = false, message = "Cannot delete currently selected recipe" };
|
||
return JsonConvert.SerializeObject(response1);
|
||
}
|
||
|
||
string recipePath = Path.Combine(_recipeFolder, $"{recipeId}.json");
|
||
|
||
if (!File.Exists(recipePath))
|
||
{
|
||
var response = new { success = false, message = "Recipe not found" };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
|
||
File.Delete(recipePath);
|
||
|
||
Console.WriteLine($"[INFO] Recipe {recipeId} deleted successfully");
|
||
|
||
var response2 = new { success = true, message = "Recipe deleted successfully", recipeId = recipeId };
|
||
return JsonConvert.SerializeObject(response2);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
Console.WriteLine($"[ERROR] Failed to delete recipe: {ex.Message}");
|
||
var response = new { success = false, message = ex.Message };
|
||
return JsonConvert.SerializeObject(response);
|
||
}
|
||
}
|
||
}
|
||
}
|