package com.dreamworks.boditech.service; import com.dreamworks.boditech.driver.task.Task; import com.dreamworks.boditech.driver.task.TaskTestEmergency; import com.dreamworks.boditech.driver.task.TaskTestRegular; import com.dreamworks.boditech.driver.task.TaskTestTubeRackPrepare; import com.dreamworks.boditech.entity.*; import com.dreamworks.boditech.entity.parameter.ParamEmergencyTaskSave; import com.dreamworks.boditech.entity.parameter.ParamTestSearch; import com.dreamworks.boditech.entity.parameter.ParamTestTubeRackTaskSave; import com.dreamworks.boditech.entity.parameter.ParamTestTubeRackTaskSaveTube; import com.dreamworks.boditech.mapper.*; import com.dreamworks.boditech.utils.MyCommon; import jakarta.annotation.Resource; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Calendar; import java.util.List; @Service public class TestService { @Resource private TestMapper testMapper; @Resource private TestStepMapper testStepMapper; @Resource private TestTubeRackTestTaskMapper testTubeRackTestTaskMapper; @Resource private TestTubeRackTestTaskTubeMapper testTubeRackTestTaskTubeMapper; @Resource private EmergencyTestTaskMapper emergencyTestTaskMapper; @Resource @Lazy private AccountService accountService; @Resource private ActionLogService actionLog; @Resource @Lazy private DeviceService deviceService; // fetch task from database public List fetchTask() { // find emergency task first // MdbEmergencyTestTask test = this.emergencyTestTaskMapper.findExecutableTask(); // if ( null != test ) { // List projectIds = (List)MyCommon.jsonToObject(test.projectIds, List.class); // List tasks = new ArrayList<>(); // for (Integer projectId : projectIds) { // TaskTestEmergency task = new TaskTestEmergency(); // task.setMdbEmergencyTestTask(test); // task.setProjectId(projectId); // tasks.add(task); // } // return tasks; // } // find test tube rack task MdbTestTubeRackTestTask rack = this.testTubeRackTestTaskMapper.findExecutableTask(); if ( null != rack ) { List tasks = new ArrayList<>(); TaskTestTubeRackPrepare prepare = new TaskTestTubeRackPrepare(); prepare.setTestService(this); prepare.setMdbTestTubeRackTestTask(rack); tasks.add(prepare); return tasks; } return new ArrayList<>(); } // test tube rack task save public MdbTestTubeRackTestTask testTubeRackTaskSave(ParamTestTubeRackTaskSave param) { if ( null == param.id ) { return this.testTubeRackTaskSaveInsert(param); } else { return this.testTubeRackTaskSaveUpdate(param); } } // test tube rack task save insert private MdbTestTubeRackTestTask testTubeRackTaskSaveInsert (ParamTestTubeRackTaskSave param) { this.actionLog.log("test-tube-rack-task.insert", param.tubeType); MdbTestTubeRackTestTask task = new MdbTestTubeRackTestTask(); task.status = "CONFIGURING"; task.editable = true; task.createdAt = System.currentTimeMillis(); task.createdBy = this.accountService.getCurrentAccountId(); task.tubeTypeDetectType = param.tubeTypeDetectType; task.tubeType = param.tubeType; this.testTubeRackTestTaskMapper.insert(task); this.testTubeRackTaskSaveUpdateTubes(task, param); return task; } // test tube rack task save update private MdbTestTubeRackTestTask testTubeRackTaskSaveUpdate (ParamTestTubeRackTaskSave param) { this.actionLog.log("test-tube-rack-task.update", param.tubeType); MdbTestTubeRackTestTask task = this.testTubeRackTestTaskMapper.findById(param.id); if ( null == task ) { throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_FOUND"); } if ( !task.editable ) { throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_EDITABLE"); } task.tubeTypeDetectType = param.tubeTypeDetectType; task.tubeType = param.tubeType; task.updatedAt = System.currentTimeMillis(); task.updatedBy = this.accountService.getCurrentAccountId(); this.testTubeRackTestTaskMapper.update(task); this.testTubeRackTaskSaveUpdateTubes(task, param); return task; } // test tube rack task save update tubes private void testTubeRackTaskSaveUpdateTubes(MdbTestTubeRackTestTask task, ParamTestTubeRackTaskSave param) { this.testTubeRackTestTaskTubeMapper.deleteAllByRackId(task.id); for (ParamTestTubeRackTaskSaveTube tube : param.tubes) { MdbTestTubeRackTestTaskTube item = new MdbTestTubeRackTestTaskTube(); item.rackId = task.id; item.index = tube.index; item.projectDetectType = tube.projectDetectType; item.sampleTypeDetectType = tube.sampleTypeDetectType; item.sampleType = tube.sampleType; item.sampleUid = tube.sampleUid; item.barCode = tube.barCode; item.attenuation = tube.attenuation; item.projectIds = MyCommon.objectToJson(tube.projectIds); item.status = MdbTestTubeRackTestTaskTube.STATUS_NEW; this.testTubeRackTestTaskTubeMapper.insert(item); } } // test tube rack task list public List testTubeRackTaskList() { return this.testTubeRackTestTaskMapper.findAll(); } // test tube rack task tube list public List testTubeRackTaskTubeListByRackId(Integer rackId) { return this.testTubeRackTestTaskTubeMapper.findAllByRackId(rackId); } // test tube rack task tube status update public void testTubeRackTaskTubeStatusUpdate( MdbTestTubeRackTestTaskTube tube ) { this.testTubeRackTestTaskTubeMapper.statusUpdate(tube); } // test tube rack task delete public void testTubeRackTaskDeleteById(Integer id) { this.actionLog.log("test-tube-rack-task.delete", id); this.testTubeRackTestTaskMapper.deleteById(id); this.testTubeRackTestTaskTubeMapper.deleteAllByRackId(id); } // test tube rack task lock public void testTubeRackTestLock(Integer id) { this.actionLog.log("test-tube-rack-task.lock", id); MdbTestTubeRackTestTask task = this.testTubeRackTestTaskMapper.findById(id); if ( null == task ) { throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_FOUND"); } if ( !task.editable ) { throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_EDITABLE"); } task.editable = false; task.status = "WAITING"; task.updatedAt = System.currentTimeMillis(); task.updatedBy = this.accountService.getCurrentAccountId(); this.testTubeRackTestTaskMapper.updateLock(task); this.deviceService.getTaskExecutor().newTaskNotify(); } // test tube rack task unlock public void testTubeRackTestUnlock(Integer id) { this.actionLog.log("test-tube-rack-task.unlock", id); MdbTestTubeRackTestTask task = this.testTubeRackTestTaskMapper.findById(id); if ( null == task ) { throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_FOUND"); } if ( task.editable ) { throw new RuntimeException("TEST_TUBE_RACK_TASK_NOT_LOCKED"); } task.editable = true; task.status = "CONFIGURING"; task.updatedAt = System.currentTimeMillis(); task.updatedBy = this.accountService.getCurrentAccountId(); this.testTubeRackTestTaskMapper.updateLock(task); } // emergency task save public void emergencyTaskSave(ParamEmergencyTaskSave param) { MdbEmergencyTestTask task = new MdbEmergencyTestTask(); task.index = param.index; task.enable = param.enable; task.isSlotLocked = true; task.projectDetectType = param.projectDetectType; task.sampleTypeDetectType = param.sampleTypeDetectType; task.sampleType = param.sampleType; task.sampleUid = param.sampleUid; task.barCode = param.barCode; task.attenuation = param.attenuation; task.updatedAt = System.currentTimeMillis(); task.updatedBy = this.accountService.getCurrentAccountId(); task.projectIds = MyCommon.objectToJson(param.projectIds); task.status = "WAITING"; task.createdAt = System.currentTimeMillis(); task.createdBy = this.accountService.getCurrentAccountId(); this.emergencyTestTaskMapper.insert(task); this.deviceService.getTaskExecutor().newTaskNotify(); } // emergency task status get public MdbEmergencyTestTask activeEmergencyTaskGetBySlot(Integer slotIndex) { return this.emergencyTestTaskMapper.activeEmergencyTaskGetBySlot(slotIndex); } // emergency task start public void emergencyTaskStart( MdbEmergencyTestTask task ) { task.status = MdbEmergencyTestTask.STATUS_EXECUTING; task.execStartedAt = System.currentTimeMillis(); this.emergencyTestTaskMapper.executeStart(task); } // emergency task end public void emergencyTaskEnd( MdbEmergencyTestTask task ) { Integer finishCount = this.testMapper.countFinishedTestsByTaskId(task.id, "emergency"); if ( finishCount < task.getProjectIdList().size() ) { return ; } task.status = MdbEmergencyTestTask.STATUS_FINISHED; task.execFinishedAt = System.currentTimeMillis(); this.emergencyTestTaskMapper.executeEnd(task); } // emergency task cancel public void emergencyTaskCancel( MdbEmergencyTestTask task ) { task.status = MdbEmergencyTestTask.STATUS_CANCELED; task.execFinishedAt = System.currentTimeMillis(); this.emergencyTestTaskMapper.executeCancel(task); } // test tube rack task current get public MdbTestTubeRackTestTask testTubeRackTaskCurrentGet() { return this.testTubeRackTestTaskMapper.findCurrentTask(); } // emergency task end public void regularTaskTubeEnd( MdbTestTubeRackTestTask task, MdbTestTubeRackTestTaskTube tube ) { // @TODO : implement this method later } // emergency task cancel public void regularTaskCancel( MdbTestTubeRackTestTask task ) { // @TODO : implement this method later } // test update public void testUpdate( MdbTest test ) { this.testMapper.update(test); } // test end public void testEnd(MdbTest test) { test.status = "FINISHED"; this.testMapper.statusUpdate(test); } // test cancel public void testCancel(MdbTest test) { test.status = "CANCELED"; this.testMapper.statusUpdate(test); } // test search public List testSearch (ParamTestSearch param) { return this.testMapper.search(param); } // test count public Integer testCount( ParamTestSearch param ) { return this.testMapper.count(param); } // create test public void insert(MdbTest test) { Calendar calendar = Calendar.getInstance(); calendar.set(Calendar.HOUR_OF_DAY, 0); calendar.set(Calendar.MINUTE, 0); calendar.set(Calendar.SECOND, 0); calendar.set(Calendar.MILLISECOND, 0); Long startTime = calendar.getTimeInMillis(); int count = this.testMapper.countByTimeRange(startTime, System.currentTimeMillis()); test.serialCode = String.format("%s_%03d", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyMMdd")), count + 1); // @TODO : startedBy should be set to the current user test.startedBy = 0; test.startedAt = System.currentTimeMillis(); this.testMapper.insert(test); } // update test public void statusUpdate(MdbTest test) { this.testMapper.statusUpdate(test); } // update test public void resultUpdate(MdbTest test) { this.testMapper.resultUpdate(test); } // log step start public void logStepStart(MdbTest test, TestStepLogEntry entry ) { entry.testId = test.id; entry.startedAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); this.testStepMapper.insert(entry); } // log step end public void logStepEnd(TestStepLogEntry entry) { entry.finishedAt = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); this.testStepMapper.update(entry); } }