diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/AstralSession.java b/src/main/java/ru/dmitriymx/astralcheckreport/AstralSession.java index de30781..4aa83c8 100644 --- a/src/main/java/ru/dmitriymx/astralcheckreport/AstralSession.java +++ b/src/main/java/ru/dmitriymx/astralcheckreport/AstralSession.java @@ -13,7 +13,7 @@ import ru.dmitriymx.astralcheckreport.objects.*; import ru.dmitriymx.tools.browser.Browser; import ru.dmitriymx.tools.browser.SimpleBrowser; -class AstralSession { +public class AstralSession { private Logger logger = LoggerFactory.getLogger(AstralSession.class.getSimpleName()); private Browser browser = new SimpleBrowser(); private Gson gson; @@ -71,7 +71,7 @@ class AstralSession { return gson.fromJson(jsonObj.get("d").getAsString(), Organization.class); } - JsonObject historyCert(int productId) { + public JsonObject historyCert(int productId) { String postData = "{\"productId\":" + productId + "}"; String jsonStr = browser.post("http://reg.astralnalog.ru/AbonentModule.aspx/GetCertificatesHistory", postData); diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/ExcelDataRow.java b/src/main/java/ru/dmitriymx/astralcheckreport/ExcelDataRow.java index 67304d1..6fa291d 100644 --- a/src/main/java/ru/dmitriymx/astralcheckreport/ExcelDataRow.java +++ b/src/main/java/ru/dmitriymx/astralcheckreport/ExcelDataRow.java @@ -7,20 +7,20 @@ package ru.dmitriymx.astralcheckreport; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.Row; -class ExcelDataRow { +public class ExcelDataRow { private Row row; ExcelDataRow(Row row) { this.row = row; } - String getInn() { + public String getInn() { Cell cellInn = row.getCell(2); cellInn.setCellType(Cell.CELL_TYPE_STRING); return cellInn.getStringCellValue(); } - String getKpp() { + public String getKpp() { Cell cellKpp = row.getCell(3); cellKpp.setCellType(Cell.CELL_TYPE_STRING); return cellKpp.getStringCellValue(); @@ -31,25 +31,25 @@ class ExcelDataRow { return cellTarif.getStringCellValue(); } - int getAddonCert() { + public int getAddonCert() { Cell cellAddonCert = row.getCell(11); cellAddonCert.setCellType(Cell.CELL_TYPE_NUMERIC); return (int)cellAddonCert.getNumericCellValue(); } - int getAddonKpp() { + public int getAddonKpp() { Cell cellAddonKpp = row.getCell(13); cellAddonKpp.setCellType(Cell.CELL_TYPE_NUMERIC); return (int)cellAddonKpp.getNumericCellValue(); } - int getAddonNaprov() { + public int getAddonNaprov() { Cell cellAddonNaprov = row.getCell(9); cellAddonNaprov.setCellType(Cell.CELL_TYPE_NUMERIC); return (int)cellAddonNaprov.getNumericCellValue(); } - boolean getEGRUL() { + public boolean getEGRUL() { Cell cell = row.getCell(13); cell.setCellType(Cell.CELL_TYPE_NUMERIC); return (int)cell.getNumericCellValue() > 0; diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/Main.java b/src/main/java/ru/dmitriymx/astralcheckreport/Main.java index fad9183..fc82358 100644 --- a/src/main/java/ru/dmitriymx/astralcheckreport/Main.java +++ b/src/main/java/ru/dmitriymx/astralcheckreport/Main.java @@ -4,19 +4,15 @@ */ package ru.dmitriymx.astralcheckreport; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import ru.dmitriymx.astralcheckreport.objects.*; +import ru.dmitriymx.astralcheckreport.tarifs.*; import java.io.File; import java.io.FileReader; import java.io.IOException; -import java.io.InputStreamReader; -import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Properties; @@ -26,10 +22,8 @@ public class Main implements Runnable { private ExcelReader excel; private Properties properties = new Properties(); public static long sleepThread = 100; - private SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); - private static Date currentDate = new Date(System.currentTimeMillis()); - private static LeftObject egrulPlugin = new LeftObject(12); - private static LeftObject astralNalogPlugin = new LeftObject(15); + public static SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy"); + public static Date currentDate = new Date(System.currentTimeMillis()); public static void main(String[] args) { new Main().start(); @@ -105,497 +99,33 @@ public class Main implements Runnable { } logger.debug("result = {}", organization); - if (data.getTarif().equalsIgnoreCase("Акция 3 месяца")) { - tarif_Akcia3Mount(astral, organization, data); + AbstractTarifProcessor tarifProcessor = null; + switch (data.getTarif().toLowerCase()) { + case "акция 3 месяца": + tarifProcessor = Akcia3MountTarifProcessor.instance; break; + case "группа компаний": + tarifProcessor = GroupCompanyTarifProcessor.instance; break; + case "оптимальный, 4 направ.": + tarifProcessor = OptimalniyTarifProcessor.instance; break; + case "базовый, 2 направ.": + tarifProcessor = BasicTarifProcessor.instance; break; + case "": + tarifProcessor = EmptyTarifProcessor.instance; break; + case "Клиент АЦ": + tarifProcessor = ClientACTarifProcessor.instance; break; + case "Стартовый, 1 направ.": + tarifProcessor = StartTarifProcessor.instance; break; + case "Авторизованный центр (АЦ)": + tarifProcessor = AuthACTarifProcessor.instance; break; + default: + logger.info("Не задана логика для тарифа: \"{}\"", data.getTarif()); } - else if (data.getTarif().equalsIgnoreCase("Группа компаний")) { - tarif_GroupCompany(organization, data); - } - else if (data.getTarif().equalsIgnoreCase("Оптимальный, 4 направ.")) { - tarif_Optimalniy(astral, organization, data); - } - else if (data.getTarif().equalsIgnoreCase("Базовый, 2 направ.")) { - tarif_Basic(astral, organization, data); - } - else if (data.getTarif().equals("")) { - tarif_Empty(astral, organization, data); - } - else if (data.getTarif().equals("Клиент АЦ")) { - tarif_AC(astral, organization, data); - } - else if (data.getTarif().equals("Стартовый, 1 направ.")) { - tarif_Start(astral, organization, data); - } - else if (data.getTarif().equals("Авторизованный центр (АЦ)")) { - tarif_AuthAC(astral, organization, data); - } - else { - logger.info("Не задана логика для тарифа: \"{}\"", data.getTarif()); + + if (tarifProcessor != null) { + tarifProcessor.process(astral, organization, data); } safeSleep(sleepThread); } } - - // Тариф: Акция 3 месяца - private void tarif_Akcia3Mount(AstralSession astral, Organization organization, ExcelDataRow data) { - // Step 0: Количество доступных продуктов - if (organization.products.size() == 0) { - logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); - return; - } - - Product product = organization.products.get(0); - Tarif tarif = product.contractTariffs.get(0); - - if (tarif.name.equalsIgnoreCase("Промо (3 месяца бесплатно)")) { - // Step I: Проверяем разницу дат. - // Разница должна быть 3 месяца - int mountInit = Integer.parseInt(tarif.initialDate.substring(5, 7)); - int mountEnd = Integer.parseInt(tarif.endDate.substring(5, 7)); - if ((mountEnd - mountInit) != 3) { - logger.error("({}/{}): Ошибка в подсчете дат!", organization.inn, organization.kpp); - return; - } - - // Step II: Проверка истории сертификатов - // Сертификатов должно быть: - // - либо один - // - либо соответствовать формуле "1 + доп.сертификаты" - JsonObject historyCert = astral.historyCert(product.id); - int totalActiveCerts = countActiveCert(historyCert); - if (totalActiveCerts > 1) { - if (totalActiveCerts != (1 + data.getAddonCert())) { - logger.error("({}/{}): Ошибка количества сертификатов!", organization.inn, organization.kpp); - } - } - - // Step III: Проверяем разницу дат. - // Сертификат должен быть выдан в тот же день или позже, чем тариф - if (product.certs.size() > 1) { - logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); - } - Cert cert = product.certs.get(0); - - long tarifDateLong = tarif.date_initialDate.getTime(); - long certDateLong = cert.startCertDate.getTime(); - - if (certDateLong < tarifDateLong) { - logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); -// return; - } - } - else { - logger.trace("Тариф игнорируется: \"{}\"", tarif.name); - } - - // Addon: проверка наличия "Астрал-Налогоплательщик" - if (product.plugins.contains(astralNalogPlugin)) { - logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); - } - } - - // Тариф: Группа компаний - private void tarif_GroupCompany(Organization organization, ExcelDataRow data) { - // Step 0: Количество доступных продуктов - if (organization.products.size() == 0) { - logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); - return; - } - - // Step I: Является ли данная компания Группой компаний - if (organization.companyGroupName == null || organization.companyGroupName.isEmpty()) { - logger.warn("({}/{}): Ошибка: не является Группой компаний", organization.inn, organization.kpp); - return; - } - - // Step II: Проверяем разницу дат. - // Сертификат должен быть выдан в тот же день или позже, чем тариф - Product product = organization.products.get(0); - Tarif tarif = product.contractTariffs.get(0); - if (product.certs.size() > 1) { - logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); - } - Cert cert = product.certs.get(0); - - long tarifDateLong = tarif.date_initialDate.getTime(); - long certDateLong = cert.startCertDate.getTime(); - - if (certDateLong < tarifDateLong) { - logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); - return; - } - - // Step III: Проверяем кол-во Направлений - if (!calcRecipients4(product, data)) { //TODO надо проверять по категориям - logger.warn("({}/{}): Внимание! Не соответствие количества направлений!", organization.inn, organization.kpp); - } - - // Addon: проверка наличия "Астрал-Налогоплательщик" - if (product.plugins.contains(astralNalogPlugin)) { - logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); - } - } - - // Тариф: Оптимальный, 4 направ. - private void tarif_Optimalniy(AstralSession astral, Organization organization, ExcelDataRow data) { - // Step 0: Количество доступных продуктов - if (organization.products.size() == 0) { - logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); - return; - } - - // Step I: Проверяем разницу дат. - // Сертификат должен быть выдан в тот же день или позже, чем тариф - Product product = organization.products.get(0); - Tarif tarif = product.contractTariffs.get(0); - if (product.certs.size() > 1) { - logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); - } - Cert cert = product.certs.get(0); - - long tarifDateLong = tarif.date_initialDate.getTime(); - long certDateLong = cert.startCertDate.getTime(); - - if (certDateLong < tarifDateLong) { - logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); - return; - } - - // Step II: Проверяем кол-во Направлений - if (!calcRecipients4(product, data)) { //TODO надо проверять по категориям - logger.warn("({}/{}): Внимание! Не соответствие количества направлений!", organization.inn, organization.kpp); - } - - // Addon: проверка наличия "Астрал-Налогоплательщик" - if (product.plugins.contains(astralNalogPlugin)) { - logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); - } - } - - // Тариф: Базовый, 2 направ. - private void tarif_Basic(AstralSession astral, Organization organization, ExcelDataRow data) { - // Step 0: Количество доступных продуктов - if (organization.products.size() == 0) { - logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); - return; - } - - // Step I: Проверяем разницу дат. - // Сертификат должен быть выдан в тот же день или позже, чем тариф - Product product = organization.products.get(0); - Tarif tarif = product.contractTariffs.get(0); - if (product.certs.size() > 1) { - logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); - } - Cert cert = product.certs.get(0); - - long tarifDateLong = tarif.date_initialDate.getTime(); - long certDateLong = cert.startCertDate.getTime(); - - if (certDateLong < tarifDateLong) { - logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); - return; - } - - // Step II: Проверяем кол-во Направлений - if (!calcRecipients2(product, data)) { //TODO надо проверять по категориям - logger.warn("({}/{}): Внимание! Не соответствие количества направлений!", organization.inn, organization.kpp); - } - - // Step III: Проверка наличия ЕГРЮЛ - if (data.getEGRUL()) { - if (!product.plugins.contains(egrulPlugin)) { - logger.warn("({}/{}): Отсутствует ЕГРЮЛ!", organization.inn, organization.kpp); - } - } else { - if (product.plugins.contains(egrulPlugin)) { - logger.error("({}/{}): Присутствует не указанный ЕГРЮЛ!", organization.inn, organization.kpp); - } - } - - // Addon: проверка наличия "Астрал-Налогоплательщик" - if (product.plugins.contains(astralNalogPlugin)) { - logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); - } - } - - // Тариф: (пустое значение) - private void tarif_Empty(AstralSession astral, Organization organization, ExcelDataRow data) { - // Step 0: Количество доступных продуктов - if (organization.products.size() == 0) { - logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); - return; - } - - // Step I: Проверяем - Product product = organization.products.get(0); - JsonObject historyCert = astral.historyCert(product.id); - int totalActiveCerts = countActiveCert(historyCert); - if (totalActiveCerts < 1 + data.getAddonCert()) { - logger.warn("({}/{}): Странно... Сертификатов меньше чем надо", organization.inn, organization.kpp); - } - else if (totalActiveCerts > 1 + data.getAddonCert()) { - logger.error("({}/{}): Ошибка: сертификатов больше чем нужно!", organization.inn, organization.kpp); - return; - } - - Tarif tarif = product.contractTariffs.get(0); - JsonArray certArr = historyCert.get("rows").getAsJsonArray(); - for (JsonElement element : certArr) { - JsonObject jsonObject = element.getAsJsonObject(); - Date certDate; - try { - certDate = sdf.parse(jsonObject.get("cell").getAsJsonArray().get(1).getAsString()); - } catch (ParseException e) { - logger.error("({}/{}): Ошибка при форматировании даты", organization.inn, organization.kpp); - return; - } - - if (certDate.before(tarif.date_initialDate)) { - logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); - } - } - - // Addon: проверка наличия "Астрал-Налогоплательщик" - if (product.plugins.contains(astralNalogPlugin)) { - logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); - } - } - - // Тариф: Клиент АЦ - private void tarif_AC(AstralSession astral, Organization organization, ExcelDataRow data) { - // Step 0: Количество доступных продуктов - if (organization.products.size() == 0) { - logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); - return; - } - - // Step I: Проверяем наличие Авторизованного центра - if (organization.products.get(0).authCenterId == null) { - logger.error("({}/{}): Не указан АЦ!", organization.inn, organization.kpp); - } - - // Addon: проверка наличия "Астрал-Налогоплательщик" - Product product = organization.products.get(0); - if (product.plugins.contains(astralNalogPlugin)) { - logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); - } - } - - // Тариф: Стартовый, 1 направ. - private void tarif_Start(AstralSession astral, Organization organization, ExcelDataRow data) { - // Step 0: Количество доступных продуктов - if (organization.products.size() == 0) { - logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); - return; - } - - // Step I: Проверяем разницу дат. - // Сертификат должен быть выдан в тот же день или позже, чем тариф - Product product = organization.products.get(0); - Tarif tarif = product.contractTariffs.get(0); - if (product.certs.size() > 1) { - logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); - } - Cert cert = product.certs.get(0); - - long tarifDateLong = tarif.date_initialDate.getTime(); - long certDateLong = cert.startCertDate.getTime(); - - if (certDateLong < tarifDateLong) { - logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); - return; - } - - // Step II: Проверяем кол-во Направлений - if (!calcRecipients1(product, data)) { //TODO надо проверять по категориям - logger.warn("({}/{}): Внимание! Не соответствие количества направлений!", organization.inn, organization.kpp); - } - - // Step III: Проверка наличия ЕГРЮЛ - if (data.getEGRUL()) { - if (!product.plugins.contains(egrulPlugin)) { - logger.warn("({}/{}): Отсутствует ЕГРЮЛ!", organization.inn, organization.kpp); - } - } else { - if (product.plugins.contains(egrulPlugin)) { - logger.error("({}/{}): Присутствует не указанный ЕГРЮЛ!", organization.inn, organization.kpp); - } - } - - // Addon: проверка наличия "Астрал-Налогоплательщик" - if (product.plugins.contains(astralNalogPlugin)) { - logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); - } - } - - // Тариф: Авторизованный центр (АЦ) - private void tarif_AuthAC(AstralSession astral, Organization organization, ExcelDataRow data) { - // Step 0: Количество доступных продуктов - if (organization.products.size() == 0) { - logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); - return; - } - - if (organization.products.get(0).categoryId != 2) { - logger.warn("({}/{}): Неверная категория продукта!", organization.inn, organization.kpp); - } - - // Addon: проверка наличия "Астрал-Налогоплательщик" - Product product = organization.products.get(0); - if (product.plugins.contains(astralNalogPlugin)) { - logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); - } - } - - private boolean calcRecipients4(Product product, ExcelDataRow data) { - int countFNS = 0, - countFSS = 0, - countRosstat = 0, - countPFR = 0, - countRosalco = 0, - countRPN = 0; - - for (Recipient recipient : product.recipients) { - switch (recipient.protocolId) { - case 12: - case 10: break; - case 6: - case 13: - countFNS += (recipient.kpp.size() > 0 ? recipient.kpp.size() : 1); - break; - case 5: countFSS++; break; - case 4: countRosstat++; break; - case 2: countPFR++; break; - case 9: countRosalco++; break; - case 15: countRPN++; break; - default: logger.warn("Не известный тип Направления: {}/{}/{}", recipient.protocolId, recipient.code, recipient.name); - } - } - - boolean boolFNS = (countFNS == 0 || countFNS == 1 + data.getAddonKpp()); - if (countFNS == 0 && data.getAddonKpp() > 0) { - logger.warn("({}/{}): Внимание! Странное значение ФНС/Доп.КПП", data.getInn(), data.getKpp()); - } - boolean boolFSS = (countFSS == 0 || countFSS == 1); - boolean boolRosstat = (countRosstat == 0 || countRosstat == 1); - boolean boolPFR = (countPFR == 0 || countPFR == 1); - - if (countFNS + countFSS + countRosstat + countPFR > 4 + data.getAddonKpp()) { - return false; - } - - boolean boolRosalco = (countRosalco == 0 || countRosalco == 1); - boolean boolRPN = (countRPN == 0 || countRPN == 1); - - return boolFNS && boolFSS && boolRosstat && boolPFR && boolRosalco && boolRPN; - } - - private boolean calcRecipients2(Product product, ExcelDataRow data) { - int countFNS = 0, - countFSS = 0, - countRosstat = 0, - countPFR = 0, - countRosalco = 0, - countRPN = 0; - - for (Recipient recipient : product.recipients) { - switch (recipient.protocolId) { - case 12: - case 10: break; - case 6: - case 13: - countFNS += (recipient.kpp.size() > 0 ? recipient.kpp.size() : 1); - break; - case 5: countFSS++; break; - case 4: countRosstat++; break; - case 2: countPFR++; break; - case 9: countRosalco++; break; - case 15: countRPN++; break; - default: logger.warn("Не известный тип Направления: {}/{}/{}", recipient.protocolId, recipient.code, recipient.name); - } - } - - boolean boolFNS = (countFNS == 0 || countFNS == 1 + data.getAddonKpp()); - if (countFNS == 0 && data.getAddonKpp() > 0) { - logger.warn("({}/{}): Внимание! Странное значение ФНС/Доп.КПП", data.getInn(), data.getInn()); - } - boolean boolFSS = (countFSS == 0 || countFSS == 1); - boolean boolRosstat = (countRosstat == 0 || countRosstat == 1); - boolean boolPFR = (countPFR == 0 || countPFR == 1); - - if (countFNS + countFSS + countRosstat + countPFR > 2 + data.getAddonKpp() + data.getAddonNaprov()) { - return false; - } - - boolean boolRosalco = (countRosalco == 0 || countRosalco == 1); - boolean boolRPN = (countRPN == 0 || countRPN == 1); - - return boolFNS && boolFSS && boolRosstat && boolPFR && boolRosalco && boolRPN; - } - - private boolean calcRecipients1(Product product, ExcelDataRow data) { - int countFNS = 0, - countFSS = 0, - countRosstat = 0, - countPFR = 0, - countRosalco = 0, - countRPN = 0; - - for (Recipient recipient : product.recipients) { - switch (recipient.protocolId) { - case 12: - case 10: break; - case 6: - case 13: - countFNS += (recipient.kpp.size() > 0 ? recipient.kpp.size() : 1); - break; - case 5: countFSS++; break; - case 4: countRosstat++; break; - case 2: countPFR++; break; - case 9: countRosalco++; break; - case 15: countRPN++; break; - default: logger.warn("Не известный тип Направления: {}/{}/{}", recipient.protocolId, recipient.code, recipient.name); - } - } - - boolean boolFNS = (countFNS == 0 || countFNS == 1 + data.getAddonKpp()); - if (countFNS == 0 && data.getAddonKpp() > 0) { - logger.warn("({}/{}): Внимание! Странное значение ФНС/Доп.КПП", data.getInn(), data.getInn()); - } - boolean boolFSS = (countFSS == 0 || countFSS == 1); - boolean boolRosstat = (countRosstat == 0 || countRosstat == 1); - boolean boolPFR = (countPFR == 0 || countPFR == 1); - - if (countFNS + countFSS + countRosstat + countPFR > 1 + data.getAddonKpp() + data.getAddonNaprov()) { - return false; - } - - boolean boolRosalco = (countRosalco == 0 || countRosalco == 1); - boolean boolRPN = (countRPN == 0 || countRPN == 1); - - return boolFNS && boolFSS && boolRosstat && boolPFR && boolRosalco && boolRPN; - } - - private int countActiveCert(JsonObject historyCert) { - JsonArray rows = historyCert.get("rows").getAsJsonArray(); - int result = 0; - for (JsonElement element : rows) { - JsonObject jsonObject = element.getAsJsonObject(); - Date endDate; - try { - endDate = sdf.parse(jsonObject.get("cell").getAsJsonArray().get(2).getAsString()); - } catch (ParseException e) { - logger.error("Ошибка при форматировании даты"); - return 0; - } - - if (endDate.after(currentDate)) { - result++; - } - } - - return result; - } } diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/AbstractTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/AbstractTarifProcessor.java new file mode 100644 index 0000000..f073c77 --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/AbstractTarifProcessor.java @@ -0,0 +1,45 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.objects.LeftObject; +import ru.dmitriymx.astralcheckreport.objects.Organization; +import ru.dmitriymx.astralcheckreport.objects.Product; + +public abstract class AbstractTarifProcessor { + private static LeftObject astralNalogPlugin = new LeftObject(15); + private Logger logger = LoggerFactory.getLogger(AbstractTarifProcessor.class); + + private boolean beforeProcess(Organization organization) { + // Step 0: Количество доступных продуктов + if (organization.products.size() == 0) { + logger.warn("({}/{}): Нет доступных продуктов!", organization.inn, organization.kpp); + return false; + } + + return true; + } + + public void process(AstralSession astral, Organization organization, ExcelDataRow data) { + if (!beforeProcess(organization)) return; + process0(astral, organization, data); + afterProcess(organization); + } + + private void afterProcess(Organization organization) { + Product product = organization.products.get(0); + + // Addon: проверка наличия "Астрал-Налогоплательщик" + if (product.plugins.contains(astralNalogPlugin)) { + logger.info("({}/{}): Обнаружен \"Астрал-Налогоплательщик\"", organization.inn, organization.kpp); + } + } + + protected abstract void process0(AstralSession astral, Organization organization, ExcelDataRow data); +} diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/Akcia3MountTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/Akcia3MountTarifProcessor.java new file mode 100644 index 0000000..a7a84f2 --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/Akcia3MountTarifProcessor.java @@ -0,0 +1,92 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.Main; +import ru.dmitriymx.astralcheckreport.objects.*; + +import java.text.ParseException; +import java.util.Date; + +/** Тариф: Акция 3 месяца */ +public class Akcia3MountTarifProcessor extends AbstractTarifProcessor { + public static final Akcia3MountTarifProcessor instance = new Akcia3MountTarifProcessor(); + private Logger logger = LoggerFactory.getLogger(Akcia3MountTarifProcessor.class); + + @Override + protected void process0(AstralSession astral, Organization organization, ExcelDataRow data) { + Product product = organization.products.get(0); + Tarif tarif = product.contractTariffs.get(0); + + if (tarif.name.equalsIgnoreCase("Промо (3 месяца бесплатно)")) { + // Step I: Проверяем разницу дат. + // Разница должна быть 3 месяца + int mountInit = Integer.parseInt(tarif.initialDate.substring(5, 7)); + int mountEnd = Integer.parseInt(tarif.endDate.substring(5, 7)); + if ((mountEnd - mountInit) != 3) { + logger.error("({}/{}): Ошибка в подсчете дат!", organization.inn, organization.kpp); + return; + } + + // Step II: Проверка истории сертификатов + // Сертификатов должно быть: + // - либо один + // - либо соответствовать формуле "1 + доп.сертификаты" + JsonObject historyCert = astral.historyCert(product.id); + int totalActiveCerts = countActiveCert(historyCert); + if (totalActiveCerts > 1) { + if (totalActiveCerts != (1 + data.getAddonCert())) { + logger.error("({}/{}): Ошибка количества сертификатов!", organization.inn, organization.kpp); + } + } + + // Step III: Проверяем разницу дат. + // Сертификат должен быть выдан в тот же день или позже, чем тариф + if (product.certs.size() > 1) { + logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); + } + Cert cert = product.certs.get(0); + + long tarifDateLong = tarif.date_initialDate.getTime(); + long certDateLong = cert.startCertDate.getTime(); + + if (certDateLong < tarifDateLong) { + logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); +// return; + } + } + else { + logger.trace("Тариф игнорируется: \"{}\"", tarif.name); + } + } + + private int countActiveCert(JsonObject historyCert) { + JsonArray rows = historyCert.get("rows").getAsJsonArray(); + int result = 0; + for (JsonElement element : rows) { + JsonObject jsonObject = element.getAsJsonObject(); + Date endDate; + try { + endDate = Main.sdf.parse(jsonObject.get("cell").getAsJsonArray().get(2).getAsString()); + } catch (ParseException e) { + logger.error("Ошибка при форматировании даты"); + return 0; + } + + if (endDate.after(Main.currentDate)) { + result++; + } + } + + return result; + } +} diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/AuthACTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/AuthACTarifProcessor.java new file mode 100644 index 0000000..9841046 --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/AuthACTarifProcessor.java @@ -0,0 +1,25 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.objects.Organization; + +/** Тариф: Авторизованный центр (АЦ) */ +public class AuthACTarifProcessor extends AbstractTarifProcessor { + public static final AuthACTarifProcessor instance = new AuthACTarifProcessor(); + private Logger logger = LoggerFactory.getLogger(AuthACTarifProcessor.class); + + @Override + protected void process0(AstralSession astral, Organization organization, ExcelDataRow data) { + // Step I + if (organization.products.get(0).categoryId != 2) { + logger.warn("({}/{}): Неверная категория продукта!", organization.inn, organization.kpp); + } + } +} diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/BasicTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/BasicTarifProcessor.java new file mode 100644 index 0000000..7779989 --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/BasicTarifProcessor.java @@ -0,0 +1,97 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.objects.*; + +/** Тариф: Базовый, 2 направ. */ +public class BasicTarifProcessor extends AbstractTarifProcessor { + public static final BasicTarifProcessor instance = new BasicTarifProcessor(); + private static LeftObject egrulPlugin = new LeftObject(12); + private Logger logger = LoggerFactory.getLogger(BasicTarifProcessor.class); + + @Override + protected void process0(AstralSession astral, Organization organization, ExcelDataRow data) { + // Step I: Проверяем разницу дат. + // Сертификат должен быть выдан в тот же день или позже, чем тариф + Product product = organization.products.get(0); + Tarif tarif = product.contractTariffs.get(0); + if (product.certs.size() > 1) { + logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); + } + Cert cert = product.certs.get(0); + + long tarifDateLong = tarif.date_initialDate.getTime(); + long certDateLong = cert.startCertDate.getTime(); + + if (certDateLong < tarifDateLong) { + logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); + return; + } + + // Step II: Проверяем кол-во Направлений + if (!calcRecipients2(product, data)) { //TODO надо проверять по категориям + logger.warn("({}/{}): Внимание! Не соответствие количества направлений!", organization.inn, organization.kpp); + } + + // Step III: Проверка наличия ЕГРЮЛ + if (data.getEGRUL()) { + if (!product.plugins.contains(egrulPlugin)) { + logger.warn("({}/{}): Отсутствует ЕГРЮЛ!", organization.inn, organization.kpp); + } + } else { + if (product.plugins.contains(egrulPlugin)) { + logger.error("({}/{}): Присутствует не указанный ЕГРЮЛ!", organization.inn, organization.kpp); + } + } + } + + private boolean calcRecipients2(Product product, ExcelDataRow data) { + int countFNS = 0, + countFSS = 0, + countRosstat = 0, + countPFR = 0, + countRosalco = 0, + countRPN = 0; + + for (Recipient recipient : product.recipients) { + switch (recipient.protocolId) { + case 12: + case 10: break; + case 6: + case 13: + countFNS += (recipient.kpp.size() > 0 ? recipient.kpp.size() : 1); + break; + case 5: countFSS++; break; + case 4: countRosstat++; break; + case 2: countPFR++; break; + case 9: countRosalco++; break; + case 15: countRPN++; break; + default: logger.warn("Не известный тип Направления: {}/{}/{}", recipient.protocolId, recipient.code, recipient.name); + } + } + + boolean boolFNS = (countFNS == 0 || countFNS == 1 + data.getAddonKpp()); + if (countFNS == 0 && data.getAddonKpp() > 0) { + logger.warn("({}/{}): Внимание! Странное значение ФНС/Доп.КПП", data.getInn(), data.getInn()); + } + boolean boolFSS = (countFSS == 0 || countFSS == 1); + boolean boolRosstat = (countRosstat == 0 || countRosstat == 1); + boolean boolPFR = (countPFR == 0 || countPFR == 1); + + if (countFNS + countFSS + countRosstat + countPFR > 2 + data.getAddonKpp() + data.getAddonNaprov()) { + return false; + } + + boolean boolRosalco = (countRosalco == 0 || countRosalco == 1); + boolean boolRPN = (countRPN == 0 || countRPN == 1); + + return boolFNS && boolFSS && boolRosstat && boolPFR && boolRosalco && boolRPN; + } +} diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/ClientACTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/ClientACTarifProcessor.java new file mode 100644 index 0000000..d406402 --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/ClientACTarifProcessor.java @@ -0,0 +1,25 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.objects.Organization; + +/** Тариф: Клиент АЦ */ +public class ClientACTarifProcessor extends AbstractTarifProcessor { + public static final ClientACTarifProcessor instance = new ClientACTarifProcessor(); + private Logger logger = LoggerFactory.getLogger(ClientACTarifProcessor.class); + + @Override + protected void process0(AstralSession astral, Organization organization, ExcelDataRow data) { + // Step I: Проверяем наличие Авторизованного центра + if (organization.products.get(0).authCenterId == null) { + logger.error("({}/{}): Не указан АЦ!", organization.inn, organization.kpp); + } + } +} diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/EmptyTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/EmptyTarifProcessor.java new file mode 100644 index 0000000..ea69841 --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/EmptyTarifProcessor.java @@ -0,0 +1,79 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.Main; +import ru.dmitriymx.astralcheckreport.objects.Organization; +import ru.dmitriymx.astralcheckreport.objects.Product; +import ru.dmitriymx.astralcheckreport.objects.Tarif; + +import java.text.ParseException; +import java.util.Date; + +/** Тариф: (пустое значение) */ +public class EmptyTarifProcessor extends AbstractTarifProcessor { + public static final EmptyTarifProcessor instance = new EmptyTarifProcessor(); + private Logger logger = LoggerFactory.getLogger(EmptyTarifProcessor.class); + + @Override + protected void process0(AstralSession astral, Organization organization, ExcelDataRow data) { + // Step I: Проверяем + Product product = organization.products.get(0); + JsonObject historyCert = astral.historyCert(product.id); + int totalActiveCerts = countActiveCert(historyCert); + if (totalActiveCerts < 1 + data.getAddonCert()) { + logger.warn("({}/{}): Странно... Сертификатов меньше чем надо", organization.inn, organization.kpp); + } + else if (totalActiveCerts > 1 + data.getAddonCert()) { + logger.error("({}/{}): Ошибка: сертификатов больше чем нужно!", organization.inn, organization.kpp); + return; + } + + Tarif tarif = product.contractTariffs.get(0); + JsonArray certArr = historyCert.get("rows").getAsJsonArray(); + for (JsonElement element : certArr) { + JsonObject jsonObject = element.getAsJsonObject(); + Date certDate; + try { + certDate = Main.sdf.parse(jsonObject.get("cell").getAsJsonArray().get(1).getAsString()); + } catch (ParseException e) { + logger.error("({}/{}): Ошибка при форматировании даты", organization.inn, organization.kpp); + return; + } + + if (certDate.before(tarif.date_initialDate)) { + logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); + } + } + } + + private int countActiveCert(JsonObject historyCert) { + JsonArray rows = historyCert.get("rows").getAsJsonArray(); + int result = 0; + for (JsonElement element : rows) { + JsonObject jsonObject = element.getAsJsonObject(); + Date endDate; + try { + endDate = Main.sdf.parse(jsonObject.get("cell").getAsJsonArray().get(2).getAsString()); + } catch (ParseException e) { + logger.error("Ошибка при форматировании даты"); + return 0; + } + + if (endDate.after(Main.currentDate)) { + result++; + } + } + + return result; + } +} diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/GroupCompanyTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/GroupCompanyTarifProcessor.java new file mode 100644 index 0000000..776f43b --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/GroupCompanyTarifProcessor.java @@ -0,0 +1,91 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.objects.*; + +/** Тариф: Группа компаний */ +public class GroupCompanyTarifProcessor extends AbstractTarifProcessor { + public static final GroupCompanyTarifProcessor instance = new GroupCompanyTarifProcessor(); + private Logger logger = LoggerFactory.getLogger(GroupCompanyTarifProcessor.class); + + @Override + protected void process0(AstralSession astral, Organization organization, ExcelDataRow data) { + // Step I: Является ли данная компания Группой компаний + if (organization.companyGroupName == null || organization.companyGroupName.isEmpty()) { + logger.warn("({}/{}): Ошибка: не является Группой компаний", organization.inn, organization.kpp); + return; + } + + // Step II: Проверяем разницу дат. + // Сертификат должен быть выдан в тот же день или позже, чем тариф + Product product = organization.products.get(0); + Tarif tarif = product.contractTariffs.get(0); + if (product.certs.size() > 1) { + logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); + } + Cert cert = product.certs.get(0); + + long tarifDateLong = tarif.date_initialDate.getTime(); + long certDateLong = cert.startCertDate.getTime(); + + if (certDateLong < tarifDateLong) { + logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); + return; + } + + // Step III: Проверяем кол-во Направлений + if (!calcRecipients4(product, data)) { //TODO надо проверять по категориям + logger.warn("({}/{}): Внимание! Не соответствие количества направлений!", organization.inn, organization.kpp); + } + } + + private boolean calcRecipients4(Product product, ExcelDataRow data) { + int countFNS = 0, + countFSS = 0, + countRosstat = 0, + countPFR = 0, + countRosalco = 0, + countRPN = 0; + + for (Recipient recipient : product.recipients) { + switch (recipient.protocolId) { + case 12: + case 10: break; + case 6: + case 13: + countFNS += (recipient.kpp.size() > 0 ? recipient.kpp.size() : 1); + break; + case 5: countFSS++; break; + case 4: countRosstat++; break; + case 2: countPFR++; break; + case 9: countRosalco++; break; + case 15: countRPN++; break; + default: logger.warn("Не известный тип Направления: {}/{}/{}", recipient.protocolId, recipient.code, recipient.name); + } + } + + boolean boolFNS = (countFNS == 0 || countFNS == 1 + data.getAddonKpp()); + if (countFNS == 0 && data.getAddonKpp() > 0) { + logger.warn("({}/{}): Внимание! Странное значение ФНС/Доп.КПП", data.getInn(), data.getKpp()); + } + boolean boolFSS = (countFSS == 0 || countFSS == 1); + boolean boolRosstat = (countRosstat == 0 || countRosstat == 1); + boolean boolPFR = (countPFR == 0 || countPFR == 1); + + if (countFNS + countFSS + countRosstat + countPFR > 4 + data.getAddonKpp()) { + return false; + } + + boolean boolRosalco = (countRosalco == 0 || countRosalco == 1); + boolean boolRPN = (countRPN == 0 || countRPN == 1); + + return boolFNS && boolFSS && boolRosstat && boolPFR && boolRosalco && boolRPN; + } +} diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/OptimalniyTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/OptimalniyTarifProcessor.java new file mode 100644 index 0000000..eee7b98 --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/OptimalniyTarifProcessor.java @@ -0,0 +1,85 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.objects.*; + +/** Тариф: Оптимальный, 4 направ. */ +public class OptimalniyTarifProcessor extends AbstractTarifProcessor { + public static final OptimalniyTarifProcessor instance = new OptimalniyTarifProcessor(); + private Logger logger = LoggerFactory.getLogger(OptimalniyTarifProcessor.class); + + @Override + protected void process0(AstralSession astral, Organization organization, ExcelDataRow data) { + // Step I: Проверяем разницу дат. + // Сертификат должен быть выдан в тот же день или позже, чем тариф + Product product = organization.products.get(0); + Tarif tarif = product.contractTariffs.get(0); + if (product.certs.size() > 1) { + logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); + } + Cert cert = product.certs.get(0); + + long tarifDateLong = tarif.date_initialDate.getTime(); + long certDateLong = cert.startCertDate.getTime(); + + if (certDateLong < tarifDateLong) { + logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); + return; + } + + // Step II: Проверяем кол-во Направлений + if (!calcRecipients4(product, data)) { //TODO надо проверять по категориям + logger.warn("({}/{}): Внимание! Не соответствие количества направлений!", organization.inn, organization.kpp); + } + } + + private boolean calcRecipients4(Product product, ExcelDataRow data) { + int countFNS = 0, + countFSS = 0, + countRosstat = 0, + countPFR = 0, + countRosalco = 0, + countRPN = 0; + + for (Recipient recipient : product.recipients) { + switch (recipient.protocolId) { + case 12: + case 10: break; + case 6: + case 13: + countFNS += (recipient.kpp.size() > 0 ? recipient.kpp.size() : 1); + break; + case 5: countFSS++; break; + case 4: countRosstat++; break; + case 2: countPFR++; break; + case 9: countRosalco++; break; + case 15: countRPN++; break; + default: logger.warn("Не известный тип Направления: {}/{}/{}", recipient.protocolId, recipient.code, recipient.name); + } + } + + boolean boolFNS = (countFNS == 0 || countFNS == 1 + data.getAddonKpp()); + if (countFNS == 0 && data.getAddonKpp() > 0) { + logger.warn("({}/{}): Внимание! Странное значение ФНС/Доп.КПП", data.getInn(), data.getKpp()); + } + boolean boolFSS = (countFSS == 0 || countFSS == 1); + boolean boolRosstat = (countRosstat == 0 || countRosstat == 1); + boolean boolPFR = (countPFR == 0 || countPFR == 1); + + if (countFNS + countFSS + countRosstat + countPFR > 4 + data.getAddonKpp()) { + return false; + } + + boolean boolRosalco = (countRosalco == 0 || countRosalco == 1); + boolean boolRPN = (countRPN == 0 || countRPN == 1); + + return boolFNS && boolFSS && boolRosstat && boolPFR && boolRosalco && boolRPN; + } +} diff --git a/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/StartTarifProcessor.java b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/StartTarifProcessor.java new file mode 100644 index 0000000..fb62230 --- /dev/null +++ b/src/main/java/ru/dmitriymx/astralcheckreport/tarifs/StartTarifProcessor.java @@ -0,0 +1,97 @@ +/* + * DmitriyMX + * 2016-06-08 + */ +package ru.dmitriymx.astralcheckreport.tarifs; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import ru.dmitriymx.astralcheckreport.AstralSession; +import ru.dmitriymx.astralcheckreport.ExcelDataRow; +import ru.dmitriymx.astralcheckreport.objects.*; + +/** Тариф: Стартовый, 1 направ. */ +public class StartTarifProcessor extends AbstractTarifProcessor { + public static final StartTarifProcessor instance = new StartTarifProcessor(); + private static LeftObject egrulPlugin = new LeftObject(12); + private Logger logger = LoggerFactory.getLogger(StartTarifProcessor.class); + + @Override + protected void process0(AstralSession astral, Organization organization, ExcelDataRow data) { + // Step I: Проверяем разницу дат. + // Сертификат должен быть выдан в тот же день или позже, чем тариф + Product product = organization.products.get(0); + Tarif tarif = product.contractTariffs.get(0); + if (product.certs.size() > 1) { + logger.warn("({}/{}): Обнаружено более 1 сертификата!", organization.inn, organization.kpp); + } + Cert cert = product.certs.get(0); + + long tarifDateLong = tarif.date_initialDate.getTime(); + long certDateLong = cert.startCertDate.getTime(); + + if (certDateLong < tarifDateLong) { + logger.error("({}/{}): Ошибка: сертификат выдан раньше тарифа!", organization.inn, organization.kpp); + return; + } + + // Step II: Проверяем кол-во Направлений + if (!calcRecipients1(product, data)) { //TODO надо проверять по категориям + logger.warn("({}/{}): Внимание! Не соответствие количества направлений!", organization.inn, organization.kpp); + } + + // Step III: Проверка наличия ЕГРЮЛ + if (data.getEGRUL()) { + if (!product.plugins.contains(egrulPlugin)) { + logger.warn("({}/{}): Отсутствует ЕГРЮЛ!", organization.inn, organization.kpp); + } + } else { + if (product.plugins.contains(egrulPlugin)) { + logger.error("({}/{}): Присутствует не указанный ЕГРЮЛ!", organization.inn, organization.kpp); + } + } + } + + private boolean calcRecipients1(Product product, ExcelDataRow data) { + int countFNS = 0, + countFSS = 0, + countRosstat = 0, + countPFR = 0, + countRosalco = 0, + countRPN = 0; + + for (Recipient recipient : product.recipients) { + switch (recipient.protocolId) { + case 12: + case 10: break; + case 6: + case 13: + countFNS += (recipient.kpp.size() > 0 ? recipient.kpp.size() : 1); + break; + case 5: countFSS++; break; + case 4: countRosstat++; break; + case 2: countPFR++; break; + case 9: countRosalco++; break; + case 15: countRPN++; break; + default: logger.warn("Не известный тип Направления: {}/{}/{}", recipient.protocolId, recipient.code, recipient.name); + } + } + + boolean boolFNS = (countFNS == 0 || countFNS == 1 + data.getAddonKpp()); + if (countFNS == 0 && data.getAddonKpp() > 0) { + logger.warn("({}/{}): Внимание! Странное значение ФНС/Доп.КПП", data.getInn(), data.getInn()); + } + boolean boolFSS = (countFSS == 0 || countFSS == 1); + boolean boolRosstat = (countRosstat == 0 || countRosstat == 1); + boolean boolPFR = (countPFR == 0 || countPFR == 1); + + if (countFNS + countFSS + countRosstat + countPFR > 1 + data.getAddonKpp() + data.getAddonNaprov()) { + return false; + } + + boolean boolRosalco = (countRosalco == 0 || countRosalco == 1); + boolean boolRPN = (countRPN == 0 || countRPN == 1); + + return boolFNS && boolFSS && boolRosstat && boolPFR && boolRosalco && boolRPN; + } +}