Это рабочее приложение, которое я разработал во время своей первой стажировки. Я помещаю это здесь, чтобы дать любому разработчику отправную точку. К сожалению, оно не запустится, если вы попробуете его локально, поскольку это приложение было создано с использованием частного локального сервиса на моем рабочем месте. Тем не менее, я надеюсь, что код кому-то пригодится.
Большая часть полезного кода находится в файле LaborDB — внутри папки DB — где показано, как подключаться к API и другие вещи. Имейте в виду, что я удалил некоторые конфиденциальные значения ключевых переменных/констант, такие как пароли и имена пользователей. Кроме того, этот инструмент осуществлял подключения к различным базам данных, не имеющим ничего общего с INFOR VISUAL API.
Это список необходимых DLL для использования API:
Это набор используемых конфигураций. Чтобы настроить это, выберите проект в обозревателе решений (Visual Studio), после чего должна появиться опция.
Прежде чем вносить какие-либо изменения в этот инструмент, необходимо изучить несколько понятий, чтобы лучше понять, как он работает.
###БИЛЕТЫ
Во-первых, записи, сделанные сотрудниками, называются билетами и бывают двух типов: косвенные и прямые.
Косвенный
Косвенные заявки не связаны с каким-либо РАБОЧИМ ЗАКАЗОМ. Если присмотреться к таблице LABOR_TICKET, то можно увидеть, что один столбец имеет решающее значение для определения того, является ли заявка косвенной или прямой: WORKORDER_BASE_ID. Это поле имеет значение NULL для каждого косвенного билета, а столбец INDIRECT_ID всегда является обязательным.
Прямой
Прямые заявки всегда имеют связанный с ними РАБОЧИЙ ЗАКАЗ. В этом случае столбцы WORKORDER_BASE_ID, WORKORDER_LOT_ID, WORKORDER_SPLIT_ID, WORKORDER_SUB_ID и OPERATION_SEQ_NO являются обязательными всегда.
Подключение к API
Для подключения к API мы используем класс Dbms, вызывая его метод OpenDirect. В процессе получения данных из базы данных SQL вам необходимо открыть, подготовить, выполнить и закрыть соединение.
//get the product
public static Model.WorkOrderModel getWorkOrderId(string baseId, string instance)
{
//open con to the api
conOpen();
Model.WorkOrderModel wo = new Model.WorkOrderModel();
string query = "Select BASE_ID, LOT_ID, SPLIT_ID, STATUS FROM VMFG.WORK_ORDER WHERE USER_9 LIKE '%,' + ? + ',%'";
GeneralQuery gen = null;
gen = new GeneralQuery(instName);
gen.Prepare("WORK_ORDER", query);
gen.Parameters[0] = baseId;
gen.Execute();
if (gen.Tables["WORK_ORDER"].Rows.Count > 0)
{
wo.baseId = gen.Tables["WORK_ORDER"].Rows[0]["BASE_ID"].ToString();
wo.lotId = gen.Tables["WORK_ORDER"].Rows[0]["LOT_ID"].ToString();
wo.splitId = gen.Tables["WORK_ORDER"].Rows[0]["SPLIT_ID"].ToString();
wo.status = gen.Tables["WORK_ORDER"].Rows[0]["STATUS"].ToString();
}
Dbms.Close(instName);
return wo;
}
Чтобы открыть соединение с API, вызовите функцию conOpen. Это вспомогательная функция.
public static void conOpen()
{
Dbms.OpenDirect(instName, provider, "", source, user, password);
}
Получение данных
Самый общий способ получить данные из базы данных с помощью API — использовать класс GeneralQuery.
GeneralQuery gen = new GeneralQuery(instName);
gen.Prepare("WORKORDER", "Select BASE_ID, SUB_ID, PART_ID FROM VMFG.WORK_ORDER WHERE BASE_ID = ?");
gen.Parameters[0] = baseId;
gen.Execute();
Чтение возвращенных записей
Данные, возвращаемые после вызова метода Execute(), сохраняются в том же объекте, который использовался для их запроса.
if (gen.Tables["WORKORDER"].Rows.Count > 0)
{
for (var i = 0; i <= gen.Tables["WORKORDER"].Rows.Count - 1; i++)
{
workOrders.Add(gen.Tables["WORKORDER"].Rows[i]["SUB_ID"].ToString() + " " + gen.Tables["WORKORDER"].Rows[i]["PART_ID"].ToString());
}
Dbms.Close(instName);
return workOrders;
}
Чтение возвращенных записей с помощью функций SQL
В тех случаях, когда запрос содержит функции SQL, способ доступа к возвращаемым данным меняется.
Model.DatePeriodModel dp = new Model.DatePeriodModel();
GeneralQuery gen = null;
gen = new GeneralQuery(instName);
gen.Prepare("ACCOUNT_PERIOD", "SELECT MIN(BEGIN_DATE) FROM VMFG.ACCOUNT_PERIOD WHERE STATUS = 'A' AND YEAR(BEGIN_DATE) = YEAR(GETDATE()) AND CALENDAR_ID = 'BACH'");
gen.Execute();
if (gen.Tables["ACCOUNT_PERIOD"].Rows.Count > 0)
{
dp.min = DateTime.Parse(gen.Tables["ACCOUNT_PERIOD"].Rows[0]["Column1"].ToString());
}
Сохранение данных
В этом решении данные сохраняются только в двух случаях: при сохранении новой заявки и при сохранении изменений в существующей заявке. Класс LaborDB всего содержит три метода, связанных с сохранением данных.
Сохранение ПРЯМЫХ И КОСВЕННЫХ билетов
Для сохранения нового билета мы используем класс LaborTicket, обратите внимание, что для него требуется экземпляр подключения к API. Как для непрямых, так и для прямых билетов процесс одинаков, и отличается только набором сохраняемой информации (см. информацию о БИЛЕТАХ выше).
//open con to the api
conOpen();
//new labor ticket
LaborTicket ticket = new LaborTicket(instName);
ticket.Prepare();
//preparing the data
DataRow dr = (DataRow)ticket.NewRunLaborRow(1);
dr["BASE_ID"] = baseId;
dr["LOT_ID"] = lotId;
dr["SPLIT_ID"] = splitId;
dr["SUB_ID"] = leg;
dr["SEQ_NO"] = Int32.Parse(opn);
dr["TRANSACTION_TYPE"] = "RUN";
dr["EMPLOYEE_ID"] = employeeId;
dr["HOURLY_COST"] = hourlyCost;
dr["HOURS_WORKED"] = hoursworked;
dr["MULTIPLIER_1"] = overtime.Equals("OT") ? 1.500 : 1.000;
dr["TRANSACTION_DATE"] = date;
dr["SHIFT_DATE"] = date;
dr["SITE_ID"] = "BACH";
//api method to save
try
{
ticket.Save();
}
catch (Exception ex)
{
Dbms.Close(instName);
}
Dbms.Close(instName);
Обновление ПРЯМЫХ и КОСВЕННЫХ билетов
Для обновления заявки мы используем класс EditLaborTicket. Процесс аналогичен сохранению нового билета. Разница в том, что для обновления билета требуется его идентификатор.
//open con to the api
conOpen();
//new edit labor ticket
EditLaborTicket editTicket = new EditLaborTicket(instName);
editTicket.Prepare();
//preparin the data
DataRow dr;
dr = (DataRow)editTicket.NewEditLaborRow(ticketId);
dr["SITE_ID"] = "BACH";
dr["INDIRECT_ID"] = indirectId;
dr["HOURS_WORKED"] = hoursWorked;
dr["MULTIPLIER_1"] = overtime.Equals("OT") ? 1.500 : 1.000;
//api method to save
try
{
editTicket.Save();
}
catch
{
Dbms.Close(instName);
}
Dbms.Close(instName);
Удаление ПРЯМЫХ и КОСВЕННЫХ билетов
Для удаления заявки мы используем класс DeleteLaborTicket. Вам нужно только сообщить идентификатор билета.
//open con to the api
conOpen();
//new delete labor ticket
DeleteLaborTicket deleteTicket = new DeleteLaborTicket(instName);
deleteTicket.Prepare();
//preparing the data
DataRow dr;
dr = (DataRow)deleteTicket.NewDeleteLaborRow(ticketId);
//api method to delete
try
{
deleteTicket.Save();
}
catch
{
Dbms.Close(instName);
}
Dbms.Close(instName);