reports-service http://jira.mfd.msk:8088/browse/CLS-28 часть P1 (todo P2)

This commit is contained in:
AKurakin 2022-12-28 20:18:39 +03:00
parent c6c44b4549
commit 20b05c763d
9 changed files with 184 additions and 29 deletions

View file

@ -3,7 +3,7 @@ package ru.spcex.clearing.reports.reports;
/**
* Идентификаторы отчётов
*/
public enum ReportId {
public enum ReportId {//todo переименовать в соответствии с именами файлов ()
PA_BT2_B, PA_BT2_IV,
BT13_11, BT13_12,

View file

@ -2,8 +2,10 @@ package ru.spcex.clearing.reports.reports.bt_17_4;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import ru.spcex.clearing.reports.reports.ReportId;
import ru.spcex.clearing.reports.reports.ReportWithClearingStatus;
import ru.spcex.clearing.reports.xml_test.FormattedLocalDateConverter;
import java.time.LocalDate;
import java.time.LocalDateTime;
@ -41,10 +43,6 @@ public class ReportBR_0420314_P1 extends ReportWithClearingStatus {
@XStreamAlias("company_clearingCode")
protected String companyClearingCode;
@XStreamAsAttribute
@XStreamAlias("paymentInstruction_senderId")
private String paymentInstructionSenderId;
@XStreamAsAttribute
@XStreamAlias("profileDocument_id")
private String profileDocumentId;
@ -66,31 +64,36 @@ public class ReportBR_0420314_P1 extends ReportWithClearingStatus {
private String clearingMemberCategoryClearingMemberCategory;
@XStreamAsAttribute
@XStreamAlias("profileDocument_documentTypeAndValidFromDate")
private String profileDocumentDocumentTypeAndValidFromDate;
@XStreamAlias("liabilitiesClaimsAssets_contract")
private String liabilitiesClaimsAssets_contract;
@XStreamAsAttribute
@XStreamAlias("liabilitiesClaimsAssets_liabilitiesQuantity")
private String liabilitiesClaimsAssetsLiabilitiesQuantity;
@XStreamAlias("liabilitiesClaimsAssets_tradingDate")
@XStreamConverter(value = FormattedLocalDateConverter.class, strings = {"dd.MM.yyyy"})
private LocalDate liabilitiesClaimsAssets_tradingDate;
@XStreamAsAttribute
@XStreamAlias("liabilitiesClaimsAssests_liabilitiesQuantity")
private String liabilitiesClaimsAssests_liabilitiesQuantity;
public Info_0420314_P1(String companyClearingCode,
String paymentInstructionSenderId,
String profileDocumentId,
String companyFullName,
String companySymbolCode,
String companySymbolValue,
String clearingMemberCategoryClearingMemberCategory,
String profileDocumentDocumentTypeAndValidFromDate,
String liabilitiesClaimsAssetsLiabilitiesQuantity) {
String liabilitiesClaimsAssets_contract,
LocalDate liabilitiesClaimsAssets_tradingDate,
String liabilitiesClaimsAssets_comment) {
this.companyClearingCode = companyClearingCode;
this.paymentInstructionSenderId = paymentInstructionSenderId;
this.profileDocumentId = profileDocumentId;
this.companyFullName = companyFullName;
this.companySymbolCode = companySymbolCode;
this.companySymbolValue = companySymbolValue;
this.clearingMemberCategoryClearingMemberCategory = clearingMemberCategoryClearingMemberCategory;
this.profileDocumentDocumentTypeAndValidFromDate = profileDocumentDocumentTypeAndValidFromDate;
this.liabilitiesClaimsAssetsLiabilitiesQuantity = liabilitiesClaimsAssetsLiabilitiesQuantity;
this.liabilitiesClaimsAssets_contract = liabilitiesClaimsAssets_contract;
this.liabilitiesClaimsAssets_tradingDate = liabilitiesClaimsAssets_tradingDate;
this.liabilitiesClaimsAssests_liabilitiesQuantity = liabilitiesClaimsAssests_liabilitiesQuantity;
}
}

View file

@ -4,6 +4,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ru.spcex.clearing.reports.reports.AbstractReport;
import java.math.BigDecimal;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
@ -45,6 +46,11 @@ public abstract class ReportDataCollector<T extends AbstractReport> {
return val.toString();
}
protected String toString(BigDecimal val) {
if (val == null) return null;
return val.toString(); // todo есть ли требования на точность знаков?
}
protected String toString(Instant val) {
if (val == null) return null;
return DATE_TIME_FORMATTER.format(val.atZone(ZoneId.systemDefault()));

View file

@ -123,7 +123,7 @@ public class ReportsService {
"companySymbolCode",
"companySymbolValue",
"clearingMemberCategoryClearingMemberCategory",
"profileDocumentDocumentTypeAndValidFromDate",
LocalDate.of(2022,11,10),
"liabilitiesClaimsAssetsLiabilitiesQuantity"
);
reportBR_0420314P1.getRows().add(info_0420314P1);

View file

@ -18,9 +18,7 @@ import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;
@Component
public class Bt17_1_P1_collector extends ReportDataCollector<ReportBR_0420315_P1> {
@ -63,29 +61,27 @@ public class Bt17_1_P1_collector extends ReportDataCollector<ReportBR_0420315_P1
ALLOW_CLEARING_STATUS //clearingStatus.getCode() "OK"
);
ClearingStatusDictionary allowClearingStatus = clearingStatusDictionaryImdg.getSingleObjectByFieldValues(Map.of("code", ALLOW_CLEARING_STATUS));
if (allowClearingStatus == null) {
throw new IllegalStateException("ClearingStatusDictionary with code=\"" + ALLOW_CLEARING_STATUS + "\" not fount");
}
final Long allowClearingStatusId = allowClearingStatus.getId(); // "OK"
final Long allowClearingStatusId = MapUtil.getDictionaryIdByCode(clearingStatusDictionaryImdg, ALLOW_CLEARING_STATUS); // "OK"
String ql = String.format("'%s' <= refundDate and refundDate <= '%s' and clearingStatus=%s",
startDate, endDate, allowClearingStatusId);
Collection<LiabilitiesClaimsAssets> liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql);
Map<Long, List<LiabilitiesClaimsAssets>> indexByCompany = MapUtil.indexList(liabilities, LiabilitiesClaimsAssets::getCompanyId);
company_for:
for (Map.Entry<Long, List<LiabilitiesClaimsAssets>> companyEntry : indexByCompany.entrySet()) {
final Long companyId = companyEntry.getKey();
List<LiabilitiesClaimsAssets> liabilitiesOfCompany = companyEntry.getValue();
Company company = companyImdg.getSingleObjectByID(companyId);
if (company != null) {
ClearingMemberCategory cmc = clearingMemberCategoryImdg.getSingleObjectByFieldValues(Map.of("companyId", companyId));
String checkCategory = cmc == null ? null : cmc.getClearingMemberCategory();
if (!ALLOW_CLEARING_MEMBER_CATEGORY.contains(checkCategory)) {
Collection<ClearingMemberCategory> cmcLst = clearingMemberCategoryImdg.getCollectionObjectsByFieldValues(Map.of("companyId", companyId));
boolean checkCategory = cmcLst.stream()
.anyMatch(cmc -> ALLOW_CLEARING_MEMBER_CATEGORY.contains(cmc.getClearingMemberCategory()));
if (!checkCategory) {
// фильтруются <> I, V
log.trace("Filtered company[{}] ClearingMemberCategory[{}].ClearingMemberCategory={}",
companyId, cmc == null ? null : cmc.getId(), checkCategory);
continue;
log.trace("Filtered company[{}] ClearingMemberCategory no match: {}",
companyId, cmcLst);
continue company_for;
}
HashSet<String> onMarket = new HashSet<>();

View file

@ -1,12 +1,26 @@
package ru.spcex.clearing.reports.services.collector;
import org.apache.commons.lang3.StringUtils;
import ru.clearing.platform.dictionary.AbstractDictionary;
import ru.spcex.platform.classes.base.interfaces.WithId;
import ru.spcex.platform.imdg.api.Imdg;
import java.util.*;
import java.util.function.Function;
public class MapUtil {
public static <V> String joinMultiString(Collection<V> from, Function<V, String> stringFieldExtractor) {
ArrayList<String> strToJoin = new ArrayList<>(from.size());
for (V obj : from) {
String v = stringFieldExtractor.apply(obj);
if (v != null) {
strToJoin.add(v);
}
}
return StringUtils.join(strToJoin, ",");
}
public static <K, V extends WithId> Map<K, V> index(Collection<V> from, Function<V, K> indexFieldExtractor) {
Map<K, V> index = new HashMap<>();
for (V obj : from) {
@ -30,4 +44,12 @@ public class MapUtil {
}
return index;
}
public static <TD extends AbstractDictionary> Long getDictionaryIdByCode(Imdg<TD> dImdg, String code) {
TD dictItem = dImdg.getSingleObjectByFieldValues(Map.of("code", code));
if (dictItem == null) {
throw new IllegalStateException(dImdg.getMapName() + " with code=\"" + code + "\" not fount");
}
return dictItem.getId();
}
}

View file

@ -0,0 +1,105 @@
package ru.spcex.clearing.reports.services.collector;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import ru.clearing.classes.statics.data.company.Company;
import ru.clearing.classes.statics.data.company.CompanySymbols;
import ru.clearing.classes.statics.data.generated.ClearingMemberCategory;
import ru.clearing.classes.transaction.data.execution.LiabilitiesClaimsAssets;
import ru.clearing.platform.dictionary.ClearingStatusDictionary;
import ru.spcex.clearing.imdg.IMDGDistributedNames;
import ru.spcex.clearing.reports.reports.bt_17_4.ReportBR_0420314_P1;
import ru.spcex.clearing.reports.services.ReportDataCollector;
import ru.spcex.platform.enumeration.ClearingStatus;
import ru.spcex.platform.enumeration.DocumentTypes;
import ru.spcex.platform.imdg.api.Imdg;
import ru.spcex.platform.imdg.api.ImdgProvider;
import ru.spcex.platform.utils.time.TimeUtil;
import java.time.LocalDate;
import java.util.Collection;
import java.util.Map;
/**
* accountTransactionLiabilities
*/
@Component
public class Repbr0420314_P1_bt_17_4_collector extends ReportDataCollector<ReportBR_0420314_P1> {
private Imdg<Company> companyImdg;
private Imdg<CompanySymbols> companySymbolsImdg;
private Imdg<ClearingMemberCategory> clearingMemberCategoryImdg;
private Imdg<LiabilitiesClaimsAssets> liabilitiesClaimsAssetsImdg;
private Imdg<ClearingStatusDictionary> clearingStatusDictionaryImdg;
protected static final String ALLOW_CLEARING_STATUS = ClearingStatus.OK.getKey();
@Autowired
public Repbr0420314_P1_bt_17_4_collector(ImdgProvider imdgProvider) {
companyImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_Company, Company.class);
liabilitiesClaimsAssetsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_LiabilitiesClaimsAssets, LiabilitiesClaimsAssets.class);
companySymbolsImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_CompanySymbols, CompanySymbols.class);
clearingMemberCategoryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingMemberCategory, ClearingMemberCategory.class);
clearingStatusDictionaryImdg = imdgProvider.getImdg(IMDGDistributedNames.Map_ClearingStatusDictionary, ClearingStatusDictionary.class);
}
protected CompanySymbols findSymbol(DocumentTypes docType, Long companyId) {
CompanySymbols companySymbol = companySymbolsImdg.getSingleObjectByFieldValues(Map.of(
"companySymbol", docType.getKey(),
"companyId", companyId
));
return companySymbol;
}
@Override
public ReportBR_0420314_P1 collectReportWithPeriod(LocalDate startDate, LocalDate endDate) {
validateDateRange(startDate, endDate);
ReportBR_0420314_P1 reportBR_0420312P1 = new ReportBR_0420314_P1(startDate, endDate, "BR",
ALLOW_CLEARING_STATUS //clearingStatus.getCode() "OK"
);
final Long allowClearingStatusId = MapUtil.getDictionaryIdByCode(clearingStatusDictionaryImdg, ALLOW_CLEARING_STATUS); // "OK"
String ql = String.format("'%s' <= refundDate and refundDate <= '%s' and clearingStatus=%s",
startDate, endDate, allowClearingStatusId);
Collection<LiabilitiesClaimsAssets> liabilities = liabilitiesClaimsAssetsImdg.getCollectionObjectsBySQL(ql);
for (LiabilitiesClaimsAssets liability: liabilities) {
final Long companyId = liability.getCompanyId();
Company company = companyImdg.getSingleObjectByID(companyId);
Collection<ClearingMemberCategory> cmcLst = clearingMemberCategoryImdg.getCollectionObjectsByFieldValues(Map.of("companyId", companyId));
// boolean checkCategory = cmcLst.stream().anyMatch(cmc -> ALLOW_CLEARING_MEMBER_CATEGORY.contains(cmc.getClearingMemberCategory()));
// if (!checkCategory) {
// // фильтруются <> I, V
// log.trace("Filtered company[{}] ClearingMemberCategory no match: {}",
// companyId, cmcLst);
// continue company_for;
// }
String cleanMemberCategories = MapUtil.joinMultiString(cmcLst, ClearingMemberCategory::getClearingMemberCategory);
CompanySymbols companySymbolCntr = findSymbol(DocumentTypes.cntr, company.getId());
CompanySymbols companySymbolINN = findSymbol(DocumentTypes.inn, company.getId());
CompanySymbols companySymbolOGRN = findSymbol(DocumentTypes.ogrn, company.getId());
ReportBR_0420314_P1.Info_0420314_P1 info_0420314P1 = new ReportBR_0420314_P1.Info_0420314_P1(
company.getClearingCode(),
toString(companySymbolCntr == null? null : companySymbolCntr.getId()),
company.getFullName(),
(companySymbolINN == null ? null : companySymbolINN.getCompanySymbolValue()),
(companySymbolOGRN == null? null : companySymbolOGRN.getCompanySymbolValue()),
cleanMemberCategories, // может быть несколько, тогда через запятую перечислить
toString(liability.getRefundPaymentId()),
TimeUtil.toLocalDate(liability.getTradingDate()),
toString(liability.getLiabilitiesQuantity())
);
reportBR_0420312P1.getRows().add(info_0420314P1);
}
return reportBR_0420312P1;
}
@Override
public Class<ReportBR_0420314_P1> getReportClass() {
return ReportBR_0420314_P1.class;
}
}

View file

@ -59,4 +59,9 @@ public class TimeUtil {
public static Instant strToInstant(String date) {
return localDateToInstant(Objects.requireNonNull(strToLocalDate(date)));
}
public static LocalDate toLocalDate(Instant date) {
if (date == null) return null;
return LocalDate.ofInstant(date, ZoneId.systemDefault());
}
}

View file

@ -0,0 +1,18 @@
package ru.spcex.platform.utils.time;
import org.junit.jupiter.api.Test;
import java.time.Instant;
import java.time.LocalDate;
import static org.junit.jupiter.api.Assertions.*;
class TimeUtilTest {
@Test
void toLocalDate() {
Instant date1 = Instant.ofEpochMilli(1234567890123L);
LocalDate date2 = TimeUtil.toLocalDate(date1);
assertEquals("2009-02-14", date2.toString());
}
}