Zum Hauptinhalt springen

12. Order-Dienst

Der Zugriff erfolgt über client.order(). Der gesamte Lebenszyklus eines Arbeitsauftrags (Work Order) — Erstellen → Starten → Unterbrechen/Fortsetzen → Beenden — wird über eine Zustandsmaschine auf Basis von ISA-88 verwaltet.

11.1 Arbeitsauftragsstatus (auf Basis von ISA-88)

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

└─ (또는) ──abort()──► ABORTED
StatusBedeutungÜbergangsmethode
WAITWartend (Initialzustand direkt nach der Erstellung)Ergebnis von create()
STARTIn Bearbeitungstart(), resume()
PAUSEPausiertpause()
ENDRegulär abgeschlossenend()
ABORTEDAbbruch (nicht regulär beendet)abort()

Bei Aufrufen, für die kein Statusübergang möglich ist (z. B. erneuter Aufruf von start() im bereits bestehenden Status START), antwortet der Server mit OK + data.success=false, und die V5-Methode gibt false zurück.

11.2 Methodenübersicht

CRUD

MethodeRückgabetypHTTPEndpunkt
create(OrderRequestV5)OrderResponseV5 oder nullPOST/api/v5/order
update(order_id, OrderRequestV5)OrderResponseV5 oder nullPUT/api/v5/order/{id}
delete(order_id)booleanDELETE/api/v5/order/{id}
get(order_id)OrderResponseV5 oder nullGET/api/v5/order/{id}
list()List<OrderResponseV5>GET/api/v5/order
exists(order_id)booleanGET/api/v5/order/{id}/exists

Lebenszyklus (alle geben boolean zurück)

MethodeHTTPEndpunkt
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

FeldTypBeschreibung
order_idStringArbeitsauftrags-ID (PK)
titleStringAuftragstitel
descriptionStringBeschreibung
site_idStringZugehöriger Standort
asset_idStringZiel-Asset (Equipment)
customer_idStringKunde (optional)
product_idStringZu fertigendes Produkt
employee_idStringZuständiger Mitarbeiter (optional)
target_unitslongSollmenge
unitStringEinheit (EA, KG usw.)
time_per_unit_in_mslongStandardzeit pro Einheit
fix_start_timestamplongGeplanter Startzeitpunkt (Millisekunden)
fix_end_timestamplongGeplanter Endzeitpunkt (Millisekunden)
external_order_idStringAuftrags-ID des externen Systems
statusString(nur Antwort) Aktueller Status

11.4 Anwendungsbeispiele

Arbeitsauftrag erstellen

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);

Standard-Lebenszyklus

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);

Abbruch

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

Einzelabfrage / Existenzprüfung

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");

Gesamtliste

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());
}

Nur laufende Arbeitsaufträge (clientseitiger Filter)

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());

Arbeitsaufträge je Asset

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

Statistik nach Status

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));

Ändern / Löschen

// 수정 (계획 시간 연장)
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 Anwendungsszenarien

Szenario — Automatische Erstellung von Arbeitsaufträgen bei MES-Anbindung

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);
}

Szenario — Helper für sichere Statusübergänge

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);
}

Nächste Schritte