93 lines
3.4 KiB
Java
93 lines
3.4 KiB
Java
package com.zioinfo.mes.plan;
|
|
|
|
import com.zioinfo.mes.admin.AuditService;
|
|
import com.zioinfo.mes.ai.AiService;
|
|
import com.zioinfo.mes.common.ApiResponse;
|
|
import com.zioinfo.mes.common.AuthSupport;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.security.core.Authentication;
|
|
import org.springframework.web.bind.annotation.*;
|
|
|
|
import java.time.LocalDate;
|
|
import java.time.format.DateTimeFormatter;
|
|
import java.util.List;
|
|
import java.util.Map;
|
|
|
|
/**
|
|
* 생산계획 API + AI 일정 최적화. 조회 Viewer+, 변경 Manager+.
|
|
*/
|
|
@RestController
|
|
@RequestMapping("/api/mes/plans")
|
|
@RequiredArgsConstructor
|
|
public class PlanController {
|
|
|
|
private final PlanMapper mapper;
|
|
private final AuditService audit;
|
|
private final AiService ai;
|
|
|
|
@GetMapping
|
|
public ApiResponse<List<MesPlan>> list(@RequestParam(required = false) String status,
|
|
@RequestParam(required = false) String itemCode) {
|
|
return ApiResponse.ok(mapper.findAll(status, itemCode));
|
|
}
|
|
|
|
@GetMapping("/{id}")
|
|
public ApiResponse<MesPlan> get(@PathVariable Long id) {
|
|
return ApiResponse.ok(require(id));
|
|
}
|
|
|
|
@PostMapping
|
|
public ApiResponse<MesPlan> create(@RequestBody MesPlan p, Authentication auth) {
|
|
AuthSupport.requireManager(auth);
|
|
if (p.getItemCode() == null) throw new IllegalArgumentException("ERR-PLAN-400: itemCode 필수");
|
|
if (p.getPlanNo() == null || p.getPlanNo().isBlank())
|
|
p.setPlanNo("PLAN-" + LocalDate.now().format(DateTimeFormatter.BASIC_ISO_DATE) + "-" + (System.currentTimeMillis() % 100000));
|
|
if (p.getStatus() == null) p.setStatus("PLANNED");
|
|
p.setCreatedBy(AuthSupport.actor(auth));
|
|
mapper.insert(p);
|
|
audit.log("PLAN_CREATE", p.getPlanNo(), "item=" + p.getItemCode());
|
|
return ApiResponse.ok(mapper.findById(p.getId()));
|
|
}
|
|
|
|
@PutMapping("/{id}")
|
|
public ApiResponse<MesPlan> update(@PathVariable Long id, @RequestBody MesPlan p, Authentication auth) {
|
|
AuthSupport.requireManager(auth);
|
|
require(id);
|
|
p.setId(id);
|
|
mapper.update(p);
|
|
audit.log("PLAN_UPDATE", p.getPlanNo(), "id=" + id);
|
|
return ApiResponse.ok(mapper.findById(id));
|
|
}
|
|
|
|
@PutMapping("/{id}/status")
|
|
public ApiResponse<MesPlan> status(@PathVariable Long id, @RequestBody StatusRequest req, Authentication auth) {
|
|
AuthSupport.requireManager(auth);
|
|
MesPlan cur = require(id);
|
|
mapper.updateStatus(id, req.status());
|
|
audit.log("PLAN_STATUS", cur.getPlanNo(), cur.getStatus() + " -> " + req.status());
|
|
return ApiResponse.ok(mapper.findById(id));
|
|
}
|
|
|
|
/** AI 일정 최적화 — 납기/셋업 기준 순서 제안. */
|
|
@PostMapping("/optimize")
|
|
public ApiResponse<List<Map<String, Object>>> optimize(@RequestBody List<Map<String, Object>> orders) {
|
|
return ApiResponse.ok(ai.scheduleOptimize(orders));
|
|
}
|
|
|
|
@DeleteMapping("/{id}")
|
|
public ApiResponse<Void> delete(@PathVariable Long id, Authentication auth) {
|
|
AuthSupport.requireManager(auth);
|
|
mapper.delete(id);
|
|
audit.log("PLAN_DELETE", String.valueOf(id), "");
|
|
return ApiResponse.ok(null);
|
|
}
|
|
|
|
private MesPlan require(Long id) {
|
|
MesPlan p = mapper.findById(id);
|
|
if (p == null) throw new RuntimeException("ERR-PLAN-404: 생산계획 없음");
|
|
return p;
|
|
}
|
|
|
|
record StatusRequest(String status) {}
|
|
}
|