이것은 제가 첫 인턴십 동안 개발한 실제 애플리케이션입니다. 나는 모든 개발자에게 출발점을 제공하기 위해 여기에 넣었습니다. 아쉽게도 이 애플리케이션은 제가 근무하는 회사의 프라이빗 로컬 서비스를 이용하여 만든 애플리케이션이기 때문에 로컬에서 실행해 보면 실행이 되지 않습니다. 그럼에도 불구하고 이 코드가 누군가에게 유용하길 바랍니다.
유용한 코드의 대부분은 API 및 기타 항목에 연결하는 방법을 보여주는 LaborDB 파일(DB 폴더 내부)에 있습니다. 비밀번호 및 사용자 이름과 같은 주요 변수/상수 중 일부 민감한 값을 제거했다는 점을 명심하세요. 또한 이 도구는 INFOR VISUAL API와 관련이 없는 다른 데이터베이스에 연결했습니다.
API를 사용하는 데 필요한 DLL 목록은 다음과 같습니다.
사용된 구성 세트입니다. 이를 설정하려면 솔루션 탐색기(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에 연결하기 위해 OpenDirect 메소드를 호출하는 Dbms 클래스를 사용합니다. 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());
}
데이터 저장
이 솔루션에 데이터가 저장되는 경우는 새 티켓을 저장할 때와 기존 티켓에 대한 수정 사항을 저장할 때뿐입니다. Class LaborDB에는 데이터 저장과 관련된 총 3가지 메소드가 포함되어 있습니다.
직접 및 간접 티켓 저장
새 티켓을 저장하려면 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 클래스를 사용합니다. 프로세스는 새 티켓을 저장할 때와 유사합니다. 차이점은 티켓을 업데이트하려면 ID가 필요하다는 것입니다.
//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 클래스를 사용합니다. 티켓의 ID만 알려주시면 됩니다.
//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);