가격 동기화 배치 작업
This commit is contained in:
parent
67ade461dd
commit
51ab84aea3
@ -219,7 +219,7 @@ public class JobLauncherController {
|
|||||||
* @throws JobRestartException
|
* @throws JobRestartException
|
||||||
*/
|
*/
|
||||||
@Scheduled(cron = "0 0 0 * * *")
|
@Scheduled(cron = "0 0 0 * * *")
|
||||||
public String adminUserStep()
|
public String adminUserJob()
|
||||||
throws JobInstanceAlreadyCompleteException,
|
throws JobInstanceAlreadyCompleteException,
|
||||||
JobExecutionAlreadyRunningException,
|
JobExecutionAlreadyRunningException,
|
||||||
JobParametersInvalidException,
|
JobParametersInvalidException,
|
||||||
@ -238,4 +238,34 @@ public class JobLauncherController {
|
|||||||
|
|
||||||
return "OK";
|
return "OK";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 가격 동기화 배치
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* @throws JobInstanceAlreadyCompleteException
|
||||||
|
* @throws JobExecutionAlreadyRunningException
|
||||||
|
* @throws JobParametersInvalidException
|
||||||
|
* @throws JobRestartException
|
||||||
|
*/
|
||||||
|
@Scheduled(cron = "0 0 0 * * *")
|
||||||
|
public String priceJob()
|
||||||
|
throws JobInstanceAlreadyCompleteException,
|
||||||
|
JobExecutionAlreadyRunningException,
|
||||||
|
JobParametersInvalidException,
|
||||||
|
JobRestartException {
|
||||||
|
|
||||||
|
String jobName = "priceJob";
|
||||||
|
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";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,157 @@
|
|||||||
|
package com.interplug.qcast.batch.master;
|
||||||
|
|
||||||
|
import com.interplug.qcast.biz.displayItem.DisplayItemService;
|
||||||
|
import com.interplug.qcast.biz.displayItem.dto.PriceItemSyncResponse;
|
||||||
|
import com.interplug.qcast.biz.displayItem.dto.PriceSyncRequest;
|
||||||
|
import com.interplug.qcast.biz.displayItem.dto.PriceSyncResponse;
|
||||||
|
import com.interplug.qcast.util.InterfaceQsp;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.batch.core.*;
|
||||||
|
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.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;
|
||||||
|
|
||||||
|
/** Price 동기화 배치 */
|
||||||
|
@Configuration
|
||||||
|
@Slf4j
|
||||||
|
public class PriceJobConfiguration implements JobExecutionListener {
|
||||||
|
|
||||||
|
private final InterfaceQsp interfaceQsp;
|
||||||
|
private final DisplayItemService displayItemService;
|
||||||
|
|
||||||
|
@Value("${qsp.master-price-batch-url}")
|
||||||
|
private String qspInterfaceUrl;
|
||||||
|
|
||||||
|
private PriceSyncResponse priceSyncResponse;
|
||||||
|
|
||||||
|
public PriceJobConfiguration(InterfaceQsp interfaceQsp, DisplayItemService displayItemService) {
|
||||||
|
this.interfaceQsp = interfaceQsp;
|
||||||
|
this.displayItemService = displayItemService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beforeJob(JobExecution jobExecution) {
|
||||||
|
log.info("Job 시작: 초기화 메서드 호출 중...");
|
||||||
|
try {
|
||||||
|
PriceSyncRequest priceSyncRequest = new PriceSyncRequest();
|
||||||
|
priceSyncRequest.setAllYn("Y");
|
||||||
|
|
||||||
|
this.priceSyncResponse =
|
||||||
|
interfaceQsp.callApiData(
|
||||||
|
HttpMethod.GET, qspInterfaceUrl, priceSyncRequest, PriceSyncResponse.class);
|
||||||
|
log.info("API 호출 완료, 항목 수: {}", this.priceSyncResponse.getModulePriceList().size());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("priceSyncResponse 갱신 중 오류: {}", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Job priceJob(JobRepository jobRepository, Step modulePriceStep, Step bosPriceStep) {
|
||||||
|
return new JobBuilder("priceJob", jobRepository)
|
||||||
|
.start(modulePriceStep)
|
||||||
|
.next(bosPriceStep)
|
||||||
|
.listener(this)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> Step buildStep(
|
||||||
|
String stepName,
|
||||||
|
JobRepository jobRepository,
|
||||||
|
PlatformTransactionManager transactionManager,
|
||||||
|
ItemReader<T> reader,
|
||||||
|
ItemWriter<T> writer) {
|
||||||
|
return new StepBuilder(stepName, jobRepository)
|
||||||
|
.<T, T>chunk(100, transactionManager)
|
||||||
|
.reader(reader)
|
||||||
|
.writer(writer)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Step modulePriceStep(
|
||||||
|
JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||||
|
return buildStep(
|
||||||
|
"modulePriceStep",
|
||||||
|
jobRepository,
|
||||||
|
transactionManager,
|
||||||
|
modulePriceListReader(),
|
||||||
|
createWriter(
|
||||||
|
(items) -> {
|
||||||
|
try {
|
||||||
|
log.debug("Module Price batch processing {} items", items.size());
|
||||||
|
displayItemService.setPriceSyncSave(items);
|
||||||
|
log.debug("Successfully processed Module Price batch");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error processing Module Price batch: {}", e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Failed to process Module Price batch", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"module price"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public Step bosPriceStep(
|
||||||
|
JobRepository jobRepository, PlatformTransactionManager transactionManager) {
|
||||||
|
return buildStep(
|
||||||
|
"bosPriceStep",
|
||||||
|
jobRepository,
|
||||||
|
transactionManager,
|
||||||
|
bosPriceListReader(),
|
||||||
|
createWriter(
|
||||||
|
(items) -> {
|
||||||
|
try {
|
||||||
|
log.debug("Bos Price batch processing {} items", items.size());
|
||||||
|
displayItemService.setPriceSyncSave(items);
|
||||||
|
log.debug("Successfully processed Bos Price batch");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error processing Bos Price batch: {}", e.getMessage(), e);
|
||||||
|
throw new RuntimeException("Failed to process Bos Price batch", e);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"bos price"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> ListItemReader<T> createReader(List<T> items, String readerName) {
|
||||||
|
log.info("{}Reader 호출됨...", readerName);
|
||||||
|
return new ListItemReader<>(items != null ? items : Collections.emptyList());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@StepScope
|
||||||
|
public ListItemReader<PriceItemSyncResponse> modulePriceListReader() {
|
||||||
|
return createReader(
|
||||||
|
priceSyncResponse != null ? priceSyncResponse.getModulePriceList() : null, "store");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@StepScope
|
||||||
|
public ListItemReader<PriceItemSyncResponse> bosPriceListReader() {
|
||||||
|
return createReader(
|
||||||
|
priceSyncResponse != null ? priceSyncResponse.getBosPriceList() : null, "user");
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> ItemWriter<T> createWriter(Consumer<List<T>> processor, String writerName) {
|
||||||
|
return items -> {
|
||||||
|
try {
|
||||||
|
List<T> itemList = (List<T>) items.getItems();
|
||||||
|
processor.accept(itemList);
|
||||||
|
log.info("{}Writer: {} items 처리 완료", writerName, items.size());
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("{}Writer 오류: {}", writerName, e.getMessage());
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,9 +1,6 @@
|
|||||||
package com.interplug.qcast.biz.displayItem;
|
package com.interplug.qcast.biz.displayItem;
|
||||||
|
|
||||||
import com.interplug.qcast.biz.displayItem.dto.BomSyncResponse;
|
import com.interplug.qcast.biz.displayItem.dto.*;
|
||||||
import com.interplug.qcast.biz.displayItem.dto.DisplayItemRequest;
|
|
||||||
import com.interplug.qcast.biz.displayItem.dto.ItemResponse;
|
|
||||||
import com.interplug.qcast.biz.displayItem.dto.ItemSyncResponse;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
@ -43,4 +40,13 @@ public interface DisplayItemMapper {
|
|||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
int setBomSyncSave(BomSyncResponse bomInfoSync);
|
int setBomSyncSave(BomSyncResponse bomInfoSync);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 아이템 가격 정보 동기화
|
||||||
|
*
|
||||||
|
* @param priceItemSyncResponse 아이템 가격 정보
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
int setPriceItemSyncSave(PriceItemSyncResponse priceItemSyncResponse);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,9 +1,6 @@
|
|||||||
package com.interplug.qcast.biz.displayItem;
|
package com.interplug.qcast.biz.displayItem;
|
||||||
|
|
||||||
import com.interplug.qcast.biz.displayItem.dto.BomSyncResponse;
|
import com.interplug.qcast.biz.displayItem.dto.*;
|
||||||
import com.interplug.qcast.biz.displayItem.dto.DisplayItemRequest;
|
|
||||||
import com.interplug.qcast.biz.displayItem.dto.ItemResponse;
|
|
||||||
import com.interplug.qcast.biz.displayItem.dto.ItemSyncResponse;
|
|
||||||
import com.interplug.qcast.biz.estimate.EstimateMapper;
|
import com.interplug.qcast.biz.estimate.EstimateMapper;
|
||||||
import com.interplug.qcast.biz.estimate.dto.NoteRequest;
|
import com.interplug.qcast.biz.estimate.dto.NoteRequest;
|
||||||
import com.interplug.qcast.biz.estimate.dto.NoteResponse;
|
import com.interplug.qcast.biz.estimate.dto.NoteResponse;
|
||||||
@ -108,4 +105,19 @@ public class DisplayItemService {
|
|||||||
}
|
}
|
||||||
return cnt;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 아이템 가격 정보 동기화
|
||||||
|
*
|
||||||
|
* @param priceItemSyncList 가격 목록
|
||||||
|
* @return
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public int setPriceSyncSave(List<PriceItemSyncResponse> priceItemSyncList) throws Exception {
|
||||||
|
int cnt = 0;
|
||||||
|
for (PriceItemSyncResponse priceItemSyncResponse : priceItemSyncList) {
|
||||||
|
cnt += displayItemMapper.setPriceItemSyncSave(priceItemSyncResponse);
|
||||||
|
}
|
||||||
|
return cnt;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,21 @@
|
|||||||
|
package com.interplug.qcast.biz.displayItem.dto;
|
||||||
|
|
||||||
|
import com.interplug.qcast.util.DefaultResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/** 아이템 동기화 Response */
|
||||||
|
@Data
|
||||||
|
public class PriceItemSyncResponse extends DefaultResponse {
|
||||||
|
@Schema(description = "Price Pattern(정가 : 510,.A가격 : 513, C가격 : 514)")
|
||||||
|
String pricePattern;
|
||||||
|
|
||||||
|
@Schema(description = "Material Number")
|
||||||
|
String itemId;
|
||||||
|
|
||||||
|
@Schema(description = "Price Amount")
|
||||||
|
String salePrice;
|
||||||
|
|
||||||
|
@Schema(description = "Price Amount")
|
||||||
|
String costPrice;
|
||||||
|
}
|
||||||
@ -0,0 +1,11 @@
|
|||||||
|
package com.interplug.qcast.biz.displayItem.dto;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/** 가격 동기화 Request */
|
||||||
|
@Data
|
||||||
|
public class PriceSyncRequest {
|
||||||
|
@Schema(description = "All Material Master Yn")
|
||||||
|
private String allYn;
|
||||||
|
}
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
package com.interplug.qcast.biz.displayItem.dto;
|
||||||
|
|
||||||
|
import com.interplug.qcast.util.DefaultResponse;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import java.util.List;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
/** 가격 동기화 Response */
|
||||||
|
@Data
|
||||||
|
public class PriceSyncResponse extends DefaultResponse {
|
||||||
|
|
||||||
|
@Schema(description = "Module Price")
|
||||||
|
private List<PriceItemSyncResponse> modulePriceList;
|
||||||
|
|
||||||
|
@Schema(description = "Bos Price")
|
||||||
|
private List<PriceItemSyncResponse> bosPriceList;
|
||||||
|
}
|
||||||
@ -43,6 +43,7 @@ qsp:
|
|||||||
master-bom-batch-url: /api/master/bomList
|
master-bom-batch-url: /api/master/bomList
|
||||||
master-business-charger-batch-url: /api/user/businessChargerList
|
master-business-charger-batch-url: /api/user/businessChargerList
|
||||||
master-admin-user-batch-url: /api/admin/userList
|
master-admin-user-batch-url: /api/admin/userList
|
||||||
|
master-price-batch-url: /api/master/priceList
|
||||||
simulation-guide-info-url: /api/simulation/guideInfo
|
simulation-guide-info-url: /api/simulation/guideInfo
|
||||||
aes256.key: jpqcellQ123456!!
|
aes256.key: jpqcellQ123456!!
|
||||||
auto.login.aes256.key: _autoL!!
|
auto.login.aes256.key: _autoL!!
|
||||||
|
|||||||
@ -43,6 +43,7 @@ qsp:
|
|||||||
master-bom-batch-url: /api/master/bomList
|
master-bom-batch-url: /api/master/bomList
|
||||||
master-business-charger-batch-url: /api/user/businessChargerList
|
master-business-charger-batch-url: /api/user/businessChargerList
|
||||||
master-admin-user-batch-url: /api/admin/userList
|
master-admin-user-batch-url: /api/admin/userList
|
||||||
|
master-price-batch-url: /api/master/priceList
|
||||||
simulation-guide-info-url: /api/simulation/guideInfo
|
simulation-guide-info-url: /api/simulation/guideInfo
|
||||||
aes256.key: jpqcellQ123456!!
|
aes256.key: jpqcellQ123456!!
|
||||||
auto.login.aes256.key: _autoL!!
|
auto.login.aes256.key: _autoL!!
|
||||||
|
|||||||
@ -43,6 +43,7 @@ qsp:
|
|||||||
master-bom-batch-url: /api/master/bomList
|
master-bom-batch-url: /api/master/bomList
|
||||||
master-business-charger-batch-url: /api/user/businessChargerList
|
master-business-charger-batch-url: /api/user/businessChargerList
|
||||||
master-admin-user-batch-url: /api/admin/userList
|
master-admin-user-batch-url: /api/admin/userList
|
||||||
|
master-price-batch-url: /api/master/priceList
|
||||||
simulation-guide-info-url: /api/simulation/guideInfo
|
simulation-guide-info-url: /api/simulation/guideInfo
|
||||||
aes256.key: jpqcellQ123456!!
|
aes256.key: jpqcellQ123456!!
|
||||||
auto.login.aes256.key: _autoL!!
|
auto.login.aes256.key: _autoL!!
|
||||||
|
|||||||
@ -278,4 +278,33 @@
|
|||||||
, GETDATE()
|
, GETDATE()
|
||||||
);
|
);
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
<insert id="setPriceItemSyncSave" parameterType="com.interplug.qcast.biz.displayItem.dto.PriceItemSyncResponse" >
|
||||||
|
/* sqlid : com.interplug.qcast.displayItem.setPriceItemSyncSave */
|
||||||
|
MERGE M_PRICE_PATTERN_MONEY AS A
|
||||||
|
USING
|
||||||
|
( SELECT #{pricePattern} AS PRICE_PATTERN
|
||||||
|
, #{itemId} AS ITEM_ID
|
||||||
|
) AS D
|
||||||
|
ON (
|
||||||
|
A.PRICE_PATTERN = D.PRICE_PATTERN
|
||||||
|
AND A.ITEM_ID = D.ITEM_ID
|
||||||
|
)
|
||||||
|
WHEN MATCHED THEN
|
||||||
|
UPDATE SET
|
||||||
|
SALE_PRICE = #{salePrice}
|
||||||
|
, COST_PRICE = #{costPrice}
|
||||||
|
WHEN NOT MATCHED THEN
|
||||||
|
INSERT (
|
||||||
|
PRICE_PATTERN
|
||||||
|
, ITEM_ID
|
||||||
|
, SALE_PRICE
|
||||||
|
, COST_PRICE
|
||||||
|
) VALUES (
|
||||||
|
#{pricePattern}
|
||||||
|
, #{itemId}
|
||||||
|
, #{salePrice}
|
||||||
|
, #{costPrice}
|
||||||
|
);
|
||||||
|
</insert>
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user