0

оптимизация: перенос тарифов в классы

This commit is contained in:
2016-06-08 01:12:45 +03:00
parent d695d99c7f
commit c846e7e4d9
12 changed files with 671 additions and 505 deletions

View File

@@ -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);

View File

@@ -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;

View File

@@ -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;
}
}

View File

@@ -0,0 +1,45 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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);
}

View File

@@ -0,0 +1,92 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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;
}
}

View File

@@ -0,0 +1,25 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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);
}
}
}

View File

@@ -0,0 +1,97 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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;
}
}

View File

@@ -0,0 +1,25 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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);
}
}
}

View File

@@ -0,0 +1,79 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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;
}
}

View File

@@ -0,0 +1,91 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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;
}
}

View File

@@ -0,0 +1,85 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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;
}
}

View File

@@ -0,0 +1,97 @@
/*
* DmitriyMX <mail@dmitriymx.ru>
* 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;
}
}