From 299bc998e3d8f32e1ce8412c6b7063ef142d7d28 Mon Sep 17 00:00:00 2001 From: rjy1537 Date: Fri, 8 Nov 2024 16:54:01 +0900 Subject: [PATCH] =?UTF-8?q?Bom=20Master=20=EB=8F=99=EA=B8=B0=ED=99=94=20?= =?UTF-8?q?=EB=B0=B0=EC=B9=98=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../qcast/batch/JobLauncherController.java | 30 +++++++ .../qcast/batch/master/BomConfiguration.java | 81 +++++++++++++++++++ .../biz/displayItem/DisplayItemMapper.java | 19 +++++ .../biz/displayItem/DisplayItemService.java | 24 +++++- .../biz/displayItem/dto/BomSyncResponse.java | 25 ++++++ .../mappers/displayItem/displayItemMapper.xml | 38 +++++++++ 6 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 src/main/java/com/interplug/qcast/batch/master/BomConfiguration.java create mode 100644 src/main/java/com/interplug/qcast/biz/displayItem/dto/BomSyncResponse.java diff --git a/src/main/java/com/interplug/qcast/batch/JobLauncherController.java b/src/main/java/com/interplug/qcast/batch/JobLauncherController.java index 1e30e270..d79b24a1 100644 --- a/src/main/java/com/interplug/qcast/batch/JobLauncherController.java +++ b/src/main/java/com/interplug/qcast/batch/JobLauncherController.java @@ -148,4 +148,34 @@ public class JobLauncherController { return "OK"; } + + /** + * BOM 아이템 동기화 배치 + * + * @return + * @throws JobInstanceAlreadyCompleteException + * @throws JobExecutionAlreadyRunningException + * @throws JobParametersInvalidException + * @throws JobRestartException + */ + @Scheduled(cron = "0 0 0 * * *") + public String bomJob() + throws JobInstanceAlreadyCompleteException, + JobExecutionAlreadyRunningException, + JobParametersInvalidException, + JobRestartException { + + String jobName = "bomJob"; + Job job = jobs.get(jobName); + if (job == null) { + return "Job " + jobName + " not found"; + } + + JobParameters jobParameters = + new JobParametersBuilder().addDate("time", new Date()).toJobParameters(); + + jobLauncher.run(job, jobParameters); + + return "OK"; + } } diff --git a/src/main/java/com/interplug/qcast/batch/master/BomConfiguration.java b/src/main/java/com/interplug/qcast/batch/master/BomConfiguration.java new file mode 100644 index 00000000..d5225292 --- /dev/null +++ b/src/main/java/com/interplug/qcast/batch/master/BomConfiguration.java @@ -0,0 +1,81 @@ +package com.interplug.qcast.batch.master; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.interplug.qcast.biz.displayItem.DisplayItemService; +import com.interplug.qcast.biz.displayItem.dto.BomSyncResponse; +import com.interplug.qcast.util.InterfaceQsp; +import java.util.Collections; +import java.util.List; +import org.springframework.batch.core.Job; +import org.springframework.batch.core.JobExecutionListener; +import org.springframework.batch.core.Step; +import org.springframework.batch.core.configuration.annotation.StepScope; +import org.springframework.batch.core.job.builder.JobBuilder; +import org.springframework.batch.core.repository.JobRepository; +import org.springframework.batch.core.step.builder.StepBuilder; +import org.springframework.batch.item.ItemProcessor; +import org.springframework.batch.item.ItemReader; +import org.springframework.batch.item.ItemWriter; +import org.springframework.batch.item.support.ListItemReader; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.http.HttpMethod; +import org.springframework.transaction.PlatformTransactionManager; + +/** chunk 방식의 Job을 생성하는 Configuration */ +@Configuration +public class BomConfiguration implements JobExecutionListener { + private final DisplayItemService displayItemService; + + private final InterfaceQsp interfaceQsp; + + List bomSyncList; + + @Value("${qsp.master-bom-batch-url}") + private String qspInterfaceUrl; + + public BomConfiguration(DisplayItemService displayItemService, InterfaceQsp interfaceQsp) { + this.displayItemService = displayItemService; + this.interfaceQsp = interfaceQsp; + } + + @Bean + public Job bomJob(JobRepository jobRepository, Step bomStep) { + return new JobBuilder("bomJob", jobRepository).start(bomStep).build(); + } + + @Bean + public Step bomStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) + throws Exception { + return new StepBuilder("bomStep", jobRepository) + .chunk(100, transactionManager) + .reader(bomReader()) + .processor(bomProcessor()) + .writer(bomWriter()) + .build(); + } + + @Bean + @StepScope + public ItemReader bomReader() throws Exception { + this.bomSyncList = + interfaceQsp.callApiData( + HttpMethod.GET, qspInterfaceUrl, null, new TypeReference>() {}); + return (bomSyncList != null) + ? new ListItemReader<>(bomSyncList) + : new ListItemReader<>(Collections.emptyList()); + } + + @Bean + public ItemProcessor bomProcessor() { + return item -> item; + } + + @Bean + public ItemWriter bomWriter() { + return items -> { + displayItemService.setBomSyncSave((List) items.getItems()); + }; + } +} diff --git a/src/main/java/com/interplug/qcast/biz/displayItem/DisplayItemMapper.java b/src/main/java/com/interplug/qcast/biz/displayItem/DisplayItemMapper.java index b553dc1e..f750db67 100644 --- a/src/main/java/com/interplug/qcast/biz/displayItem/DisplayItemMapper.java +++ b/src/main/java/com/interplug/qcast/biz/displayItem/DisplayItemMapper.java @@ -1,5 +1,6 @@ package com.interplug.qcast.biz.displayItem; +import com.interplug.qcast.biz.displayItem.dto.BomSyncResponse; import com.interplug.qcast.biz.displayItem.dto.DisplayItemRequest; import com.interplug.qcast.biz.displayItem.dto.ItemResponse; import com.interplug.qcast.biz.displayItem.dto.ItemSyncResponse; @@ -24,4 +25,22 @@ public interface DisplayItemMapper { * @throws Exception */ int setItemSyncSave(ItemSyncResponse itemInfoSync); + + /** + * BOM 아이템 정보 삭제 + * + * @param bomInfoSync 아이템 정보 + * @return + * @throws Exception + */ + int deleteBomSync(BomSyncResponse bomInfoSync); + + /** + * BOM 아이템 정보 동기화 + * + * @param bomInfoSync 아이템 정보 + * @return + * @throws Exception + */ + int setBomSyncSave(BomSyncResponse bomInfoSync); } diff --git a/src/main/java/com/interplug/qcast/biz/displayItem/DisplayItemService.java b/src/main/java/com/interplug/qcast/biz/displayItem/DisplayItemService.java index d9e6a568..2cbc67f0 100644 --- a/src/main/java/com/interplug/qcast/biz/displayItem/DisplayItemService.java +++ b/src/main/java/com/interplug/qcast/biz/displayItem/DisplayItemService.java @@ -1,5 +1,6 @@ package com.interplug.qcast.biz.displayItem; +import com.interplug.qcast.biz.displayItem.dto.BomSyncResponse; import com.interplug.qcast.biz.displayItem.dto.DisplayItemRequest; import com.interplug.qcast.biz.displayItem.dto.ItemResponse; import com.interplug.qcast.biz.displayItem.dto.ItemSyncResponse; @@ -82,7 +83,28 @@ public class DisplayItemService { public int setItemSyncSave(List itemSyncList) throws Exception { int cnt = 0; for (ItemSyncResponse itemSyncData : itemSyncList) { - displayItemMapper.setItemSyncSave(itemSyncData); + cnt += displayItemMapper.setItemSyncSave(itemSyncData); + } + return cnt; + } + + /** + * 아이템 정보 동기화 + * + * @param bomSyncList 아이템 목록 + * @return + * @throws Exception + */ + public int setBomSyncSave(List bomSyncList) throws Exception { + int cnt = 0; + for (BomSyncResponse bomSyncData : bomSyncList) { + if ("D".equals(bomSyncData.getStatCd())) { + // Bom 아이템 삭제 처리 + cnt += displayItemMapper.deleteBomSync(bomSyncData); + } else { + // Bom 아이템 수정/등록 처리 + cnt += displayItemMapper.setBomSyncSave(bomSyncData); + } } return cnt; } diff --git a/src/main/java/com/interplug/qcast/biz/displayItem/dto/BomSyncResponse.java b/src/main/java/com/interplug/qcast/biz/displayItem/dto/BomSyncResponse.java new file mode 100644 index 00000000..a8fe8d05 --- /dev/null +++ b/src/main/java/com/interplug/qcast/biz/displayItem/dto/BomSyncResponse.java @@ -0,0 +1,25 @@ +package com.interplug.qcast.biz.displayItem.dto; + +import com.interplug.qcast.util.DefaultResponse; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +/** Bom 아이템 동기화 Response */ +@Data +public class BomSyncResponse extends DefaultResponse { + + @Schema(description = "Material Number") + String packageItemId; + + @Schema(description = "Bom Code") + String itemId; + + @Schema(description = "Amount") + String amount; + + @Schema(description = "Manual Flag") + String manualFlg; + + @Schema(description = "Status Code(A, D)") + String statCd; +} diff --git a/src/main/resources/mappers/displayItem/displayItemMapper.xml b/src/main/resources/mappers/displayItem/displayItemMapper.xml index 697d4efa..bbaa65ce 100644 --- a/src/main/resources/mappers/displayItem/displayItemMapper.xml +++ b/src/main/resources/mappers/displayItem/displayItemMapper.xml @@ -240,4 +240,42 @@ , GETDATE() ); + + + DELETE FROM M_PACKAGE_ITEM + WHERE + PACKAGE_ITEM_ID = #{packageItemId} + AND ITEM_ID = #{itemId} + + + + /* sqlid : com.interplug.qcast.displayItem.setBomSyncSave */ + MERGE M_PACKAGE_ITEM AS A + USING + ( SELECT #{itemId} AS ITEM_ID + , #{packageItemId} AS PACKAGE_ITEM_ID + ) AS D + ON ( + A.PACKAGE_ITEM_ID = D.PACKAGE_ITEM_ID + AND A.ITEM_ID = D.ITEM_ID + ) + WHEN MATCHED THEN + UPDATE SET + AMOUNT = #{amount} + , LAST_EDIT_DATETIME = GETDATE() + WHEN NOT MATCHED THEN + INSERT ( + PACKAGE_ITEM_ID + , ITEM_ID + , AMOUNT + , MANUAL_FLG + , LAST_EDIT_DATETIME + ) VALUES ( + #{packageItemId} + , #{itemId} + , #{amount} + , CASE WHEN #{manualFlg} = 'FALSE' THEN 0 ELSE 1 END + , GETDATE() + ); +