견적서 QSP 연동 API 개발
This commit is contained in:
parent
0183cbf4c0
commit
282fa9bfb0
@ -22,14 +22,14 @@ public class EstimateController {
|
||||
@Operation(description = "1차점 가격 관리 목록을 조회한다.")
|
||||
@GetMapping("/price/store-price-list")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public PriceResponse selectStorePriceList(PriceRequest priceRequest) throws Exception {
|
||||
public EstimateApiResponse selectStorePriceList(PriceRequest priceRequest) throws Exception {
|
||||
return estimateService.selectStorePriceList(priceRequest);
|
||||
}
|
||||
|
||||
@Operation(description = "아이템 가격 목록을 조회한다.")
|
||||
@PostMapping("/price/item-price-list")
|
||||
@ResponseStatus(HttpStatus.OK)
|
||||
public PriceResponse selectItemPriceList(@RequestBody PriceRequest priceRequest)
|
||||
public EstimateApiResponse selectItemPriceList(@RequestBody PriceRequest priceRequest)
|
||||
throws Exception {
|
||||
return estimateService.selectItemPriceList(priceRequest);
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
package com.interplug.qcast.biz.estimate;
|
||||
|
||||
import com.interplug.qcast.biz.estimate.dto.*;
|
||||
import com.interplug.qcast.biz.object.dto.*;
|
||||
import java.util.List;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
@ -13,6 +12,9 @@ public interface EstimateMapper {
|
||||
// 견적서 PDF 상세 확인
|
||||
public EstimateResponse selectEstimatePdfDetail(EstimateRequest estimateRequest);
|
||||
|
||||
// 견적서 API 상세 확인
|
||||
public EstimateSendResponse selectEstimateApiDetail(EstimateRequest estimateRequest);
|
||||
|
||||
// 견적서 아이템 목록 조회
|
||||
public List<ItemResponse> selectEstimateItemList(EstimateRequest estimateRequest);
|
||||
|
||||
@ -31,6 +33,9 @@ public interface EstimateMapper {
|
||||
// 견적서 정보 수정
|
||||
public int updateEstimate(EstimateRequest estimateRequest);
|
||||
|
||||
// 견적서 API 정보 수정
|
||||
public int updateEstimateApi(EstimateRequest estimateRequest);
|
||||
|
||||
// 견적서 지붕재 등록
|
||||
public int insertEstimateRoof(RoofRequest roofRequest);
|
||||
|
||||
|
||||
@ -21,7 +21,6 @@ import com.interplug.qcast.util.InterfaceQsp;
|
||||
import io.micrometer.common.util.StringUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.awt.*;
|
||||
import java.beans.BeanInfo;
|
||||
import java.beans.Introspector;
|
||||
import java.beans.PropertyDescriptor;
|
||||
@ -62,13 +61,13 @@ public class EstimateService {
|
||||
@Autowired private PwrGnrSimService pwrGnrSimService;
|
||||
|
||||
/**
|
||||
* 1차점 price 관리 목록 조회
|
||||
* QSP 1차점 price 관리 목록 조회
|
||||
*
|
||||
* @param priceRequest 1차점 price 관련 정보
|
||||
* @return PriceResponse 1차점 price 목록
|
||||
* @throws Exception
|
||||
*/
|
||||
public PriceResponse selectStorePriceList(PriceRequest priceRequest) throws Exception {
|
||||
public EstimateApiResponse selectStorePriceList(PriceRequest priceRequest) throws Exception {
|
||||
// Validation
|
||||
if (StringUtils.isEmpty(priceRequest.getSaleStoreId())) {
|
||||
throw new QcastException(
|
||||
@ -86,7 +85,7 @@ public class EstimateService {
|
||||
message.getMessage("common.message.required.data", "Estimate Type"));
|
||||
}
|
||||
|
||||
PriceResponse response = null;
|
||||
EstimateApiResponse response = null;
|
||||
/* [1]. QSP API (url + param) Setting */
|
||||
String url = QSP_API_URL + "/api/price/storePriceList";
|
||||
String apiUrl =
|
||||
@ -104,7 +103,7 @@ public class EstimateService {
|
||||
com.fasterxml.jackson.databind.ObjectMapper om =
|
||||
new com.fasterxml.jackson.databind.ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
response = om.readValue(strResponse, PriceResponse.class);
|
||||
response = om.readValue(strResponse, EstimateApiResponse.class);
|
||||
} else {
|
||||
// [msg] No data
|
||||
throw new QcastException(ErrorCode.NOT_FOUND, message.getMessage("common.message.no.data"));
|
||||
@ -114,11 +113,13 @@ public class EstimateService {
|
||||
}
|
||||
|
||||
/**
|
||||
* QSP 아이템 가격 목록 조회
|
||||
*
|
||||
* @param priceRequest
|
||||
* @return PriceResponse
|
||||
* @throws Exception
|
||||
*/
|
||||
public PriceResponse selectItemPriceList(PriceRequest priceRequest) throws Exception {
|
||||
public EstimateApiResponse selectItemPriceList(PriceRequest priceRequest) throws Exception {
|
||||
// Validation
|
||||
if (StringUtils.isEmpty(priceRequest.getSaleStoreId())) {
|
||||
throw new QcastException(
|
||||
@ -136,7 +137,7 @@ public class EstimateService {
|
||||
message.getMessage("common.message.required.data", "Price Code"));
|
||||
}
|
||||
|
||||
PriceResponse response = null;
|
||||
EstimateApiResponse response = null;
|
||||
/* [1]. QSP API CALL -> Response */
|
||||
String strResponse =
|
||||
interfaceQsp.callApi(
|
||||
@ -146,7 +147,7 @@ public class EstimateService {
|
||||
com.fasterxml.jackson.databind.ObjectMapper om =
|
||||
new com.fasterxml.jackson.databind.ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
response = om.readValue(strResponse, PriceResponse.class);
|
||||
response = om.readValue(strResponse, EstimateApiResponse.class);
|
||||
} else {
|
||||
// [msg] No data
|
||||
throw new QcastException(ErrorCode.NOT_FOUND, message.getMessage("common.message.no.data"));
|
||||
@ -488,9 +489,11 @@ public class EstimateService {
|
||||
estimateMapper.deleteEstimateItemList(estimateRequest);
|
||||
|
||||
// 견적서 아이템 신규 추가
|
||||
int j = 1;
|
||||
for (ItemRequest itemRequest : itemList) {
|
||||
itemRequest.setObjectNo(estimateRequest.getObjectNo());
|
||||
itemRequest.setPlanNo(estimateRequest.getPlanNo());
|
||||
itemRequest.setDispOrder(String.valueOf(j++));
|
||||
itemRequest.setPartAdd(
|
||||
!StringUtils.isEmpty(itemRequest.getPartAdd()) ? itemRequest.getPartAdd() : "0");
|
||||
itemRequest.setItemChangeFlg(
|
||||
@ -501,6 +504,19 @@ public class EstimateService {
|
||||
|
||||
estimateMapper.insertEstimateItem(itemRequest);
|
||||
}
|
||||
|
||||
// QSP Q.CAST SEND API
|
||||
List<EstimateSendResponse> resultList = new ArrayList<EstimateSendResponse>();
|
||||
resultList = this.sendEstimateApi(estimateRequest);
|
||||
// API에서 받은 문서번호 업데이트
|
||||
for (EstimateSendResponse result : resultList) {
|
||||
estimateRequest.setObjectNo(result.getObjectNo());
|
||||
estimateRequest.setPlanNo(result.getPlanNo());
|
||||
estimateRequest.setDocNo(result.getDocNo());
|
||||
estimateRequest.setSyncFlg(result.getSyncFlg());
|
||||
|
||||
estimateMapper.updateEstimateApi(estimateRequest);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -717,6 +733,14 @@ public class EstimateService {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 아이템 목록을 통한 견적서 가격 자동계산
|
||||
*
|
||||
* @param estimateResponse 견적서 정보
|
||||
* @param itemList 아이템 정보 목록
|
||||
* @param unitPriceFlg 가격 표시 코드
|
||||
* @throws Exception
|
||||
*/
|
||||
public void selectTotalPriceInfo(
|
||||
EstimateResponse estimateResponse, List<ItemResponse> itemList, String unitPriceFlg)
|
||||
throws Exception {
|
||||
@ -791,7 +815,7 @@ public class EstimateService {
|
||||
}
|
||||
|
||||
// 부가세 계산 (10프로)
|
||||
vatPrice = supplyPrice.multiply(new BigDecimal("0.01"));
|
||||
vatPrice = supplyPrice.multiply(new BigDecimal("0.1"));
|
||||
// 총 가격 합산 (공급가 + 부가세)
|
||||
totPrice = totPrice.add(supplyPrice.add(vatPrice));
|
||||
|
||||
@ -807,6 +831,86 @@ public class EstimateService {
|
||||
estimateResponse.setTotPrice(String.valueOf(totPrice.setScale(0, BigDecimal.ROUND_HALF_UP)));
|
||||
}
|
||||
|
||||
/**
|
||||
* QSP Q.CAST 견적서 전송 API
|
||||
*
|
||||
* @param estimateRequest 견적서 요청 정보
|
||||
* @return String 문서번호
|
||||
* @throws Exception
|
||||
*/
|
||||
public List<EstimateSendResponse> sendEstimateApi(EstimateRequest estimateRequest)
|
||||
throws Exception {
|
||||
EstimateSendRequest estimateSendRequest = new EstimateSendRequest();
|
||||
List<EstimateSendResponse> quoteList = new ArrayList<EstimateSendResponse>();
|
||||
String docNo = "";
|
||||
|
||||
// 견적서 상세 조회
|
||||
EstimateSendResponse estimateSendResponse =
|
||||
estimateMapper.selectEstimateApiDetail(estimateRequest);
|
||||
|
||||
if (estimateSendResponse == null) {
|
||||
throw new QcastException(ErrorCode.NOT_FOUND, message.getMessage("common.message.no.data"));
|
||||
} else {
|
||||
estimateSendResponse.setSaveType("3");
|
||||
estimateSendResponse.setSyncFlg("0");
|
||||
estimateSendResponse.setConstructSpecification(
|
||||
!StringUtils.isEmpty(estimateRequest.getConstructSpecification())
|
||||
? estimateRequest.getConstructSpecification().split("、")[0]
|
||||
: "");
|
||||
estimateSendResponse.setDelFlg("1".equals(estimateSendResponse.getDelFlg()) ? "Y" : "N");
|
||||
|
||||
// 아이템 목록 조회
|
||||
List<ItemResponse> estimateItemList = estimateMapper.selectEstimateItemList(estimateRequest);
|
||||
estimateSendResponse.setItemList(estimateItemList);
|
||||
|
||||
// 첨부파일 목록 조회
|
||||
FileRequest fileDeleteReq = new FileRequest();
|
||||
fileDeleteReq.setObjectNo(estimateRequest.getObjectNo());
|
||||
fileDeleteReq.setPlanNo(estimateRequest.getPlanNo());
|
||||
fileDeleteReq.setCategory("10");
|
||||
|
||||
List<FileResponse> fileList = fileMapper.selectFileList(fileDeleteReq);
|
||||
estimateSendResponse.setFileList(fileList);
|
||||
|
||||
quoteList.add(estimateSendResponse);
|
||||
estimateSendRequest.setQuoteList(quoteList);
|
||||
}
|
||||
|
||||
EstimateApiResponse response = null;
|
||||
/* [1]. QSP API CALL -> Response */
|
||||
String strResponse =
|
||||
interfaceQsp.callApi(
|
||||
HttpMethod.POST, QSP_API_URL + "/api/master/qcastQuotationSave", estimateSendRequest);
|
||||
|
||||
if (!"".equals(strResponse)) {
|
||||
com.fasterxml.jackson.databind.ObjectMapper om =
|
||||
new com.fasterxml.jackson.databind.ObjectMapper()
|
||||
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
|
||||
response = om.readValue(strResponse, EstimateApiResponse.class);
|
||||
|
||||
Map<String, Object> result = (Map<String, Object>) response.getData();
|
||||
|
||||
if (result != null) {
|
||||
List<Map<String, Object>> succList = (List<Map<String, Object>>) result.get("successList");
|
||||
for (Map<String, Object> succ : succList) {
|
||||
if (succ != null) {
|
||||
for (EstimateSendResponse data : quoteList) {
|
||||
if (data.getObjectNo().equals(succ.get("objectNo"))
|
||||
&& data.getPlanNo().equals(succ.get("planNo"))) {
|
||||
data.setSyncFlg("1");
|
||||
data.setDocNo(String.valueOf(succ.get("docNo")));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
log.error("sendEstimateApi >>> " + message.getMessage("common.message.no.data"));
|
||||
}
|
||||
|
||||
return quoteList;
|
||||
}
|
||||
|
||||
public Map<String, Object> convertVoToMap(Object vo) {
|
||||
Map<String, Object> result = new HashMap<String, Object>();
|
||||
|
||||
|
||||
@ -3,7 +3,7 @@ package com.interplug.qcast.biz.estimate.dto;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class PriceResponse {
|
||||
public class EstimateApiResponse {
|
||||
/** API response result */
|
||||
private Object result;
|
||||
|
||||
@ -150,6 +150,9 @@ public class EstimateRequest {
|
||||
@Schema(description = "가격코드")
|
||||
private String priceCd;
|
||||
|
||||
@Schema(description = "QSP 동기화 여부")
|
||||
private String syncFlg;
|
||||
|
||||
@Schema(description = "비고")
|
||||
private String remarks;
|
||||
|
||||
|
||||
@ -0,0 +1,11 @@
|
||||
package com.interplug.qcast.biz.estimate.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EstimateSendRequest {
|
||||
@Schema(description = "견적서 목록 정보")
|
||||
List<EstimateSendResponse> quoteList;
|
||||
}
|
||||
@ -0,0 +1,115 @@
|
||||
package com.interplug.qcast.biz.estimate.dto;
|
||||
|
||||
import com.interplug.qcast.biz.file.dto.FileResponse;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.util.List;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class EstimateSendResponse {
|
||||
@Schema(description = "물건번호")
|
||||
private String objectNo;
|
||||
|
||||
@Schema(description = "플랜번호")
|
||||
private String planNo;
|
||||
|
||||
@Schema(description = "판매점 ID")
|
||||
private String saleStoreId;
|
||||
|
||||
@Schema(description = "물건명")
|
||||
private String objectName;
|
||||
|
||||
@Schema(description = "견적서 등록일")
|
||||
private String estimateDetailCreateDate;
|
||||
|
||||
@Schema(description = "수취회사명")
|
||||
private String receiveCompanyName;
|
||||
|
||||
@Schema(description = "수취자명")
|
||||
private String receiveUser;
|
||||
|
||||
@Schema(description = "배송지 우편번호")
|
||||
private String deliveryZipNo;
|
||||
|
||||
@Schema(description = "배송지 주소")
|
||||
private String deliveryTarget;
|
||||
|
||||
@Schema(description = "배송지 연락처")
|
||||
private String deliveryTel;
|
||||
|
||||
@Schema(description = "배송 희망일")
|
||||
private String deliveryHopeDate;
|
||||
|
||||
@Schema(description = "사양확장일")
|
||||
private String specificationConfirmDate;
|
||||
|
||||
@Schema(description = "결제기간일")
|
||||
private String paymentTerms;
|
||||
|
||||
@Schema(description = "차종류 코드")
|
||||
private String carKindCd;
|
||||
|
||||
@Schema(description = "Track 종류 코드")
|
||||
private String trackKind;
|
||||
|
||||
@Schema(description = "Track 10톤 배송일")
|
||||
private String track10tDelivery;
|
||||
|
||||
@Schema(description = "Track 무게 코드")
|
||||
private String trackWeight;
|
||||
|
||||
@Schema(description = "Track 시간 지정")
|
||||
private String trackTimeSpecify;
|
||||
|
||||
@Schema(description = "Track 시간")
|
||||
private String trackTime;
|
||||
|
||||
@Schema(description = "포리프트 여부")
|
||||
private String forklift;
|
||||
|
||||
@Schema(description = "전압여부 (주택:0, 저압:1)")
|
||||
private String houseClassCd;
|
||||
|
||||
@Schema(description = "영업사원 코드")
|
||||
private String businessChargerCd;
|
||||
|
||||
@Schema(description = "영업사원 그룹 코드")
|
||||
private String businessGroupCd;
|
||||
|
||||
@Schema(description = "시공방법")
|
||||
private String constructSpecification;
|
||||
|
||||
@Schema(description = "북면설치여부")
|
||||
private String northArrangement;
|
||||
|
||||
@Schema(description = "견적서 타입 (YJSS, YJOD)")
|
||||
private String estimateType;
|
||||
|
||||
@Schema(description = "주택패키지 단가")
|
||||
private String pkgAsp;
|
||||
|
||||
@Schema(description = "삭제여부")
|
||||
private String delFlg;
|
||||
|
||||
@Schema(description = "마지막 수정일")
|
||||
private String lastEditDatetime;
|
||||
|
||||
@Schema(description = "마지막 수정자")
|
||||
private String lastEditUser;
|
||||
|
||||
@Schema(description = "저장타입(3:Q.CAST III)")
|
||||
private String saveType;
|
||||
|
||||
@Schema(description = "문서번호")
|
||||
private String docNo;
|
||||
|
||||
@Schema(description = "동기화 처리여부")
|
||||
private String syncFlg;
|
||||
|
||||
// 데이터 목록 관련 정보
|
||||
@Schema(description = "아이템 목록")
|
||||
List<ItemResponse> itemList;
|
||||
|
||||
@Schema(description = "첨부파일 목록")
|
||||
List<FileResponse> fileList;
|
||||
}
|
||||
@ -116,9 +116,12 @@ public class ObjectRequest {
|
||||
@Schema(description = "검색 - 판매점ID")
|
||||
private String schSaleStoreId;
|
||||
|
||||
@Schema(description = "검색 - 선택판매점ID")
|
||||
@Schema(description = "검색 - 선택판매점 1차점 ID")
|
||||
private String schSelSaleStoreId;
|
||||
|
||||
@Schema(description = "검색 - 선택판매점 2차점 ID")
|
||||
private String schOtherSelSaleStoreId;
|
||||
|
||||
@Schema(description = "검색 - 주소")
|
||||
private String schAddress;
|
||||
|
||||
|
||||
@ -106,6 +106,48 @@
|
||||
ON T.CREATE_SALE_STORE_ID = SS2.SALE_STORE_ID
|
||||
</select>
|
||||
|
||||
<select id="selectEstimateApiDetail" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest" resultType="com.interplug.qcast.biz.estimate.dto.EstimateSendResponse">
|
||||
/* sqlid : com.interplug.qcast.biz.estimate.selectEstimateDetail */
|
||||
SELECT
|
||||
O.OBJECT_NO
|
||||
, O.SALE_STORE_ID
|
||||
, O.OBJECT_NAME
|
||||
, O.RECEIVE_COMPANY_NAME
|
||||
, O.RECEIVE_USER
|
||||
, O.DELIVERY_ZIP_NO
|
||||
, O.DELIVERY_TARGET
|
||||
, O.DELIVERY_TEL
|
||||
, O.DELIVERY_HOPE_DATE
|
||||
, O.SPECIFICATION_CONFIRM_DATE
|
||||
, O.PAYMENT_TERMS
|
||||
, O.CAR_KIND_CD
|
||||
, O.TRACK_KAIND AS TRACK_KIND
|
||||
, O.TRACK_10T_DELIVERY
|
||||
, O.TRACK_WEIGHT
|
||||
, O.TRACK_TIME_SPECIFY
|
||||
, O.TRACK_TIME
|
||||
, O.FORKLIFT
|
||||
, O.HOUSE_CLASS_CD
|
||||
, O.BUSINESS_CHARGER_CD
|
||||
, O.BUSINESS_GROUP_CD
|
||||
, P.PLAN_NO
|
||||
, P.CONSTRUCT_SPECIFICATION
|
||||
, P.NORTH_ARRANGEMENT
|
||||
, P.ESTIMATE_TYPE
|
||||
, P.PKG_ASP
|
||||
, P.DEL_FLG
|
||||
, CONVERT(NVARCHAR(10), P.CREATE_DATETIME, 121) AS ESTIMATE_DETAIL_CREATE_DATE
|
||||
, P.LAST_EDIT_DATETIME
|
||||
, P.LAST_EDIT_USER
|
||||
FROM T_PLAN P WITH (NOLOCK)
|
||||
INNER JOIN T_OBJECT O WITH (NOLOCK)
|
||||
ON P.OBJECT_NO = O.OBJECT_NO
|
||||
INNER JOIN M_SALES_STORE SS WITH(NOLOCK)
|
||||
ON O.SALE_STORE_ID = SS.SALE_STORE_ID
|
||||
WHERE P.OBJECT_NO = #{objectNo}
|
||||
AND P.PLAN_NO = #{planNo}
|
||||
</select>
|
||||
|
||||
<select id="selectEstimateItemList" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest" resultType="com.interplug.qcast.biz.estimate.dto.ItemResponse">
|
||||
/* sqlid : com.interplug.qcast.biz.estimate.selectEstimateItemList */
|
||||
SELECT
|
||||
@ -281,6 +323,16 @@
|
||||
AND PLAN_NO = #{planNo}
|
||||
</update>
|
||||
|
||||
<update id="updateEstimateApi" parameterType="com.interplug.qcast.biz.estimate.dto.EstimateRequest">
|
||||
/* sqlid : com.interplug.qcast.biz.estimate.updateEstimateApi */
|
||||
UPDATE T_PLAN
|
||||
SET
|
||||
DOC_NO = #{docNo}
|
||||
, SYNC_FLG = #{syncFlg}
|
||||
WHERE OBJECT_NO = #{objectNo}
|
||||
AND PLAN_NO = #{planNo}
|
||||
</update>
|
||||
|
||||
<insert id="insertEstimateItem" parameterType="com.interplug.qcast.biz.estimate.dto.ItemRequest">
|
||||
/* sqlid : com.interplug.qcast.biz.estimate.insertEstimateItem */
|
||||
INSERT INTO T_PART_ESTIMATE
|
||||
|
||||
@ -220,9 +220,16 @@
|
||||
<if test='schSaleStoreId != null and schSaleStoreId != ""'>
|
||||
AND O.SALE_STORE_ID LIKE '%' + #{schSaleStoreId} + '%'
|
||||
</if>
|
||||
<if test='schSelSaleStoreId != null and schSelSaleStoreId != ""'>
|
||||
AND O.SALE_STORE_ID = #{schSelSaleStoreId}
|
||||
</if>
|
||||
<choose>
|
||||
<when test='schOtherSelSaleStoreId != null and schOtherSelSaleStoreId != ""'>
|
||||
/* 2차점까지 고름 */
|
||||
AND O.SALE_STORE_ID = #{schOtherSelSaleStoreId}
|
||||
</when>
|
||||
<when test='schSelSaleStoreId != null and schSelSaleStoreId != ""'>
|
||||
/* 1차점까지만 고름 */
|
||||
AND O.SALE_STORE_ID = #{schSelSaleStoreId}
|
||||
</when>
|
||||
</choose>
|
||||
<if test='schAddress != null and schAddress != ""'>
|
||||
AND O.ADDRESS LIKE '%' + #{schAddress} + '%'
|
||||
</if>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user