メインコンテンツまでスキップ

12. Order サービス

client.order() でアクセスします。作業指示(Work Order)の 生成 → 開始 → 中断/再開 → 終了 までの全ライフサイクルを ISA-88 ベースのステートマシンで管理します。

11.1 作業指示の状態 (ISA-88 ベース)

CREATE → WAIT ──start()──► START ──pause()──► PAUSE
│ │
│ resume()
│ │
▼ ▼
END ◄──end()──── START

└─ (또는) ──abort()──► ABORTED
状態意味遷移メソッド
WAIT待機 (生成直後の初期状態)create() の結果
START進行中start(), resume()
PAUSE一時停止pause()
END正常完了end()
ABORTED異常終了abort()

状態遷移が不可能な呼び出し(例:すでに START 状態で start() を再呼び出し)に対しては、サーバーが OK + data.success=false 応答を返し、V5 メソッドは false を返します。

11.2 メソッド一覧

CRUD

メソッド戻り値の型HTTPエンドポイント
create(OrderRequestV5)OrderResponseV5 または nullPOST/api/v5/order
update(order_id, OrderRequestV5)OrderResponseV5 または nullPUT/api/v5/order/{id}
delete(order_id)booleanDELETE/api/v5/order/{id}
get(order_id)OrderResponseV5 または nullGET/api/v5/order/{id}
list()List<OrderResponseV5>GET/api/v5/order
exists(order_id)booleanGET/api/v5/order/{id}/exists

ライフサイクル (すべて boolean を返す)

メソッドHTTPエンドポイント
start(order_id)POST/api/v5/order/{id}/start
end(order_id)POST/api/v5/order/{id}/end
pause(order_id)POST/api/v5/order/{id}/pause
resume(order_id)POST/api/v5/order/{id}/resume
abort(order_id)POST/api/v5/order/{id}/abort

11.3 OrderRequestV5 / OrderResponseV5

フィールド説明
order_idString作業指示 ID (PK)
titleString作業タイトル
descriptionString説明
site_idString所属サイト
asset_idString対象アセット (Equipment)
customer_idString顧客 (任意)
product_idString生産する製品
employee_idString担当従業員 (任意)
target_unitslong目標数量
unitString単位 (EA、KG など)
time_per_unit_in_mslong単位当たり標準時間
fix_start_timestamplong計画開始時刻 (ミリ秒)
fix_end_timestamplong計画終了時刻 (ミリ秒)
external_order_idString外部システムの注文 ID
statusString(応答専用) 現在の状態

11.4 使用例

作業指示の生成

import plantpulse.api.v5.dto.request.OrderRequestV5;
import plantpulse.api.v5.dto.response.OrderResponseV5;

OrderRequestV5 req = new OrderRequestV5();
req.setOrder_id("ORD_20260514_001");
req.setTitle("5월 14일 1교대 생산");
req.setDescription("PROD_A001 500개 생산");
req.setSite_id("SITE_DJ");
req.setAsset_id("ASSET_DJ_M_0001");
req.setProduct_id("PROD_A001");
req.setCustomer_id("CUST_001");
req.setEmployee_id("EMP_E12345");
req.setTarget_units(500);
req.setUnit("EA");
req.setTime_per_unit_in_ms(5_000);

long now = System.currentTimeMillis();
req.setFix_start_timestamp(now);
req.setFix_end_timestamp(now + 4 * 3600_000L);
req.setExternal_order_id("MES-2026-0514-001");

OrderResponseV5 created = client.order().create(req);

標準ライフサイクル

String orderId = "ORD_20260514_001";

// WAIT → START
if (!client.order().start(orderId)) {
System.err.println("시작 실패 — fix_start_timestamp가 미래이거나 이미 진행중");
return;
}

// 잠시 후 — 일시중지
client.order().pause(orderId);

// 재개
client.order().resume(orderId);

// 정상 종료
client.order().end(orderId);

異常終了

// abort 는 별도 인자 없이 호출. 상세 사유는 update() 로 description/notes 에 기록.
if (!client.order().abort("ORD_20260514_001")) {
System.err.println("중단 실패");
}

単件照会 / 存在確認

OrderResponseV5 o = client.order().get("ORD_20260514_001");
if (o != null) {
System.out.println("상태: " + o.getStatus());
System.out.println("목표: " + o.getTarget_units() + " " + o.getUnit());
}

boolean exists = client.order().exists("ORD_20260514_001");

全件リスト

import java.util.List;

List<OrderResponseV5> all = client.order().list();
for (OrderResponseV5 o : all) {
System.out.printf("[%s] %s — %s%n",
o.getStatus(), o.getOrder_id(), o.getTitle());
}

進行中の作業指示のみ (クライアント側フィルタ)

import java.util.stream.Collectors;

List<OrderResponseV5> active = client.order().list().stream()
.filter(o -> "START".equals(o.getStatus())
|| "PAUSE".equals(o.getStatus()))
.collect(Collectors.toList());

アセット別の作業指示

String assetId = "ASSET_DJ_M_0001";
List<OrderResponseV5> assetOrders = client.order().list().stream()
.filter(o -> assetId.equals(o.getAsset_id()))
.collect(Collectors.toList());

状態別統計

import java.util.Map;

Map<String, Long> byStatus = client.order().list().stream()
.collect(Collectors.groupingBy(
OrderResponseV5::getStatus,
Collectors.counting()));

byStatus.forEach((status, count) ->
System.out.printf("%s: %d건%n", status, count));

修正 / 削除

// 수정 (계획 시간 연장)
OrderRequestV5 update = new OrderRequestV5();
update.setOrder_id("ORD_20260514_001");
update.setTitle("5월 14일 1교대 생산 (연장)");
// ... 모든 필드 다시 세팅 ...
update.setFix_end_timestamp(System.currentTimeMillis() + 8 * 3600_000L);
client.order().update("ORD_20260514_001", update);

// 삭제 (취소 처리)
client.order().delete("ORD_20260514_001");

11.5 活用シナリオ

シナリオ — MES 連携による作業指示の自動生成

import java.text.SimpleDateFormat;
import java.util.Date;

SimpleDateFormat df = new SimpleDateFormat("yyyyMMdd");
String today = df.format(new Date());

// 외부 MES 큐에서 받은 주문을 V5 Order로 변환
for (MesOrder mes : mesQueue) {
OrderRequestV5 req = new OrderRequestV5();
req.setOrder_id("ORD_" + today + "_" + String.format("%03d", mes.seq));
req.setSite_id("SITE_DJ");
req.setAsset_id(mes.equipId);
req.setProduct_id(mes.productId);
req.setTarget_units(mes.qty);
req.setExternal_order_id(mes.mesOrderId);
req.setFix_start_timestamp(mes.plannedStart);
req.setFix_end_timestamp(mes.plannedEnd);
client.order().create(req);
}

シナリオ — 安全な状態遷移ヘルパー

public static boolean safeStart(APIClient_V5 client, String orderId) {
OrderResponseV5 o = client.order().get(orderId);
if (o == null) {
log.warn("작업지시 없음: " + orderId);
return false;
}
if (!"WAIT".equals(o.getStatus())) {
log.warn("WAIT 상태가 아님: " + o.getStatus());
return false;
}
return client.order().start(orderId);
}

次のステップ