Merge remote-tracking branch 'origin/develop' into develop
All checks were successful
IntegryManagementSystem_Multi/pipeline/head This commit looks good

This commit is contained in:
2024-11-13 11:00:07 +01:00
69 changed files with 2551 additions and 1443 deletions

View File

@@ -82,6 +82,21 @@
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
</SHUTDOWN> </SHUTDOWN>
</ConfigurationWrapper> </ConfigurationWrapper>
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Profile ">
<option name="USE_ENV_VARIABLES" value="true" />
<STARTUP>
<option name="USE_DEFAULT" value="true" />
<option name="SCRIPT" value="" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="" />
</STARTUP>
<SHUTDOWN>
<option name="USE_DEFAULT" value="true" />
<option name="SCRIPT" value="" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="" />
</SHUTDOWN>
</ConfigurationWrapper>
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Run"> <ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Run">
<option name="USE_ENV_VARIABLES" value="true" /> <option name="USE_ENV_VARIABLES" value="true" />
<STARTUP> <STARTUP>

View File

@@ -4,7 +4,7 @@
<option name="USE_SOCKET_TRANSPORT" value="true" /> <option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" /> <option name="SERVER_MODE" value="false" />
<option name="SHMEM_ADDRESS" /> <option name="SHMEM_ADDRESS" />
<option name="HOST" value="localhost" /> <option name="HOST" value="192.168.3.16" />
<option name="PORT" value="8000" /> <option name="PORT" value="8000" />
<option name="AUTO_RESTART" value="false" /> <option name="AUTO_RESTART" value="false" />
<RunnerSettings RunnerId="Debug"> <RunnerSettings RunnerId="Debug">

View File

@@ -1,6 +1,6 @@
<component name="ProjectRunConfigurationManager"> <component name="ProjectRunConfigurationManager">
<configuration default="false" name="Tomcat (FAST)" type="#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory" factoryName="Local" APPLICATION_SERVER_NAME="Tomcat" ALTERNATIVE_JRE_ENABLED="false"> <configuration default="false" name="Tomcat (FAST)" type="#com.intellij.j2ee.web.tomcat.TomcatRunConfigurationFactory" factoryName="Local" APPLICATION_SERVER_NAME="Tomcat" ALTERNATIVE_JRE_ENABLED="false">
<option name="COMMON_VM_ARGUMENTS" value="-DDISABLE_DROOLS_COMPILE=TRUE -Xms6G -Xmx6G -XX:MaxPermSize=1G -XX:PermSize=512M" /> <option name="COMMON_VM_ARGUMENTS" value="-DDISABLE_DROOLS_COMPILE=TRUE -Xms1G -Xmx6G" />
<deployment> <deployment>
<artifact name="ems-engine:war exploded"> <artifact name="ems-engine:war exploded">
<settings> <settings>
@@ -82,6 +82,21 @@
<option name="PROGRAM_PARAMETERS" value="" /> <option name="PROGRAM_PARAMETERS" value="" />
</SHUTDOWN> </SHUTDOWN>
</ConfigurationWrapper> </ConfigurationWrapper>
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Profile ">
<option name="USE_ENV_VARIABLES" value="true" />
<STARTUP>
<option name="USE_DEFAULT" value="true" />
<option name="SCRIPT" value="" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="" />
</STARTUP>
<SHUTDOWN>
<option name="USE_DEFAULT" value="true" />
<option name="SCRIPT" value="" />
<option name="VM_PARAMETERS" value="" />
<option name="PROGRAM_PARAMETERS" value="" />
</SHUTDOWN>
</ConfigurationWrapper>
<ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Run"> <ConfigurationWrapper VM_VAR="JAVA_OPTS" RunnerId="Run">
<option name="USE_ENV_VARIABLES" value="true" /> <option name="USE_ENV_VARIABLES" value="true" />
<STARTUP> <STARTUP>

View File

@@ -75,7 +75,6 @@ import java.util.regex.Pattern;
@RestController @RestController
@Scope("request") @Scope("request")
public class EmsController { public class EmsController {
private final Logger logger = LogManager.getLogger(); private final Logger logger = LogManager.getLogger();

View File

@@ -0,0 +1,60 @@
package it.integry.ems.controller;
import it.integry.ems.response.ServiceRestResponse;
import it.integry.ems.service.EntityProcessor;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems_model.entity.WtbJrept;
import it.integry.ems_model.types.OperationType;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRSaver;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
@RestController
@Scope("request")
@RequestMapping("report-management")
public class ReportManagementController {
@Autowired
private MultiDBTransactionManager multiDBTransactionManager;
@Autowired
private EntityProcessor entityProcessor;
@RequestMapping(value = "/compile/{reportId}", method = RequestMethod.GET)
public @ResponseBody ServiceRestResponse compile(@PathVariable("reportId") long reportId) throws Exception {
WtbJrept wtbJrept = new WtbJrept()
.setId(reportId);
wtbJrept.setOperation(OperationType.SELECT_OBJECT);
wtbJrept = entityProcessor.processEntity(wtbJrept, multiDBTransactionManager);
byte[] jrxml = Base64.decodeBase64(wtbJrept.getB64Jrxml());
ByteArrayInputStream bais = new ByteArrayInputStream(jrxml);
final JasperReport compiledReport = JasperCompileManager.compileReport(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JRSaver.saveObject(compiledReport, baos);
wtbJrept.setCompiledJasper(ArrayUtils.toObject(baos.toByteArray()));
wtbJrept.setOperation(OperationType.UPDATE);
entityProcessor.processEntity(wtbJrept, multiDBTransactionManager);
return ServiceRestResponse.createPositiveResponse();
}
}

View File

@@ -97,12 +97,16 @@ public class EntityHierarchy {
public static class Field { public static class Field {
private java.lang.reflect.Field field; private java.lang.reflect.Field field;
private PK primaryKey;
private Identity identity; private Identity identity;
private SqlField sqlField; private SqlField sqlField;
private ImportFromParent importFromParent; private ImportFromParent importFromParent;
private ObjectStorage objectStorage; private ObjectStorage objectStorage;
private Blob blob; private Blob blob;
private Clob clob; private Clob clob;
private VarBinary varBinary;
private String fieldName;
public java.lang.reflect.Field getField() { public java.lang.reflect.Field getField() {
return field; return field;
@@ -110,9 +114,14 @@ public class EntityHierarchy {
public Field setField(java.lang.reflect.Field field) { public Field setField(java.lang.reflect.Field field) {
this.field = field; this.field = field;
this.fieldName = field.getName();
return this; return this;
} }
public boolean isPrimaryKey() {
return primaryKey != null;
}
public boolean isSqlField() { public boolean isSqlField() {
return sqlField != null; return sqlField != null;
} }
@@ -137,6 +146,17 @@ public class EntityHierarchy {
return identity != null; return identity != null;
} }
public boolean isVarBinary() { return varBinary != null; }
public PK getPrimaryKey() {
return primaryKey;
}
public Field setPrimaryKey(PK primaryKey) {
this.primaryKey = primaryKey;
return this;
}
public Identity getIdentity() { public Identity getIdentity() {
return identity; return identity;
} }
@@ -190,5 +210,18 @@ public class EntityHierarchy {
this.clob = clob; this.clob = clob;
return this; return this;
} }
public VarBinary getVarBinary() {
return varBinary;
}
public Field setVarBinary(VarBinary varBinary) {
this.varBinary = varBinary;
return this;
}
public String getFieldName() {
return fieldName;
}
} }
} }

View File

@@ -0,0 +1,60 @@
package it.integry.ems.dto;
public class Quartet<A, B, C, D> {
private final A first;
private final B second;
private final C third;
private final D fourth;
public Quartet(A first, B second, C third, D fourth) {
this.first = first;
this.second = second;
this.third = third;
this.fourth = fourth;
}
public A getFirst() {
return first;
}
public B getSecond() {
return second;
}
public C getThird() {
return third;
}
public D getFourth() {
return fourth;
}
public A getValue0() {
return first;
}
public B getValue1() {
return second;
}
public C getValue2() {
return third;
}
public D getValue3() {
return fourth;
}
@Override
public String toString() {
return "Quartet{" +
"first=" + first +
", second=" + second +
", third=" + third +
", fourth=" + fourth +
'}';
}
}

View File

@@ -11,6 +11,7 @@ import it.integry.ems.response.ServiceRestResponse;
import it.integry.ems.service.HttpRestWrapper; import it.integry.ems.service.HttpRestWrapper;
import it.integry.ems.settings.Model.AvailableConnectionsModel; import it.integry.ems.settings.Model.AvailableConnectionsModel;
import it.integry.ems.settings.Model.SettingsModel; import it.integry.ems.settings.Model.SettingsModel;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems.utility.UtilityDebug; import it.integry.ems.utility.UtilityDebug;
import it.integry.ems_model.config.EmsRestConstants; import it.integry.ems_model.config.EmsRestConstants;
import it.integry.ems_model.utility.UtilityDB; import it.integry.ems_model.utility.UtilityDB;
@@ -21,8 +22,6 @@ import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -62,19 +61,16 @@ public class LicenseComponent {
final HashMap<String, String> listAziende = new HashMap<>(); final HashMap<String, String> listAziende = new HashMap<>();
for (AvailableConnectionsModel model : settingsModel.getAvailableConnections()) { for (AvailableConnectionsModel model : settingsModel.getAvailableConnections(true)) {
if (model.getInternalDb()) { DataSource ds = new DataSource();
ds.initialize(model.getProfileName());
Connection conn = ds.getConnection();
DataSource ds = new DataSource(); String sql = "SELECT part_iva FROM azienda WHERE part_iva is not null";
ds.initialize(model.getProfileName()); String partIva = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(conn, sql);
Connection conn = ds.getConnection(); if (!UtilityString.isNullOrEmpty(partIva)) listAziende.put(model.getProfileName(), partIva);
String sql = "SELECT part_iva FROM azienda WHERE part_iva is not null"; ds.forceClose();
String partIva = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(conn, sql);
if (!UtilityString.isNullOrEmpty(partIva)) listAziende.put(model.getProfileName(), partIva);
ds.forceClose();
}
} }
String jsonBody = jsonObjectMapper.writeValueAsString(listAziende.values()); String jsonBody = jsonObjectMapper.writeValueAsString(listAziende.values());

View File

@@ -25,12 +25,14 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.springframework.web.context.ContextLoader; import org.springframework.web.context.ContextLoader;
import javax.validation.constraints.NotNull;
import java.io.IOException; import java.io.IOException;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.List; import java.util.List;
public abstract class BaseMigration implements MigrationModelInterface { public abstract class BaseMigration implements MigrationModelInterface {
@@ -66,6 +68,14 @@ public abstract class BaseMigration implements MigrationModelInterface {
} }
protected @NotNull List<HashMap<String, Object>> executeQuery(String sql) throws SQLException, IOException {
return UtilityDB.executeSimpleQuery(advancedDataSource.getConnection(), sql);
}
protected @NotNull <T>List<T> executeQueryDTO(String sql, Class<T> clazz) throws Exception {
return UtilityDB.executeSimpleQueryDTO(advancedDataSource.getConnection(), sql, clazz);
}
protected void executeStatement(String... sqls) throws SQLException, IOException { protected void executeStatement(String... sqls) throws SQLException, IOException {
executeStatement(advancedDataSource.getConnection(), sqls); executeStatement(advancedDataSource.getConnection(), sqls);
} }

View File

@@ -0,0 +1,42 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.IntegryCustomerDB;
import it.integry.ems.migration._base.MigrationModelInterface;
import it.integry.ems_model.entity.MrlDepoArtEsclusiWms;
import it.integry.ems_model.entity.MtbDepo;
import it.integry.ems_model.types.OperationType;
public class Migration_20241107192339 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
if (isCustomerDb(IntegryCustomerDB.Maggio_MaggioSrl)) {
MtbDepo mtbDepo = new MtbDepo()
.setCodMdep("01");
mtbDepo.setOperation(OperationType.NO_OP);
MrlDepoArtEsclusiWms mrlDepoArtEsclusiWms = new MrlDepoArtEsclusiWms()
.setCodMdep("01")
.setCodMgrp("COM")
.setCodMsgr("15");
mrlDepoArtEsclusiWms.setOperation(OperationType.INSERT_OR_UPDATE);
mtbDepo.getMrlDepoArtEsclusiWms().add(mrlDepoArtEsclusiWms);
mtbDepo.manageWithParentConnection(advancedDataSource.getConnection());
}
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,25 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241108153446 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
String sql = "ALTER TABLE dbo.wtb_jrept\n" +
" ADD compiled_jasper VARBINARY(MAX)";
executeStatement(sql);
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,58 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
import it.integry.ems_model.entity.WtbJrept;
import it.integry.ems_model.types.OperationType;
import it.integry.ems_model.utility.UtilityList;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.util.JRSaver;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.List;
public class Migration_20241108153628 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
String sql = "SELECT * FROM wtb_jrept";
final List<WtbJrept> wtbJrepts = executeQueryDTO(sql, WtbJrept.class);
if (UtilityList.isNullOrEmpty(wtbJrepts))
return;
for (WtbJrept w : wtbJrepts) {
byte[] jrxml = Base64.decodeBase64(w.getB64Jrxml());
if (jrxml == null)
continue;
ByteArrayInputStream bais = new ByteArrayInputStream(jrxml);
final JasperReport compiledReport = JasperCompileManager.compileReport(bais);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
JRSaver.saveObject(compiledReport, baos);
w.setCompiledJasper(ArrayUtils.toObject(baos.toByteArray()));
w.setOperation(OperationType.UPDATE);
w.manageWithParentConnection(advancedDataSource.getConnection());
}
// throw new RuntimeException("TEST");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,33 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241108172515 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
createOrUpdateFunction("suggestMtbArtEqui",
"CREATE FUNCTION dbo.suggestMtbArtEqui\n" +
"( \n" +
" @jsonParm varchar(max)\n" +
")\n" +
"RETURNS TABLE \n" +
"AS\n" +
"RETURN \n" +
"(\n" +
" -- Add the SELECT statement with parameter references here\n" +
" SELECT CONVERT(varchar(25), null ) as id_art_equi, CONVERT(varchar(255), null ) as descrizione \n" +
")");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,72 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.IntegryCustomer;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241108172544 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
if (!isCustomer(IntegryCustomer.RossoGargano)) return;
createOrUpdateFunction("suggestMtbArtEqui",
"CREATE FUNCTION dbo.suggestMtbArtEqui\n" +
"( \n" +
" @jsonParm varchar(max)\n" +
")\n" +
"RETURNS TABLE \n" +
"AS\n" +
"RETURN \n" +
"(\n" +
" with tab_json as (\n" +
"select *\n" +
"from openJson(@jsonParm) \n" +
"WITH (\n" +
" cod_mgrp VARCHAR(5) '$.cod_mgrp',\n" +
" cod_msgr VARCHAR(5) '$.cod_msgr',\n" +
" cod_mtip VARCHAR(5) '$.cod_mtip',\n" +
" cod_mstp VARCHAR(5) '$.cod_mstp',\n" +
" cod_tcol_UI VARCHAR(100) '$.cod_tcol_UI',\n" +
" marchio VARCHAR(255) '$.marchio',\n" +
" qta_cnf FLOAT '$.qta_cnf',\n" +
" peso_kg FLOAT '$.peso_kg'\n" +
") )\n" +
",art as (\n" +
"SELECT distinct mtb_aart_equi.id_art_equi, IsNull(mtb_aart_equi.descrizione,\n" +
" CONCAT_WS(' ', mtb_tipi.descrizione, mtb_aart.cod_tcol_UI, CAST(mtb_aart.qta_cnf AS FLOAT), 'x',\n" +
" CAST(mtb_aart.peso_kg AS FLOAT), mtb_stip.descrizione, mtb_aart.marchio) ) as descizione\n" +
"FROM mtb_aart \n" +
"left outer join mtb_aart_equi on mtb_aart.id_art_equi = mtb_aart_equi.id_art_equi\n" +
"left outer join mtb_tipi on mtb_aart.cod_mtip = mtb_tipi.cod_mtip\n" +
"left outer join mtb_stip on mtb_aart.cod_mtip = mtb_stip.cod_mtip and mtb_aart.cod_mstp = mtb_stip.cod_mstp \n" +
"where exists (select *\n" +
"from tab_json where mtb_aart.cod_mgrp = tab_json.cod_mgrp and\n" +
"mtb_aart.cod_msgr = tab_json.cod_msgr and \n" +
"mtb_aart.qta_cnf = tab_json.qta_cnf and\n" +
"mtb_aart.peso_kg = tab_json.peso_kg and\n" +
"(IsNull(mtb_aart.marchio,'') = isNull(tab_json.marchio,'')) and\n" +
"(IsNull(mtb_aart.cod_mtip,'') = isNull(tab_json.cod_mtip,'')) and\n" +
"(IsNull(mtb_aart.cod_mstp, '') = isNull(tab_json.cod_mstp,'')) \n" +
"))\n" +
"\n" +
"select *\n" +
"from art \n" +
"union all\n" +
"select null as id_art_eqi, upper( CONCAT_WS(' ', mtb_tipi.descrizione, cod_tcol_UI, CAST(qta_cnf AS FLOAT), 'x',\n" +
" CAST(peso_kg AS FLOAT), mtb_stip.descrizione, marchio))\n" +
"from tab_json left outer join mtb_tipi on tab_json.cod_mtip = mtb_tipi.cod_mtip\n" +
"left outer join mtb_stip on tab_json.cod_mtip = mtb_stip.cod_mtip and tab_json.cod_mstp = mtb_stip.cod_mstp \n" +
"where exists(select * from tab_json)\n" +
")");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,28 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.IntegryCustomer;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241108181101 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
createSetupQuery("SI_NO", "SI_NO", "SELECT 'S' UNION ALL SELECT 'N'");
createSetup("MTB_AART", "ID_ART_EQUI", "INSERT_AUTO", "N",
"inserisce automaticamente l'id equivalente", false, "SI_NO", false, false,
false, false, false, null, false, "SELECT 'S' UNION ALL SELECT 'N'");
if (!isCustomer(IntegryCustomer.RossoGargano)) return;
updateSetupValue("MTB_AART", "ID_ART_EQUI", "INSERT_AUTO", "S");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,25 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.IntegryCustomer;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241111094439 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
createSetup("W_PORDI_RC", "DISTRIBUZIONE_MATERIALI", "EMAL_NOTIFICATION", null,
"Inserire la mail a cui inviare gli errori", false, null, false, false,
false, false, false, null, false, null);
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,24 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241111125804 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
executeStatement("ALTER TABLE ctb_amac ADD note varchar(MAX)");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,47 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241112092604 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
createOrUpdateFunction("[suggestMtbArtEqui]", "CREATE FUNCTION [dbo].[suggestMtbArtEqui]\n" +
"( \n" +
" @jsonParm varchar(max)\n" +
")\n" +
"RETURNS TABLE \n" +
"AS\n" +
"RETURN \n" +
"\n" +
"(\n" +
"/*with tab_json as (\n" +
"select *\n" +
"from openJson(@jsonParm) \n" +
"WITH (\n" +
" cod_mgrp VARCHAR(5) '$.cod_mgrp',\n" +
" cod_msgr VARCHAR(5) '$.cod_msgr',\n" +
" cod_mtip VARCHAR(5) '$.cod_mtip',\n" +
" cod_mstp VARCHAR(5) '$.cod_mstp',\n" +
" cod_tcol_UI VARCHAR(100) '$.cod_tcol_UI',\n" +
" marchio VARCHAR(255) '$.marchio',\n" +
" qta_cnf FLOAT '$.qta_cnf',\n" +
" peso_kg FLOAT '$.peso_kg'\n" +
") )*/\n" +
" -- Add the SELECT statement with parameter references here\n" +
" SELECT CONVERT(varchar(25), null ) as id_art_equi, CONVERT(varchar(255), null ) as descrizione, 'N' as flag_equi_prezzo, 'N' as flag_equi_costo\n" +
" \n" +
")");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,73 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.IntegryCustomer;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241112092826 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
if ( !isCustomer(IntegryCustomer.RossoGargano)) return;
createOrUpdateFunction("[suggestMtbArtEqui]", "CREATE FUNCTION [dbo].[suggestMtbArtEqui]\n" +
"( \n" +
" @jsonParm varchar(max)\n" +
")\n" +
"RETURNS TABLE \n" +
"AS\n" +
"RETURN \n" +
"(\n" +
" with tab_json as (\n" +
"select *\n" +
"from openJson(@jsonParm) \n" +
"WITH (\n" +
" cod_mgrp VARCHAR(5) '$.cod_mgrp',\n" +
" cod_msgr VARCHAR(5) '$.cod_msgr',\n" +
" cod_mtip VARCHAR(5) '$.cod_mtip',\n" +
" cod_mstp VARCHAR(5) '$.cod_mstp',\n" +
" cod_tcol_UI VARCHAR(100) '$.cod_tcol_UI',\n" +
" marchio VARCHAR(255) '$.marchio',\n" +
" qta_cnf FLOAT '$.qta_cnf',\n" +
" peso_kg FLOAT '$.peso_kg'\n" +
") )\n" +
",art as (\n" +
"SELECT distinct mtb_aart_equi.id_art_equi, IsNull(mtb_aart_equi.descrizione,\n" +
" CONCAT_WS(' ', mtb_tipi.descrizione, mtb_aart.cod_tcol_UI, CAST(mtb_aart.qta_cnf AS FLOAT), 'x',\n" +
" CAST(mtb_aart.peso_kg AS FLOAT), mtb_stip.descrizione, mtb_aart.marchio) ) as descrizione,\n" +
" IsNull(mtb_aart_equi.flag_equi_prezzo, 'T') as flag_equi_prezzo, IsNull(mtb_aart_equi.flag_equi_costo,'N') as flag_equi_costo \n" +
"FROM mtb_aart \n" +
"left outer join mtb_aart_equi on mtb_aart.id_art_equi = mtb_aart_equi.id_art_equi\n" +
"left outer join mtb_tipi on mtb_aart.cod_mtip = mtb_tipi.cod_mtip\n" +
"left outer join mtb_stip on mtb_aart.cod_mtip = mtb_stip.cod_mtip and mtb_aart.cod_mstp = mtb_stip.cod_mstp \n" +
"where exists (select *\n" +
"from tab_json where mtb_aart.cod_mgrp = tab_json.cod_mgrp and\n" +
"mtb_aart.cod_msgr = tab_json.cod_msgr and \n" +
"mtb_aart.qta_cnf = tab_json.qta_cnf and\n" +
"mtb_aart.peso_kg = tab_json.peso_kg and\n" +
"(IsNull(mtb_aart.marchio,'') = isNull(tab_json.marchio,'')) and\n" +
"(IsNull(mtb_aart.cod_mtip,'') = isNull(tab_json.cod_mtip,'')) and\n" +
"(IsNull(mtb_aart.cod_mstp, '') = isNull(tab_json.cod_mstp,'')) \n" +
"))\n" +
"\n" +
"select *\n" +
"from art \n" +
"union all\n" +
"select null as id_art_eqi, upper( CONCAT_WS(' ', mtb_tipi.descrizione, cod_tcol_UI, CAST(qta_cnf AS FLOAT), 'x',\n" +
" CAST(peso_kg AS FLOAT), mtb_stip.descrizione, marchio)), 'T' as flag_equi_prezzo, 'N' as flag_equi_costo \n" +
"from tab_json left outer join mtb_tipi on tab_json.cod_mtip = mtb_tipi.cod_mtip\n" +
"left outer join mtb_stip on tab_json.cod_mtip = mtb_stip.cod_mtip and tab_json.cod_mstp = mtb_stip.cod_mstp \n" +
"where exists(select * from tab_json)\n" +
")");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,68 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241112102424 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
createOrUpdateFunction("[getListinoVenditaPedane]", "CREATE FUNCTION [dbo].[getListinoVenditaPedane](@datavalidita DATETIME, @codvlis VARCHAR(5), @codmart VARCHAR(15), @pedane INT)\n" +
" RETURNS TABLE AS\n" +
" RETURN\n" +
" WITH trasp AS (SELECT mtb_lisv_data_spese.cod_vlis,\n" +
" mtb_lisv_data_spese.versione,\n" +
" mtb_lisv_data_spese.cod_spes,\n" +
" mtb_lisv_data_spese.perc_ricarico,\n" +
" mtb_lisv_data_spese.val_ricarico,\n" +
" mtb_lisv_data_spese.perc_sconto,\n" +
" mtb_lisv_data_spese.da,\n" +
" mtb_lisv_data_spese.a\n" +
" FROM vtb_list_data\n" +
" INNER JOIN mtb_lisv_data_spese\n" +
" ON vtb_list_data.cod_vlis = mtb_lisv_data_spese.cod_vlis AND\n" +
" vtb_list_data.versione = mtb_lisv_data_spese.versione\n" +
" CROSS APPLY (SELECT MAX(id_listino) AS max_id_listino\n" +
" FROM vtb_list_data t\n" +
" WHERE t.data_iniz <= ISNULL(@datavalidita, CAST(GETDATE() AS DATE))\n" +
" AND vtb_list_data.cod_vlis = t.cod_vlis) max_lisv\n" +
" WHERE vtb_list_data.id_listino = max_lisv.max_id_listino)\n" +
"\n" +
" SELECT list.*,\n" +
" trasp.cod_spes,\n" +
" trasp.perc_ricarico,\n" +
" trasp.val_ricarico,\n" +
" trasp.perc_sconto,\n" +
" trasp.da,\n" +
" trasp.a,\n" +
" (list.prz_vend +\n" +
" IIF(list.flag_add_trasp = 1,\n" +
" ((ISNULL(val_ricarico, 0)) * list.add_val_spese) /\n" +
" IIF(ISNULL(list.colli_pedana, 1) = 0, 1, list.colli_pedana), 0)) +\n" +
" ((ISNULL(perc_ricarico, 0) * list.add_ric_spese * list.prz_vend) / 100) *\n" +
" (1 - (ISNULL(perc_sconto, 0) * list.add_sco_spese) / 100) prz_vend_trasp,\n" +
" ((list.prz_vend +\n" +
" IIF(list.flag_add_trasp = 1,\n" +
" ((ISNULL(val_ricarico, 0)) * list.add_val_spese) /\n" +
" IIF(ISNULL(list.colli_pedana, 1) = 0, 1, list.colli_pedana), 0)) +\n" +
" ((ISNULL(perc_ricarico, 0) * list.add_ric_spese * list.prz_vend) / 100) *\n" +
" (1 - (ISNULL(perc_sconto, 0) * list.add_sco_spese) / 100)) * (1 - list.perc_sco1 / 100) *\n" +
" (1 - list.perc_sco2 / 100) *\n" +
" (1 - list.perc_sco3 / 100) *\n" +
" (1 - list.perc_sco4 / 100) AS prz_vend_trasp_netto\n" +
" FROM getlistinovendita(@datavalidita, @codvlis, @codmart) list\n" +
" LEFT OUTER JOIN trasp ON list.cod_vlis = trasp.cod_vlis AND\n" +
" (@pedane IS NULL OR @pedane BETWEEN da AND a OR\n" +
" (@pedane IS NOT NULL AND da = 0 AND a = 0))");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,50 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.IntegryCustomer;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241112102706 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
if (!isCustomer(IntegryCustomer.RossoGargano)) return;
executeStatement(";with art as (select id_art_equi, \n" +
"cod_mart, \n" +
"cod_msgr,\n" +
"CONCAT_WS(' ', mtb_tipi.descrizione, mtb_aart.cod_tcol_UI, CAST(mtb_aart.qta_cnf AS FLOAT), 'x' ,\n" +
" CAST(mtb_aart.peso_kg AS FLOAT), mtb_stip.descrizione, mtb_aart.marchio) AS gruppo\n" +
"from mtb_aart\n" +
"left outer join mtb_tipi on mtb_aart.cod_mtip = mtb_tipi.cod_mtip\n" +
"left outer join mtb_stip on mtb_aart.cod_mtip = mtb_stip.cod_mtip and mtb_aart.cod_mstp = mtb_stip.cod_mstp \n" +
"where mtb_aart.cod_mgrp in ('00100','00200','00203','00210')\n" +
")\n" +
"\n" +
"select \n" +
"ISNull(max(id_art_equi) over (partition by cod_msgr, gruppo),\n" +
"\t\t\t\t min(cod_mart) over (partition by cod_msgr, gruppo)) as id_art_equi,\n" +
"gruppo AS descrizione,\n" +
"\t\t\t\t cod_mart\n" +
"into #tmpArtEqui\n" +
"from art \n" +
"\n" +
"insert into mtb_aart_equi ( id_art_equi, descrizione, flag_equi_prezzo)\n" +
"select distinct id_art_equi, descrizione, 'T' as flag_equi_prezzo from #tmpArtEqui where not exists ( select * from mtb_aart_equi where mtb_aart_equi.id_art_equi = #tmpArtEqui.id_art_equi )\n" +
"\n" +
"update mtb_aart set mtb_aart.id_art_equi = #tmpArtEqui.id_art_equi \n" +
"from mtb_aart inner join #tmpArtEqui on mtb_aart.cod_mart = #tmpArtEqui.cod_mart\n" +
"where (mtb_aart.id_art_equi is null or #tmpArtEqui.id_art_equi <> mtb_aart.id_art_equi)\n" +
"\n" +
"drop table #tmpArtEqui");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,24 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241112121357 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
executeStatement(
"IF EXISTS (SELECT * FROM SYS.syscolumns WHERE OBJECT_NAME(ID) = 'MTB_COLR' AND name = 'SYSTEM_NOTE') " +
"ALTER TABLE mtb_colr DROP COLUMN system_note ",
"ALTER TABLE mtb_colr ADD system_note varchar(255)");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,31 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.IntegryCustomerDB;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241112123240 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
if (isCustomerDb(IntegryCustomerDB.Gramm_Gramm)) {
executeStatement(
"UPDATE jtb_cicl_cq\n" +
"SET tipo_valore = 5\n" +
"WHERE valore_rif = 'Calendario'",
"UPDATE dtb_ord_cq\n" +
"SET tipo_valore = 5\n" +
"WHERE valore_rif = 'Calendario'"
);
}
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,21 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241112161551 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
executeStatement("ALTER TABLE ctb_movr_coan ADD id_lav VARCHAR(40)");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -0,0 +1,23 @@
package it.integry.ems.migration.model;
import it.integry.ems.migration._base.BaseMigration;
import it.integry.ems.migration._base.IntegryCustomer;
import it.integry.ems.migration._base.MigrationModelInterface;
public class Migration_20241112183616 extends BaseMigration implements MigrationModelInterface {
@Override
public void up() throws Exception {
if (isHistoryDB())
return;
if ( isCustomer(IntegryCustomer.Carelli))
updateSetupValue("PICKING", "ACCETTAZIONE_BOLLA", "FLAG_DISABLE_MANDATORY_TRACCIABILITA", "S");
}
@Override
public void down() throws Exception {
}
}

View File

@@ -136,11 +136,10 @@ public class MigrationSetupService {
public void executeAll() throws Exception { public void executeAll() throws Exception {
for (AvailableConnectionsModel availableConnectionsModel : settingsModel.getAvailableConnections()) { for (AvailableConnectionsModel availableConnectionsModel : settingsModel.getAvailableConnections(true)) {
if (multiDBTransactionManager.getActiveConnections().stream() if (multiDBTransactionManager.getActiveConnections().stream()
.noneMatch(advancedDataSource -> .noneMatch(advancedDataSource ->
advancedDataSource.getDataSource().getDbName().equalsIgnoreCase(availableConnectionsModel.getDbName()) && advancedDataSource.getDataSource().getDbName().equalsIgnoreCase(availableConnectionsModel.getDbName()))) {
advancedDataSource.isInternalDb())) {
multiDBTransactionManager.addConnection(availableConnectionsModel); multiDBTransactionManager.addConnection(availableConnectionsModel);
} }
} }

View File

@@ -10,7 +10,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
public class JasperDTO { public class JasperDTO {
private String b64XmlReport;//alternativa al resto, possibilmente dismetterlo private byte[] compiledJasper;
private Long reportId; private Long reportId;
private String reportName; private String reportName;
private String query; private String query;
@@ -41,12 +41,12 @@ public class JasperDTO {
return this; return this;
} }
public String getB64XmlReport() { public byte[] getCompiledJasper() {
return b64XmlReport; return compiledJasper;
} }
public JasperDTO setB64XmlReport(String b64XmlReport) { public JasperDTO setCompiledJasper(byte[] compiledJasper) {
this.b64XmlReport = b64XmlReport; this.compiledJasper = compiledJasper;
return this; return this;
} }

View File

@@ -3,6 +3,7 @@ package it.integry.ems.rules.completing;
import com.annimon.stream.ComparatorCompat; import com.annimon.stream.ComparatorCompat;
import com.annimon.stream.Optional; import com.annimon.stream.Optional;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import com.fasterxml.jackson.databind.ObjectMapper;
import it.integry.common.var.CommonConstants; import it.integry.common.var.CommonConstants;
import it.integry.ems.sync.MultiDBTransaction.Connection; import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems_model.annotation.ReloadRow; import it.integry.ems_model.annotation.ReloadRow;
@@ -991,6 +992,38 @@ public class CommonRules extends QueryRules {
return mtbAartMarchio; return mtbAartMarchio;
} }
public static String getIdArtEqui(Connection conn, MtbAart entity) throws Exception {
Map<String, Object> data = new HashMap<>();
data.put("cod_mgrp", entity.getCodMgrp());
data.put("cod_msgr", entity.getCodMsgr());
data.put("cod_mtip", entity.getCodMtip());
data.put("qta_cnf", entity.getQtaCnf());
data.put("peso_kg", entity.getPesoKg());
data.put("cod_tcol_UI",entity.getCodTcolUi());
data.put("marchio", entity.getMarchio());
// Convertire in JSON
ObjectMapper objectMapper = new ObjectMapper();
String jsonParm = objectMapper.writeValueAsString(data);
String sql =
String.format(
"SELECT * FROM dbo.suggestMtbArtEqui('%s') " ,
jsonParm);
MtbAartEqui mtbAartEqui = UtilityDB.executeSimpleQueryOnlyFirstRowDTO(conn, sql, MtbAartEqui.class);
if (mtbAartEqui != null ) {
String idArtEqui =mtbAartEqui.getIdArtEqui();
if (UtilityString.isNullOrEmpty(mtbAartEqui.getIdArtEqui())) {
idArtEqui = entity.getCodMart();
mtbAartEqui.setIdArtEqui(idArtEqui)
.setFlagEquiPrezzo("T");
mtbAartEqui.setOperation(OperationType.INSERT_OR_UPDATE);
}
return idArtEqui;
}
return null;
}
public static MtbAartEqui insEqui(Connection conn, MtbAart entity) throws Exception { public static MtbAartEqui insEqui(Connection conn, MtbAart entity) throws Exception {
String sql = "SELECT id_art_equi FROM mtb_aart_equi WHERE id_art_equi = " + UtilityDB.valueToString(entity.getIdArtEqui()); String sql = "SELECT id_art_equi FROM mtb_aart_equi WHERE id_art_equi = " + UtilityDB.valueToString(entity.getIdArtEqui());
HashMap<String, Object> map = execSingleQuery(conn, sql); HashMap<String, Object> map = execSingleQuery(conn, sql);

View File

@@ -490,14 +490,16 @@ public class OrderRules extends QueryRules {
DtbOrdr::getIdViaggio DtbOrdr::getIdViaggio
).distinct().collect(Collectors.toList()); ).distinct().collect(Collectors.toList());
String sql = if (listaIdViaggio != null && listaIdViaggio.size() > 0 ) {
String.format( String sql =
"SELECT TOP 1 cod_vvet FROM vtb_viaggi WHERE id_viaggio in (%s) ORDER BY data_ora_iniz_trasp DESC", String.format(
UtilityDB.listValueToString(listaIdViaggio)); "SELECT TOP 1 cod_vvet FROM vtb_viaggi WHERE id_viaggio in (%s) ORDER BY data_ora_iniz_trasp DESC",
UtilityDB.listValueToString(listaIdViaggio));
String codVvet = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(conn, sql); String codVvet = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(conn, sql);
if ( !UtilityString.isNullOrEmpty(codVvet)){ if (!UtilityString.isNullOrEmpty(codVvet)) {
dtbOrdt.setCodVvet(codVvet); dtbOrdt.setCodVvet(codVvet);
}
} }
} }
} }

View File

@@ -5,6 +5,7 @@ import it.integry.ems.report.dto.JasperDTO;
import it.integry.ems.report.dto.PairsDTO; import it.integry.ems.report.dto.PairsDTO;
import it.integry.ems.report.dto.ReportTypeDTO; import it.integry.ems.report.dto.ReportTypeDTO;
import it.integry.ems.report.dto.SubreportDTO; import it.integry.ems.report.dto.SubreportDTO;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.utility.UtilityDirs; import it.integry.ems.utility.UtilityDirs;
import it.integry.ems.utility.UtilityFile; import it.integry.ems.utility.UtilityFile;
@@ -13,7 +14,10 @@ import it.integry.ems.utility.UtilityURL;
import it.integry.ems_model.entity.WtbJrept; import it.integry.ems_model.entity.WtbJrept;
import it.integry.ems_model.entity.WtbJreptSetup; import it.integry.ems_model.entity.WtbJreptSetup;
import it.integry.ems_model.service.SetupGest; import it.integry.ems_model.service.SetupGest;
import it.integry.ems_model.utility.*; import it.integry.ems_model.utility.Query;
import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityHashMap;
import it.integry.ems_model.utility.UtilityString;
import net.sf.jasperreports.engine.*; import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource; import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.data.JsonDataSource; import net.sf.jasperreports.engine.data.JsonDataSource;
@@ -23,6 +27,7 @@ import net.sf.jasperreports.engine.export.JRPdfExporter;
import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter; import net.sf.jasperreports.engine.export.ooxml.JRXlsxExporter;
import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory; import net.sf.jasperreports.engine.query.JRXPathQueryExecuterFactory;
import net.sf.jasperreports.engine.type.OrientationEnum; import net.sf.jasperreports.engine.type.OrientationEnum;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.engine.util.JRXmlUtils; import net.sf.jasperreports.engine.util.JRXmlUtils;
import net.sf.jasperreports.engine.xml.JRXmlLoader; import net.sf.jasperreports.engine.xml.JRXmlLoader;
import net.sf.jasperreports.export.SimpleExporterInput; import net.sf.jasperreports.export.SimpleExporterInput;
@@ -36,15 +41,12 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.w3c.dom.Document; import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.*; import java.io.*;
import java.util.ArrayList;
import it.integry.ems.sync.MultiDBTransaction.Connection; import java.util.HashMap;
import java.util.List;
import java.text.SimpleDateFormat; import java.util.Locale;
import java.util.*;
@Service @Service
@Scope("request") @Scope("request")
@@ -55,6 +57,7 @@ public class ReportProcessor {
@Autowired @Autowired
private ResponseJSONObjectMapper jsonObjectMapper; private ResponseJSONObjectMapper jsonObjectMapper;
@Autowired @Autowired
private SetupGest setupGest; private SetupGest setupGest;
@@ -73,117 +76,46 @@ public class ReportProcessor {
return UtilityDirs.getEmsApiTempDirectoryPath() + File.separator + "report_jasper" + File.separator; return UtilityDirs.getEmsApiTempDirectoryPath() + File.separator + "report_jasper" + File.separator;
} }
public JasperDTO XMLToDTO(String xmlDto) throws Exception {
String b64Jrxml = null, query = null, whereCond = null, jsonSource = null,
params = null, /*formatoExport = null,*/ name = null;
JasperDTO jasperDTO = null; // private String prepareTempReportFile(JasperDTO jasperDTO, ArrayList<String> fileTempList) throws Exception {
Document doc = UtilityXML.convertStringToDocument(xmlDto); // String pathJrxml = null;
// String b64ReportJrxml = jasperDTO.getB64ReportJrxml();
if (doc == null) { //
throw new Exception("XML non valido"); // if (jasperDTO.getReportId() != null) {
} // JasperDTO jasperDTOTmp = this.getReportByID(jasperDTO.getReportId());
if (doc.getElementsByTagName("QUERY") != null && doc.getElementsByTagName("QUERY").getLength() > 0) { // if (b64ReportJrxml == null) {
query = doc.getElementsByTagName("QUERY").item(0).getTextContent(); // b64ReportJrxml = jasperDTOTmp.getB64ReportJrxml();
} // jasperDTO.setB64ReportJrxml(b64ReportJrxml)
if (doc.getElementsByTagName("WHERE_COND") != null && doc.getElementsByTagName("WHERE_COND").getLength() > 0) { // .setCompiledJasper(jasperDTOTmp.getCompiledJasper());
whereCond = doc.getElementsByTagName("WHERE_COND").item(0).getTextContent(); // }
} // if (jasperDTO.getSubreports() == null) {
if (doc.getElementsByTagName("JSON_SOURCE") != null && doc.getElementsByTagName("JSON_SOURCE").getLength() > 0) { // jasperDTO.setSubreports(jasperDTOTmp.getSubreports());
jsonSource = doc.getElementsByTagName("JSON_SOURCE").item(0).getTextContent(); // }
} // }
if (doc.getElementsByTagName("PARAMS") != null && doc.getElementsByTagName("PARAMS").getLength() > 0) { // /*
params = doc.getElementsByTagName("PARAMS").item(0).getTextContent(); // if(reportName != null && b64ReportJrxml==null) {
} // JasperDTO jasperDTOTmp = this.getReportByName(reportName);
if (doc.getElementsByTagName("NAME") != null && doc.getElementsByTagName("NAME").getLength() > 0) { // b64ReportJrxml = jasperDTOTmp.getB64ReportJrxml();
name = doc.getElementsByTagName("NAME").item(0).getTextContent(); // jasperDTO.setB64ReportJrxml(jasperDTOTmp.getB64ReportJrxml());
} // jasperDTO.setSubreports(jasperDTOTmp.getSubreports());
if (doc.getElementsByTagName("B64_JRXML") != null && doc.getElementsByTagName("B64_JRXML").getLength() > 0) { // }*/
b64Jrxml = doc.getElementsByTagName("B64_JRXML").item(0).getTextContent(); //
} // if (b64ReportJrxml != null) {
// SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss.SSS");
// String pathJrxmlTemp = this.getPathJrxmlTemp();
jasperDTO = new JasperDTO(); // pathJrxml = pathJrxmlTemp + "tmp" + sdf.format(new Date()) + ".jrxml";
if (!UtilityString.isNullOrEmpty(name)) { //
jasperDTO.setReportId(this.getReportID(name)); // FileOutputStream fos = new FileOutputStream(new File(pathJrxml));
// IOUtils.write(Base64.decodeBase64(b64ReportJrxml), fos);
} else { // fos.close();
if (b64Jrxml != null) { // fileTempList.add(pathJrxml);
jasperDTO.setB64ReportJrxml(b64Jrxml); //
Node subreports = doc.getElementsByTagName("SUB_REPORTS").item(0); // } else {
NodeList nodeListSubRep = subreports.getChildNodes(); // throw new Exception("Sorgente jrxml non trovato");
// }
List<SubreportDTO> subreportsList = new ArrayList<SubreportDTO>(); //
for (int i = 0; i < nodeListSubRep.getLength(); i++) { // return pathJrxml;
SubreportDTO dto = new SubreportDTO(); // }
Node currentNode = nodeListSubRep.item(i);
String jasperFilename = currentNode.getAttributes().getNamedItem("FILENAME").getNodeValue();
Node firstChild = currentNode.getFirstChild();
if ("B64_JASPER".equals(firstChild.getNodeName())) {
dto.setB64Report(firstChild.getTextContent()); // "B64_JASPER";
} else if ("B64_JRXML".equals(firstChild.getNodeName())) {
dto.setB64Jrxml(firstChild.getTextContent()); // "B64_JRXML";
}
dto.setName(jasperFilename);
subreportsList.add(dto);
}
jasperDTO.setSubreports(subreportsList);
} else {
throw new Exception("Report non identificato");
}
}
jasperDTO.setQuery(query);
jasperDTO.setWhereCond(whereCond);
jasperDTO.setJsonSource(jsonSource);
if (!UtilityString.isNullOrEmpty(params)) {
params = params.replaceAll("'", "\"");
PairsDTO[] pairs = jsonObjectMapper.readValue(params, PairsDTO[].class);
jasperDTO.setParams(Arrays.asList(pairs));
}
return jasperDTO;
}
private String prepareTempReportFile(JasperDTO jasperDTO, ArrayList<String> fileTempList) throws Exception {
String pathJrxml = null;
String b64ReportJrxml = jasperDTO.getB64ReportJrxml();
if (jasperDTO.getReportId() != null) {
JasperDTO jasperDTOTmp = this.getReportByID(jasperDTO.getReportId());
if (b64ReportJrxml == null) {
b64ReportJrxml = jasperDTOTmp.getB64ReportJrxml();
jasperDTO.setB64ReportJrxml(b64ReportJrxml);
}
if (jasperDTO.getSubreports() == null) {
jasperDTO.setSubreports(jasperDTOTmp.getSubreports());
}
}
/*
if(reportName != null && b64ReportJrxml==null) {
JasperDTO jasperDTOTmp = this.getReportByName(reportName);
b64ReportJrxml = jasperDTOTmp.getB64ReportJrxml();
jasperDTO.setB64ReportJrxml(jasperDTOTmp.getB64ReportJrxml());
jasperDTO.setSubreports(jasperDTOTmp.getSubreports());
}*/
if (b64ReportJrxml != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd-HH.mm.ss.SSS");
String pathJrxmlTemp = this.getPathJrxmlTemp();
pathJrxml = pathJrxmlTemp + "tmp" + sdf.format(new Date()) + ".jrxml";
FileOutputStream fos = new FileOutputStream(new File(pathJrxml));
IOUtils.write(Base64.decodeBase64(b64ReportJrxml), fos);
fos.close();
fileTempList.add(pathJrxml);
} else {
throw new Exception("Sorgente jrxml non trovato");
}
return pathJrxml;
}
private String getSubreportPath() throws Exception { private String getSubreportPath() throws Exception {
return this.getPathJrxmlTemp(); return this.getPathJrxmlTemp();
@@ -234,48 +166,45 @@ public class ReportProcessor {
} }
} }
private JasperPrint fillReportJavabean(JasperDesign jasperDesign, HashMap<String, Object> hm_parameters, List<Object> javabeans) throws Exception { private JasperPrint fillReportJavabean(JasperReport jasperReport, HashMap<String, Object> hm_parameters, List<Object> javabeans) throws Exception {
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JRDataSource jrds = new JRBeanCollectionDataSource(javabeans); JRDataSource jrds = new JRBeanCollectionDataSource(javabeans);
return JasperFillManager.fillReport(jasperReport, hm_parameters, jrds); return JasperFillManager.fillReport(jasperReport, hm_parameters, jrds);
} }
private JasperPrint fillReportJsonsource(JasperDesign jasperDesign, HashMap<String, Object> hm_parameters, String jsonSource) throws Exception { private JasperPrint fillReportJsonsource(JasperReport jasperReport, HashMap<String, Object> hm_parameters, String jsonSource) throws Exception {
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
InputStream stream = new ByteArrayInputStream(jsonSource.getBytes("UTF-8")); InputStream stream = new ByteArrayInputStream(jsonSource.getBytes("UTF-8"));
JsonDataSource ds = new JsonDataSource(stream); JsonDataSource ds = new JsonDataSource(stream);
ds.setLocale(Locale.US); ds.setLocale(Locale.US);
return JasperFillManager.fillReport(jasperReport, hm_parameters, ds); return JasperFillManager.fillReport(jasperReport, hm_parameters, ds);
} }
private JasperPrint fillReportSql(JasperDesign jasperDesign, HashMap<String, Object> hm_parameters, String query, String whereCond) throws Exception { private JasperPrint fillReportSql(JasperDesign jasperDesign, JasperReport jasperReport, HashMap<String, Object> hm_parameters, String query, String whereCond) throws Exception {
String sql = !UtilityString.isNullOrEmpty(query) ? query : jasperDesign.getQuery().getText(); String sql = !UtilityString.isNullOrEmpty(query) ? query : jasperReport.getQuery().getText();
if (whereCond != null && whereCond.replaceAll("\\s+", "").compareTo("1=1") != 0) { if (whereCond != null && whereCond.replaceAll("\\s+", "").compareTo("1=1") != 0) {
// sql = sql.replaceAll("(?i)where", "WHERE"); // GESTITA NEL METODO la sostituzione in addwhereCond è case sensitive, con le parole chiave tutte in maiuscolo // sql = sql.replaceAll("(?i)where", "WHERE"); // GESTITA NEL METODO la sostituzione in addwhereCond è case sensitive, con le parole chiave tutte in maiuscolo
sql = UtilityDB.addwhereCond(sql, whereCond, true, true, true); sql = UtilityDB.addwhereCond(sql, whereCond, true, true, true);
JRDesignQuery newQuery = new JRDesignQuery(); JRDesignQuery newQuery = new JRDesignQuery();
newQuery.setText(sql); newQuery.setText(sql);
jasperDesign.setQuery(newQuery); jasperDesign.setQuery(newQuery);
jasperReport = JasperCompileManager.compileReport(jasperDesign);
} }
/*JRFileVirtualizer virtualizer = new JRFileVirtualizer(50, System.getProperty("java.io.tmpdir")); /*JRFileVirtualizer virtualizer = new JRFileVirtualizer(50, System.getProperty("java.io.tmpdir"));
virtualizer.setReadOnly(false); virtualizer.setReadOnly(false);
hm_parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer); */ hm_parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer); */
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
//virtualizer.cleanup(); //virtualizer.cleanup();
return JasperFillManager.fillReport(jasperReport, hm_parameters, multiDBTransactionManager.getPrimaryConnection()); return JasperFillManager.fillReport(jasperReport, hm_parameters, multiDBTransactionManager.getPrimaryConnection());
} }
private JasperPrint fillReportXpath(JasperDesign jasperDesign, HashMap<String, Object> hm_parameters, String query, String whereCond) throws Exception { private JasperPrint fillReportXpath(JasperReport jasperReport, HashMap<String, Object> hm_parameters, String query, String whereCond) throws Exception {
String sql = !UtilityString.isNullOrEmpty(query) ? query : jasperDesign.getQuery().getText(); String sql = !UtilityString.isNullOrEmpty(query) ? query : jasperReport.getQuery().getText();
if (whereCond != null && whereCond.replaceAll("\\s+", "").compareTo("1=1") != 0) { if (whereCond != null && whereCond.replaceAll("\\s+", "").compareTo("1=1") != 0) {
sql = UtilityDB.addwhereCond(query, whereCond, true); sql = UtilityDB.addwhereCond(query, whereCond, true);
} }
String fileXml = UtilityDB.query2XML(sql, multiDBTransactionManager.getPrimaryConnection(), "root", "righe"); String fileXml = UtilityDB.query2XML(sql, multiDBTransactionManager.getPrimaryConnection(), "root", "righe");
if (fileXml != null && fileXml.length() > 0) { if (fileXml != null && !fileXml.isEmpty()) {
Document doc = JRXmlUtils.parse(IOUtils.toInputStream(fileXml, "UTF-8")); Document doc = JRXmlUtils.parse(IOUtils.toInputStream(fileXml, "UTF-8"));
hm_parameters.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, doc); hm_parameters.put(JRXPathQueryExecuterFactory.PARAMETER_XML_DATA_DOCUMENT, doc);
} else { } else {
@@ -286,7 +215,6 @@ public class ReportProcessor {
virtualizer.setReadOnly(false); */ virtualizer.setReadOnly(false); */
//hm_parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer); //hm_parameters.put(JRParameter.REPORT_VIRTUALIZER, virtualizer);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
//virtualizer.cleanup(); //virtualizer.cleanup();
return JasperFillManager.fillReport(jasperReport, hm_parameters, multiDBTransactionManager.getPrimaryConnection()); return JasperFillManager.fillReport(jasperReport, hm_parameters, multiDBTransactionManager.getPrimaryConnection());
} }
@@ -313,26 +241,23 @@ public class ReportProcessor {
} }
public byte[] processReport(JasperDTO jasperDTO) throws Exception { public byte[] processReport(JasperDTO jasperDTO) throws Exception {
ArrayList<String> fileTempList = new ArrayList<String>(); ArrayList<String> filesToClean = new ArrayList<String>();
try { try {
String b64XmlReport = jasperDTO.getB64XmlReport();
if (!UtilityString.isNullOrEmpty(b64XmlReport)) {
String xmlDto = new String(Base64.decodeBase64(b64XmlReport.getBytes()));
jasperDTO = this.XMLToDTO(xmlDto);
}
if (!UtilityString.isNullOrEmpty(jasperDTO.getReportName()) && jasperDTO.getReportId() == null) { if (!UtilityString.isNullOrEmpty(jasperDTO.getReportName()) && jasperDTO.getReportId() == null) {
jasperDTO.setReportId(getReportID(jasperDTO.getReportName())); jasperDTO.setReportId(getReportID(jasperDTO.getReportName()));
} }
//Refill
jasperDTO = getReportByID(jasperDTO.getReportId(), jasperDTO.getParams());
if (jasperDTO.getOrientation() == null && jasperDTO.getReportId() != null) { if (jasperDTO.getOrientation() == null && jasperDTO.getReportId() != null) {
String sql = "SELECT orientation FROM " + WtbJrept.ENTITY + " WHERE id = " + UtilityDB.valueToString(jasperDTO.getReportId()); String sql = "SELECT orientation FROM " + WtbJrept.ENTITY + " WHERE id = " + UtilityDB.valueToString(jasperDTO.getReportId());
int orientation = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(multiDBTransactionManager.getPrimaryConnection(), sql); int orientation = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(multiDBTransactionManager.getPrimaryConnection(), sql);
jasperDTO.setOrientation(WtbJreptSetup.Orientation.from(orientation)); jasperDTO.setOrientation(WtbJreptSetup.Orientation.from(orientation));
} }
String pathJrxml = this.prepareTempReportFile(jasperDTO, fileTempList); // this.prepareTempReportFile(jasperDTO);
this.prepareTempSubreportFiles(jasperDTO, fileTempList); this.prepareTempSubreportFiles(jasperDTO, filesToClean);
String jsonSource = jasperDTO.getJsonSource(); String jsonSource = jasperDTO.getJsonSource();
List<Object> javaBeans = jasperDTO.getJavaBeans(); List<Object> javaBeans = jasperDTO.getJavaBeans();
@@ -363,26 +288,37 @@ public class ReportProcessor {
jasperReportsContext.setProperty("net.sf.jasperreports.default.pdf.embedded", "true"); jasperReportsContext.setProperty("net.sf.jasperreports.default.pdf.embedded", "true");
jasperReportsContext.setProperty("net.sf.jasperreports.query.executer.factory.xmla-mdx", "net.sf.jasperreports.engine.query.JRXmlaQueryExecuterFactory"); jasperReportsContext.setProperty("net.sf.jasperreports.query.executer.factory.xmla-mdx", "net.sf.jasperreports.engine.query.JRXmlaQueryExecuterFactory");
JasperDesign jasperDesign = JRXmlLoader.load(pathJrxml); byte[] jrxml = Base64.decodeBase64(jasperDTO.getB64ReportJrxml());
JasperDesign jasperDesign = JRXmlLoader.load(new ByteArrayInputStream(jrxml));
JasperReport jasperReport = null;
if (jasperDTO.getCompiledJasper() != null) {
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(jasperDTO.getCompiledJasper());
jasperReport = (JasperReport) JRLoader.loadObject(byteArrayInputStream);
} else {
jasperReport = JasperCompileManager.compileReport(jasperDesign);
}
JasperPrint jp; JasperPrint jp;
if (javaBeans != null) { if (javaBeans != null) {
hm_parameters.put("REPORT_CONNECTION", multiDBTransactionManager.getPrimaryConnection()); hm_parameters.put("REPORT_CONNECTION", multiDBTransactionManager.getPrimaryConnection());
jp = this.fillReportJavabean(jasperDesign, hm_parameters, javaBeans); jp = this.fillReportJavabean(jasperReport, hm_parameters, javaBeans);
} else if (!UtilityString.isNullOrEmpty(jsonSource)) { } else if (!UtilityString.isNullOrEmpty(jsonSource)) {
hm_parameters.put("REPORT_CONNECTION", multiDBTransactionManager.getPrimaryConnection()); hm_parameters.put("REPORT_CONNECTION", multiDBTransactionManager.getPrimaryConnection());
jp = this.fillReportJsonsource(jasperDesign, hm_parameters, jsonSource); jp = this.fillReportJsonsource(jasperReport, hm_parameters, jsonSource);
} else { } else {
String query = jasperDTO.getQuery(); String query = jasperDTO.getQuery();
String whereCond = jasperDTO.getWhereCond(); String whereCond = jasperDTO.getWhereCond();
String queryLanguage = jasperDesign.getQuery().getLanguage().toLowerCase(); String queryLanguage = jasperReport.getQuery().getLanguage().toLowerCase();
if ("sql".equalsIgnoreCase(queryLanguage)) { if ("sql".equalsIgnoreCase(queryLanguage)) {
jp = this.fillReportSql(jasperDesign, hm_parameters, query, whereCond); jp = this.fillReportSql(jasperDesign, jasperReport, hm_parameters, query, whereCond);
} else if ("xpath".equalsIgnoreCase(queryLanguage)) { } else if ("xpath".equalsIgnoreCase(queryLanguage)) {
jp = this.fillReportXpath(jasperDesign, hm_parameters, query, whereCond); jp = this.fillReportXpath(jasperReport, hm_parameters, query, whereCond);
} else { } else {
throw new Exception("Query language '" + queryLanguage + "' non supportato"); throw new Exception("Query language '" + queryLanguage + "' non supportato");
@@ -392,11 +328,7 @@ public class ReportProcessor {
throw new Exception("JasperPrint non valido"); throw new Exception("JasperPrint non valido");
} }
if (!jp.getPages().isEmpty()) {/* if (!jp.getPages().isEmpty()) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
JRAbstractExporter exporter = null;
if(("PDF").equals(outFormat)){*/
if (jasperDTO.getOrientation() != null) { if (jasperDTO.getOrientation() != null) {
switch (jasperDTO.getOrientation()) { switch (jasperDTO.getOrientation()) {
@@ -453,7 +385,7 @@ public class ReportProcessor {
} catch (Exception e) { } catch (Exception e) {
throw e; throw e;
} finally { } finally {
this.cleanTempFiles(fileTempList); this.cleanTempFiles(filesToClean);
} }
} }
@@ -497,9 +429,10 @@ public class ReportProcessor {
return paramsMap; return paramsMap;
} }
private JasperDTO getReportByID(Long reportId) throws Exception { private JasperDTO getReportByID(Long reportId, List<PairsDTO> params) throws Exception {
String sql = "SELECT id, " + String sql = "SELECT id, " +
" CONVERT(TEXT, b64_jrxml) AS b64_jrxml " + " CONVERT(TEXT, b64_jrxml) AS b64_jrxml," +
" compiled_jasper " +
"FROM " + WtbJrept.ENTITY + " " + "FROM " + WtbJrept.ENTITY + " " +
"WHERE id = " + UtilityDB.valueToString(reportId); "WHERE id = " + UtilityDB.valueToString(reportId);
@@ -508,8 +441,10 @@ public class ReportProcessor {
if (result == null) throw new Exception("Report non valido"); if (result == null) throw new Exception("Report non valido");
JasperDTO jasperDTO = new JasperDTO() JasperDTO jasperDTO = new JasperDTO()
.setParams(params)
.setReportId(UtilityHashMap.getValueIfExists(result, "id")) .setReportId(UtilityHashMap.getValueIfExists(result, "id"))
.setB64ReportJrxml(UtilityHashMap.getValueIfExists(result, "b64_jrxml")); .setB64ReportJrxml(UtilityHashMap.getValueIfExists(result, "b64_jrxml"))
.setCompiledJasper(UtilityHashMap.getValueIfExists(result, "compiled_jasper"));
sql = "SELECT jasper_filename, b64_jasper " + sql = "SELECT jasper_filename, b64_jasper " +
"FROM wtb_jrepr_sub " + "FROM wtb_jrepr_sub " +

View File

@@ -19,7 +19,6 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.locks.ReentrantLock; import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -53,7 +52,7 @@ public class UnitaTerritorialiService {
private void updateComuni() { private void updateComuni() {
try { try {
logger.info("Avvio aggiornamento comuni"); logger.info("Avvio aggiornamento comuni");
updateIfNeeded().get(); updateIfNeeded();
logger.info(String.format("Aggiornati %d comuni, %d province, %d regioni", comuni.size(), unita.stream().filter(x -> x.getTipologiaId() == 1).count(), regioni.size())); logger.info(String.format("Aggiornati %d comuni, %d province, %d regioni", comuni.size(), unita.stream().filter(x -> x.getTipologiaId() == 1).count(), regioni.size()));
} catch (Exception e) { } catch (Exception e) {
logger.error("Errore aggiornamento comuni", e); logger.error("Errore aggiornamento comuni", e);
@@ -62,37 +61,31 @@ public class UnitaTerritorialiService {
} }
// Metodo che verifica se occorre aggiornare il servizio // Metodo che verifica se occorre aggiornare il servizio
private Future<Void> updateIfNeeded() { private void updateIfNeeded() throws Exception {
return executor.submit(() -> { Instant currentLastModifiedSource = getLastModifiedSource();
Instant currentLastModifiedSource = getLastModifiedSource().get(); if (lastModifiedSource.isBefore(currentLastModifiedSource)) {
if (lastModifiedSource.isBefore(currentLastModifiedSource)) { update();
update().get(); }
}
return null;
});
} }
// Metodo che aggiorna i dati del servizio // Metodo che aggiorna i dati del servizio
private Future<Void> update() { private void update() throws Exception {
return executor.submit(() -> { HttpURLConnection connectionIstat = (HttpURLConnection) new URL(PERMALINK_ISTAT).openConnection();
HttpURLConnection connectionIstat = (HttpURLConnection) new URL(PERMALINK_ISTAT).openConnection(); connectionIstat.setRequestMethod("GET");
connectionIstat.setRequestMethod("GET");
int responseCodeIstat = connectionIstat.getResponseCode(); int responseCodeIstat = connectionIstat.getResponseCode();
if (responseCodeIstat != 200) { if (responseCodeIstat != 200) {
return null; return;
} }
updateLocker.lock(); updateLocker.lock();
try (InputStream streamIstat = connectionIstat.getInputStream()) { try (InputStream streamIstat = connectionIstat.getInputStream()) {
if (updateServiceData(streamIstat)) { if (updateServiceData(streamIstat)) {
lastModifiedSource = Instant.now(); // Recupera la data di modifica dal server lastModifiedSource = Instant.now(); // Recupera la data di modifica dal server
}
} finally {
updateLocker.unlock();
} }
return null; } finally {
}); updateLocker.unlock();
}
} }
// Metodo che legge e converte i dati Istat // Metodo che legge e converte i dati Istat
@@ -214,71 +207,55 @@ public class UnitaTerritorialiService {
} }
// Metodo che restituisce la data di ultima modifica // Metodo che restituisce la data di ultima modifica
private Future<Instant> getLastModifiedSource() { private Instant getLastModifiedSource() throws Exception {
return executor.submit(() -> { HttpURLConnection connection = (HttpURLConnection) new URL(PERMALINK_ISTAT).openConnection();
HttpURLConnection connection = (HttpURLConnection) new URL(PERMALINK_ISTAT).openConnection(); connection.setRequestMethod("HEAD");
connection.setRequestMethod("HEAD"); connection.connect();
connection.connect(); int responseCode = connection.getResponseCode();
int responseCode = connection.getResponseCode(); if (responseCode != 200) {
if (responseCode != 200) {
return Instant.MIN;
}
String lastModified = connection.getHeaderField("Last-Modified");
if (lastModified != null) {
return Instant.now(); // Converti in Instant, se necessario
}
return Instant.MIN; return Instant.MIN;
}); }
String lastModified = connection.getHeaderField("Last-Modified");
if (lastModified != null) {
return Instant.now(); // Converti in Instant, se necessario
}
return Instant.MIN;
} }
// Metodi pubblici per accedere ai dati aggiornati // Metodi pubblici per accedere ai dati aggiornati
public Future<List<IstatComuneDataRow>> getUpdatedDataSource() { public List<IstatComuneDataRow> getUpdatedDataSource() throws Exception {
return executor.submit(() -> { updateIfNeeded();
updateIfNeeded().get(); return dataSource;
return dataSource;
});
} }
public Future<List<Regione>> getUpdatedRegioni() { public List<Regione> getUpdatedRegioni() throws Exception {
return executor.submit(() -> { updateIfNeeded();
updateIfNeeded().get(); return regioni;
return regioni;
});
} }
public Future<List<UnitaSovracomunale>> getUpdatedUnitaSovracomunali() { public List<UnitaSovracomunale> getUpdatedUnitaSovracomunali() throws Exception {
return executor.submit(() -> { updateIfNeeded();
updateIfNeeded().get(); return unita;
return unita;
});
} }
public Future<List<TipologiaUnitaSovracomunale>> getUpdatedTipologieUnitaSovracomunali() { public List<TipologiaUnitaSovracomunale> getUpdatedTipologieUnitaSovracomunali() throws Exception {
return executor.submit(() -> { updateIfNeeded();
updateIfNeeded().get(); return tipologieUnitaSovracomunali;
return tipologieUnitaSovracomunali;
});
} }
public Future<List<Comune>> getUpdatedComuni() { public List<Comune> getUpdatedComuni() throws Exception {
return executor.submit(() -> { updateIfNeeded();
updateIfNeeded().get(); return comuni;
return comuni;
});
} }
public Future<List<TipologiaComune>> getUpdatedTipologieComuni() { public List<TipologiaComune> getUpdatedTipologieComuni() throws Exception {
return executor.submit(() -> { updateIfNeeded();
updateIfNeeded().get(); return tipologieComuni;
return tipologieComuni;
});
} }
public Future<List<RipartizioneGeografica>> getUpdatedRipartizioniGeografiche() { public List<RipartizioneGeografica> getUpdatedRipartizioniGeografiche() throws Exception {
return executor.submit(() -> { updateIfNeeded();
updateIfNeeded().get(); return ripartizioniGeografiche;
return ripartizioniGeografiche;
});
} }
public List<Regione> getRegioni() { public List<Regione> getRegioni() {
@@ -294,7 +271,7 @@ public class UnitaTerritorialiService {
} }
public List<Comune> getComuni() { public List<Comune> getComuni() {
return (List<Comune>) ((ArrayList<Comune>)comuni).clone(); return (List<Comune>) ((ArrayList<Comune>) comuni).clone();
} }
public List<TipologiaComune> getTipologieComuni() { public List<TipologiaComune> getTipologieComuni() {

View File

@@ -10,6 +10,8 @@ import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Component @Component
public class SettingsModel implements InitializingBean { public class SettingsModel implements InitializingBean {
@@ -94,8 +96,14 @@ public class SettingsModel implements InitializingBean {
return this; return this;
} }
public ArrayList<AvailableConnectionsModel> getAvailableConnections() { public List<AvailableConnectionsModel> getAvailableConnections() {
return availableConnections.get(); return getAvailableConnections(false);
}
public List<AvailableConnectionsModel> getAvailableConnections(boolean onlyInternal) {
return availableConnections.get().stream()
.filter(x -> !onlyInternal || x.getInternalDb())
.collect(Collectors.toList());
} }
public void addAvailableConnection(AvailableConnectionsModel availableConnectionsModel) { public void addAvailableConnection(AvailableConnectionsModel availableConnectionsModel) {

View File

@@ -51,7 +51,7 @@ public class AsyncManager {
@PostContextConstruct @PostContextConstruct
public void init() { public void init() {
if (true || (!UtilityDebug.isDebugExecution() && !UtilityDebug.isIntegryServer())) { if ((!UtilityDebug.isDebugExecution() && !UtilityDebug.isIntegryServer())) {
looperService.add(this::internalCachePublicationsSetup, 5 * 60 * 1000, "sync-setup-cache"); looperService.add(this::internalCachePublicationsSetup, 5 * 60 * 1000, "sync-setup-cache");
looperService.add(this::consumeToBeSavedQueue, 20 * 1000, "sync-flush-data"); looperService.add(this::consumeToBeSavedQueue, 20 * 1000, "sync-flush-data");
} }
@@ -137,7 +137,7 @@ public class AsyncManager {
//TODO: Calc transaction group ID here //TODO: Calc transaction group ID here
if (transactionGroupId == null) transactionGroupId = getNextTransactionGroupId(connection, publicationId); if (transactionGroupId == null) transactionGroupId = getNextTransactionGroupId(connection, publicationId);
ResponseJSONObjectMapper jsonObjectMapper = ContextLoader.getCurrentWebApplicationContext().getBean(ResponseJSONObjectMapper.class); ResponseJSONObjectMapper jsonObjectMapper = Objects.requireNonNull(ContextLoader.getCurrentWebApplicationContext()).getBean(ResponseJSONObjectMapper.class);
StbTransactionLog stbTransactionLog = new StbTransactionLog() StbTransactionLog stbTransactionLog = new StbTransactionLog()
.setCreatedAt(UtilityLocalDate.getNowTime()) .setCreatedAt(UtilityLocalDate.getNowTime())
@@ -180,7 +180,7 @@ public class AsyncManager {
String insertSQL = "INSERT INTO " + StbTransactionLog.ENTITY + " (publication_group_id, created_at, user_name, entities, entities_json, group_id)" + String insertSQL = "INSERT INTO " + StbTransactionLog.ENTITY + " (publication_group_id, created_at, user_name, entities, entities_json, group_id)" +
" VALUES (?, ?, ?, ?, ?, ?)"; " VALUES (?, ?, ?, ?, ?, ?)";
Map.Entry<String, StbTransactionLog> itemToSave = null; Map.Entry<String, StbTransactionLog> itemToSave;
while ((itemToSave = toBeSavedQueue.poll()) != null) { while ((itemToSave = toBeSavedQueue.poll()) != null) {
final Map.Entry<String, StbTransactionLog> finalItemToSave = itemToSave; final Map.Entry<String, StbTransactionLog> finalItemToSave = itemToSave;
final StbTransactionLog stbTransactionLog = finalItemToSave.getValue(); final StbTransactionLog stbTransactionLog = finalItemToSave.getValue();
@@ -188,7 +188,7 @@ public class AsyncManager {
AvailableConnectionsModel connectionModel = databaseConnections.stream() AvailableConnectionsModel connectionModel = databaseConnections.stream()
.filter(x -> x.getDbName().equalsIgnoreCase(finalItemToSave.getKey())) .filter(x -> x.getDbName().equalsIgnoreCase(finalItemToSave.getKey()))
.findFirst() .findFirst()
.get(); .orElse(null);
try (MultiDBTransactionManager multiDBTransactionManager = new MultiDBTransactionManager(connectionModel); try (MultiDBTransactionManager multiDBTransactionManager = new MultiDBTransactionManager(connectionModel);
SQLServerPreparedStatement insertBulkPs = (SQLServerPreparedStatement) multiDBTransactionManager.prepareStatement(insertSQL)) { SQLServerPreparedStatement insertBulkPs = (SQLServerPreparedStatement) multiDBTransactionManager.prepareStatement(insertSQL)) {

View File

@@ -0,0 +1,11 @@
package it.integry.ems_model.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface VarBinary {
}

View File

@@ -15,6 +15,7 @@ import io.minio.errors.ErrorResponseException;
import it.integry.common.var.CommonConstants; import it.integry.common.var.CommonConstants;
import it.integry.common.var.EmsDBConst; import it.integry.common.var.EmsDBConst;
import it.integry.ems.dto.EntityHierarchy; import it.integry.ems.dto.EntityHierarchy;
import it.integry.ems.dto.Quartet;
import it.integry.ems.object_storage.minio.MinIONotEnabledException; import it.integry.ems.object_storage.minio.MinIONotEnabledException;
import it.integry.ems.object_storage.minio.MinIOService; import it.integry.ems.object_storage.minio.MinIOService;
import it.integry.ems.rules.completing.CommonRules; import it.integry.ems.rules.completing.CommonRules;
@@ -37,8 +38,8 @@ import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityHashMap; import it.integry.ems_model.utility.UtilityHashMap;
import it.integry.ems_model.utility.UtilityString; import it.integry.ems_model.utility.UtilityString;
import it.integry.ems_model.utility.UtilityZip; import it.integry.ems_model.utility.UtilityZip;
import kotlin.Triple;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.DateUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
@@ -574,6 +575,9 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
String columnName = entry.getKey(); String columnName = entry.getKey();
Object columnValue = entry.getValue(); Object columnValue = entry.getValue();
//Test
final List<EntityHierarchy.Field> entityFields = entity.getEntityHolder().getEntityFields(entity.getClass(), x -> x.getFieldName().equalsIgnoreCase(columnName));
Field field = entity.getEntityHolder().getFieldByName(entity.getClass().getSimpleName(), columnName); Field field = entity.getEntityHolder().getFieldByName(entity.getClass().getSimpleName(), columnName);
if (field == null) continue; if (field == null) continue;
@@ -1364,7 +1368,6 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
} }
public void insertEntity() throws Exception { public void insertEntity() throws Exception {
java.sql.Connection con = connection.getConnection(); java.sql.Connection con = connection.getConnection();
if (!(con instanceof SQLServerConnection)) { if (!(con instanceof SQLServerConnection)) {
throw new Exception("Impossibile processare una entity su una connessione diversa da SQL Server"); throw new Exception("Impossibile processare una entity su una connessione diversa da SQL Server");
@@ -1394,25 +1397,25 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
field.isIdentity() field.isIdentity()
); );
final List<kotlin.Triple<String, Object, Boolean>> preparedFieldsToQuery = prepareFieldsToQuery(fields); final List<Quartet<String, Object, Boolean, Object>> preparedFieldsToQuery = prepareFieldsToQuery(fields);
// preparedField: 1 = sql_field_name, 2 = value_to_save, 3 = is_identity // preparedField: 1 = sql_field_name, 2 = value_to_save, 3 = is_identity, 4 = old_value (if present)
boolean containsIdentity = false; boolean containsIdentity = false;
String identityFieldName = null; String identityFieldName = null;
long insertedIdentity = -1; long insertedIdentity = -1;
final Triple<String, Object, Boolean> identityData = preparedFieldsToQuery.stream() final Quartet<String, Object, Boolean, Object> identityData = preparedFieldsToQuery.stream()
.filter(Triple::getThird) .filter(Quartet::getValue2)
.findFirst() .findFirst()
.orElse(null); .orElse(null);
if (identityData != null) { if (identityData != null) {
containsIdentity = true; containsIdentity = true;
identityFieldName = identityData.getFirst(); identityFieldName = identityData.getValue0();
} }
final List<Triple<String, Object, Boolean>> fieldsWithoutIdentityAndNotNull = preparedFieldsToQuery.stream() final List<Quartet<String, Object, Boolean, Object>> fieldsWithoutIdentityAndNotNull = preparedFieldsToQuery.stream()
.filter(x -> !x.getThird() && x.getSecond() != null) .filter(x -> !x.getValue2() && x.getValue1() != null)
.collect(Collectors.toList()); .collect(Collectors.toList());
@@ -1420,7 +1423,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
.append(getTableName()) .append(getTableName())
.append(" (") .append(" (")
.append(StringUtils.join( .append(StringUtils.join(
fieldsWithoutIdentityAndNotNull.stream().map(Triple::getFirst).collect(Collectors.toList()), ",")) fieldsWithoutIdentityAndNotNull.stream().map(Quartet::getValue0).collect(Collectors.toList()), ","))
.append(") VALUES ("); .append(") VALUES (");
StringBuilder insertSqlTrace = new StringBuilder(insertSQL.toString()); StringBuilder insertSqlTrace = new StringBuilder(insertSQL.toString());
@@ -1441,7 +1444,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
containsIdentity ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS)) { containsIdentity ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS)) {
for (int i = 1; i <= fieldsWithoutIdentityAndNotNull.size(); i++) { for (int i = 1; i <= fieldsWithoutIdentityAndNotNull.size(); i++) {
final Object value = fieldsWithoutIdentityAndNotNull.get(i - 1).getSecond(); final Object value = fieldsWithoutIdentityAndNotNull.get(i - 1).getValue1();
insertBulkPs.setObject(i, value); insertBulkPs.setObject(i, value);
insertSqlTrace.append(UtilityDB.valueToString(value)); insertSqlTrace.append(UtilityDB.valueToString(value));
@@ -1493,6 +1496,14 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
} }
public void updateEntity() throws Exception { public void updateEntity() throws Exception {
java.sql.Connection con = connection.getConnection();
if (!(con instanceof SQLServerConnection)) {
throw new Exception("Impossibile processare una entity su una connessione diversa da SQL Server");
}
SQLServerConnection sqlServerConnection = (SQLServerConnection) con;
if (nativeSql != null) { if (nativeSql != null) {
PreparedStatement pstm = connection.prepareStatement(nativeSql); PreparedStatement pstm = connection.prepareStatement(nativeSql);
pstm.setQueryTimeout(queryTimeoutSeconds); pstm.setQueryTimeout(queryTimeoutSeconds);
@@ -1501,42 +1512,146 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
return; return;
} }
List<Field> fields = getEntityHolder().getFields(this.getClass());
List<String> campi = new ArrayList<>();
List<String> where = new ArrayList<>();
Map<Integer, Object> mapLob = getFieldToUpdate(fields, campi, where);
ForeignKeyRules.chkConstraint(connection, this.getChkConstraintSql()); ForeignKeyRules.chkConstraint(connection, this.getChkConstraintSql());
UniqueKeyRules.chkConstraint(connection, this); UniqueKeyRules.chkConstraint(connection, this);
if (!campi.isEmpty()) { List<EntityHierarchy.Field> fields = getEntityHolder()
String sql = "UPDATE " + getTableName() + " SET " + StringUtils.join(campi, ","); .getEntityFields(this.getClass(), field ->
field.isObjectStorage() ||
field.isSqlField() ||
field.isClob() ||
field.isBlob() ||
field.isIdentity()
);
final List<Quartet<String, Object, Boolean, Object>> preparedFieldsToQuery = prepareFieldsToQuery(fields);
// preparedField: 1 = sql_field_name, 2 = value_to_save, 3 = is_identity, 4 = old_value (if present)
if (getOldPk() != null) { boolean containsIdentity = false;
whereCond = getWhereCondOldPk(); String identityFieldName = null;
} else if (whereCond == null || (whereCond.split(" AND ").length != where.size() && !where.isEmpty())) { long insertedIdentity = -1;
whereCond = StringUtils.join(where, " AND ");
}
sql += " WHERE " + whereCond; final Quartet<String, Object, Boolean, Object> identityData = preparedFieldsToQuery.stream()
.filter(Quartet::getValue2)
.findFirst()
.orElse(null);
logger.trace("Query tracing: {}", sql); if (identityData != null) {
containsIdentity = true;
identityFieldName = identityData.getValue0();
}
try { final List<Quartet<String, Object, Boolean, Object>> fieldsWithoutIdentityAndNotNull = preparedFieldsToQuery.stream()
PreparedStatement pstm = connection.prepareStatement(sql); .filter(x -> !x.getValue2() && x.getValue1() != null)
setupBinaryParams(mapLob, pstm); .collect(Collectors.toList());
pstm.setQueryTimeout(queryTimeoutSeconds); StringBuilder updateSQL = new StringBuilder("UPDATE ")
pstm.executeUpdate(); .append(getTableName())
pstm.close(); .append(" SET ");
} catch (SQLException e) {
throw new EntityException(e, this, sql); for (int i = 0; i < fieldsWithoutIdentityAndNotNull.size(); i++) {
updateSQL
.append(fieldsWithoutIdentityAndNotNull.get(i).getValue0())
.append(" = ?");
if (i < fieldsWithoutIdentityAndNotNull.size() - 1)
updateSQL.append(",");
}
final List<Quartet<String, Object, Boolean, Object>> whereCondData = preparedFieldsToQuery.stream()
.filter(x -> x.getValue3() != null)
.collect(Collectors.toList());
if (getOldPk() != null) {
updateSQL
.append(" WHERE ")
.append(getWhereCondOldPk());
} else if (!whereCondData.isEmpty()) {
updateSQL
.append(" WHERE ");
for (int i = 0; i < whereCondData.size(); i++) {
Quartet<String, Object, Boolean, Object> whereCondItem = whereCondData.get(i);
updateSQL.append(whereCondItem.getValue0())
.append(" = ")
.append(whereCondItem.getValue3());
if (i < whereCondData.size() - 1)
updateSQL.append(" AND ");
} }
} }
StringBuilder updateSqlTrace = new StringBuilder("UPDATE ")
.append(getTableName())
.append(" SET ");
try (SQLServerPreparedStatement updateBulkPs =
(SQLServerPreparedStatement) sqlServerConnection.prepareStatement(
updateSQL.toString(),
containsIdentity ? Statement.RETURN_GENERATED_KEYS : Statement.NO_GENERATED_KEYS)) {
for (int i = 1; i <= fieldsWithoutIdentityAndNotNull.size(); i++) {
final Object value = fieldsWithoutIdentityAndNotNull.get(i - 1).getSecond();
if (value instanceof Byte[]) {
updateBulkPs.setBytes(i, ArrayUtils.toPrimitive((Byte[]) value));
} else
updateBulkPs.setObject(i, value);
updateSqlTrace.append(fieldsWithoutIdentityAndNotNull.get(i - 1).getValue0())
.append(" = ")
.append(UtilityDB.valueToString(value));
if (i <= fieldsWithoutIdentityAndNotNull.size() - 1)
updateSqlTrace.append(",");
}
updateSqlTrace.append(" ").append(updateSQL.substring(updateSQL.indexOf("WHERE")));
logger.trace("Query tracing: {}", updateSqlTrace);
long updatedRowCount = updateBulkPs.executeLargeUpdate();
String a = "";
}
// OLD
// List<Field> fields = getEntityHolder().getFields(this.getClass());
//
// List<String> campi = new ArrayList<>();
// List<String> where = new ArrayList<>();
//
//
// Map<Integer, Object> mapLob = getFieldToUpdate(fields, campi, where);
//
// if (!campi.isEmpty()) {
// String sql = "UPDATE " + getTableName() + " SET " + StringUtils.join(campi, ",");
//
//
// if (getOldPk() != null) {
// whereCond = getWhereCondOldPk();
// } else if (whereCond == null || (whereCond.split(" AND ").length != where.size() && !where.isEmpty())) {
// whereCond = StringUtils.join(where, " AND ");
// }
//
// sql += " WHERE " + whereCond;
//
// logger.trace("Query tracing: {}", sql);
//
// try {
// PreparedStatement pstm = connection.prepareStatement(sql);
// setupBinaryParams(mapLob, pstm);
//
// pstm.setQueryTimeout(queryTimeoutSeconds);
// pstm.executeUpdate();
// pstm.close();
// } catch (SQLException e) {
// throw new EntityException(e, this, sql);
// }
// }
} }
public void setParentPKAndImportFromParent(EntityBase parent, Boolean isChild) throws InvocationTargetException, IllegalAccessException { public void setParentPKAndImportFromParent(EntityBase parent, Boolean isChild) throws InvocationTargetException, IllegalAccessException {
@@ -1557,19 +1672,18 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
} }
private void updateChildrenForeignIdentity() throws IllegalAccessException { private void updateChildrenForeignIdentity() throws IllegalAccessException {
List<Field> fields = getEntityHolder().getFields(this.getClass()); final List<EntityHierarchy.Field> entityFields = getEntityHolder().getEntityFields(this.getClass(), null);
Optional<Field> identityOptionalField = Stream.of(fields).filter(x -> x.isAnnotationPresent(Identity.class)).findFirst(); boolean isIdentityPresent = entityFields.stream().anyMatch(EntityHierarchy.Field::isIdentity);
if (identityOptionalField.isPresent()) { if (isIdentityPresent) {
Field identityField = identityOptionalField.get(); Field identityField = entityFields.stream().filter(EntityHierarchy.Field::isIdentity).findFirst().get().getField();
identityField.setAccessible(true); identityField.setAccessible(true);
//SqlField sqlObject = identityField.getAnnotation(SqlField.class);
List<Field> entityChildFields = Stream.of(fields).filter(x -> x.isAnnotationPresent(EntityChild.class)).toList(); final List<Field> entityChildrenFields = getEntityHolder().getEntityChildrenFields(this.getClass());
for (Field entityChildField : entityChildFields) { for (Field entityChildField : entityChildrenFields) {
entityChildField.setAccessible(true); entityChildField.setAccessible(true);
Object entityChildFieldObject; Object entityChildFieldObject;
@@ -1590,7 +1704,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
} }
private void setParentIdentityIfExists(String parentIdentityFieldName, Long value) throws IllegalAccessException { private void setParentIdentityIfExists(String parentIdentityFieldName, Long value) throws IllegalAccessException {
Optional<Field> importFromParentFieldOptional = Stream.of(getClass().getDeclaredFields()).filter(x -> { final java.util.Optional<Field> importFromParentFieldOptional = Arrays.stream(getClass().getDeclaredFields()).filter(x -> {
x.setAccessible(true); x.setAccessible(true);
return x.isAnnotationPresent(ImportFromParent.class) && x.getAnnotation(ImportFromParent.class).value().equals(parentIdentityFieldName); return x.isAnnotationPresent(ImportFromParent.class) && x.getAnnotation(ImportFromParent.class).value().equals(parentIdentityFieldName);
}).findFirst(); }).findFirst();
@@ -1857,8 +1971,8 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
return whereCondOldPk; return whereCondOldPk;
} }
private List<kotlin.Triple<String, Object, Boolean>> prepareFieldsToQuery(List<EntityHierarchy.Field> fields) throws Exception { private List<Quartet<String, Object, Boolean, Object>> prepareFieldsToQuery(List<EntityHierarchy.Field> fields) throws Exception {
List<kotlin.Triple<String, Object, Boolean>> resultList = new ArrayList<>(); List<Quartet<String, Object, Boolean, Object>> resultList = new ArrayList<>();
for (EntityHierarchy.Field entityHierachyfield : fields) { for (EntityHierarchy.Field entityHierachyfield : fields) {
Field field = entityHierachyfield.getField(); Field field = entityHierachyfield.getField();
@@ -1887,7 +2001,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
if (!UtilityString.isNullOrEmpty(refUuid)) { if (!UtilityString.isNullOrEmpty(refUuid)) {
final String refUuidFinalName = "ref_uuid" + (objectStorage.suffix() > 0 ? objectStorage.suffix() : ""); final String refUuidFinalName = "ref_uuid" + (objectStorage.suffix() > 0 ? objectStorage.suffix() : "");
resultList.add(new kotlin.Triple<>(refUuidFinalName, refUuid, false)); resultList.add(new Quartet<>(refUuidFinalName, refUuid, false, null));
} }
if (!SettingsModel.getInstance().getMinioConfiguration().isEnableOldSave()) continue; if (!SettingsModel.getInstance().getMinioConfiguration().isEnableOldSave()) continue;
@@ -1899,6 +2013,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
boolean nullableValue = true; boolean nullableValue = true;
SqlField sqlField = entityHierachyfield.getSqlField(); SqlField sqlField = entityHierachyfield.getSqlField();
Object prevValue = entityHierachyfield.isPrimaryKey() ? SqlFieldHolder.getSqlValueFieldAsString(originalObject, sqlField.trimSpaces()) : null;
if (entityHierachyfield.isSqlField()) { if (entityHierachyfield.isSqlField()) {
defaultValue = sqlField.defaultObjectValue(); defaultValue = sqlField.defaultObjectValue();
@@ -1917,7 +2032,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
if (entityHierachyfield.isSqlField() && entityHierachyfield.isIdentity()) { if (entityHierachyfield.isSqlField() && entityHierachyfield.isIdentity()) {
//Escludiamo il campo identity dalla insert //Escludiamo il campo identity dalla insert
resultList.add(new Triple<>(SqlFieldHolder.getSqlValue(sqlField.value(), field), null, true)); resultList.add(new Quartet<>(SqlFieldHolder.getSqlValue(sqlField.value(), field), null, true, prevValue));
continue; continue;
} }
@@ -1933,17 +2048,19 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
if (entityHierachyfield.isClob()) { if (entityHierachyfield.isClob()) {
if (originalObject != null) if (originalObject != null)
resultList.add(new Triple<>( resultList.add(new Quartet<>(
SqlFieldHolder.getSqlValue(sqlField.value(), field), SqlFieldHolder.getSqlValue(sqlField.value(), field),
prepareClobData(originalObject), prepareClobData(originalObject),
false)); false,
prevValue));
} else if (entityHierachyfield.isBlob()) { } else if (entityHierachyfield.isBlob()) {
if (originalObject != null) if (originalObject != null)
resultList.add(new Triple<>( resultList.add(new Quartet<>(
SqlFieldHolder.getSqlValue(sqlField.value(), field), SqlFieldHolder.getSqlValue(sqlField.value(), field),
prepareBlobData(originalObject), prepareBlobData(originalObject),
false)); false,
prevValue));
} else { } else {
Object finalValue = SqlFieldHolder.getSqlValueFieldAsObject(originalObject == null ? defaultValue : originalObject, sqlField.trimSpaces()); Object finalValue = SqlFieldHolder.getSqlValueFieldAsObject(originalObject == null ? defaultValue : originalObject, sqlField.trimSpaces());
@@ -1963,7 +2080,7 @@ public abstract class EntityBase implements Serializable, Cloneable, EntityInter
// .replaceAll("\n", "' + CHAR(10) + '"); // .replaceAll("\n", "' + CHAR(10) + '");
} }
resultList.add(new Triple<>(SqlFieldHolder.getSqlValue(sqlField.value(), field), finalValue, false)); resultList.add(new Quartet<>(SqlFieldHolder.getSqlValue(sqlField.value(), field), finalValue, false, prevValue));
} }
} }

View File

@@ -123,12 +123,14 @@ public class EntityPropertyHolder {
for (Field declaredField : declaredFields) { for (Field declaredField : declaredFields) {
analyzedFields.add(new EntityHierarchy.Field() analyzedFields.add(new EntityHierarchy.Field()
.setField(declaredField) .setField(declaredField)
.setPrimaryKey(declaredField.getAnnotation(PK.class))
.setIdentity(declaredField.getAnnotation(Identity.class)) .setIdentity(declaredField.getAnnotation(Identity.class))
.setSqlField(declaredField.getAnnotation(SqlField.class)) .setSqlField(declaredField.getAnnotation(SqlField.class))
.setImportFromParent(declaredField.getAnnotation(ImportFromParent.class)) .setImportFromParent(declaredField.getAnnotation(ImportFromParent.class))
.setObjectStorage(declaredField.getAnnotation(ObjectStorage.class)) .setObjectStorage(declaredField.getAnnotation(ObjectStorage.class))
.setClob(declaredField.getAnnotation(Clob.class)) .setClob(declaredField.getAnnotation(Clob.class))
.setBlob(declaredField.getAnnotation(Blob.class))); .setBlob(declaredField.getAnnotation(Blob.class))
.setVarBinary(declaredField.getAnnotation(VarBinary.class)));
} }

View File

@@ -16,6 +16,7 @@ import it.integry.ems_model.config.EmsRestConstants;
import it.integry.ems_model.db.ResultSetMapper; import it.integry.ems_model.db.ResultSetMapper;
import it.integry.ems_model.entity.*; import it.integry.ems_model.entity.*;
import it.integry.ems_model.entity._enum.FlagEvaso; import it.integry.ems_model.entity._enum.FlagEvaso;
import it.integry.ems_model.entity._enum.TipoValore;
import it.integry.ems_model.exception.DataConverterNotFoundException; import it.integry.ems_model.exception.DataConverterNotFoundException;
import it.integry.ems_model.service.SetupGest; import it.integry.ems_model.service.SetupGest;
import it.integry.ems_model.types.OperationType; import it.integry.ems_model.types.OperationType;
@@ -83,7 +84,7 @@ public class GeneraOrdLav {
"where gtb_anag.cod_anag = %s", "where gtb_anag.cod_anag = %s",
codVdes, codAnag); codVdes, codAnag);
HashMap<String, Object> datiDest = UtilityDB.executeSimpleQueryOnlyFirstRow(conn, sql); HashMap<String, Object> datiDest = UtilityDB.executeSimpleQueryOnlyFirstRow(conn, sql);
if (datiDest != null && datiDest.size() > 0) { if (datiDest != null && !datiDest.isEmpty()) {
desCom = UtilityHashMap.getValueIfExists(datiDest, "descr_com"); desCom = UtilityHashMap.getValueIfExists(datiDest, "descr_com");
isTerzista = UtilityHashMap.getValueIfExists(datiDest, "is_terzista"); isTerzista = UtilityHashMap.getValueIfExists(datiDest, "is_terzista");
} }
@@ -93,6 +94,10 @@ public class GeneraOrdLav {
// Se c'è il check del terzista e il fornitore è un terzista allora // Se c'è il check del terzista e il fornitore è un terzista allora
// bisognerà acquisire il deposito del terzista // bisognerà acquisire il deposito del terzista
codMdep = getDepositoTerzista(conn, codAnag, codVdes); codMdep = getDepositoTerzista(conn, codAnag, codVdes);
if (UtilityString.isNullOrEmpty(codMdep)) {
codMdep = dtbOrdt.getCodMdep();
}
} }
} }
// Verifica esistenza lavoratore associato all'utente connesso // Verifica esistenza lavoratore associato all'utente connesso
@@ -322,7 +327,7 @@ public class GeneraOrdLav {
.setColliPedana(row.getColliPedana()) .setColliPedana(row.getColliPedana())
.setCodTcolUl(row.getCodTcolUl()) .setCodTcolUl(row.getCodTcolUl())
.setCodTcolUi(row.getCodTcolUi()) .setCodTcolUi(row.getCodTcolUi())
.setFlagEvasoProd(flagEvasoProd.getValue().toString()) .setFlagEvasoProd(flagEvasoProd!=null?flagEvasoProd.getValue().toString():null)
.setGeneraOrdLavDaProd(dtbOrdt.isGeneraOrdLavDaProd()); .setGeneraOrdLavDaProd(dtbOrdt.isGeneraOrdLavDaProd());
String flagAnnulla = "N"; String flagAnnulla = "N";
@@ -1072,7 +1077,7 @@ public class GeneraOrdLav {
.setCodProdPri(ordT.getCodProd()); .setCodProdPri(ordT.getCodProd());
ordT.getDtbOrdSteps().add(ordStep); ordT.getDtbOrdSteps().add(ordStep);
return; return; // F3678 SMSM301637A
} }
/* /*
@@ -1305,7 +1310,8 @@ public class GeneraOrdLav {
+ " jtb_cicl_cq.controllo, " + " jtb_cicl_cq.controllo, "
+ " jtb_cicl_cq.valore_rif, " + " jtb_cicl_cq.valore_rif, "
+ " jtb_cicl_cq.num_rip, " + " jtb_cicl_cq.num_rip, "
+ " jtb_cicl_cq.tipologia " + " jtb_cicl_cq.tipologia, "
+ " jtb_cicl_cq.tipo_valore "
+ "FROM jtb_cicl_cq " + "FROM jtb_cicl_cq "
+ "WHERE jtb_cicl_cq.cod_prod = %s " + "WHERE jtb_cicl_cq.cod_prod = %s "
+ "ORDER BY jtb_cicl_cq.id_riga ", + "ORDER BY jtb_cicl_cq.id_riga ",
@@ -1320,6 +1326,7 @@ public class GeneraOrdLav {
.setValoreRif(UtilityHashMap.getValueIfExists(cq, "valore_rif")) .setValoreRif(UtilityHashMap.getValueIfExists(cq, "valore_rif"))
.setNumRip(UtilityHashMap.getValueIfExists(cq, "num_rip")) .setNumRip(UtilityHashMap.getValueIfExists(cq, "num_rip"))
.setTipologia(UtilityHashMap.getValueIfExists(cq, "tipologia")) .setTipologia(UtilityHashMap.getValueIfExists(cq, "tipologia"))
.setTipoValore(TipoValore.from(UtilityHashMap.getValueIfExists(cq, "tipo_valore")))
.setNumFase(numFase); .setNumFase(numFase);
ordCQ.setOperation(OperationType.INSERT); ordCQ.setOperation(OperationType.INSERT);
listOrdCQ.add(ordCQ); listOrdCQ.add(ordCQ);

View File

@@ -15,6 +15,7 @@ import it.integry.ems_model.business_logic.dto.ExplodeDistDTO;
import it.integry.ems_model.config.EmsRestConstants; import it.integry.ems_model.config.EmsRestConstants;
import it.integry.ems_model.db.ResultSetMapper; import it.integry.ems_model.db.ResultSetMapper;
import it.integry.ems_model.entity.*; import it.integry.ems_model.entity.*;
import it.integry.ems_model.entity._enum.TipoValore;
import it.integry.ems_model.rules.util.DroolsUtil; import it.integry.ems_model.rules.util.DroolsUtil;
import it.integry.ems_model.service.SetupGest; import it.integry.ems_model.service.SetupGest;
import it.integry.ems_model.types.OperationType; import it.integry.ems_model.types.OperationType;
@@ -865,7 +866,8 @@ public class ProductionBusinessLogic {
+ " jtb_cicl_cq.controllo, " + " jtb_cicl_cq.controllo, "
+ " jtb_cicl_cq.valore_rif, " + " jtb_cicl_cq.valore_rif, "
+ " jtb_cicl_cq.num_rip, " + " jtb_cicl_cq.num_rip, "
+ " jtb_cicl_cq.tipologia " + " jtb_cicl_cq.tipologia, "
+ " jtb_cicl_cq.tipo_valore "
+ "FROM jtb_cicl_cq " + "FROM jtb_cicl_cq "
+ "WHERE jtb_cicl_cq.cod_prod = " + UtilityDB.valueToString(codProd) + " " + "WHERE jtb_cicl_cq.cod_prod = " + UtilityDB.valueToString(codProd) + " "
+ "ORDER BY jtb_cicl_cq.id_riga "; + "ORDER BY jtb_cicl_cq.id_riga ";
@@ -888,6 +890,7 @@ public class ProductionBusinessLogic {
ordCQ.setNumRip(numRip); ordCQ.setNumRip(numRip);
ordCQ.setNumFase(numFase); ordCQ.setNumFase(numFase);
ordCQ.setTipologia(tipologia); ordCQ.setTipologia(tipologia);
ordCQ.setTipoValore(TipoValore.from(rs.getShort("tipo_valore")));
if (isRoot) { if (isRoot) {
ordCQ.setNumFase(numFase + datiDist.getNumFase()); ordCQ.setNumFase(numFase + datiDist.getNumFase());
} else { } else {

View File

@@ -59,6 +59,9 @@ public class CtbAmac extends EntityBase {
@SqlField(value = "machine_type", nullable = false, defaultObjectValue = "0") @SqlField(value = "machine_type", nullable = false, defaultObjectValue = "0")
private Integer machineType; private Integer machineType;
@SqlField(value = "note", nullable = true)
private String note;
@EntityChild @EntityChild
private List<CrlAmacArt> crlAmacArt = new ArrayList<>(); private List<CrlAmacArt> crlAmacArt = new ArrayList<>();
@@ -193,11 +196,20 @@ public class CtbAmac extends EntityBase {
return ctbAmacManutenzioni; return ctbAmacManutenzioni;
} }
public CtbAmac setCtbAmacManutenzioniy(List<CtbAmacManutenzioni> ctbAmacManutenzioni) { public CtbAmac setCtbAmacManutenzioni(List<CtbAmacManutenzioni> ctbAmacManutenzioni) {
this.ctbAmacManutenzioni = ctbAmacManutenzioni; this.ctbAmacManutenzioni = ctbAmacManutenzioni;
return this; return this;
} }
public String getNote() {
return note;
}
public CtbAmac setNote(String note) {
this.note = note;
return this;
}
@Override @Override
protected void insertChilds() throws Exception { protected void insertChilds() throws Exception {
for (CrlAmacArt crlAmacArt : getCrlAmacArt()) { for (CrlAmacArt crlAmacArt : getCrlAmacArt()) {
@@ -267,4 +279,7 @@ public class CtbAmac extends EntityBase {
return from(val); return from(val);
} }
} }
} }

View File

@@ -68,6 +68,9 @@ public class CtbMovrCoan extends EntityBase {
@SqlField(value = "partita_mag_prod", maxLength = 20) @SqlField(value = "partita_mag_prod", maxLength = 20)
private String partitaMagProd; private String partitaMagProd;
@SqlField(value = "id_lav", maxLength = 40)
private String idLav;
public CtbMovrCoan() { public CtbMovrCoan() {
super(logger); super(logger);
} }
@@ -197,4 +200,12 @@ public class CtbMovrCoan extends EntityBase {
this.partitaMagProd = partitaMagProd; this.partitaMagProd = partitaMagProd;
return this; return this;
} }
public String getIdLav() {
return idLav;
}
public void setIdLav(String idLav) {
this.idLav = idLav;
}
} }

View File

@@ -402,6 +402,15 @@ public class DtbDoct extends DtbBaseDocT implements EquatableEntityInterface<Dtb
super(logger); super(logger);
} }
public DtbDoct(String codAnag, String codDtip, Date dataDoc, Integer numDoc, String serDoc) {
super(logger);
this.codAnag = codAnag;
this.codDtip = codDtip;
this.dataDoc = dataDoc;
this.numDoc = numDoc;
this.serDoc = serDoc;
}
public String getCodAnag() { public String getCodAnag() {
return codAnag; return codAnag;
} }

View File

@@ -790,16 +790,17 @@ public class GtbAnag extends EntityBase implements EquatableEntityInterface<GtbA
return Objects.equals(getCodAnag(), other.getCodAnag()); return Objects.equals(getCodAnag(), other.getCodAnag());
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if (this == o) return true;
if (!(o instanceof GtbAnag)) return false; if (!(o instanceof GtbAnag)) return false;
GtbAnag gtbAnag = (GtbAnag) o; GtbAnag gtbAnag = (GtbAnag) o;
return Objects.equals(getCodAnag(), gtbAnag.getCodAnag()) && Objects.equals(getRagSoc(), gtbAnag.getRagSoc()) && Objects.equals(getIndirizzo(), gtbAnag.getIndirizzo()) && Objects.equals(getCap(), gtbAnag.getCap()) && Objects.equals(getCitta(), gtbAnag.getCitta()) && Objects.equals(getProv(), gtbAnag.getProv()) && Objects.equals(getNazione(), gtbAnag.getNazione()) && Objects.equals(getTelefono(), gtbAnag.getTelefono()) && Objects.equals(getFax(), gtbAnag.getFax()) && Objects.equals(getPartIva(), gtbAnag.getPartIva()) && Objects.equals(getCodFisc(), gtbAnag.getCodFisc()) && Objects.equals(getNote(), gtbAnag.getNote()) && Objects.equals(getPersonaRif(), gtbAnag.getPersonaRif()) && Objects.equals(getAllegato(), gtbAnag.getAllegato()) && Objects.equals(geteMail(), gtbAnag.geteMail()) && Objects.equals(geteMailPec(), gtbAnag.geteMailPec()) && Objects.equals(getFlagPersonaFg(), gtbAnag.getFlagPersonaFg()) && Objects.equals(getSesso(), gtbAnag.getSesso()) && Objects.equals(getCodCentroAzi(), gtbAnag.getCodCentroAzi()) && Objects.equals(getCodRuop(), gtbAnag.getCodRuop()) && Objects.equals(getDataNascita(), gtbAnag.getDataNascita()) && Objects.equals(getLuogoNascita(), gtbAnag.getLuogoNascita()) && Objects.equals(getProvNascita(), gtbAnag.getProvNascita()) && Objects.equals(getNome(), gtbAnag.getNome()) && Objects.equals(getRagSoc2(), gtbAnag.getRagSoc2()) && Objects.equals(getClasseMerito(), gtbAnag.getClasseMerito()) && Objects.equals(getDataIns(), gtbAnag.getDataIns()) && Objects.equals(getNumCell(), gtbAnag.getNumCell()) && Objects.equals(getCciaa(), gtbAnag.getCciaa()) && Objects.equals(getTipoAzienda(), gtbAnag.getTipoAzienda()) && Objects.equals(getCuuPa(), gtbAnag.getCuuPa()) && Objects.equals(getCognome(), gtbAnag.getCognome()) && Objects.equals(getDiacod(), gtbAnag.getDiacod()) && Objects.equals(getLat(), gtbAnag.getLat()) && Objects.equals(getLng(), gtbAnag.getLng()) && Objects.equals(getFlagInformativa(), gtbAnag.getFlagInformativa()) && Objects.equals(getFlagConsenso(), gtbAnag.getFlagConsenso()) && Objects.equals(getRegFisc(), gtbAnag.getRegFisc()) && Objects.equals(getDataMod(), gtbAnag.getDataMod()) && Objects.equals(getPrecode(), gtbAnag.getPrecode()) && Objects.equals(getInsDestinatario(), gtbAnag.getInsDestinatario()) && Objects.equals(getCodSoggetto(), gtbAnag.getCodSoggetto()) && Objects.equals(getVtbCliePersRif(), gtbAnag.getVtbCliePersRif()) && Objects.equals(getVtbDest(), gtbAnag.getVtbDest()) && Objects.equals(getVtbClieFido(), gtbAnag.getVtbClieFido()) && Objects.equals(getCtbPlafondIva(), gtbAnag.getCtbPlafondIva()) && Objects.equals(getTtbClieLine(), gtbAnag.getTtbClieLine()) && Objects.equals(getGrlAnagJrepts(), gtbAnag.getGrlAnagJrepts()) && Objects.equals(getGtbAnagNote(), gtbAnag.getGtbAnagNote()) && Objects.equals(getGtbAnagConai(), gtbAnag.getGtbAnagConai()) && Objects.equals(getVtbClie(), gtbAnag.getVtbClie()) && Objects.equals(getAtbForn(), gtbAnag.getAtbForn()) && Objects.equals(getOltbSoggetti(), gtbAnag.getOltbSoggetti()) && Objects.equals(getGtbAnagInfo(), gtbAnag.getGtbAnagInfo()) && Objects.equals(getCtbAnag(), gtbAnag.getCtbAnag()); return Objects.equals(getCodAnag(), gtbAnag.getCodAnag()) && Objects.equals(getRagSoc(), gtbAnag.getRagSoc()) && Objects.equals(getIndirizzo(), gtbAnag.getIndirizzo()) && Objects.equals(getCap(), gtbAnag.getCap()) && Objects.equals(getCitta(), gtbAnag.getCitta()) && Objects.equals(getProv(), gtbAnag.getProv()) && Objects.equals(getNazione(), gtbAnag.getNazione()) && Objects.equals(getTelefono(), gtbAnag.getTelefono()) && Objects.equals(getFax(), gtbAnag.getFax()) && Objects.equals(getPartIva(), gtbAnag.getPartIva()) && Objects.equals(getCodFisc(), gtbAnag.getCodFisc()) && Objects.equals(getNote(), gtbAnag.getNote()) && Objects.equals(getPersonaRif(), gtbAnag.getPersonaRif()) && Objects.equals(getAllegato(), gtbAnag.getAllegato()) && Objects.equals(geteMail(), gtbAnag.geteMail()) && Objects.equals(geteMailPec(), gtbAnag.geteMailPec()) && Objects.equals(getFlagPersonaFg(), gtbAnag.getFlagPersonaFg()) && Objects.equals(getSesso(), gtbAnag.getSesso()) && Objects.equals(getCodCentroAzi(), gtbAnag.getCodCentroAzi()) && Objects.equals(getCodRuop(), gtbAnag.getCodRuop()) && Objects.equals(getDataNascita(), gtbAnag.getDataNascita()) && Objects.equals(getLuogoNascita(), gtbAnag.getLuogoNascita()) && Objects.equals(getProvNascita(), gtbAnag.getProvNascita()) && Objects.equals(getNome(), gtbAnag.getNome()) && Objects.equals(getRagSoc2(), gtbAnag.getRagSoc2()) && Objects.equals(getClasseMerito(), gtbAnag.getClasseMerito()) && Objects.equals(getDataIns(), gtbAnag.getDataIns()) && Objects.equals(getNumCell(), gtbAnag.getNumCell()) && Objects.equals(getCciaa(), gtbAnag.getCciaa()) && Objects.equals(getTipoAzienda(), gtbAnag.getTipoAzienda()) && Objects.equals(getCuuPa(), gtbAnag.getCuuPa()) && Objects.equals(getCognome(), gtbAnag.getCognome()) && Objects.equals(getDiacod(), gtbAnag.getDiacod()) && Objects.equals(getLat(), gtbAnag.getLat()) && Objects.equals(getLng(), gtbAnag.getLng()) && Objects.equals(getFlagInformativa(), gtbAnag.getFlagInformativa()) && Objects.equals(getFlagConsenso(), gtbAnag.getFlagConsenso()) && Objects.equals(getRegFisc(), gtbAnag.getRegFisc()) && Objects.equals(getDataMod(), gtbAnag.getDataMod()) && Objects.equals(getPrecode(), gtbAnag.getPrecode()) && Objects.equals(getInsDestinatario(), gtbAnag.getInsDestinatario()) && Objects.equals(getCodSoggetto(), gtbAnag.getCodSoggetto());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(getCodAnag(), getRagSoc(), getIndirizzo(), getCap(), getCitta(), getProv(), getNazione(), getTelefono(), getFax(), getPartIva(), getCodFisc(), getNote(), getPersonaRif(), getAllegato(), geteMail(), geteMailPec(), getFlagPersonaFg(), getSesso(), getCodCentroAzi(), getCodRuop(), getDataNascita(), getLuogoNascita(), getProvNascita(), getNome(), getRagSoc2(), getClasseMerito(), getDataIns(), getNumCell(), getCciaa(), getTipoAzienda(), getCuuPa(), getCognome(), getDiacod(), getLat(), getLng(), getFlagInformativa(), getFlagConsenso(), getRegFisc(), getDataMod(), getPrecode(), getInsDestinatario(), getCodSoggetto(), getVtbCliePersRif(), getVtbDest(), getVtbClieFido(), getCtbPlafondIva(), getTtbClieLine(), getGrlAnagJrepts(), getGtbAnagNote(), getGtbAnagConai(), getVtbClie(), getAtbForn(), getOltbSoggetti(), getGtbAnagInfo(), getCtbAnag()); return Objects.hash(getCodAnag(), getRagSoc(), getIndirizzo(), getCap(), getCitta(), getProv(), getNazione(), getTelefono(), getFax(), getPartIva(), getCodFisc(), getNote(), getPersonaRif(), getAllegato(), geteMail(), geteMailPec(), getFlagPersonaFg(), getSesso(), getCodCentroAzi(), getCodRuop(), getDataNascita(), getLuogoNascita(), getProvNascita(), getNome(), getRagSoc2(), getClasseMerito(), getDataIns(), getNumCell(), getCciaa(), getTipoAzienda(), getCuuPa(), getCognome(), getDiacod(), getLat(), getLng(), getFlagInformativa(), getFlagConsenso(), getRegFisc(), getDataMod(), getPrecode(), getInsDestinatario(), getCodSoggetto());
} }
} }

View File

@@ -3,17 +3,16 @@ package it.integry.ems_model.entity;
import com.fasterxml.jackson.annotation.JsonTypeName; import com.fasterxml.jackson.annotation.JsonTypeName;
import it.integry.ems_model.annotation.*; import it.integry.ems_model.annotation.*;
import it.integry.ems_model.base.EntityBase; import it.integry.ems_model.base.EntityBase;
import org.kie.api.definition.type.PropertyReactive;
import java.util.ArrayList;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.kie.api.definition.type.PropertyReactive;
@PropertyReactive @PropertyReactive
@Table(MrlDepoArtEsclusiWms.ENTITY) @Table(MrlDepoArtEsclusiWms.ENTITY)
@JsonTypeName(MrlDepoArtEsclusiWms.ENTITY) @JsonTypeName(MrlDepoArtEsclusiWms.ENTITY)
public class MrlDepoArtEsclusiWms extends EntityBase { public class MrlDepoArtEsclusiWms extends EntityBase {
private final static Logger logger = LogManager.getLogger(); private final static Logger logger = LogManager.getLogger(MrlDepoArtEsclusiWms.class);
public static final String ENTITY = "mrl_depo_art_esclusi_wms"; public static final String ENTITY = "mrl_depo_art_esclusi_wms";
@@ -54,63 +53,71 @@ public class MrlDepoArtEsclusiWms extends EntityBase {
return id; return id;
} }
public void setId(Long id) { public MrlDepoArtEsclusiWms setId(Long id) {
this.id = id; this.id = id;
return this;
} }
public String getCodMdep() { public String getCodMdep() {
return codMdep; return codMdep;
} }
public void setCodMdep(String codMdep) { public MrlDepoArtEsclusiWms setCodMdep(String codMdep) {
this.codMdep = codMdep; this.codMdep = codMdep;
return this;
} }
public String getCodMgrp() { public String getCodMgrp() {
return codMgrp; return codMgrp;
} }
public void setCodMgrp(String codMgrp) { public MrlDepoArtEsclusiWms setCodMgrp(String codMgrp) {
this.codMgrp = codMgrp; this.codMgrp = codMgrp;
return this;
} }
public String getCodMsgr() { public String getCodMsgr() {
return codMsgr; return codMsgr;
} }
public void setCodMsgr(String codMsgr) { public MrlDepoArtEsclusiWms setCodMsgr(String codMsgr) {
this.codMsgr = codMsgr; this.codMsgr = codMsgr;
return this;
} }
public String getCodMsfa() { public String getCodMsfa() {
return codMsfa; return codMsfa;
} }
public void setCodMsfa(String codMsfa) { public MrlDepoArtEsclusiWms setCodMsfa(String codMsfa) {
this.codMsfa = codMsfa; this.codMsfa = codMsfa;
return this;
} }
public String getCodMtip() { public String getCodMtip() {
return codMtip; return codMtip;
} }
public void setCodMtip(String codMtip) { public MrlDepoArtEsclusiWms setCodMtip(String codMtip) {
this.codMtip = codMtip; this.codMtip = codMtip;
return this;
} }
public String getCodMstp() { public String getCodMstp() {
return codMstp; return codMstp;
} }
public void setCodMstp(String codMstp) { public MrlDepoArtEsclusiWms setCodMstp(String codMstp) {
this.codMstp = codMstp; this.codMstp = codMstp;
return this;
} }
public String getCodMart() { public String getCodMart() {
return codMart; return codMart;
} }
public void setCodMart(String codMart) { public MrlDepoArtEsclusiWms setCodMart(String codMart) {
this.codMart = codMart; this.codMart = codMart;
return this;
} }
} }

View File

@@ -303,6 +303,8 @@ public class MtbAart extends EntityBase implements EquatableEntityInterface<MtbA
@SqlField(value = "tipo_codice_imballo", maxLength = 10) @SqlField(value = "tipo_codice_imballo", maxLength = 10)
private String tipoCodiceImballo; private String tipoCodiceImballo;
private Boolean setIdArtEqui;
@Priority(1) @Priority(1)
private MtbAartMarchio mtbAartMarchio; private MtbAartMarchio mtbAartMarchio;
@@ -1184,6 +1186,15 @@ public class MtbAart extends EntityBase implements EquatableEntityInterface<MtbA
return this; return this;
} }
public Boolean getSetIdArtEqui() {
return setIdArtEqui;
}
public MtbAart setSetIdArtEqui(Boolean setIdArtEqui) {
this.setIdArtEqui = setIdArtEqui;
return this;
}
public List<MtbAartAnag> getMtbAartAnag() { public List<MtbAartAnag> getMtbAartAnag() {
return mtbAartAnag; return mtbAartAnag;
} }

View File

@@ -151,6 +151,9 @@ public class MtbColr extends EntityBase implements EquatableEntityInterface<MtbC
@SqlField(value = "cod_art_for", maxLength = 25) @SqlField(value = "cod_art_for", maxLength = 25)
private String codArtFor; private String codArtFor;
@SqlField(value = "system_note", maxLength = 255)
private String systemNote;
@EntityChild @EntityChild
MtbColrInfoProd mtbColrInfoProd; MtbColrInfoProd mtbColrInfoProd;
@@ -548,6 +551,15 @@ public class MtbColr extends EntityBase implements EquatableEntityInterface<MtbC
return this; return this;
} }
public String getSystemNote() {
return systemNote;
}
public MtbColr setSystemNote(String systemNote) {
this.systemNote = systemNote;
return this;
}
public MtbPartitaMag getMtbPartitaMag() { public MtbPartitaMag getMtbPartitaMag() {
return mtbPartitaMag; return mtbPartitaMag;
} }

View File

@@ -855,11 +855,11 @@ public class VtbDest extends EntityBase implements EquatableEntityInterface<VtbD
if (this == o) return true; if (this == o) return true;
if (!(o instanceof VtbDest)) return false; if (!(o instanceof VtbDest)) return false;
VtbDest vtbDest = (VtbDest) o; VtbDest vtbDest = (VtbDest) o;
return Objects.equals(getCodAnag(), vtbDest.getCodAnag()) && Objects.equals(getCodVdes(), vtbDest.getCodVdes()) && Objects.equals(getDestinatario(), vtbDest.getDestinatario()) && Objects.equals(getIndirizzo(), vtbDest.getIndirizzo()) && Objects.equals(getCap(), vtbDest.getCap()) && Objects.equals(getCitta(), vtbDest.getCitta()) && Objects.equals(getProv(), vtbDest.getProv()) && Objects.equals(getNazione(), vtbDest.getNazione()) && Objects.equals(getTel(), vtbDest.getTel()) && Objects.equals(getFax(), vtbDest.getFax()) && Objects.equals(getNote(), vtbDest.getNote()) && Objects.equals(getFonte(), vtbDest.getFonte()) && Objects.equals(getCodCentroAzi(), vtbDest.getCodCentroAzi()) && Objects.equals(getGgCons(), vtbDest.getGgCons()) && Objects.equals(getCodAliqOut(), vtbDest.getCodAliqOut()) && Objects.equals(getCodAliqIn(), vtbDest.getCodAliqIn()) && Objects.equals(getDescrizAliqOut(), vtbDest.getDescrizAliqOut()) && Objects.equals(getCodVzon(), vtbDest.getCodVzon()) && Objects.equals(getCodVlis(), vtbDest.getCodVlis()) && Objects.equals(getCodVage(), vtbDest.getCodVage()) && Objects.equals(getPersonaRif(), vtbDest.getPersonaRif()) && Objects.equals(getPartIva(), vtbDest.getPartIva()) && Objects.equals(getCodAffiliazione(), vtbDest.getCodAffiliazione()) && Objects.equals(getIndirizzoLegale(), vtbDest.getIndirizzoLegale()) && Objects.equals(getCapLegale(), vtbDest.getCapLegale()) && Objects.equals(getCittaLegale(), vtbDest.getCittaLegale()) && Objects.equals(getProvLegale(), vtbDest.getProvLegale()) && Objects.equals(getNazioneLegale(), vtbDest.getNazioneLegale()) && Objects.equals(getCodMdep(), vtbDest.getCodMdep()) && Objects.equals(getFlagDomicRiba(), vtbDest.getFlagDomicRiba()) && Objects.equals(getFlagAttivo(), vtbDest.getFlagAttivo()) && Objects.equals(getFlagEsponi(), vtbDest.getFlagEsponi()) && Objects.equals(getRagSocLegale(), vtbDest.getRagSocLegale()) && Objects.equals(getCodAlis(), vtbDest.getCodAlis()) && Objects.equals(getCodVpre(), vtbDest.getCodVpre()) && Objects.equals(getCodVcom(), vtbDest.getCodVcom()) && Objects.equals(getCodScoCli(), vtbDest.getCodScoCli()) && Objects.equals(geteMail(), vtbDest.geteMail()) && Objects.equals(getDataCessazione(), vtbDest.getDataCessazione()) && Objects.equals(getDataAttivazione(), vtbDest.getDataAttivazione()) && Objects.equals(getCodVvet(), vtbDest.getCodVvet()) && Objects.equals(getGgChiusura(), vtbDest.getGgChiusura()) && Objects.equals(getTipoNegozio(), vtbDest.getTipoNegozio()) && Objects.equals(getCodEan(), vtbDest.getCodEan()) && Objects.equals(getFlagStampaPrezzi(), vtbDest.getFlagStampaPrezzi()) && Objects.equals(getCodAliq(), vtbDest.getCodAliq()) && Objects.equals(getCodGriglia(), vtbDest.getCodGriglia()) && Objects.equals(getCodAcc(), vtbDest.getCodAcc()) && Objects.equals(getCodVtip(), vtbDest.getCodVtip()) && Objects.equals(getCodVset(), vtbDest.getCodVset()) && Objects.equals(getCodVseg(), vtbDest.getCodVseg()) && Objects.equals(getCodVatt(), vtbDest.getCodVatt()) && Objects.equals(getCodFisc(), vtbDest.getCodFisc()) && Objects.equals(getCuuPa(), vtbDest.getCuuPa()) && Objects.equals(geteMailPec(), vtbDest.geteMailPec()) && Objects.equals(getFlagStabileOrg(), vtbDest.getFlagStabileOrg()) && Objects.equals(getLat(), vtbDest.getLat()) && Objects.equals(getLng(), vtbDest.getLng()) && Objects.equals(getTermCons(), vtbDest.getTermCons()) && Objects.equals(getItinerario(), vtbDest.getItinerario()) && Objects.equals(getImpMinOrd(), vtbDest.getImpMinOrd()) && Objects.equals(getPartIvaLegale(), vtbDest.getPartIvaLegale()) && Objects.equals(getCodFiscLegale(), vtbDest.getCodFiscLegale()) && Objects.equals(getPrecode(), vtbDest.getPrecode()) && Objects.equals(getVtbDestIntercode(), vtbDest.getVtbDestIntercode()); return Objects.equals(getCodAnag(), vtbDest.getCodAnag()) && Objects.equals(getCodVdes(), vtbDest.getCodVdes()) && Objects.equals(getDestinatario(), vtbDest.getDestinatario()) && Objects.equals(getIndirizzo(), vtbDest.getIndirizzo()) && Objects.equals(getCap(), vtbDest.getCap()) && Objects.equals(getCitta(), vtbDest.getCitta()) && Objects.equals(getProv(), vtbDest.getProv()) && Objects.equals(getNazione(), vtbDest.getNazione()) && Objects.equals(getTel(), vtbDest.getTel()) && Objects.equals(getFax(), vtbDest.getFax()) && Objects.equals(getNote(), vtbDest.getNote()) && Objects.equals(getFonte(), vtbDest.getFonte()) && Objects.equals(getCodCentroAzi(), vtbDest.getCodCentroAzi()) && Objects.equals(getGgCons(), vtbDest.getGgCons()) && Objects.equals(getCodAliqOut(), vtbDest.getCodAliqOut()) && Objects.equals(getCodAliqIn(), vtbDest.getCodAliqIn()) && Objects.equals(getDescrizAliqOut(), vtbDest.getDescrizAliqOut()) && Objects.equals(getCodVzon(), vtbDest.getCodVzon()) && Objects.equals(getCodVlis(), vtbDest.getCodVlis()) && Objects.equals(getCodVage(), vtbDest.getCodVage()) && Objects.equals(getPersonaRif(), vtbDest.getPersonaRif()) && Objects.equals(getPartIva(), vtbDest.getPartIva()) && Objects.equals(getCodAffiliazione(), vtbDest.getCodAffiliazione()) && Objects.equals(getIndirizzoLegale(), vtbDest.getIndirizzoLegale()) && Objects.equals(getCapLegale(), vtbDest.getCapLegale()) && Objects.equals(getCittaLegale(), vtbDest.getCittaLegale()) && Objects.equals(getProvLegale(), vtbDest.getProvLegale()) && Objects.equals(getNazioneLegale(), vtbDest.getNazioneLegale()) && Objects.equals(getCodMdep(), vtbDest.getCodMdep()) && Objects.equals(getFlagDomicRiba(), vtbDest.getFlagDomicRiba()) && Objects.equals(getFlagAttivo(), vtbDest.getFlagAttivo()) && Objects.equals(getFlagEsponi(), vtbDest.getFlagEsponi()) && Objects.equals(getRagSocLegale(), vtbDest.getRagSocLegale()) && Objects.equals(getCodAlis(), vtbDest.getCodAlis()) && Objects.equals(getCodVpre(), vtbDest.getCodVpre()) && Objects.equals(getCodVcom(), vtbDest.getCodVcom()) && Objects.equals(getCodScoCli(), vtbDest.getCodScoCli()) && Objects.equals(geteMail(), vtbDest.geteMail()) && Objects.equals(getDataCessazione(), vtbDest.getDataCessazione()) && Objects.equals(getDataAttivazione(), vtbDest.getDataAttivazione()) && Objects.equals(getCodVvet(), vtbDest.getCodVvet()) && Objects.equals(getGgChiusura(), vtbDest.getGgChiusura()) && Objects.equals(getTipoNegozio(), vtbDest.getTipoNegozio()) && Objects.equals(getCodEan(), vtbDest.getCodEan()) && Objects.equals(getFlagStampaPrezzi(), vtbDest.getFlagStampaPrezzi()) && Objects.equals(getCodAliq(), vtbDest.getCodAliq()) && Objects.equals(getCodGriglia(), vtbDest.getCodGriglia()) && Objects.equals(getCodAcc(), vtbDest.getCodAcc()) && Objects.equals(getCodVtip(), vtbDest.getCodVtip()) && Objects.equals(getCodVset(), vtbDest.getCodVset()) && Objects.equals(getCodVseg(), vtbDest.getCodVseg()) && Objects.equals(getCodVatt(), vtbDest.getCodVatt()) && Objects.equals(getCodFisc(), vtbDest.getCodFisc()) && Objects.equals(getCuuPa(), vtbDest.getCuuPa()) && Objects.equals(geteMailPec(), vtbDest.geteMailPec()) && Objects.equals(getFlagStabileOrg(), vtbDest.getFlagStabileOrg()) && Objects.equals(getLat(), vtbDest.getLat()) && Objects.equals(getLng(), vtbDest.getLng()) && Objects.equals(getTermCons(), vtbDest.getTermCons()) && Objects.equals(getItinerario(), vtbDest.getItinerario()) && Objects.equals(getImpMinOrd(), vtbDest.getImpMinOrd()) && Objects.equals(getPartIvaLegale(), vtbDest.getPartIvaLegale()) && Objects.equals(getCodFiscLegale(), vtbDest.getCodFiscLegale()) && Objects.equals(getPrecode(), vtbDest.getPrecode());
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(getCodAnag(), getCodVdes(), getDestinatario(), getIndirizzo(), getCap(), getCitta(), getProv(), getNazione(), getTel(), getFax(), getNote(), getFonte(), getCodCentroAzi(), getGgCons(), getCodAliqOut(), getCodAliqIn(), getDescrizAliqOut(), getCodVzon(), getCodVlis(), getCodVage(), getPersonaRif(), getPartIva(), getCodAffiliazione(), getIndirizzoLegale(), getCapLegale(), getCittaLegale(), getProvLegale(), getNazioneLegale(), getCodMdep(), getFlagDomicRiba(), getFlagAttivo(), getFlagEsponi(), getRagSocLegale(), getCodAlis(), getCodVpre(), getCodVcom(), getCodScoCli(), geteMail(), getDataCessazione(), getDataAttivazione(), getCodVvet(), getGgChiusura(), getTipoNegozio(), getCodEan(), getFlagStampaPrezzi(), getCodAliq(), getCodGriglia(), getCodAcc(), getCodVtip(), getCodVset(), getCodVseg(), getCodVatt(), getCodFisc(), getCuuPa(), geteMailPec(), getFlagStabileOrg(), getLat(), getLng(), getTermCons(), getItinerario(), getImpMinOrd(), getPartIvaLegale(), getCodFiscLegale(), getPrecode(), getVtbDestIntercode()); return Objects.hash(getCodAnag(), getCodVdes(), getDestinatario(), getIndirizzo(), getCap(), getCitta(), getProv(), getNazione(), getTel(), getFax(), getNote(), getFonte(), getCodCentroAzi(), getGgCons(), getCodAliqOut(), getCodAliqIn(), getDescrizAliqOut(), getCodVzon(), getCodVlis(), getCodVage(), getPersonaRif(), getPartIva(), getCodAffiliazione(), getIndirizzoLegale(), getCapLegale(), getCittaLegale(), getProvLegale(), getNazioneLegale(), getCodMdep(), getFlagDomicRiba(), getFlagAttivo(), getFlagEsponi(), getRagSocLegale(), getCodAlis(), getCodVpre(), getCodVcom(), getCodScoCli(), geteMail(), getDataCessazione(), getDataAttivazione(), getCodVvet(), getGgChiusura(), getTipoNegozio(), getCodEan(), getFlagStampaPrezzi(), getCodAliq(), getCodGriglia(), getCodAcc(), getCodVtip(), getCodVset(), getCodVseg(), getCodVatt(), getCodFisc(), getCuuPa(), geteMailPec(), getFlagStabileOrg(), getLat(), getLng(), getTermCons(), getItinerario(), getImpMinOrd(), getPartIvaLegale(), getCodFiscLegale(), getPrecode());
} }
} }

View File

@@ -4,11 +4,12 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
import it.integry.ems_model.annotation.*; import it.integry.ems_model.annotation.*;
import it.integry.ems_model.base.EntityBase; import it.integry.ems_model.base.EntityBase;
import it.integry.ems_model.utility.UtilityDB; import it.integry.ems_model.utility.UtilityDB;
import org.kie.api.definition.type.PropertyReactive;
import java.util.List;
import java.util.ArrayList;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.kie.api.definition.type.PropertyReactive;
import java.util.ArrayList;
import java.util.List;
@Master @Master
@PropertyReactive @PropertyReactive
@@ -63,6 +64,10 @@ public class WtbJrept extends EntityBase {
@SqlField(value = "orientation", nullable = false) @SqlField(value = "orientation", nullable = false)
private WtbJreptSetup.Orientation orientation; private WtbJreptSetup.Orientation orientation;
@VarBinary
@SqlField(value = "compiled_jasper", nullable = false)
private Byte[] compiledJasper;
@EntityChild @EntityChild
private List<WtbJrepr> wtbJrepr = new ArrayList<>(); private List<WtbJrepr> wtbJrepr = new ArrayList<>();
@@ -227,6 +232,15 @@ public class WtbJrept extends EntityBase {
return this; return this;
} }
public Byte[] getCompiledJasper() {
return compiledJasper;
}
public WtbJrept setCompiledJasper(Byte[] compiledJasper) {
this.compiledJasper = compiledJasper;
return this;
}
public List<WtbJrepr> getWtbJrepr() { public List<WtbJrepr> getWtbJrepr() {
return wtbJrepr; return wtbJrepr;
} }

View File

@@ -19,6 +19,7 @@ import it.integry.ems_model.utility.UtilityDB;
import it.integry.ems_model.utility.UtilityLocalDate; import it.integry.ems_model.utility.UtilityLocalDate;
import it.integry.ems_model.utility.UtilityString; import it.integry.ems_model.utility.UtilityString;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@@ -191,6 +192,8 @@ public class SqlFieldHolder {
return data; return data;
} }
}; };
} else if (dtoType.equals(Byte[].class) && sqlType.equals(byte[].class)) {
converter = data -> ArrayUtils.toObject((byte[]) data);
} else if (dtoType.equals(LatLng.class)) { } else if (dtoType.equals(LatLng.class)) {
WKTReader readerWkt = new WKTReader((new GeometryFactory(new PrecisionModel(), 4326))); WKTReader readerWkt = new WKTReader((new GeometryFactory(new PrecisionModel(), 4326)));

View File

@@ -10,6 +10,7 @@ import it.integry.ems_model.types.OperationType
import it.integry.ems.sync.MultiDBTransaction.Connection; import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems.utility.UtilityFile import it.integry.ems.utility.UtilityFile
import it.integry.ems.exception.CheckConstraintException import it.integry.ems.exception.CheckConstraintException
import it.integry.ems_model.utility.UtilityDB
global Connection conn global Connection conn
global String username global String username
@@ -126,6 +127,18 @@ then
} }
end end
rule "completeSetIdArtEquiAuto"
no-loop
when
eval(completeRulesEnabled)
$entity : MtbAart(idArtEqui == null && setIdArtEqui != null && setIdArtEqui && operation != OperationType.DELETE)
then
String idArtEqui = CommonRules.getIdArtEqui(conn, $entity);
modify($entity){
setIdArtEqui(idArtEqui)}
end
rule "completeInsEqui" rule "completeInsEqui"
no-loop no-loop
when when
@@ -190,6 +203,17 @@ then
modify ( $entity ) { setArticoloComposto("N") } modify ( $entity ) { setArticoloComposto("N") }
end end
rule "completeSetIdArtEqui"
no-loop
when
eval(completeRulesEnabled)
$entity : MtbAart(setIdArtEqui == null)
then
String sql = "select CAst( case when dbo.getGestSetup( 'MTB_AART', 'ID_ART_EQUI', 'INSERT_AUTO') = 'N' THEN 0 ELSE 1 END as BIT)";
Boolean setSetIdArtEqui = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(conn, sql);
modify ( $entity ) { setSetIdArtEqui(setSetIdArtEqui) }
end
rule "completeDescrEstesaArt" rule "completeDescrEstesaArt"
when when
eval(completeRulesEnabled) eval(completeRulesEnabled)

View File

@@ -26,8 +26,6 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
@@ -263,34 +261,6 @@ public class EmsEngineController {
return response; return response;
} }
@RequestMapping(value = EmsRestConstants.PATH_PROCESS_JASPER, method = RequestMethod.POST)
public @ResponseBody
List<ServiceRestResponse> processJasper(HttpServletRequest request,
@RequestParam(CommonConstants.PROFILE_DB) String configuration,
@RequestBody(required = true) String b64inputValue) {
List<ServiceRestResponse> response = new ArrayList<ServiceRestResponse>();
try {
String xmlDto = new String(Base64.decodeBase64(b64inputValue));
JasperDTO jasperDTO = reportProcessor.XMLToDTO(xmlDto);
FileItem fi = new FileItem();
byte[] bytes = emsEngineService.processReport(jasperDTO);
if (bytes != null) {
fi.setFileb64Content(new String(Base64.encodeBase64(bytes)));
}
response.add(new ServiceRestResponse(EsitoType.OK, multiDBTransactionManager.getPrimaryDatasource().getProfile(), fi));
} catch (JRException e) {
logger.error(e.toString() + " - Cause: " + e.getCause());
response.add(new ServiceRestResponse(EsitoType.KO, configuration, e));
} catch (Exception e) {
logger.error(request.getRequestURI(), e);
response.add(new ServiceRestResponse(EsitoType.KO, configuration, e));
}
return response;
}
@RequestMapping(value = EmsRestConstants.PATH_RETRIEVE_GRL_ANAG_JREPT_TYPES, method = RequestMethod.GET) @RequestMapping(value = EmsRestConstants.PATH_RETRIEVE_GRL_ANAG_JREPT_TYPES, method = RequestMethod.GET)
public @ResponseBody public @ResponseBody
ServiceRestResponse retrieveGrlAnagJreptTypes(HttpServletRequest request) { ServiceRestResponse retrieveGrlAnagJreptTypes(HttpServletRequest request) {

View File

@@ -177,10 +177,10 @@ public class ToscaSalesService {
.setRagSoc(ragSoc.length() >= 40 ? ragSoc.substring(0, 39) : ragSoc) .setRagSoc(ragSoc.length() >= 40 ? ragSoc.substring(0, 39) : ragSoc)
.setNote(ragSoc) .setNote(ragSoc)
.setDiacod(order.getCounterPNr()) .setDiacod(order.getCounterPNr())
.setOperation(OperationType.INSERT); .setOperation(OperationType.INSERT_OR_UPDATE);
VtbClie clie = new VtbClie(); VtbClie clie = new VtbClie();
clie.setOperation(OperationType.INSERT); clie.setOperation(OperationType.INSERT_OR_UPDATE);
gtbAnag.setVtbClie(clie); gtbAnag.setVtbClie(clie);
entityProcessor.processEntity(gtbAnag, true, multiDBTransactionManager); entityProcessor.processEntity(gtbAnag, true, multiDBTransactionManager);
order.setCodAnag(gtbAnag.getCodAnag()); order.setCodAnag(gtbAnag.getCodAnag());

View File

@@ -10,22 +10,22 @@ import it.integry.ems.production.dto.MRPCreaOrdineLavDTO;
import it.integry.ems.production.service.MrpDailyMaterialReqService; import it.integry.ems.production.service.MrpDailyMaterialReqService;
import it.integry.ems.production.service.MrpService; import it.integry.ems.production.service.MrpService;
import it.integry.ems.production.service.ProductionService; import it.integry.ems.production.service.ProductionService;
import it.integry.ems.response.EsitoType;
import it.integry.ems.response.ServiceRestResponse; import it.integry.ems.response.ServiceRestResponse;
import it.integry.ems.rules.businessLogic.dto.LoadColliDTO; import it.integry.ems.rules.businessLogic.dto.LoadColliDTO;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems_model.config.EmsRestConstants; import it.integry.ems_model.config.EmsRestConstants;
import it.integry.ems_model.entity.DtbDoct;
import it.integry.ems_model.entity.DtbOrdt; import it.integry.ems_model.entity.DtbOrdt;
import it.integry.ems_model.utility.Query; import it.integry.ems_model.utility.UtilityDate;
import it.integry.ems_model.utility.UtilityDB; import it.integry.ems_model.utility.UtilityString;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Date; import java.util.Date;
import java.util.List;
@RestController @RestController
@Scope(value = "request") @Scope(value = "request")
@@ -108,22 +108,55 @@ public class ProductionController {
@RequestMapping(value = "/distribuzioneMateriali", method = RequestMethod.GET) @RequestMapping(value = "/distribuzioneMateriali", method = RequestMethod.GET)
public @ResponseBody public @ResponseBody
ServiceRestResponse distribuzioneMateriali(@RequestParam String codAnag, ServiceRestResponse distribuzioneMateriali() throws Exception {
@RequestParam String codDtip,
@RequestParam Date dataDoc,
@RequestParam String serDoc,
@RequestParam Integer numDoc) throws Exception {
String sql = Query.format(
"SELECT * \n" +
"FROM dtb_doct WHERE dtb_doct.cod_anag = %s\n" +
" AND dtb_doct.cod_dtip = %s\n" +
" AND dtb_doct.data_doc = %s\n" +
" AND dtb_doct.ser_doc = %s\n" +
" AND dtb_doct.num_doc = %s",
codAnag, codDtip, dataDoc, serDoc, numDoc
);
DtbDoct dtbDoct = UtilityDB.executeSimpleQueryOnlyFirstRowDTO(multiDBTransactionManager.getPrimaryConnection(), sql, DtbDoct.class);
return ServiceRestResponse.createPositiveResponse(productionService.distribuzioneMateriali(dtbDoct)); return ServiceRestResponse.createPositiveResponse(productionService.distribuzioneMateriali());
} }
@RequestMapping(value = "/attribuzioneCostoMaterialiLavorazione", method = RequestMethod.POST)
public @ResponseBody ServiceRestResponse attribuzioneCostoMaterialiLavorazione(
HttpServletRequest request,
@RequestParam(CommonConstants.PROFILE_DB) String profileDb,
@RequestParam Integer giorni,
@RequestParam(name = "data", required = false) String dataS,
@RequestParam(required = false) String codProd,
@RequestParam(required = false) String codJcom,
@RequestParam(required = false) String partitaMag
) {
try {
Date dataFine = UtilityString.isNullOrEmpty(dataS) ? new Date() : UtilityDate.RecognizeDate(dataS);
Date dataIniz = UtilityDate.dateAdd(dataFine, giorni);
productionService.attribuzioneCostoMaterialiLavorazione(dataIniz, dataFine, codProd, partitaMag, codJcom);
return ServiceRestResponse.createPositiveResponse();
} catch (Exception e) {
try {
multiDBTransactionManager.rollbackAll();
} catch (Exception ex) {
logger.error(request.getRequestURI(), e);
}
logger.error(request.getRequestURI(), e);
return new ServiceRestResponse(EsitoType.KO, profileDb, e);
}
}
@RequestMapping(value = "/getDettaglioCostiLavorazioneProdotto", method = RequestMethod.GET)
public @ResponseBody ServiceRestResponse getDettaglioCostiLavorazioneProdotto(
HttpServletRequest request,
@RequestParam(CommonConstants.PROFILE_DB) String profileDB,
@RequestParam String codProd,
@RequestParam(required = false) String codJcom,
@RequestParam(required = false) String partitaMag
) {
try {
return ServiceRestResponse.createPositiveResponse(productionService.getDettaglioCostiProd(codProd, partitaMag, codJcom));
} catch (Exception e) {
logger.error(request.getRequestURI(), e);
return new ServiceRestResponse(EsitoType.KO, profileDB, e);
}
}
} }

View File

@@ -0,0 +1,82 @@
package it.integry.ems.production.dto;
import java.util.Date;
import java.util.Objects;
public class ArticoloPartitaCommessaDTO {
private String codMart;
private String codJcom;
private String partitaMag;
private Date dataOrd;
private Integer numOrd;
public ArticoloPartitaCommessaDTO() {
}
public ArticoloPartitaCommessaDTO(String codMart, String codJcom, String partitaMag, Date dataOrd, Integer numOrd) {
this.codMart = codMart;
this.codJcom = codJcom;
this.partitaMag = partitaMag;
this.dataOrd = dataOrd;
this.numOrd = numOrd;
}
public String getCodMart() {
return codMart;
}
public ArticoloPartitaCommessaDTO setCodMart(String codMart) {
this.codMart = codMart;
return this;
}
public String getCodJcom() {
return codJcom;
}
public ArticoloPartitaCommessaDTO setCodJcom(String codJcom) {
this.codJcom = codJcom;
return this;
}
public String getPartitaMag() {
return partitaMag;
}
public ArticoloPartitaCommessaDTO setPartitaMag(String partitaMag) {
this.partitaMag = partitaMag;
return this;
}
public Date getDataOrd() {
return dataOrd;
}
public ArticoloPartitaCommessaDTO setDataOrd(Date dataOrd) {
this.dataOrd = dataOrd;
return this;
}
public Integer getNumOrd() {
return numOrd;
}
public ArticoloPartitaCommessaDTO setNumOrd(Integer numOrd) {
this.numOrd = numOrd;
return this;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ArticoloPartitaCommessaDTO that = (ArticoloPartitaCommessaDTO) o;
return Objects.equals(getCodMart(), that.getCodMart()) && Objects.equals(getCodJcom(), that.getCodJcom()) && Objects.equals(getPartitaMag(), that.getPartitaMag()) && Objects.equals(getDataOrd(), that.getDataOrd()) && Objects.equals(getNumOrd(), that.getNumOrd());
}
@Override
public int hashCode() {
return Objects.hash(getCodMart(), getCodJcom(), getPartitaMag(), getDataOrd(), getNumOrd());
}
}

View File

@@ -0,0 +1,131 @@
package it.integry.ems.production.dto;
import it.integry.ems_model.annotation.SqlField;
import java.math.BigDecimal;
import java.time.LocalDate;
public class DettaglioCostiDTO {
@SqlField("gruppo")
private String gruppo;
@SqlField("cod_jcom")
private String codJcom;
@SqlField("cod_prod")
private String codProd;
@SqlField("partita_mag_prod")
private String partitaMagProd;
@SqlField("qta_prod")
private BigDecimal qtaProd;
@SqlField("cod_mart")
private String codMart;
@SqlField("partita_mag")
private String partitaMag;
@SqlField("qta_doc")
private BigDecimal qtaDoc;
@SqlField("val_doc")
private BigDecimal valDoc;
@SqlField("data_ord")
private LocalDate dataOrd;
@SqlField("num_ord")
private Integer numOrd;
public String getGruppo() {
return gruppo;
}
public DettaglioCostiDTO setGruppo(String gruppo) {
this.gruppo = gruppo;
return this;
}
public String getCodJcom() {
return codJcom;
}
public DettaglioCostiDTO setCodJcom(String codJcom) {
this.codJcom = codJcom;
return this;
}
public String getCodProd() {
return codProd;
}
public DettaglioCostiDTO setCodProd(String codProd) {
this.codProd = codProd;
return this;
}
public String getPartitaMagProd() {
return partitaMagProd;
}
public DettaglioCostiDTO setPartitaMagProd(String partitaMagProd) {
this.partitaMagProd = partitaMagProd;
return this;
}
public BigDecimal getQtaProd() {
return qtaProd;
}
public DettaglioCostiDTO setQtaProd(BigDecimal qtaProd) {
this.qtaProd = qtaProd;
return this;
}
public String getCodMart() {
return codMart;
}
public DettaglioCostiDTO setCodMart(String codMart) {
this.codMart = codMart;
return this;
}
public String getPartitaMag() {
return partitaMag;
}
public DettaglioCostiDTO setPartitaMag(String partitaMag) {
this.partitaMag = partitaMag;
return this;
}
public BigDecimal getQtaDoc() {
return qtaDoc;
}
public DettaglioCostiDTO setQtaDoc(BigDecimal qtaDoc) {
this.qtaDoc = qtaDoc;
return this;
}
public BigDecimal getValDoc() {
return valDoc;
}
public DettaglioCostiDTO setValDoc(BigDecimal valDoc) {
this.valDoc = valDoc;
return this;
}
public LocalDate getDataOrd() {
return dataOrd;
}
public DettaglioCostiDTO setDataOrd(LocalDate dataOrd) {
this.dataOrd = dataOrd;
return this;
}
public Integer getNumOrd() {
return numOrd;
}
public DettaglioCostiDTO setNumOrd(Integer numOrd) {
this.numOrd = numOrd;
return this;
}
}

View File

@@ -3,6 +3,7 @@ package it.integry.ems.production.service;
import com.annimon.stream.Optional; import com.annimon.stream.Optional;
import com.annimon.stream.Stream; import com.annimon.stream.Stream;
import it.integry.common.var.CommonConstants; import it.integry.common.var.CommonConstants;
import it.integry.ems.Import.dto.AnomalieDTO;
import it.integry.ems.document.dto.ChiusuraLavorazioneDTO; import it.integry.ems.document.dto.ChiusuraLavorazioneDTO;
import it.integry.ems.document.service.DocumentProdService; import it.integry.ems.document.service.DocumentProdService;
import it.integry.ems.exception.MissingDataException; import it.integry.ems.exception.MissingDataException;
@@ -11,6 +12,8 @@ import it.integry.ems.production.dto.*;
import it.integry.ems.rules.businessLogic.LoadColliService; import it.integry.ems.rules.businessLogic.LoadColliService;
import it.integry.ems.rules.businessLogic.dto.LoadColliDTO; import it.integry.ems.rules.businessLogic.dto.LoadColliDTO;
import it.integry.ems.service.EntityProcessor; import it.integry.ems.service.EntityProcessor;
import it.integry.ems.service.MailService;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.utility.UtilityEntity; import it.integry.ems.utility.UtilityEntity;
import it.integry.ems_model.base.EntityBase; import it.integry.ems_model.base.EntityBase;
@@ -27,12 +30,11 @@ import org.springframework.stereotype.Service;
import java.io.IOException; import java.io.IOException;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.math.RoundingMode;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.SQLException; import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.time.LocalDate; import java.time.LocalDate;
import java.time.ZoneId; import java.time.ZoneId;
import java.util.*; import java.util.*;
@@ -53,6 +55,9 @@ public class ProductionService {
@Autowired @Autowired
private LoadColliService loadColliService; private LoadColliService loadColliService;
@Autowired
private MailService mailService;
public void chiudiGiornata(ChiudiGiornataDTO datiChiusura) throws Exception { public void chiudiGiornata(ChiudiGiornataDTO datiChiusura) throws Exception {
Connection conn = multiDBTransactionManager.getPrimaryConnection(); Connection conn = multiDBTransactionManager.getPrimaryConnection();
HashMap<String, String> setupCruscotto = setupGest.getSetupSection(conn, "CRUSCOTTO_PRODUZIONE", "SETUP"); HashMap<String, String> setupCruscotto = setupGest.getSetupSection(conn, "CRUSCOTTO_PRODUZIONE", "SETUP");
@@ -1141,7 +1146,51 @@ public class ProductionService {
return entities; return entities;
} }
public List<EntityBase> distribuzioneMateriali(DtbDoct dtbDoct) throws Exception { public List<EntityBase> distribuzioneMateriali() throws Exception {
String sql =
"SELECT dtb_doct.*\n" +
"FROM dtb_doct INNER JOIN dtb_tipi ON dtb_doct.cod_dtip = dtb_tipi.cod_dtip\n" +
"WHERE dtb_tipi.gestione = 'L' \n" +
" AND dtb_doct.id_lotto is not null \n" +
" AND (dtb_tipi.segno_qta_car < 0 OR segno_qta_scar > 0 ) \n" +
" AND data_doc BETWEEN DATEADD(MONTH, -1, CAST(GETDATE() AS DATE)) AND CAST(GETDATE() AS DATE)";
List<DtbDoct> dtbDocts = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sql, DtbDoct.class);
List<EntityBase> entities = new ArrayList<>();
List<AnomalieDTO> anomalieDTOS = new ArrayList<>();
for (DtbDoct dtbDoct : dtbDocts) {
distribuzioneMateriali(dtbDoct);
entities.add(distribuzioneMateriali(dtbDoct));
if (dtbDoct.getException() != null) {
anomalieDTOS.add(
AnomalieDTO.error(
String.format(
"Errore nell'aggiornamento del documento %s del %s n. %s/%s: %s",
dtbDoct.getCodDtip(),
new SimpleDateFormat(CommonConstants.DATE_FORMAT_YMD).format(dtbDoct.getDataDoc()),
dtbDoct.getSerDoc(),
dtbDoct.getNumDoc(),
dtbDoct.getException().getMessage()
)));
}
}
if (anomalieDTOS.size() > 0) {
String emailForLog = setupGest.getSetup("W_PORDI_RC", "DISTRIBUZIONE_MATERIALI", "EMAL_NOTIFICATION");
if (!UtilityString.isNullOrEmpty(emailForLog))
mailService.sendErrorMail(multiDBTransactionManager, emailForLog, "Errore durante la procedure di distribuzione materiali",
"Errore durante la procedure di distribuzione materiali",
entities.stream().filter(x -> x.getException() != null).collect(Collectors.toList()),
null, anomalieDTOS, null);
}
return entities;
}
public DtbDoct distribuzioneMateriali(DtbDoct dtbDoct) throws Exception {
Connection conn = multiDBTransactionManager.getPrimaryConnection(); Connection conn = multiDBTransactionManager.getPrimaryConnection();
String sql = Query.format( String sql = Query.format(
"SELECT * FROM dtb_docr WHERE cod_dtip = %s AND num_doc = %s AND data_doc = %s AND cod_anag = %s AND ser_doc = %s", "SELECT * FROM dtb_docr WHERE cod_dtip = %s AND num_doc = %s AND data_doc = %s AND cod_anag = %s AND ser_doc = %s",
@@ -1309,8 +1358,8 @@ public class ProductionService {
} }
dtbDoct.setOperation(OperationType.UPDATE); dtbDoct.setOperation(OperationType.UPDATE);
entityProcessor.processEntity(dtbDoct, multiDBTransactionManager);
return entityProcessor.processEntity(dtbDoct, multiDBTransactionManager); return dtbDoct;
} }
public static BigDecimal sumQtaOrd(List<RigheLottLavDTO> righeLottLavDTOList) { public static BigDecimal sumQtaOrd(List<RigheLottLavDTO> righeLottLavDTOList) {
@@ -1318,4 +1367,213 @@ public class ProductionService {
.map(RigheLottLavDTO::getQta_ord) .map(RigheLottLavDTO::getQta_ord)
.reduce(BigDecimal.ZERO, BigDecimal::add); .reduce(BigDecimal.ZERO, BigDecimal::add);
} }
public List<DettaglioCostiDTO> getDettaglioCostiProd(String codProd, String partitaMag, String codJcom) throws Exception {
String sql = "WITH ordini AS (SELECT dtb_ordt.cod_prod,\n" +
" dtb_ordt.partita_mag AS partita_mag_prod,\n" +
" dtb_ord_steps.cod_jfas,\n" +
" dtb_ord_steps.data_iniz,\n" +
" dtb_ord_steps.data_fine,\n" +
" dtb_ordt.gestione,\n" +
" dtb_ordt.cod_jcom,\n" +
" dtb_ordt.data_ord,\n" +
" dtb_ordt.num_ord,\n" +
" IIF(dtb_ordt.qta_evasa_prod = 0, dtb_ordt.qta_prod, dtb_ordt.qta_evasa_prod) *\n" +
" dtb_ordt.rap_conv_prod AS qta_prod\n" +
" FROM dtb_ordt\n" +
" INNER JOIN dtb_ord_steps\n" +
" ON dtb_ordt.gestione = dtb_ord_steps.gestione AND\n" +
" dtb_ordt.data_ord = dtb_ord_steps.data_ord AND\n" +
" dtb_ordt.num_ord = dtb_ord_steps.num_ord\n" +
" WHERE dtb_ordt.gestione = 'L'),\n" +
" produzioni_commessa AS (SELECT cod_jfas,\n" +
" cod_jcom,\n" +
" data_lav,\n" +
" SUM(qta_prod) AS qta_prod\n" +
" FROM (SELECT DISTINCT cod_jfas,\n" +
" cod_jcom,\n" +
" CAST(data_iniz AS DATE) AS data_lav,\n" +
" qta_prod\n" +
" FROM ordini) ord\n" +
"\n" +
" GROUP BY cod_jfas, cod_jcom, data_lav)\n" +
" ,\n" +
" rapportini AS (SELECT jtb_rlavr.cod_jfas,\n" +
" jtb_rlavr.cod_jcom,\n" +
" jtb_rlavr.cod_jflav,\n" +
" jtb_rlavr.ore,\n" +
" jvw_timbrature.ingresso,\n" +
" jvw_timbrature.uscita,\n" +
" ordini.cod_prod,\n" +
" ordini.partita_mag_prod,\n" +
" ordini.qta_prod,\n" +
" produzioni_commessa.qta_prod AS prd_comm,\n" +
" ROUND((ordini.qta_prod / produzioni_commessa.qta_prod) *\n" +
" jtb_rlavr.ore,\n" +
" 5) ora_lav_ord,\n" +
" ROUND(ordini.qta_prod / produzioni_commessa.qta_prod *\n" +
" jtb_rlavr.ore, 5) *\n" +
" jtb_flav.costo_ord AS costo_lav,\n" +
" ordini.data_ord,\n" +
" ordini.num_ord\n" +
" FROM jtb_rlavt\n" +
" INNER JOIN jtb_rlavr ON jtb_rlavt.cod_jflav = jtb_rlavr.cod_jflav AND\n" +
" jtb_rlavt.data_lav = jtb_rlavr.data_lav\n" +
" INNER JOIN jtb_flav ON jtb_rlavt.cod_jflav = jtb_flav.cod_jflav\n" +
" LEFT OUTER JOIN jvw_timbrature ON jtb_rlavt.cod_jflav = jvw_timbrature.cod_jflav AND\n" +
" jtb_rlavt.data_lav = jvw_timbrature.data_lav\n" +
" INNER JOIN ordini ON jtb_rlavr.cod_jcom = ordini.cod_jcom AND\n" +
" jtb_rlavr.cod_jfas = ordini.cod_jfas AND\n" +
" ((jtb_rlavt.data_lav BETWEEN CAST(ordini.data_iniz AS DATE) AND CAST(ordini.data_fine AS DATE))\n" +
" OR (jtb_rlavt.data_lav <= CAST(ordini.data_iniz AS DATE) AND\n" +
" ordini.data_fine IS NULL))\n" +
" INNER JOIN produzioni_commessa ON jtb_rlavr.cod_jfas = produzioni_commessa.cod_jfas AND\n" +
" jtb_rlavr.cod_jcom = produzioni_commessa.cod_jcom AND\n" +
" jtb_rlavr.data_lav = produzioni_commessa.data_lav\n" +
" WHERE jtb_rlavr.ore <> 0)" +
" , doc_l AS (SELECT dtb_docr.cod_mart,\n" +
" dtb_docr.partita_mag,\n" +
" dtb_docr.data_ord,\n" +
" dtb_docr.num_ord,\n" +
" SUM(dtb_docr.qta_doc) AS qta_doc,\n" +
" SUM(dtb_docr.qta_doc * IIF(dtb_docr.partita_mag IS NULL,\n" +
" [dbo].[f_GetCostoUltArt_depo](dtb_doct.data_reg, dtb_doct.cod_mdep,\n" +
" dtb_docr.cod_mart),\n" +
" mtb_partita_mag.costo_unt_um_mag)) AS val_doc\n" +
" FROM dtb_doct\n" +
" INNER JOIN dtb_docr ON dtb_doct.cod_anag = dtb_docr.cod_anag AND\n" +
" dtb_doct.cod_dtip = dtb_docr.cod_dtip AND\n" +
" dtb_doct.data_doc = dtb_docr.data_doc AND\n" +
" dtb_doct.ser_doc = dtb_docr.ser_doc AND\n" +
" dtb_doct.num_doc = dtb_docr.num_doc\n" +
" INNER JOIN dtb_tipi ON dtb_doct.cod_dtip = dtb_tipi.cod_dtip\n" +
" LEFT OUTER JOIN mtb_partita_mag ON dtb_docr.cod_mart = mtb_partita_mag.cod_mart AND\n" +
" dtb_docr.partita_mag = mtb_partita_mag.partita_mag\n" +
" WHERE dtb_doct.gestione = 'L'\n" +
" AND (dtb_tipi.segno_qta_car < 0 OR dtb_tipi.segno_qta_scar > 0)\n" +
" GROUP BY dtb_docr.cod_mart,\n" +
" dtb_docr.partita_mag,\n" +
" dtb_docr.data_ord,\n" +
" dtb_docr.num_ord)\n" +
"\n" +
"SELECT 'M' AS gruppo,\n" +
" dtb_ordt.cod_jcom,\n" +
" dtb_ordt.cod_prod,\n" +
" dtb_ordt.partita_mag AS partitaMagProd,\n" +
" IIF(dtb_ordt.qta_evasa_prod = 0, dtb_ordt.qta_prod, dtb_ordt.qta_evasa_prod) * dtb_ordt.rap_conv_prod AS qta_prod,\n" +
" doc_l.cod_mart,\n" +
" doc_l.partita_mag,\n" +
" doc_l.qta_doc,\n" +
" doc_l.val_doc,\n" +
" dtb_ordt.data_ord,\n" +
" dtb_ordt.num_ord\n" +
"FROM dtb_ordt\n" +
" INNER JOIN doc_l ON dtb_ordt.data_ord = doc_l.data_ord AND dtb_ordt.num_ord = doc_l.num_ord\n" +
"WHERE cod_prod = " + UtilityDB.valueToString(codProd) + "\n" +
" AND cod_jcom = " + UtilityDB.valueToString(codJcom) + "\n" +
" AND (" + UtilityDB.valueToString(partitaMag) + " IS NULL OR dtb_ordt.partita_mag = " + UtilityDB.valueToString(partitaMag) + ")\n" +
" AND dtb_ordt.gestione = 'L'\n" +
"UNION ALL\n" +
"SELECT DISTINCT 'R' AS gruppo,\n" +
" cod_jcom,\n" +
" rapportini.cod_prod,\n" +
" rapportini.partita_mag_prod AS partitaMagProd,\n" +
" rapportini.qta_prod,\n" +
" rapportini.cod_jflav AS cod_mart,\n" +
" rapportini.cod_jfas AS partita_mag,\n" +
" ora_lav_ord,\n" +
" costo_lav,\n" +
" data_ord,\n" +
" num_ord\n" +
"FROM rapportini\n" +
"WHERE cod_prod = " + UtilityDB.valueToString(codProd) + "\n" +
" AND cod_jcom = " + UtilityDB.valueToString(codJcom) + "\n" +
" AND (" + UtilityDB.valueToString(partitaMag) + " IS NULL OR rapportini.partita_mag_prod = " + UtilityDB.valueToString(partitaMag) + ")\n" +
"UNION ALL\n" +
"SELECT 'T' AS gruppo,\n" +
" dtb_ordt.cod_jcom,\n" +
" dtb_ordt.cod_prod,\n" +
" dtb_ordt.partita_mag AS partitaMagProd,\n" +
" IIF(dtb_ordt.qta_evasa_prod = 0, dtb_ordt.qta_prod, dtb_ordt.qta_evasa_prod) AS qta_prod,\n" +
" dtb_ords.cod_spes,\n" +
" NULL,\n" +
" IIF(dtb_ordt.qta_evasa_prod = 0, dtb_ordt.qta_prod, dtb_ordt.qta_evasa_prod) AS qta_doc,\n" +
" IIF(dtb_ordt.qta_evasa_prod = 0, dtb_ordt.qta_prod, dtb_ordt.qta_evasa_prod) * dtb_ords.val_unt AS val_doc,\n" +
" dtb_ordt.data_ord,\n" +
" dtb_ordt.num_ord\n" +
"FROM dtb_ordt\n" +
" INNER JOIN dtb_ords ON dtb_ordt.data_ord = dtb_ords.data_ord AND dtb_ordt.num_ord = dtb_ords.num_ord AND\n" +
" dtb_ordt.gestione = dtb_ords.gestione\n" +
" INNER JOIN gtb_anag ON dtb_ordt.cod_anag = gtb_anag.cod_anag\n" +
"WHERE cod_prod = " + UtilityDB.valueToString(codProd) + "\n" +
" AND cod_jcom = " + UtilityDB.valueToString(codJcom) + "\n" +
" AND (" + UtilityDB.valueToString(partitaMag) + " IS NULL OR dtb_ordt.partita_mag = " + UtilityDB.valueToString(partitaMag) + ")\n" +
" AND dtb_ordt.gestione = 'L'\n" +
" AND NOT EXISTS(SELECT * FROM azienda WHERE azienda.part_iva = gtb_anag.part_iva)\n" +
"ORDER BY data_ord, num_ord, cod_jcom, cod_prod, 4, gruppo";
return UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sql, DettaglioCostiDTO.class);
}
public void attribuzioneCostoMaterialiLavorazione(Date dataIniz, Date dataFine, String codProd, String partitaMag, String codJcom) throws Exception {
String codDtipLav = setupGest.getSetup(multiDBTransactionManager.getPrimaryConnection(), "W_PORDI_RC", "SETUP_DOCUMENTI", "COD_DTIP_CAR");
String codDtipLavTerzi = setupGest.getSetup(multiDBTransactionManager.getPrimaryConnection(), "DATI_AZIENDA", "CONTO_LAVORO", "COD_DTIP_CLAV");
//cerco tutti i documenti di lavorazione creati nel periodo selezionato
String sql = "SELECT dtb_docr.*\n" +
"FROM dtb_docr\n" +
" INNER JOIN dtb_doct ON dtb_docr.cod_anag = dtb_doct.cod_anag AND dtb_docr.cod_dtip = dtb_doct.cod_dtip AND\n" +
" dtb_docr.data_doc = dtb_doct.data_doc AND dtb_docr.ser_doc = dtb_doct.ser_doc AND\n" +
" dtb_docr.num_doc = dtb_doct.num_doc AND dtb_docr.cod_mart = dtb_doct.cod_prod\n" +
"WHERE dtb_doct.data_doc BETWEEN " + UtilityDB.valueToString(dataIniz) + " AND " + UtilityDB.valueToString(dataFine) + "\n" +
" AND dtb_doct.cod_dtip in (" + UtilityDB.valueToString(codDtipLav) + " , "+UtilityDB.valueToString(codDtipLavTerzi)+")\n" +
" AND (" + UtilityDB.valueToString(codProd) + " IS NULL OR dtb_doct.cod_prod = " + UtilityDB.valueToString(codProd) + ")\n" +
" AND (" + UtilityDB.valueToString(codJcom) + " IS NULL OR dtb_doct.cod_jcom = " + UtilityDB.valueToString(codJcom) + ")\n" +
" AND (" + UtilityDB.valueToString(partitaMag) + " IS NULL OR dtb_doct.partita_mag = " + UtilityDB.valueToString(partitaMag) + ")";
List<DtbDocr> documentiLav = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sql, DtbDocr.class);
if (UtilityList.isNullOrEmpty(documentiLav))
return;
// raggruppo per articolo/commessa/partita/ordine
List<ArticoloPartitaCommessaDTO> listToCheck = documentiLav
.stream()
.map(x -> new ArticoloPartitaCommessaDTO(x.getCodMart(), x.getCodJcom(), x.getPartitaMag(), x.getDataOrd(), x.getNumOrd()))
.distinct()
.collect(Collectors.toList());
for (ArticoloPartitaCommessaDTO dataToCheck : listToCheck) {
//prendo dettaglio costi per articolo commessa partita
List<DettaglioCostiDTO> dettaglioCosti = getDettaglioCostiProd(dataToCheck.getCodMart(), dataToCheck.getPartitaMag(), dataToCheck.getCodJcom());
if (UtilityList.isNullOrEmpty(dettaglioCosti))
continue;
//filtro solo i costi dell'ordine richiesto
List<DettaglioCostiDTO> costiOrdine = dettaglioCosti.stream()
.filter(c ->
Objects.equals(UtilityLocalDate.localDateToDate(c.getDataOrd()), dataToCheck.getDataOrd()) &&
Objects.equals(c.getNumOrd(), dataToCheck.getNumOrd())
)
.collect(Collectors.toList());
// il costoUnitario è la somma dei costi divisi per la quantità prodotta nell'ordine
BigDecimal costoProdUnt = costiOrdine.stream()
.map(x -> x.getValDoc().divide(x.getQtaProd(), 5, RoundingMode.HALF_UP))
.reduce(BigDecimal.ZERO, BigDecimal::add);
//aggiorno le righe dei vari documenti (mantenendo lo stesso filtro ovviamente)
List<DtbDocr> righeDaAggiornare = documentiLav.stream()
.filter(x -> new ArticoloPartitaCommessaDTO(x.getCodMart(), x.getCodJcom(), x.getPartitaMag(), x.getDataOrd(), x.getNumOrd()).equals(dataToCheck))
.peek(r -> {
r.setValUnt(costoProdUnt)
.setCostoUnt(costoProdUnt)
.setOperation(OperationType.UPDATE);
}).collect(Collectors.toList());
List<DtbDoct> docDaAggiornare = righeDaAggiornare.stream().map(r -> new DtbDoct(r.getCodAnag(), r.getCodDtip(), r.getDataDoc(), r.getNumDoc(), r.getSerDoc())).distinct().collect(Collectors.toList());
docDaAggiornare = docDaAggiornare.stream().peek(d -> {
d.setDtbDocr(righeDaAggiornare.stream()
.filter(r -> d.equals(new DtbDoct(r.getCodAnag(), r.getCodDtip(), r.getDataDoc(), r.getNumDoc(), r.getSerDoc())))
.collect(Collectors.toList()));
}).collect(Collectors.toList());
entityProcessor.processEntityList(docDaAggiornare, true);
}
}
} }

View File

@@ -27,9 +27,11 @@ import it.integry.ems.response.EsitoType;
import it.integry.ems.response.FileItem; import it.integry.ems.response.FileItem;
import it.integry.ems.response.ServiceRestResponse; import it.integry.ems.response.ServiceRestResponse;
import it.integry.ems.retail.dto.AnomalieResiDTO; import it.integry.ems.retail.dto.AnomalieResiDTO;
import it.integry.ems.retail.dto.GiacenzaDTO;
import it.integry.ems.retail.dto.OrdChkConsDTO; import it.integry.ems.retail.dto.OrdChkConsDTO;
import it.integry.ems.retail.pvmRetail.dto.*; import it.integry.ems.retail.pvmRetail.dto.*;
import it.integry.ems.retail.pvmRetail.dto.save.*; import it.integry.ems.retail.pvmRetail.dto.save.*;
import it.integry.ems.retail.service.GiacenzaPvHandlerService;
import it.integry.ems.rules.businessLogic.LoadColliService; import it.integry.ems.rules.businessLogic.LoadColliService;
import it.integry.ems.rules.businessLogic.dto.LoadColliDTO; import it.integry.ems.rules.businessLogic.dto.LoadColliDTO;
import it.integry.ems.rules.completing.OrderRules; import it.integry.ems.rules.completing.OrderRules;
@@ -136,6 +138,9 @@ public class PvmService {
@Autowired @Autowired
private UserSession userSession; private UserSession userSession;
@Autowired
private GiacenzaPvHandlerService giacenzaPvHandlerService;
public List<OrdChkConsDTO> chkDisponibilitaCons(Date dataCons, String citta) throws Exception { public List<OrdChkConsDTO> chkDisponibilitaCons(Date dataCons, String citta) throws Exception {
String profileDb = null; String profileDb = null;
HashMap<String, Object> userData = systemService.login(requestDataDTO.getUsername(), requestDataDTO.getPassword(), "", profileDb); HashMap<String, Object> userData = systemService.login(requestDataDTO.getUsername(), requestDataDTO.getPassword(), "", profileDb);
@@ -1553,6 +1558,7 @@ public class PvmService {
private MtbColt saveColli(ColloDTO colloDTO, Date dateCreate, String gestione, String segno, String annotazioni, private MtbColt saveColli(ColloDTO colloDTO, Date dateCreate, String gestione, String segno, String annotazioni,
String codMdep, String codDtip) throws Exception { String codMdep, String codDtip) throws Exception {
boolean saveGiacenza = false;
DatiFiltroDTO filtroOrdini; DatiFiltroDTO filtroOrdini;
if ("A".equals(gestione)) { if ("A".equals(gestione)) {
segno = "1"; segno = "1";
@@ -1569,29 +1575,28 @@ public class PvmService {
+ " section = 'DOC_INTERNI' and key_section = 'COD_DTIP_'+ case when " + " section = 'DOC_INTERNI' and key_section = 'COD_DTIP_'+ case when "
+ UtilityDB.valueToString(annotazioni) + " = 'TRASFERIMENTO' THEN 'TRASF_L' ELSE " + UtilityDB.valueToString(annotazioni) + " = 'TRASFERIMENTO' THEN 'TRASF_L' ELSE "
+ UtilityDB.valueToString(annotazioni) + " END "; + UtilityDB.valueToString(annotazioni) + " END ";
PreparedStatement info = multiDBTransactionManager.prepareStatement(sql);
ResultSet res = info.executeQuery(); codDtip = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(multiDBTransactionManager.getPrimaryConnection(), sql);
if (res.next()) {
codDtip = res.getString("value"); } else if (!UtilityString.isNullOrEmpty(codDtip) &&
} setupGest.getSetup(multiDBTransactionManager.getPrimaryConnection(), "DATI_AZIENDA", "GIACENZA_DA_INV", "TIPO_DOC_RETT").equalsIgnoreCase(codDtip)){
res.close(); saveGiacenza = true;
info.close();
} }
} }
MtbColt collo = new MtbColt(); MtbColt collo = new MtbColt();
collo.setOperation(OperationType.INSERT); collo.setOperation(OperationType.INSERT);
collo.setGestione(gestione); collo.setGestione(gestione)
collo.setSegno(Integer.parseInt(segno)); .setSegno(Integer.parseInt(segno))
collo.setCodMdep(codMdep); .setCodMdep(codMdep)
collo.setDataCollo(UtilityLocalDate.getNow()); .setDataCollo(UtilityLocalDate.getNow())
collo.setAnnotazioni(annotazioni); .setAnnotazioni(annotazioni)
collo.setCodDtipProvv(codDtip.toUpperCase()); .setCodDtipProvv(codDtip.toUpperCase())
collo.setOraFinePrep(dateCreate); .setOraFinePrep(dateCreate)
collo.setCodAnag(colloDTO.getCodAnag()); .setCodAnag(colloDTO.getCodAnag())
collo.setDataDocProvv(colloDTO.getDataDoc()); .setDataDocProvv(colloDTO.getDataDoc())
collo.setNumDocProvv(colloDTO.getNumDoc()); .setNumDocProvv(colloDTO.getNumDoc())
collo.setCodAnag(colloDTO.getCodAnag()); .setCodAnag(colloDTO.getCodAnag())
collo.setCodVdes(colloDTO.getCodVdes()); .setCodVdes(colloDTO.getCodVdes());
// VERIFICARE SE NEL COLLO CI SONO I DATI DELL'ORDINE // VERIFICARE SE NEL COLLO CI SONO I DATI DELL'ORDINE
Boolean existOrd = false; Boolean existOrd = false;
@@ -1606,15 +1611,15 @@ public class PvmService {
+ UtilityDB.valueToString(gestione) + " and data_ord = " + UtilityDB.valueToString(gestione) + " and data_ord = "
+ UtilityDB.valueDateToString(dataOrd, DATE_FORMAT_YMD) + " and num_ord = " + UtilityDB.valueDateToString(dataOrd, DATE_FORMAT_YMD) + " and num_ord = "
+ numOrd; + numOrd;
PreparedStatement info = multiDBTransactionManager.prepareStatement(query);
ResultSet res = info.executeQuery(); HashMap<String, Object> dati = UtilityDB.executeSimpleQueryOnlyFirstRow(multiDBTransactionManager.getPrimaryConnection(), query);
if (res.next()) {
collo.setCodAnag(res.getString("cod_anag")); if (UtilityHashMap.isPresent(dati)) {
collo.setCodVdes(res.getString("cod_vdes")); collo.setCodAnag(UtilityHashMap.getValueIfExists(dati, "cod_anag"));
collo.setCodVlis(res.getString("listino")); collo.setCodVdes(UtilityHashMap.getValueIfExists(dati, "cod_vdes"));
collo.setCodVlis(UtilityHashMap.getValueIfExists(dati, "listino"));
} }
res.close();
info.close();
collo.setDataOrd(dataOrd); collo.setDataOrd(dataOrd);
collo.setNumOrd(numOrd); collo.setNumOrd(numOrd);
} else { } else {
@@ -1654,24 +1659,14 @@ public class PvmService {
if (UtilityString.isNullOrEmpty(codMart) && !UtilityString.isNullOrEmpty(codBarre)) { if (UtilityString.isNullOrEmpty(codMart) && !UtilityString.isNullOrEmpty(codBarre)) {
String query = "SELECT cod_mart FROM mvw_barcode WHERE REPLICATE('0', 13 - LEN(cod_barre)) + cod_barre = " + UtilityDB.valueToString(codBarre); String query = "SELECT cod_mart FROM mvw_barcode WHERE REPLICATE('0', 13 - LEN(cod_barre)) + cod_barre = " + UtilityDB.valueToString(codBarre);
PreparedStatement info = multiDBTransactionManager.prepareStatement(query); codMart = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(multiDBTransactionManager.getPrimaryConnection(), query);
ResultSet res = info.executeQuery();
if (res.next()) {
codMart = res.getString("cod_mart");
}
res.close();
info.close();
} }
if (!UtilityString.isNullOrEmpty(codMart) && "A".equals(gestione)) { if (!UtilityString.isNullOrEmpty(codMart) && "A".equals(gestione)) {
String query = "SELECT cod_comp FROM mtb_comp WHERE cod_mart = " + UtilityDB.valueToString(codMart); String query = "SELECT cod_comp FROM mtb_comp WHERE cod_mart = " + UtilityDB.valueToString(codMart);
PreparedStatement info = multiDBTransactionManager.prepareStatement(query); codMart = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(multiDBTransactionManager.getPrimaryConnection(), query);
ResultSet res = info.executeQuery();
if (res.next()) {
codMart = res.getString("cod_comp");
}
res.close();
info.close();
} }
BigDecimal qtaCol = artRow.getQta(); BigDecimal qtaCol = artRow.getQta();
@@ -1697,6 +1692,17 @@ public class PvmService {
row.setNumOrd(collo.getNumOrd()); row.setNumOrd(collo.getNumOrd());
row.setRigaOrd(artRow.getRigaOrd()); row.setRigaOrd(artRow.getRigaOrd());
} }
if (saveGiacenza) {
GiacenzaDTO giacenzaPvArticolo = giacenzaPvHandlerService.getGiacenzaPvArticolo(multiDBTransactionManager.getPrimaryDatasource().getDbName(),
multiDBTransactionManager.getPrimaryConnection(),
codMdep, codMart);
if (giacenzaPvArticolo != null){
ObjectMapper objectMapper = new ObjectMapper();
String jsonParm = objectMapper.writeValueAsString(giacenzaPvArticolo);
row.setSystemNote(jsonParm);
}
}
rowList.add(row); rowList.add(row);
} }
collo.setMtbColr(rowList); collo.setMtbColr(rowList);

View File

@@ -0,0 +1,350 @@
package it.integry.ems.retail.service;
import it.integry.ems.retail.dto.GiacenzaDTO;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems_model.service.SetupGest;
import it.integry.ems_model.utility.Query;
import it.integry.ems_model.utility.UtilityDB;
import org.springframework.stereotype.Component;
import org.springframework.web.context.ContextLoader;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
@Component
public class GiacenzaPvHandlerService {
private final HashMap<String, HashMap<String, List<GiacenzaDTO>>> listGiacenzaPv = new HashMap<>();
public void setGiacenzaPv(String profileDb, String codMdep, List<GiacenzaDTO> giacenzaDTOS) {
if ( !listGiacenzaPv.containsKey(profileDb.toUpperCase()) ) {
listGiacenzaPv.put(profileDb.toUpperCase(), new HashMap<>());
}
HashMap<String, List<GiacenzaDTO>> giacenzeMap = listGiacenzaPv.get(profileDb.toUpperCase());
if (!giacenzeMap.containsKey(codMdep.toUpperCase())) {
giacenzeMap.put(codMdep.toUpperCase(), new ArrayList<>());
}
giacenzeMap.put(codMdep.toUpperCase(), giacenzaDTOS);
listGiacenzaPv.put(profileDb.toUpperCase(), giacenzeMap);
}
public GiacenzaDTO getGiacenzaPvArticolo(String dbName, Connection connection, String codMdep, String codMart) throws Exception {
HashMap<String, HashMap<String, List<GiacenzaDTO>>> inputMap = listGiacenzaPv;
List<GiacenzaDTO> giacenzaPv = getGiacenzaPvDBName(inputMap, dbName).get(codMdep);
if (giacenzaPv == null) {
GiacenzaService giacenzaService = new GiacenzaService();
giacenzaPv = retrieveGiacenza(dbName, connection, codMdep);
setGiacenzaPv(dbName, codMdep, giacenzaPv);
}
if (giacenzaPv != null)
return giacenzaPv.stream()
.filter(x-> x.getCodMart().equalsIgnoreCase(codMart))
.findFirst()
.orElse(null);
return null;
}
public List<GiacenzaDTO> retrieveGiacenza(String dbName, Connection connection, String codMdep) throws Exception {
String sql = Query.format(
"SELECT cod_mdep FROM stb_gest_setup_depo WHERE gest_name = %s AND section = %s AND key_section = %S AND value = %S",
"DATI_AZIENDA", "GIACENZA_DA_INV", "REPLACE_DEPO", codMdep);
String codMdepNew = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(connection, sql);
String whereCond = UtilityDB.valueToString(codMdep);
if (codMdepNew != null) {
whereCond += ", " + UtilityDB.valueToString(codMdepNew);
}
sql = "WITH art AS (SELECT mtb_aart.cod_mart AS cod_mart,\n" +
" IIF(mtb_aart.articolo_composto = 'S'\n" +
" AND mtb_comp.cod_comp IS NOT NULL, mtb_comp.cod_comp, mtb_aart.cod_mart) AS cod_mart_mov,\n" +
" ISNULL(mtb_comp.qta_std, 1) AS qta_std\n" +
" FROM mtb_aart\n" +
" LEFT OUTER JOIN mtb_comp\n" +
" ON mtb_aart.cod_mart = mtb_comp.cod_mart\n" +
" AND mtb_aart.articolo_composto = 'S'),\n" +
" movimenti AS (SELECT mtb_movi.cod_mart,\n" +
" mtb_movi.data_reg,\n" +
" mtb_movi.qta_car AS qta_car,\n" +
" mtb_movi.qta_scar AS qta_scar,\n" +
" dtb_doct.data_ins,\n" +
" 'D' AS tipo_car\n" +
" FROM mtb_movi\n" +
" INNER JOIN dtb_doct\n" +
" ON dtb_doct.cod_anag = mtb_movi.cod_anag\n" +
" AND dtb_doct.cod_dtip = mtb_movi.cod_dtip\n" +
" AND dtb_doct.data_doc = mtb_movi.data_doc\n" +
" AND dtb_doct.ser_doc = mtb_movi.ser_doc\n" +
" AND dtb_doct.num_doc = mtb_movi.num_doc\n" +
" WHERE mtb_movi.cod_mdep IN (" + whereCond + ") and dtb_doct.data_ins >= dateadd(day, - 7, cast(getdate() AS DATE))\n" +
" UNION ALL\n" +
" SELECT wdtb_docr.cod_mart,\n" +
" wdtb_doct.data_reg,\n" +
" wdtb_docr.qta_doc * wdtb_docr.rap_conv,\n" +
" 0,\n" +
" wdtb_doct.data_mod,\n" +
" 'W' AS tipo_car\n" +
" FROM wdtb_doct\n" +
" INNER JOIN wdtb_docr\n" +
" ON wdtb_doct.cod_anag = wdtb_docr.cod_anag\n" +
" AND wdtb_doct.cod_dtip = wdtb_docr.cod_dtip\n" +
" AND wdtb_doct.data_doc = wdtb_docr.data_doc\n" +
" AND wdtb_doct.ser_doc = wdtb_docr.ser_doc\n" +
" AND wdtb_doct.num_doc = wdtb_docr.num_doc\n" +
" WHERE wdtb_doct.flag_elaborato = 'N'\n" +
" AND wdtb_doct.cod_mdep IN (" + whereCond + ") and wdtb_doct.data_ins >= dateadd(day, - 7, cast(getdate() AS DATE))\n" +
" UNION ALL\n" +
" SELECT ntb_docr.cod_mart,\n" +
" ntb_doct.date_only_doc AS data_reg,\n" +
" 0,\n" +
" ntb_docr.qta_doc * ntb_docr.qta_cnf,\n" +
" ntb_doct.data_import,\n" +
" NULL AS tipo_car\n" +
" FROM ntb_doct\n" +
" INNER JOIN ntb_docr\n" +
" ON ntb_doct.cod_mdep = ntb_docr.cod_mdep\n" +
" AND ntb_doct.cod_cassa = ntb_docr.cod_cassa\n" +
" AND ntb_doct.data_doc = ntb_docr.data_doc\n" +
" LEFT OUTER JOIN dtb_tipi\n" +
" ON ntb_doct.cod_dtip_val = dtb_tipi.cod_dtip\n" +
" WHERE ntb_doct.cod_mdep IN (" + whereCond + ") and ntb_doct.data_import >= dateadd(day, - 7, cast(getdate() AS DATE))\n" +
" AND ntb_doct.causale = 'V'\n" +
" AND (\n" +
" ntb_doct.data_doc_val IS NULL\n" +
" OR dtb_tipi.segno_qta_scar = 0\n" +
" )\n" +
" AND NOT EXISTS (SELECT *\n" +
" FROM dtb_doct\n" +
" INNER JOIN mtb_depo ON dtb_doct.cod_mdep = mtb_depo.cod_mdep AND\n" +
" dtb_doct.cod_dtip = mtb_depo.cod_dtip\n" +
" WHERE date_only_doc = dtb_doct.data_doc\n" +
" AND ntb_doct.cod_mdep = dtb_doct.cod_mdep)),\n" +
" inventario_provvisorio AS (SELECT art.cod_mart_mov AS cod_mart,\n" +
" SUM(qta_col * art.qta_std) AS qta_col,\n" +
" data_ins,\n" +
" MAX(data_ins) OVER ( PARTITION BY art.cod_mart_mov) AS max_data_ins\n" +
" FROM mtb_colt\n" +
" INNER JOIN mtb_colr\n" +
" ON mtb_colt.gestione = mtb_colr.gestione\n" +
" AND mtb_colt.data_collo = mtb_colr.data_collo\n" +
" AND mtb_colt.ser_collo = mtb_colr.ser_collo\n" +
" AND mtb_colt.num_collo = mtb_colr.num_collo\n" +
" INNER JOIN (SELECT mtb_aart.cod_mart AS cod_mart,\n" +
" IIF(mtb_aart.articolo_composto = 'S'\n" +
" AND mtb_comp.cod_comp IS NOT NULL,\n" +
" mtb_comp.cod_comp, mtb_aart.cod_mart) AS cod_mart_mov,\n" +
" ISNULL(mtb_comp.qta_std, 1) AS qta_std\n" +
" FROM mtb_aart\n" +
" LEFT OUTER JOIN mtb_comp\n" +
" ON mtb_aart.cod_mart = mtb_comp.cod_mart) art\n" +
" ON mtb_colr.cod_mart = art.cod_mart\n" +
" WHERE mtb_colt.cod_dtip_provv = 'RGIAC'\n" +
" AND mtb_colt.data_distribuzione IS NULL\n" +
" AND mtb_colt.cod_mdep IN (" + whereCond + ")\n" +
" GROUP BY art.cod_mart_mov, mtb_colt.data_collo, data_ins),\n" +
" selezione_giacenza AS (SELECT ISNULL(ip.cod_mart, gp.cod_mart) AS cod_mart,\n" +
" ISNULL(ip.qta_col, gp.qta_car) AS qta_car,\n" +
" ISNULL(IIF(gp.data_ins < ip.data_ins, 0, gp.qta_scar), 0) AS qta_scar,\n" +
" ISNULL(ip.data_ins, gp.data_ins) AS data_ins,\n" +
" ISNULL(ip.data_ins, gp.data_reg) AS data_reg,\n" +
" IIF(ip.data_ins IS NULL, 0, 1) AS is_invent,\n" +
" ip.data_ins AS last_rgiac\n" +
" FROM carelli_giacenza_prog gp\n" +
" LEFT JOIN inventario_provvisorio ip\n" +
" ON ip.cod_mart = gp.cod_mart\n" +
" AND max_data_ins = ip.data_ins\n" +
" AND (gp.data_ins < ip.data_ins)\n" +
" WHERE gp.cod_mdep IN (" + whereCond + ")),\n" +
" mov AS (SELECT art.cod_mart_mov AS cod_mart,\n" +
" SUM(movimenti.qta_car * qta_std) + ISNULL(giac.qta_car, 0) AS qta_car,\n" +
" SUM(movimenti.qta_scar * qta_std) + ISNULL(giac.qta_scar, 0) AS qta_scar,\n" +
" GETDATE() AS data_ins\n" +
"\n" +
" FROM movimenti\n" +
" INNER JOIN art ON movimenti.cod_mart = art.cod_mart\n" +
" LEFT OUTER JOIN selezione_giacenza giac ON giac.cod_mart = art.cod_mart_mov\n" +
" WHERE (\n" +
" (movimenti.data_reg >= CAST(ISNULL(giac.data_reg, GETDATE()) AS DATE) AND\n" +
" (giac.data_ins IS NULL OR (movimenti.data_ins >= giac.data_ins))) OR\n" +
" (\n" +
" (movimenti.tipo_car = 'W') AND (\n" +
" (giac.data_ins IS NULL OR (movimenti.data_ins >= giac.data_ins)) OR\n" +
" (is_invent = 1 AND (movimenti.data_ins >= last_rgiac)) OR\n" +
" (is_invent = 0 AND movimenti.data_ins >= ISNULL(giac.data_reg, CAST(GETDATE() AS DATE)))\n" +
" )\n" +
" )\n" +
" )\n" +
"\n" +
" GROUP BY art.cod_mart_mov, giac.qta_car, giac.qta_scar),\n" +
" inv AS (SELECT ISNULL(r.cod_mart, k.cod_mart) AS cod_mart,\n" +
" ISNULL(r.qta_car, ISNULL(k.qta_car, 0)) - ISNULL(r.qta_scar, ISNULL(k.qta_scar, 0)) AS qta_inv,\n" +
" ISNULL(k.data_ins, CAST(GETDATE() AS DATE)) AS data_inventario\n" +
" FROM mov r\n" +
" FULL OUTER JOIN selezione_giacenza k\n" +
" ON k.cod_mart = r.cod_mart),\n" +
" final AS (SELECT cod_mart, qta_inv, data_inventario\n" +
" FROM inv\n" +
" UNION\n" +
" SELECT mtb_comp.cod_mart,\n" +
" ROUND(SUM(ISNULL(qta_inv, 0)) / SUM(qta_std), 2),\n" +
" MAX(data_inventario)\n" +
" FROM mtb_aart\n" +
" INNER JOIN mtb_comp ON mtb_aart.cod_mart = mtb_comp.cod_mart\n" +
" LEFT OUTER JOIN inv ON mtb_comp.cod_comp = inv.cod_mart\n" +
" WHERE mtb_aart.articolo_composto = 'S'\n" +
" AND mtb_aart.flag_stato = 'A'\n" +
" GROUP BY mtb_comp.cod_mart)\n" +
"SELECT final.cod_mart,\n" +
" descrizione,\n" +
" qta_inv,\n" +
" data_inventario,\n" +
" " + UtilityDB.valueToString(codMdep) + " AS cod_mdep\n" +
"FROM final\n" +
" INNER JOIN mtb_aart ON final.cod_mart = mtb_aart.cod_mart";
List<GiacenzaDTO> listGiacenza = UtilityDB.executeSimpleQueryDTO(connection, sql, GiacenzaDTO.class);
String listiniAcquisto = new SetupGest().getSetup(connection,"DATI_AZIENDA", "GIACENZA_DA_INV", "LISTINI_ACQUISTO");
List<String> listini = Arrays.asList(listiniAcquisto.split("\\|"));
sql = "WITH incoming_stock_documenti AS (\n" +
"/*\n" +
"Estrazione dei documenti (bolle web) di merce consegnata\n" +
"*/\n" +
"\n" +
" SELECT wdtb_doct.cod_mdep,\n" +
" wdtb_docr.cod_mart,\n" +
" wdtb_docr.data_ord,\n" +
" wdtb_docr.num_ord,\n" +
" riga_ord,\n" +
" wdtb_doct.cod_anag,\n" +
" wdtb_docr.qta_doc * wdtb_docr.rap_conv AS qta_doc,\n" +
" wdtb_doct.flag_elaborato\n" +
" FROM wdtb_doct\n" +
" INNER JOIN wdtb_docr\n" +
" ON wdtb_doct.cod_anag = wdtb_docr.cod_anag AND wdtb_doct.cod_dtip = wdtb_docr.cod_dtip AND\n" +
" wdtb_doct.data_doc = wdtb_docr.data_doc AND wdtb_doct.ser_doc = wdtb_docr.ser_doc AND\n" +
" wdtb_doct.num_doc = wdtb_docr.num_doc\n" +
" WHERE wdtb_doct.data_ins >= dateadd(DAY, - 21, CAST(getdate() AS DATE))\n" +
" AND wdtb_doct.cod_mdep = " + UtilityDB.valueToString(codMdep) + ")\n" +
" , incoming_stock_ordini AS (\n" +
"/*\n" +
"Estrazione degli ordini d'acquisto in consegna\n" +
"*/\n" +
" SELECT r.cod_mdep,\n" +
" r.cod_mart,\n" +
" CASE\n" +
" WHEN r.data_cons = r.data_ord\n" +
" THEN CAST(getdate() AS DATE)\n" +
" ELSE r.data_cons\n" +
" END AS data_cons,\n" +
" r.qta_ord,\n" +
" r.data_ord,\n" +
" r.riga_ord,\n" +
" r.num_ord,\n" +
" cod_anag\n" +
" FROM dtb_ordt t\n" +
" INNER JOIN dtb_ordr r\n" +
" ON t.gestione = r.gestione\n" +
" AND t.data_ord = r.data_ord\n" +
" AND t.num_ord = r.num_ord\n" +
" WHERE\n" +
" -- ordini acquisto\n" +
" t.gestione = 'A'\n" +
" -- ordini non annullati\n" +
" AND t.flag_annulla = 'N'\n" +
" -- ordii non sospesi\n" +
" AND t.flag_sospeso = 'N'\n" +
" AND (\n" +
" -- ordini futuri\n" +
" (r.data_cons >= CAST(getdate() AS DATE))\n" +
" OR\n" +
" -- ordini fuori piano logistico (r.data_cons = r.data_ord), inevasi e fatti negli ultimi 3 giorni\n" +
" (\n" +
" r.data_cons = r.data_ord\n" +
" AND flag_evaso = 'I'\n" +
" AND r.data_ord >= dateadd(DAY, - 3, CAST(getdate() AS DATE))\n" +
" )\n" +
" )\n" +
" -- prendiamo i soli ordini del SECCO, sarà da modificare quando inizieranno ad ordinare anche altri (es. APULD)\n" +
" AND t.listino IN (" + UtilityDB.listValueToString(listini) + ")\n" +
" -- ordine non ancora evaso\n" +
" AND flag_evaso <> 'E'\n" +
" -- filtro solamente un Pdv\n" +
" AND r.cod_mdep = " + UtilityDB.valueToString(codMdep) + ")\n" +
" , incoming_stock_doc_consegnati AS (\n" +
"/*\n" +
"Estrazione dei documenti consegnati\n" +
"*/\n" +
" SELECT DISTINCT wdtb_docr.num_ord, wdtb_docr.data_ord, wdtb_doct.cod_anag\n" +
" FROM wdtb_doct\n" +
" INNER JOIN wdtb_docr\n" +
" ON wdtb_doct.cod_anag = wdtb_docr.cod_anag AND wdtb_doct.cod_dtip = wdtb_docr.cod_dtip AND\n" +
" wdtb_doct.data_doc = wdtb_docr.data_doc AND wdtb_doct.ser_doc = wdtb_docr.ser_doc AND\n" +
" wdtb_doct.num_doc = wdtb_docr.num_doc\n" +
" WHERE wdtb_doct.data_ins >= dateadd(DAY, - 7, CAST(getdate() AS DATE))\n" +
" AND wdtb_doct.flag_elaborato = 'N')\n" +
"\n" +
"-- Step 4) Unione delle estrazioni precedenti [MySQL]\n" +
"\n" +
"SELECT ISNULL(d.cod_mdep, o.cod_mdep) AS store_code,\n" +
" ISNULL(d.cod_mart, o.cod_mart) AS art_code,\n" +
" data_cons,\n" +
" SUM(ISNULL(qta_doc, qta_ord)) AS incoming_stock\n" +
"FROM incoming_stock_ordini o\n" +
" FULL OUTER JOIN incoming_stock_documenti d\n" +
" ON o.cod_mdep = d.cod_mdep AND o.cod_mart = d.cod_mart AND o.data_ord = d.data_ord AND\n" +
" o.num_ord = d.num_ord AND o.cod_anag = d.cod_anag AND o.riga_ord = d.riga_ord\n" +
" LEFT JOIN incoming_stock_doc_consegnati k\n" +
" ON o.num_ord = k.num_ord AND o.cod_anag = k.cod_anag AND o.data_ord = k.data_ord\n" +
"WHERE (flag_elaborato = 'I' OR flag_elaborato IS NULL)\n" +
" AND ((d.cod_mart IS NOT NULL) OR (d.cod_mart IS NULL AND k.num_ord IS NULL))\n" +
"GROUP BY ISNULL(d.cod_mdep, o.cod_mdep), ISNULL(d.cod_mart, o.cod_mart), data_cons, k.num_ord\n";
List<HashMap<String, Object>> merceInArrivo = UtilityDB.executeSimpleQuery(connection, sql);
if (listGiacenza != null) {
merceInArrivo
.forEach(merce -> {
String storeCode = (String) merce.get("store_code");
String artCode = (String) merce.get("art_code");
BigDecimal incomingStock = (BigDecimal) merce.get("incoming_stock");
listGiacenza.stream()
.filter(x -> x.getCodMart().equals(artCode) && x.getCodMdep().equals(storeCode))
.findFirst()
.ifPresent(x -> {
x.setIncomingStock(incomingStock);
});
});
}
if ( listGiacenza != null && listGiacenza.size() > 0 ){
setGiacenzaPv(dbName,
codMdep,
listGiacenza);
}
return listGiacenza;
}
private HashMap<String, List<GiacenzaDTO>> getGiacenzaPvDBName(HashMap<String, HashMap<String, List<GiacenzaDTO>>> inputData, String profileDb) {
if (!inputData.containsKey(profileDb))
inputData.put(profileDb, new HashMap<>());
return inputData.get(profileDb);
}
}

View File

@@ -4,9 +4,11 @@ import com.annimon.stream.Stream;
import it.integry.ems.exception.PrimaryDatabaseNotPresentException; import it.integry.ems.exception.PrimaryDatabaseNotPresentException;
import it.integry.ems.expansion.RunnableThrowable; import it.integry.ems.expansion.RunnableThrowable;
import it.integry.ems.javabeans.RequestDataDTO; import it.integry.ems.javabeans.RequestDataDTO;
import it.integry.ems.production.service.MrpSetupHandlerService;
import it.integry.ems.retail.dto.GiacenzaDTO; import it.integry.ems.retail.dto.GiacenzaDTO;
import it.integry.ems.retail.pvmRetail.service.PvmService; import it.integry.ems.retail.pvmRetail.service.PvmService;
import it.integry.ems.service.EntityProcessor; import it.integry.ems.service.EntityProcessor;
import it.integry.ems.sync.MultiDBTransaction.Connection;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.utility.UtilityEntity; import it.integry.ems.utility.UtilityEntity;
import it.integry.ems_model.base.EntityBase; import it.integry.ems_model.base.EntityBase;
@@ -40,6 +42,8 @@ public class GiacenzaService {
PvmService pvmService; PvmService pvmService;
@Autowired @Autowired
EntityProcessor entityProcessor; EntityProcessor entityProcessor;
@Autowired
private GiacenzaPvHandlerService giacenzaPvHandlerService;
private final Logger logger = LogManager.getLogger(); private final Logger logger = LogManager.getLogger();
@@ -508,284 +512,6 @@ public class GiacenzaService {
} }
public List<GiacenzaDTO> retrieveGiacenza(String codMdep) throws Exception { public List<GiacenzaDTO> retrieveGiacenza(String codMdep) throws Exception {
return giacenzaPvHandlerService.retrieveGiacenza(multiDBTransactionManager.getPrimaryDatasource().getDbName(), multiDBTransactionManager.getPrimaryConnection(), codMdep);
String sql = Query.format(
"SELECT cod_mdep FROM stb_gest_setup_depo WHERE gest_name = %s AND section = %s AND key_section = %S AND value = %S",
"DATI_AZIENDA", "GIACENZA_DA_INV", "REPLACE_DEPO", codMdep);
String codMdepNew = UtilityDB.executeSimpleQueryOnlyFirstRowFirstColumn(multiDBTransactionManager.getPrimaryConnection(), sql);
String whereCond = UtilityDB.valueToString(codMdep);
if (codMdepNew != null) {
whereCond += ", " + UtilityDB.valueToString(codMdepNew);
}
sql = "WITH art AS (SELECT mtb_aart.cod_mart AS cod_mart,\n" +
" IIF(mtb_aart.articolo_composto = 'S'\n" +
" AND mtb_comp.cod_comp IS NOT NULL, mtb_comp.cod_comp, mtb_aart.cod_mart) AS cod_mart_mov,\n" +
" ISNULL(mtb_comp.qta_std, 1) AS qta_std\n" +
" FROM mtb_aart\n" +
" LEFT OUTER JOIN mtb_comp\n" +
" ON mtb_aart.cod_mart = mtb_comp.cod_mart\n" +
" AND mtb_aart.articolo_composto = 'S'),\n" +
" movimenti AS (SELECT mtb_movi.cod_mart,\n" +
" mtb_movi.data_reg,\n" +
" mtb_movi.qta_car AS qta_car,\n" +
" mtb_movi.qta_scar AS qta_scar,\n" +
" dtb_doct.data_ins,\n" +
" 'D' AS tipo_car\n" +
" FROM mtb_movi\n" +
" INNER JOIN dtb_doct\n" +
" ON dtb_doct.cod_anag = mtb_movi.cod_anag\n" +
" AND dtb_doct.cod_dtip = mtb_movi.cod_dtip\n" +
" AND dtb_doct.data_doc = mtb_movi.data_doc\n" +
" AND dtb_doct.ser_doc = mtb_movi.ser_doc\n" +
" AND dtb_doct.num_doc = mtb_movi.num_doc\n" +
" WHERE mtb_movi.cod_mdep IN (" + whereCond + ") and dtb_doct.data_ins >= dateadd(day, - 7, cast(getdate() AS DATE))\n" +
" UNION ALL\n" +
" SELECT wdtb_docr.cod_mart,\n" +
" wdtb_doct.data_reg,\n" +
" wdtb_docr.qta_doc * wdtb_docr.rap_conv,\n" +
" 0,\n" +
" wdtb_doct.data_mod,\n" +
" 'W' AS tipo_car\n" +
" FROM wdtb_doct\n" +
" INNER JOIN wdtb_docr\n" +
" ON wdtb_doct.cod_anag = wdtb_docr.cod_anag\n" +
" AND wdtb_doct.cod_dtip = wdtb_docr.cod_dtip\n" +
" AND wdtb_doct.data_doc = wdtb_docr.data_doc\n" +
" AND wdtb_doct.ser_doc = wdtb_docr.ser_doc\n" +
" AND wdtb_doct.num_doc = wdtb_docr.num_doc\n" +
" WHERE wdtb_doct.flag_elaborato = 'N'\n" +
" AND wdtb_doct.cod_mdep IN (" + whereCond + ") and wdtb_doct.data_ins >= dateadd(day, - 7, cast(getdate() AS DATE))\n" +
" UNION ALL\n" +
" SELECT ntb_docr.cod_mart,\n" +
" ntb_doct.date_only_doc AS data_reg,\n" +
" 0,\n" +
" ntb_docr.qta_doc * ntb_docr.qta_cnf,\n" +
" ntb_doct.data_import,\n" +
" NULL AS tipo_car\n" +
" FROM ntb_doct\n" +
" INNER JOIN ntb_docr\n" +
" ON ntb_doct.cod_mdep = ntb_docr.cod_mdep\n" +
" AND ntb_doct.cod_cassa = ntb_docr.cod_cassa\n" +
" AND ntb_doct.data_doc = ntb_docr.data_doc\n" +
" LEFT OUTER JOIN dtb_tipi\n" +
" ON ntb_doct.cod_dtip_val = dtb_tipi.cod_dtip\n" +
" WHERE ntb_doct.cod_mdep IN (" + whereCond + ") and ntb_doct.data_import >= dateadd(day, - 7, cast(getdate() AS DATE))\n" +
" AND ntb_doct.causale = 'V'\n" +
" AND (\n" +
" ntb_doct.data_doc_val IS NULL\n" +
" OR dtb_tipi.segno_qta_scar = 0\n" +
" )\n" +
" AND NOT EXISTS (SELECT *\n" +
" FROM dtb_doct\n" +
" INNER JOIN mtb_depo ON dtb_doct.cod_mdep = mtb_depo.cod_mdep AND\n" +
" dtb_doct.cod_dtip = mtb_depo.cod_dtip\n" +
" WHERE date_only_doc = dtb_doct.data_doc\n" +
" AND ntb_doct.cod_mdep = dtb_doct.cod_mdep)),\n" +
" inventario_provvisorio AS (SELECT art.cod_mart_mov AS cod_mart,\n" +
" SUM(qta_col * art.qta_std) AS qta_col,\n" +
" data_ins,\n" +
" MAX(data_ins) OVER ( PARTITION BY art.cod_mart_mov) AS max_data_ins\n" +
" FROM mtb_colt\n" +
" INNER JOIN mtb_colr\n" +
" ON mtb_colt.gestione = mtb_colr.gestione\n" +
" AND mtb_colt.data_collo = mtb_colr.data_collo\n" +
" AND mtb_colt.ser_collo = mtb_colr.ser_collo\n" +
" AND mtb_colt.num_collo = mtb_colr.num_collo\n" +
" INNER JOIN (SELECT mtb_aart.cod_mart AS cod_mart,\n" +
" IIF(mtb_aart.articolo_composto = 'S'\n" +
" AND mtb_comp.cod_comp IS NOT NULL,\n" +
" mtb_comp.cod_comp, mtb_aart.cod_mart) AS cod_mart_mov,\n" +
" ISNULL(mtb_comp.qta_std, 1) AS qta_std\n" +
" FROM mtb_aart\n" +
" LEFT OUTER JOIN mtb_comp\n" +
" ON mtb_aart.cod_mart = mtb_comp.cod_mart) art\n" +
" ON mtb_colr.cod_mart = art.cod_mart\n" +
" WHERE mtb_colt.cod_dtip_provv = 'RGIAC'\n" +
" AND mtb_colt.data_distribuzione IS NULL\n" +
" AND mtb_colt.cod_mdep IN (" + whereCond + ")\n" +
" GROUP BY art.cod_mart_mov, mtb_colt.data_collo, data_ins),\n" +
" selezione_giacenza AS (SELECT ISNULL(ip.cod_mart, gp.cod_mart) AS cod_mart,\n" +
" ISNULL(ip.qta_col, gp.qta_car) AS qta_car,\n" +
" ISNULL(IIF(gp.data_ins < ip.data_ins, 0, gp.qta_scar), 0) AS qta_scar,\n" +
" ISNULL(ip.data_ins, gp.data_ins) AS data_ins,\n" +
" ISNULL(ip.data_ins, gp.data_reg) AS data_reg,\n" +
" IIF(ip.data_ins IS NULL, 0, 1) AS is_invent,\n" +
" ip.data_ins AS last_rgiac\n" +
" FROM carelli_giacenza_prog gp\n" +
" LEFT JOIN inventario_provvisorio ip\n" +
" ON ip.cod_mart = gp.cod_mart\n" +
" AND max_data_ins = ip.data_ins\n" +
" AND (gp.data_ins < ip.data_ins)\n" +
" WHERE gp.cod_mdep IN (" + whereCond + ")),\n" +
" mov AS (SELECT art.cod_mart_mov AS cod_mart,\n" +
" SUM(movimenti.qta_car * qta_std) + ISNULL(giac.qta_car, 0) AS qta_car,\n" +
" SUM(movimenti.qta_scar * qta_std) + ISNULL(giac.qta_scar, 0) AS qta_scar,\n" +
" GETDATE() AS data_ins\n" +
"\n" +
" FROM movimenti\n" +
" INNER JOIN art ON movimenti.cod_mart = art.cod_mart\n" +
" LEFT OUTER JOIN selezione_giacenza giac ON giac.cod_mart = art.cod_mart_mov\n" +
" WHERE (\n" +
" (movimenti.data_reg >= CAST(ISNULL(giac.data_reg, GETDATE()) AS DATE) AND\n" +
" (giac.data_ins IS NULL OR (movimenti.data_ins >= giac.data_ins))) OR\n" +
" (\n" +
" (movimenti.tipo_car = 'W') AND (\n" +
" (giac.data_ins IS NULL OR (movimenti.data_ins >= giac.data_ins)) OR\n" +
" (is_invent = 1 AND (movimenti.data_ins >= last_rgiac)) OR\n" +
" (is_invent = 0 AND movimenti.data_ins >= ISNULL(giac.data_reg, CAST(GETDATE() AS DATE)))\n" +
" )\n" +
" )\n" +
" )\n" +
"\n" +
" GROUP BY art.cod_mart_mov, giac.qta_car, giac.qta_scar),\n" +
" inv AS (SELECT ISNULL(r.cod_mart, k.cod_mart) AS cod_mart,\n" +
" ISNULL(r.qta_car, ISNULL(k.qta_car, 0)) - ISNULL(r.qta_scar, ISNULL(k.qta_scar, 0)) AS qta_inv,\n" +
" ISNULL(k.data_ins, CAST(GETDATE() AS DATE)) AS data_inventario\n" +
" FROM mov r\n" +
" FULL OUTER JOIN selezione_giacenza k\n" +
" ON k.cod_mart = r.cod_mart),\n" +
" final AS (SELECT cod_mart, qta_inv, data_inventario\n" +
" FROM inv\n" +
" UNION\n" +
" SELECT mtb_comp.cod_mart,\n" +
" ROUND(SUM(ISNULL(qta_inv, 0)) / SUM(qta_std), 2),\n" +
" MAX(data_inventario)\n" +
" FROM mtb_aart\n" +
" INNER JOIN mtb_comp ON mtb_aart.cod_mart = mtb_comp.cod_mart\n" +
" LEFT OUTER JOIN inv ON mtb_comp.cod_comp = inv.cod_mart\n" +
" WHERE mtb_aart.articolo_composto = 'S'\n" +
" AND mtb_aart.flag_stato = 'A'\n" +
" GROUP BY mtb_comp.cod_mart)\n" +
"SELECT final.cod_mart,\n" +
" descrizione,\n" +
" qta_inv,\n" +
" data_inventario,\n" +
" " + UtilityDB.valueToString(codMdep) + " AS cod_mdep\n" +
"FROM final\n" +
" INNER JOIN mtb_aart ON final.cod_mart = mtb_aart.cod_mart";
List<GiacenzaDTO> listGiacenza = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sql, GiacenzaDTO.class);
String listiniAcquisto = setupGest.getSetup("DATI_AZIENDA", "GIACENZA_DA_INV", "LISTINI_ACQUISTO");
List<String> listini = Arrays.asList(listiniAcquisto.split("\\|"));
sql = "WITH incoming_stock_documenti AS (\n" +
"/*\n" +
"Estrazione dei documenti (bolle web) di merce consegnata\n" +
"*/\n" +
"\n" +
" SELECT wdtb_doct.cod_mdep,\n" +
" wdtb_docr.cod_mart,\n" +
" wdtb_docr.data_ord,\n" +
" wdtb_docr.num_ord,\n" +
" riga_ord,\n" +
" wdtb_doct.cod_anag,\n" +
" wdtb_docr.qta_doc * wdtb_docr.rap_conv AS qta_doc,\n" +
" wdtb_doct.flag_elaborato\n" +
" FROM wdtb_doct\n" +
" INNER JOIN wdtb_docr\n" +
" ON wdtb_doct.cod_anag = wdtb_docr.cod_anag AND wdtb_doct.cod_dtip = wdtb_docr.cod_dtip AND\n" +
" wdtb_doct.data_doc = wdtb_docr.data_doc AND wdtb_doct.ser_doc = wdtb_docr.ser_doc AND\n" +
" wdtb_doct.num_doc = wdtb_docr.num_doc\n" +
" WHERE wdtb_doct.data_ins >= dateadd(DAY, - 21, CAST(getdate() AS DATE))\n" +
" AND wdtb_doct.cod_mdep = " + UtilityDB.valueToString(codMdep) + ")\n" +
" , incoming_stock_ordini AS (\n" +
"/*\n" +
"Estrazione degli ordini d'acquisto in consegna\n" +
"*/\n" +
" SELECT r.cod_mdep,\n" +
" r.cod_mart,\n" +
" CASE\n" +
" WHEN r.data_cons = r.data_ord\n" +
" THEN CAST(getdate() AS DATE)\n" +
" ELSE r.data_cons\n" +
" END AS data_cons,\n" +
" r.qta_ord,\n" +
" r.data_ord,\n" +
" r.riga_ord,\n" +
" r.num_ord,\n" +
" cod_anag\n" +
" FROM dtb_ordt t\n" +
" INNER JOIN dtb_ordr r\n" +
" ON t.gestione = r.gestione\n" +
" AND t.data_ord = r.data_ord\n" +
" AND t.num_ord = r.num_ord\n" +
" WHERE\n" +
" -- ordini acquisto\n" +
" t.gestione = 'A'\n" +
" -- ordini non annullati\n" +
" AND t.flag_annulla = 'N'\n" +
" -- ordii non sospesi\n" +
" AND t.flag_sospeso = 'N'\n" +
" AND (\n" +
" -- ordini futuri\n" +
" (r.data_cons >= CAST(getdate() AS DATE))\n" +
" OR\n" +
" -- ordini fuori piano logistico (r.data_cons = r.data_ord), inevasi e fatti negli ultimi 3 giorni\n" +
" (\n" +
" r.data_cons = r.data_ord\n" +
" AND flag_evaso = 'I'\n" +
" AND r.data_ord >= dateadd(DAY, - 3, CAST(getdate() AS DATE))\n" +
" )\n" +
" )\n" +
" -- prendiamo i soli ordini del SECCO, sarà da modificare quando inizieranno ad ordinare anche altri (es. APULD)\n" +
" AND t.listino IN (" + UtilityDB.listValueToString(listini) + ")\n" +
" -- ordine non ancora evaso\n" +
" AND flag_evaso <> 'E'\n" +
" -- filtro solamente un Pdv\n" +
" AND r.cod_mdep = " + UtilityDB.valueToString(codMdep) + ")\n" +
" , incoming_stock_doc_consegnati AS (\n" +
"/*\n" +
"Estrazione dei documenti consegnati\n" +
"*/\n" +
" SELECT DISTINCT wdtb_docr.num_ord, wdtb_docr.data_ord, wdtb_doct.cod_anag\n" +
" FROM wdtb_doct\n" +
" INNER JOIN wdtb_docr\n" +
" ON wdtb_doct.cod_anag = wdtb_docr.cod_anag AND wdtb_doct.cod_dtip = wdtb_docr.cod_dtip AND\n" +
" wdtb_doct.data_doc = wdtb_docr.data_doc AND wdtb_doct.ser_doc = wdtb_docr.ser_doc AND\n" +
" wdtb_doct.num_doc = wdtb_docr.num_doc\n" +
" WHERE wdtb_doct.data_ins >= dateadd(DAY, - 7, CAST(getdate() AS DATE))\n" +
" AND wdtb_doct.flag_elaborato = 'N')\n" +
"\n" +
"-- Step 4) Unione delle estrazioni precedenti [MySQL]\n" +
"\n" +
"SELECT ISNULL(d.cod_mdep, o.cod_mdep) AS store_code,\n" +
" ISNULL(d.cod_mart, o.cod_mart) AS art_code,\n" +
" data_cons,\n" +
" SUM(ISNULL(qta_doc, qta_ord)) AS incoming_stock\n" +
"FROM incoming_stock_ordini o\n" +
" FULL OUTER JOIN incoming_stock_documenti d\n" +
" ON o.cod_mdep = d.cod_mdep AND o.cod_mart = d.cod_mart AND o.data_ord = d.data_ord AND\n" +
" o.num_ord = d.num_ord AND o.cod_anag = d.cod_anag AND o.riga_ord = d.riga_ord\n" +
" LEFT JOIN incoming_stock_doc_consegnati k\n" +
" ON o.num_ord = k.num_ord AND o.cod_anag = k.cod_anag AND o.data_ord = k.data_ord\n" +
"WHERE (flag_elaborato = 'I' OR flag_elaborato IS NULL)\n" +
" AND ((d.cod_mart IS NOT NULL) OR (d.cod_mart IS NULL AND k.num_ord IS NULL))\n" +
"GROUP BY ISNULL(d.cod_mdep, o.cod_mdep), ISNULL(d.cod_mart, o.cod_mart), data_cons, k.num_ord\n";
List<HashMap<String, Object>> merceInArrivo = UtilityDB.executeSimpleQuery(multiDBTransactionManager.getPrimaryConnection(), sql);
if (listGiacenza != null) {
merceInArrivo
.forEach(merce -> {
String storeCode = (String) merce.get("store_code");
String artCode = (String) merce.get("art_code");
BigDecimal incomingStock = (BigDecimal) merce.get("incoming_stock");
listGiacenza.stream()
.filter(x -> x.getCodMart().equals(artCode) && x.getCodMdep().equals(storeCode))
.findFirst()
.ifPresent(x -> {
x.setIncomingStock(incomingStock);
});
});
return listGiacenza;
}
return null;
} }
} }

View File

@@ -101,7 +101,7 @@ public class ListiniAcquistoHandlerService {
" descrizione,\n" + " descrizione,\n" +
" cod_mart,\n" + " cod_mart,\n" +
" cod_art_for,\n" + " cod_art_for,\n" +
" qta_cnf,\n" + " round(qta_cnf/rap_conv, 5) qta_cnf,\n" +
" unt_mis_acq,\n" + " unt_mis_acq,\n" +
" qta_min_ord,\n" + " qta_min_ord,\n" +
" flag_qta_multipla\n" + " flag_qta_multipla\n" +

View File

@@ -9,6 +9,8 @@ import com.fasterxml.jackson.databind.node.ObjectNode;
import com.google.common.base.Joiner; import com.google.common.base.Joiner;
import it.integry.common.var.CommonConstants; import it.integry.common.var.CommonConstants;
import it.integry.ems.dto.ExtendedStbActivity; import it.integry.ems.dto.ExtendedStbActivity;
import it.integry.ems.dto.Result;
import it.integry.ems.expansion.RunnableArgsThrowable;
import it.integry.ems.file_sharer.IFileSharerAttachment; import it.integry.ems.file_sharer.IFileSharerAttachment;
import it.integry.ems.file_sharer.sharers.email.EmailFileAttachment; import it.integry.ems.file_sharer.sharers.email.EmailFileAttachment;
import it.integry.ems.javabeans.RequestDataDTO; import it.integry.ems.javabeans.RequestDataDTO;
@@ -17,6 +19,7 @@ import it.integry.ems.license.LicenseStatusDTO;
import it.integry.ems.report.dto.JasperDTO; import it.integry.ems.report.dto.JasperDTO;
import it.integry.ems.report.dto.PairsDTO; import it.integry.ems.report.dto.PairsDTO;
import it.integry.ems.response.*; import it.integry.ems.response.*;
import it.integry.ems.retail.ReportVariazioni.dto.VariazioniDettaglioDTO;
import it.integry.ems.service.EntityProcessor; import it.integry.ems.service.EntityProcessor;
import it.integry.ems.service.MailService; import it.integry.ems.service.MailService;
import it.integry.ems.service.PrinterService; import it.integry.ems.service.PrinterService;
@@ -35,7 +38,9 @@ import it.integry.ems.system.exception.NotValidLicenseException;
import it.integry.ems.system.request.SystemChangePasswordRequest; import it.integry.ems.system.request.SystemChangePasswordRequest;
import it.integry.ems.system.request.SystemLoginRequest; import it.integry.ems.system.request.SystemLoginRequest;
import it.integry.ems.system.service.SystemService; import it.integry.ems.system.service.SystemService;
import it.integry.ems.utility.UtilityDirs;
import it.integry.ems.utility.UtilityEntity; import it.integry.ems.utility.UtilityEntity;
import it.integry.ems.utility.UtilityFile;
import it.integry.ems.utility.UtilityPrinter; import it.integry.ems.utility.UtilityPrinter;
import it.integry.ems_model.base.EntityBase; import it.integry.ems_model.base.EntityBase;
import it.integry.ems_model.config.EmsRestConstants; import it.integry.ems_model.config.EmsRestConstants;
@@ -48,9 +53,7 @@ import it.integry.ems_model.utility.*;
import it.integry.ems_model.utility.dto.ConvertQueryDTO; import it.integry.ems_model.utility.dto.ConvertQueryDTO;
import it.integry.security.cache.SecretKeyCacheComponent; import it.integry.security.cache.SecretKeyCacheComponent;
import it.integry.security.dto.LoginRequestDTO; import it.integry.security.dto.LoginRequestDTO;
import net.schmizz.sshj.SSHClient; import kotlin.Triple;
import net.schmizz.sshj.sftp.SFTPClient;
import net.schmizz.sshj.transport.verification.PromiscuousVerifier;
import org.apache.commons.codec.binary.Base64; import org.apache.commons.codec.binary.Base64;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.WordUtils; import org.apache.commons.lang3.text.WordUtils;
@@ -67,9 +70,13 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.nio.file.Paths;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
@RestController @RestController
@@ -1407,22 +1414,89 @@ public class SystemController {
@RequestMapping(value = EmsRestConstants.PATH_TEST, method = RequestMethod.POST) @RequestMapping(value = EmsRestConstants.PATH_TEST, method = RequestMethod.POST)
public ServiceRestResponse test(HttpServletRequest request, public ServiceRestResponse test(HttpServletRequest request,
@RequestParam(CommonConstants.PROFILE_DB) String configuration) { @RequestParam(CommonConstants.PROFILE_DB) String configuration) throws Exception {
try {
SSHClient client = new SSHClient();
client.addHostKeyVerifier(new PromiscuousVerifier());
client.connect("edis.chep.com");
client.authPassword("C0094362", "C526342");
SFTPClient sftpClient = client.newSFTPClient(); String sql = "SELECT dtb_doct.num_doc,\n" +
sftpClient.ls("/"); " dtb_doct.data_doc,\n" +
" dtb_doct.cod_anag,\n" +
" dtb_doct.cod_dtip,\n" +
" dtb_doct.ser_doc\n" +
"FROM dtb_doct\n" +
" INNER JOIN dtb_tipi ON dtb_doct.cod_dtip = dtb_tipi.cod_dtip\n" +
"WHERE dtb_doct.data_doc BETWEEN '2023/01/01' AND '2023-12-31'--BETWEEN '2024/01/01' AND GETDATE()\n" +
" AND dtb_doct.gestione = 'V'\n" +
" AND dtb_tipi.tipo_emissione = 'DIRETTA'\n" +
" AND dtb_tipi.segno_qta_scar <> 0\n" +
"ORDER BY dtb_doct.data_doc, dtb_doct.num_doc";
return ServiceRestResponse.createPositiveResponse(); final List<HashMap<String, Object>> documents = UtilityDB.executeSimpleQuery(multiDBTransactionManager.getPrimaryConnection(), sql);
} catch (Exception ex) {
logger.error(request.getRequestURI(), ex); final DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH-mm-ss")
return new ServiceRestResponse(EsitoType.KO, configuration, ex); .withZone(ZoneId.systemDefault());
String tempDir = Paths.get(UtilityDirs.getTempDirectoryPath(), "vgalimenti-export-" + dateTimeFormatter.format(LocalDateTime.now())).toString();
List<RunnableArgsThrowable<Triple<String, String, List<VariazioniDettaglioDTO>>>> calls = new ArrayList<>();
for (HashMap<String, Object> document : documents) {
String codAnag = UtilityHashMap.getValueIfExists(document, "cod_anag");
String serDoc = UtilityHashMap.getValueIfExists(document, "ser_doc");
Integer numDoc = UtilityHashMap.getValueIfExists(document, "num_doc");
Date dataDoc = UtilityHashMap.getValueIfExists(document, "data_doc");
String codDtip = UtilityHashMap.getValueIfExists(document, "cod_dtip");
calls.add(() -> {
try {
ArrayList<PairsDTO> params = new ArrayList<>();
params.add(new PairsDTO("cod_anag", codAnag));
params.add(new PairsDTO("ser_doc", serDoc));
params.add(new PairsDTO("num_doc", numDoc));
params.add(new PairsDTO("data_doc", dataDoc));
params.add(new PairsDTO("cod_dtip", codDtip));
JasperDTO jasperDTO = new JasperDTO()
.setParams(params)
.setReportId(20L);
final byte[] bytes = reportProcessor.processReport(jasperDTO);
UtilityFile.saveFile(tempDir, String.format("%s_%s_%s_%d_%s.pdf",
UtilityDate.formatDate(dataDoc, "yyyyMMdd"),
codDtip,
serDoc,
numDoc,
codAnag
), bytes);
} catch (Exception ex) {
// throw ex;
// logger.error(request.getRequestURI(), "Errore durante la generazione del pdf per il DDT [" +
// "num_doc: " + numDoc + ", " +
// "data_doc: " + dataDoc + ", " +
// "ser_doc: " + serDoc + ", " +
// "cod_anag: " + codAnag + ", " +
// "cod_dtip: " + codDtip + "] " + ex.getMessage());
throw new RuntimeException(new Exception("Errore durante la generazione del pdf per il DDT [" +
"num_doc: " + numDoc + ", " +
"data_doc: " + dataDoc + ", " +
"ser_doc: " + serDoc + ", " +
"cod_anag: " + codAnag + ", " +
"cod_dtip: " + codDtip + "] " + ex.getMessage()));
}
// break;
return null;
});
} }
final ArrayList<Result<Triple<String, String, List<VariazioniDettaglioDTO>>>> results = UtilityThread.executeParallel(calls, 10);
return ServiceRestResponse.createPositiveResponse();
} }
@RequestMapping(value = EmsRestConstants.PATH_STB_EMAIL_CONTENT_FATTURE_PASSIVE_DELETER, method = RequestMethod.POST) @RequestMapping(value = EmsRestConstants.PATH_STB_EMAIL_CONTENT_FATTURE_PASSIVE_DELETER, method = RequestMethod.POST)

View File

@@ -5,21 +5,15 @@ import it.integry.ems.javabeans.RequestDataDTO;
import it.integry.ems.response.ServiceRestResponse; import it.integry.ems.response.ServiceRestResponse;
import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager; import it.integry.ems.sync.MultiDBTransaction.MultiDBTransactionManager;
import it.integry.ems.system.exchange.service.ExchangeDocumentImportService; import it.integry.ems.system.exchange.service.ExchangeDocumentImportService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope; import org.springframework.context.annotation.Scope;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
@RestController @RestController
@Scope("request") @Scope("request")
@RequestMapping("exchange/documenti/") @RequestMapping("exchange/documenti/")
public class ExchangeDocumentImportController { public class ExchangeDocumentImportController {
private final Logger logger = LogManager.getLogger();
@Autowired @Autowired
private ExchangeDocumentImportService exchangeDocumentImportService; private ExchangeDocumentImportService exchangeDocumentImportService;
@@ -27,12 +21,23 @@ public class ExchangeDocumentImportController {
private RequestDataDTO requestDataDTO; private RequestDataDTO requestDataDTO;
@RequestMapping(value = "importAcquisto", method = RequestMethod.GET)
public @ResponseBody
ServiceRestResponse importAcquisto(@RequestParam(CommonConstants.PROFILE_DB) String profileDb,
@RequestParam() String profileDbExchange) throws Exception {
try (MultiDBTransactionManager internalDb = new MultiDBTransactionManager(profileDb);
MultiDBTransactionManager exchangeDb = new MultiDBTransactionManager(profileDbExchange)) {
exchangeDocumentImportService.importAcquisto(internalDb, exchangeDb, requestDataDTO);
}
return ServiceRestResponse.createPositiveResponse();
}
@RequestMapping(value = "importLavorazione", method = RequestMethod.GET) @RequestMapping(value = "importLavorazione", method = RequestMethod.GET)
public @ResponseBody public @ResponseBody
ServiceRestResponse importLavorazione(HttpServletRequest request, ServiceRestResponse importLavorazione(@RequestParam(CommonConstants.PROFILE_DB) String profileDb,
@RequestParam(CommonConstants.PROFILE_DB) String profileDb, @RequestParam() String profileDbExchange) throws Exception {
@RequestParam() String profileDbExchange) throws Exception {
try (MultiDBTransactionManager internalDb = new MultiDBTransactionManager(profileDb); try (MultiDBTransactionManager internalDb = new MultiDBTransactionManager(profileDb);
MultiDBTransactionManager exchangeDb = new MultiDBTransactionManager(profileDbExchange)) { MultiDBTransactionManager exchangeDb = new MultiDBTransactionManager(profileDbExchange)) {
@@ -42,12 +47,10 @@ public class ExchangeDocumentImportController {
} }
@RequestMapping(value = "importVendita", method = RequestMethod.GET) @RequestMapping(value = "importVendita", method = RequestMethod.GET)
public @ResponseBody public @ResponseBody
ServiceRestResponse importVendita(HttpServletRequest request, ServiceRestResponse importVendita(@RequestParam(CommonConstants.PROFILE_DB) String profileDb,
@RequestParam(CommonConstants.PROFILE_DB) String profileDb, @RequestParam() String profileDbExchange) throws Exception {
@RequestParam() String profileDbExchange) throws Exception {
try (MultiDBTransactionManager internalDb = new MultiDBTransactionManager(profileDb); try (MultiDBTransactionManager internalDb = new MultiDBTransactionManager(profileDb);
MultiDBTransactionManager exchangeDb = new MultiDBTransactionManager(profileDbExchange)) { MultiDBTransactionManager exchangeDb = new MultiDBTransactionManager(profileDbExchange)) {

View File

@@ -120,10 +120,12 @@ public class ExchangeDestinatariImportService {
private void singleUpdateImported(Connection connection, GtbAnag importedData, boolean useTempTable) throws Exception { private void singleUpdateImported(Connection connection, GtbAnag importedData, boolean useTempTable) throws Exception {
final HashMap<String, Object> importedKey = new HashMap<String, Object>() {{ final List<HashMap<String, Object>> importedRowKeys = importedData.getVtbDest().stream()
put("cod_anag", importedData.getCodAnag()); .map(x -> new HashMap<String, Object>() {{
}}; put("cod_anag", x.getCodAnag());
put("cod_vdes", x.getCodVdes());
}}).collect(Collectors.toList());
exchangeImportDataManagerService.updateImportedStatus(connection, "vtb_dest", importedKey, useTempTable); exchangeImportDataManagerService.updateImportedStatus(connection, "vtb_dest", importedRowKeys, useTempTable);
} }
} }

View File

@@ -46,6 +46,10 @@ public class ExchangeDocumentImportService {
private final Logger logger = LogManager.getLogger(); private final Logger logger = LogManager.getLogger();
public void importAcquisto(MultiDBTransactionManager internalMultiDb, MultiDBTransactionManager exchangeMultiDb, RequestDataDTO requestDataDTO) throws Exception {
this.internalImport(internalMultiDb, exchangeMultiDb, requestDataDTO, ExchangeImportSchemaManagerService.SchemaType.DocumentiAcquisto);
}
public void importLavorazione(MultiDBTransactionManager internalMultiDb, MultiDBTransactionManager exchangeMultiDb, RequestDataDTO requestDataDTO) throws Exception { public void importLavorazione(MultiDBTransactionManager internalMultiDb, MultiDBTransactionManager exchangeMultiDb, RequestDataDTO requestDataDTO) throws Exception {
this.internalImport(internalMultiDb, exchangeMultiDb, requestDataDTO, ExchangeImportSchemaManagerService.SchemaType.DocumentiLavorazione); this.internalImport(internalMultiDb, exchangeMultiDb, requestDataDTO, ExchangeImportSchemaManagerService.SchemaType.DocumentiLavorazione);
} }
@@ -62,6 +66,9 @@ public class ExchangeDocumentImportService {
String logType = null; String logType = null;
switch (schemaType) { switch (schemaType) {
case DocumentiAcquisto:
logType = "acquisto";
break;
case DocumentiLavorazione: case DocumentiLavorazione:
logType = "lavorazione"; logType = "lavorazione";
break; break;
@@ -78,7 +85,11 @@ public class ExchangeDocumentImportService {
String testataTableName; String testataTableName;
String righeTableName; String righeTableName;
if (schemaType == ExchangeImportSchemaManagerService.SchemaType.DocumentiLavorazione) { if (schemaType == ExchangeImportSchemaManagerService.SchemaType.DocumentiAcquisto) {
testataTableName = "dtb_doct_acq";
righeTableName = "dtb_docr_acq";
} else if (schemaType == ExchangeImportSchemaManagerService.SchemaType.DocumentiLavorazione) {
testataTableName = "dtb_doct_lav"; testataTableName = "dtb_doct_lav";
righeTableName = "dtb_docr_lav"; righeTableName = "dtb_docr_lav";
@@ -229,7 +240,7 @@ public class ExchangeDocumentImportService {
.forEach(testata -> { .forEach(testata -> {
testata.setUserName(EXCHANGE_USER); testata.setUserName(EXCHANGE_USER);
testata.setUsername(EXCHANGE_USER); testata.setUsername(EXCHANGE_USER);
testata.setUpdProgMaga(false); //testata.setUpdProgMaga(false);
testata.setDtbDocr(righe.parallelStream() testata.setDtbDocr(righe.parallelStream()
.filter(riga -> .filter(riga ->

View File

@@ -127,8 +127,8 @@ public class ExchangeFornitoriImportService {
put("cod_anag", importedData.getCodAnag()); put("cod_anag", importedData.getCodAnag());
}}; }};
exchangeImportDataManagerService.updateImportedStatus(connection, "gtb_anag_clienti", importedKey, useTempTable); exchangeImportDataManagerService.updateImportedStatus(connection, "gtb_anag_fornitori", importedKey, useTempTable);
exchangeImportDataManagerService.updateImportedStatus(connection, "vtb_clie", importedKey, useTempTable); exchangeImportDataManagerService.updateImportedStatus(connection, "atb_forn", importedKey, useTempTable);
} }
} }

View File

@@ -31,7 +31,8 @@ public class ExchangeImportSchemaManagerService {
Clienti(11), Clienti(11),
Fornitori(12), Fornitori(12),
PDCAnag(13), PDCAnag(13),
Destinatari(14); Destinatari(14),
DocumentiAcquisto(15);
private final int value; private final int value;
@@ -81,6 +82,8 @@ public class ExchangeImportSchemaManagerService {
put(SchemaType.Fornitori, Arrays.asList("gtb_anag_fornitori", "atb_forn")); put(SchemaType.Fornitori, Arrays.asList("gtb_anag_fornitori", "atb_forn"));
put(SchemaType.PDCAnag, Collections.singletonList("ctb_anag")); put(SchemaType.PDCAnag, Collections.singletonList("ctb_anag"));
put(SchemaType.Destinatari, Collections.singletonList("vtb_dest")); put(SchemaType.Destinatari, Collections.singletonList("vtb_dest"));
put(SchemaType.DocumentiAcquisto, Arrays.asList("dtb_doct_acq", "dtb_docr_acq"));
}}; }};
public List<String> getTablesBySchemaType(SchemaType schemaType) { public List<String> getTablesBySchemaType(SchemaType schemaType) {

View File

@@ -69,8 +69,8 @@ public class AnagraficaDocFinanceService {
" LEFT OUTER JOIN gtb_banc_azi_intercode ON vtb_clie.cod_banc_azi = gtb_banc_azi_intercode.cod_banc_azi AND\n" + " LEFT OUTER JOIN gtb_banc_azi_intercode ON vtb_clie.cod_banc_azi = gtb_banc_azi_intercode.cod_banc_azi AND\n" +
" gtb_banc_azi_intercode.formato = 'DOCFINANCE'\n" + " gtb_banc_azi_intercode.formato = 'DOCFINANCE'\n" +
(exportAllAnag?"": (exportAllAnag?"":
"WHERE (data_ins >= CAST(GETDATE() AS DATE)\n" + "WHERE (CAST(data_ins AS DATE)>= CAST(GETDATE() AS DATE)\n" +
" OR data_mod = CAST(GETDATE() AS DATE))\n" )+ " OR CAST(data_mod AS DATE)= CAST(GETDATE() AS DATE))\n" )+
"UNION ALL\n" + "UNION ALL\n" +
"SELECT 'ROSSOGARGA' AS azienda,\n" + "SELECT 'ROSSOGARGA' AS azienda,\n" +
" IIF(diacod > 0, diacod, ctb_cont.cod_ccon) AS codice_pdc,\n" + " IIF(diacod > 0, diacod, ctb_cont.cod_ccon) AS codice_pdc,\n" +
@@ -100,8 +100,8 @@ public class AnagraficaDocFinanceService {
" NULL AS voce_finanziaria\n" + " NULL AS voce_finanziaria\n" +
"FROM ctb_cont\n" + "FROM ctb_cont\n" +
(exportAllAnag?"": (exportAllAnag?"":
"WHERE (data_ins >= CAST(GETDATE() AS DATE)\n" + "WHERE (CAST(data_ins AS DATE)>= CAST(GETDATE() AS DATE)\n" +
" OR data_mod = CAST(GETDATE() AS DATE))"); " OR CAST(data_mod AS DATE)= CAST(GETDATE() AS DATE))");
List<AnagraficaDocFinanceDTO> anagraficaDocFinance = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sql, AnagraficaDocFinanceDTO.class); List<AnagraficaDocFinanceDTO> anagraficaDocFinance = UtilityDB.executeSimpleQueryDTO(multiDBTransactionManager.getPrimaryConnection(), sql, AnagraficaDocFinanceDTO.class);
TxtMapper<AnagraficaDocFinanceDTO> txtMapper = new TxtMapper<AnagraficaDocFinanceDTO>() TxtMapper<AnagraficaDocFinanceDTO> txtMapper = new TxtMapper<AnagraficaDocFinanceDTO>()

View File

@@ -1 +1,41 @@
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 250.32 249.54"><g id="Chiuso"><path d="M30.51,205.22A125.6,125.6,0,0,1,67.17,21.3L77.43,40A104.3,104.3,0,0,0,47,192.05Z" transform="translate(-5.19 -4.98)" style="fill:#0097cb"/><path d="M39,215.28l16-13.72a104,104,0,0,0,63.35,31.74l-.12,21.22A125.18,125.18,0,0,1,39,215.28" transform="translate(-5.19 -4.98)" style="fill:#309d48"/><path d="M131.72,254.52A124.77,124.77,0,0,0,255.51,129.75c0-2.19-.06-4-.17-6.18l-20.19.36q.15,2.89.15,5.82A104.57,104.57,0,0,1,131.62,234.32Z" transform="translate(-5.19 -4.98)" style="fill:#ea1d25"/><path d="M90,33.4a104.29,104.29,0,0,1,40.71-8.22c51.31,0,94,37,103.39,86.16l20.14-.72C243.4,51.72,192.17,5,130.74,5A124.37,124.37,0,0,0,80.17,15.65Z" transform="translate(-5.19 -4.98)" style="fill:#f7991c"/></g></svg> <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 28.4.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Livello_2_00000131351338131156323440000007316977087721992075_"
xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 200.21 200.21"
style="enable-background:new 0 0 200.21 200.21;" xml:space="preserve">
<style type="text/css">
.st0{display:none;fill:#5C25E5;}
.st1{fill:#FFFFFF;}
.st2{fill:#F39200;}
.st3{fill:#00A0DE;}
.st4{fill:#269C38;}
.st5{fill:#E62400;}
</style>
<rect x="-4.57" y="-4.57" class="st0" width="209.34" height="209.34"/>
<circle class="st1" cx="100.1" cy="100.1" r="98.01"/>
<g>
<g>
<path class="st2" d="M33.82,123.35c-4.47,0-8.48-3.14-9.41-7.69c-1.04-5.09-1.57-10.33-1.57-15.56c0-25.15,12.3-48.8,32.91-63.27
c4.35-3.05,10.34-2,13.39,2.34c3.05,4.34,2,10.34-2.34,13.39C51.31,63.44,42.07,81.21,42.07,100.1c0,3.94,0.4,7.88,1.18,11.71
c1.06,5.2-2.29,10.28-7.49,11.35C35.1,123.29,34.45,123.35,33.82,123.35z"/>
</g>
<g>
<path class="st3" d="M100.1,177.37c-15.33,0-30.14-4.48-42.85-12.96c-4.42-2.95-5.61-8.92-2.66-13.33
c2.95-4.42,8.92-5.61,13.33-2.66c9.53,6.36,20.66,9.72,32.17,9.72c18.88,0,36.64-9.23,47.51-24.69c3.05-4.34,9.05-5.39,13.39-2.33
c4.34,3.05,5.39,9.05,2.33,13.39C148.87,165.09,125.23,177.37,100.1,177.37z"/>
</g>
<g>
<path class="st4" d="M166.71,121.7c-0.56,0-1.13-0.05-1.7-0.15c-5.23-0.93-8.71-5.93-7.77-11.16c0.6-3.37,0.91-6.83,0.91-10.29
c0-7.24-1.31-14.3-3.91-20.99c-1.92-4.95,0.53-10.52,5.48-12.44s10.52,0.54,12.44,5.48c3.46,8.91,5.21,18.31,5.21,27.94
c0,4.59-0.41,9.19-1.21,13.67C175.33,118.43,171.28,121.7,166.71,121.7z"/>
</g>
<g>
<path class="st5" d="M147.03,60.99c-2.4,0-4.8-0.89-6.67-2.69c-10.87-10.47-25.16-16.23-40.26-16.23c-3.42,0-6.84,0.3-10.17,0.89
c-5.23,0.92-10.22-2.57-11.14-7.8s2.57-10.22,7.8-11.14c4.43-0.78,8.98-1.18,13.52-1.18c20.09,0,39.13,7.67,53.6,21.61
c3.82,3.68,3.94,9.77,0.26,13.59C152.07,60,149.55,60.99,147.03,60.99z"/>
</g>
<g>
<circle cx="64.07" cy="124.52" r="10.9"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 835 B

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -1,683 +1,69 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) --> <!-- Generator: Adobe Illustrator 28.4.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <svg version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px"
viewBox="0 0 250 105" style="enable-background:new 0 0 250 105;" xml:space="preserve"> viewBox="0 0 646.51 154.53" style="enable-background:new 0 0 646.51 154.53;" xml:space="preserve">
<style type="text/css"> <style type="text/css">
.st0{fill:none;} .st0{fill:#FFFFFF;}
.st1{fill:#F7BC60;}
.st2{fill:#FFFFFF;}
.st3{fill:#FFFFFF;stroke:#231F20;stroke-width:0.75;stroke-miterlimit:10;}
</style> </style>
<pattern y="105" width="69" height="69" patternUnits="userSpaceOnUse" id="Polka_Dot_Pattern" viewBox="2.1 -70.9 69 69" style="overflow:visible;"> <g id="livello_da_rimuovere">
</g>
<g id="Livello_1">
<rect x="203.9" y="37.12" class="st0" width="14.87" height="66.46"/>
<polygon class="st0" points="279.96,77.4 248.52,37.12 238.07,37.12 238.07,103.58 252.94,103.58 252.94,63.8 283.91,103.58
294.93,103.58 294.93,37.12 279.96,37.12 "/>
<polygon class="st0" points="309.61,50.11 330.41,50.11 330.41,103.58 345.38,103.58 345.38,50.11 366.09,50.11 366.09,37.12
309.61,37.12 "/>
<polygon class="st0" points="395.74,75.9 425.39,75.9 425.39,63.38 395.74,63.38 395.74,49.92 428.22,49.92 428.22,37.12
395.74,37.12 392.26,37.12 380.87,37.12 380.87,103.58 392.26,103.58 395.74,103.58 428.78,103.58 428.78,90.78 395.74,90.78 "/>
<g>
<path class="st0" d="M475.47,78.45l18.95,0.3c-0.36,1.33-0.8,2.6-1.4,3.75c-1.48,2.82-3.58,4.97-6.31,6.45
c-2.73,1.48-6.01,2.21-9.84,2.21c-3.83,0-7.22-0.89-10.17-2.68c-2.95-1.79-5.27-4.25-6.97-7.39c-1.69-3.14-2.54-6.75-2.54-10.83
c0-4.14,0.86-7.77,2.59-10.87c1.73-3.1,4.13-5.52,7.2-7.25c3.07-1.73,6.56-2.59,10.45-2.59c3.58,0,6.83,0.71,9.75,2.12
c2.92,1.41,5.41,3.5,7.48,6.26l10.16-10.17c-3.07-3.64-6.96-6.51-11.67-8.61c-4.71-2.1-9.92-3.15-15.63-3.15
c-4.96,0-9.59,0.88-13.88,2.64c-4.3,1.76-8.08,4.19-11.35,7.3c-3.26,3.1-5.8,6.71-7.63,10.82c-1.82,4.11-2.73,8.61-2.73,13.51
c0,4.83,0.89,9.32,2.68,13.46c1.79,4.14,4.25,7.78,7.39,10.92c3.14,3.14,6.82,5.6,11.06,7.39c4.24,1.79,8.8,2.68,13.7,2.68
c6.59,0,12.41-1.4,17.46-4.19c5.05-2.79,9-6.92,11.86-12.38c2.85-5.46,4.28-12.14,4.28-20.05v-2.16h-34.92V78.45z"/>
<path class="st0" d="M540.71,48.7h10.64c2.89,0,5.13,0.79,6.73,2.35c1.6,1.57,2.4,3.55,2.4,5.93c0,2.51-0.82,4.5-2.45,5.98
c-1.63,1.47-3.89,2.21-6.78,2.21h-10.54V48.7z M564.52,73.83c3.39-1.63,6.02-3.91,7.91-6.83c1.88-2.92,2.83-6.38,2.83-10.4
c0-3.77-0.93-7.12-2.78-10.07c-1.85-2.95-4.44-5.26-7.76-6.92c-3.33-1.66-7.22-2.49-11.67-2.49h-12.33h-3.48h-11.39v66.46h14.87
v-27.3h1.52l19.75,27.3h17.6l-21.19-27.82C560.61,75.35,562.66,74.73,564.52,73.83"/>
</g>
<polygon class="st0" points="629.66,37.12 615.54,61.31 601.42,37.12 584.29,37.12 608.01,75.84 608.01,103.58 622.98,103.58
622.98,75.26 646.51,37.12 "/>
<g>
<path class="st0" d="M10.98,100.52c-4.47,0-8.48-3.14-9.41-7.69C0.53,87.74,0,82.5,0,77.27C0,52.12,12.3,28.47,32.91,14
c4.35-3.05,10.34-2,13.39,2.34c3.05,4.34,2,10.34-2.34,13.39C28.47,40.61,19.23,58.38,19.23,77.27c0,3.94,0.4,7.88,1.18,11.71
c1.06,5.2-2.29,10.28-7.49,11.35C12.26,100.45,11.62,100.52,10.98,100.52z"/>
</g>
<g>
<path class="st0" d="M77.27,154.53c-15.33,0-30.14-4.48-42.85-12.96c-4.42-2.95-5.61-8.92-2.66-13.33
c2.95-4.42,8.92-5.61,13.33-2.66c9.53,6.36,20.66,9.72,32.17,9.72c18.88,0,36.64-9.23,47.51-24.69c3.05-4.34,9.05-5.39,13.39-2.33
c4.34,3.05,5.39,9.05,2.33,13.39C126.03,142.25,102.39,154.53,77.27,154.53z"/>
</g>
<g>
<path class="st0" d="M143.87,98.86c-0.56,0-1.13-0.05-1.7-0.15c-5.23-0.93-8.71-5.93-7.77-11.16c0.6-3.37,0.91-6.83,0.91-10.29
c0-7.24-1.31-14.3-3.91-20.99c-1.92-4.95,0.53-10.52,5.48-12.44c4.95-1.92,10.52,0.54,12.44,5.48c3.46,8.91,5.21,18.31,5.21,27.94
c0,4.59-0.41,9.19-1.21,13.67C152.49,95.6,148.44,98.86,143.87,98.86z"/>
</g>
<g>
<path class="st0" d="M124.19,38.15c-2.4,0-4.8-0.89-6.67-2.69c-10.87-10.47-25.16-16.23-40.26-16.23c-3.42,0-6.84,0.3-10.17,0.89
c-5.23,0.92-10.22-2.57-11.14-7.8s2.57-10.22,7.8-11.14C68.18,0.4,72.73,0,77.27,0c20.09,0,39.13,7.67,53.6,21.61
c3.82,3.68,3.94,9.77,0.26,13.59C129.23,37.16,126.71,38.15,124.19,38.15z"/>
</g>
<g>
<circle class="st0" cx="41.24" cy="101.68" r="10.9"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g> <g>
<rect x="2.1" y="-70.9" class="st0" width="69" height="69"/>
<rect x="2.1" y="-70.9" class="st1" width="69" height="69"/>
<g>
<path class="st2" d="M61.8-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-71.7,61.8-71.7,61.8-71.7
C61.8-71.6,61.8-71.6,61.8-71.7"/>
<path class="st2" d="M54.1-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-71.7,54.1-71.7,54.1-71.7
C54.1-71.6,54.1-71.6,54.1-71.7"/>
<path class="st2" d="M46.4-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.4-71.7,46.4-71.7,46.4-71.7
C46.4-71.6,46.4-71.6,46.4-71.7"/>
<path class="st2" d="M38.8-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-71.7,38.8-71.7,38.8-71.7
C38.8-71.6,38.8-71.6,38.8-71.7"/>
<path class="st2" d="M31.1-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-71.7,31.1-71.7,31.1-71.7
C31.1-71.6,31.1-71.6,31.1-71.7"/>
<path class="st2" d="M23.4-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.4-71.7,23.4-71.7,23.4-71.7
C23.4-71.6,23.4-71.6,23.4-71.7"/>
<path class="st2" d="M15.8-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-71.7,15.8-71.7,15.8-71.7
C15.8-71.6,15.8-71.6,15.8-71.7"/>
<path class="st2" d="M8.1-71.7c0,0.1,0,0.1,0,0.2C8-71.4,8-71.4,7.9-71.3c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.1-71.7,8.1-71.7,8.1-71.7
C8.1-71.6,8.1-71.6,8.1-71.7"/>
<path class="st2" d="M0.4-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C0.8-69.4,1-69,1.2-68.9c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.4-71.7,0.4-71.7,0.4-71.7
C0.4-71.6,0.4-71.6,0.4-71.7"/>
</g>
<g>
<path class="st2" d="M69.4-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-71.7,69.4-71.7,69.4-71.7
C69.4-71.6,69.4-71.6,69.4-71.7"/>
</g>
<path class="st2" d="M0.5-71.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C0.9-69.4,1-69,1.3-68.9c0.2,0,0.4-0.1,0.5-0.1c0.2,0,0.4,0,0.6-0.1
c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2c0-0.1,0.1-0.2,0.1-0.3
c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8c-0.2,0-0.3,0.1-0.4,0.2
c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-71.7,0.5-71.7,0.5-71.7C0.5-71.6,0.5-71.6,0.5-71.7"/>
<g>
<g>
<path class="st2" d="M69.4-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-64,69.4-64.1,69.4-64C69.4-64,69.4-64,69.4-64"
/>
<path class="st2" d="M61.8-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-64,61.8-64.1,61.8-64C61.8-64,61.8-64,61.8-64"
/>
<path class="st2" d="M54.1-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-64,54.1-64.1,54.1-64C54.1-64,54.1-64,54.1-64"
/>
<path class="st2" d="M46.5-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-64,46.5-64.1,46.5-64C46.5-64,46.5-64,46.5-64"
/>
<path class="st2" d="M38.8-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-64,38.8-64.1,38.8-64C38.8-64,38.8-64,38.8-64"
/>
<path class="st2" d="M31.1-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-64,31.1-64.1,31.1-64C31.1-64,31.1-64,31.1-64"
/>
<path class="st2" d="M23.5-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-64,23.5-64.1,23.5-64C23.5-64,23.5-64,23.5-64"
/>
<path class="st2" d="M15.8-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-64,15.8-64.1,15.8-64C15.8-64,15.8-64,15.8-64"
/>
<path class="st2" d="M8.2-64c0,0.1,0,0.1,0,0.2C8.1-63.7,8-63.7,8-63.7c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C8-62.2,8.2-62,8.3-61.9c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.2-64,8.2-64.1,8.2-64C8.1-64,8.1-64,8.2-64"/>
<path class="st2" d="M0.5-64c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5C2.8-62,3-61.9,3.1-62c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-64,0.5-64.1,0.5-64C0.5-64,0.5-64,0.5-64"/>
</g>
<g>
<path class="st2" d="M69.4-56.3c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-56.4,69.4-56.4,69.4-56.3
C69.4-56.3,69.4-56.3,69.4-56.3"/>
<path class="st2" d="M61.8-56.3c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-56.4,61.8-56.4,61.8-56.3
C61.8-56.3,61.8-56.3,61.8-56.3"/>
<path class="st2" d="M54.1-56.3c0,0.1,0,0.1,0,0.2C54-56.1,54-56.1,53.9-56c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-56.4,54.1-56.4,54.1-56.3
C54.1-56.3,54.1-56.3,54.1-56.3"/>
<path class="st2" d="M46.5-56.3c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-56.4,46.5-56.4,46.5-56.3
C46.5-56.3,46.5-56.3,46.5-56.3"/>
<path class="st2" d="M38.8-56.3c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-56.4,38.8-56.4,38.8-56.3
C38.8-56.3,38.8-56.3,38.8-56.3"/>
<path class="st2" d="M31.1-56.3c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-56.4,31.1-56.4,31.1-56.3
C31.1-56.3,31.1-56.3,31.1-56.3"/>
<path class="st2" d="M23.5-56.3c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-56.4,23.5-56.4,23.5-56.3
C23.5-56.3,23.5-56.3,23.5-56.3"/>
<path class="st2" d="M15.8-56.3c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-56.4,15.8-56.4,15.8-56.3
C15.8-56.3,15.8-56.3,15.8-56.3"/>
<path class="st2" d="M8.2-56.3c0,0.1,0,0.1,0,0.2C8.1-56.1,8-56.1,8-56c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.2-56.4,8.2-56.4,8.2-56.3
C8.1-56.3,8.1-56.3,8.2-56.3"/>
<path class="st2" d="M0.5-56.3c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-56.4,0.5-56.4,0.5-56.3
C0.5-56.3,0.5-56.3,0.5-56.3"/>
</g>
<g>
<path class="st2" d="M69.4-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-48.7,69.4-48.8,69.4-48.7
C69.4-48.7,69.4-48.7,69.4-48.7"/>
<path class="st2" d="M61.8-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-48.7,61.8-48.8,61.8-48.7
C61.8-48.7,61.8-48.7,61.8-48.7"/>
<path class="st2" d="M54.1-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-48.7,54.1-48.8,54.1-48.7
C54.1-48.7,54.1-48.7,54.1-48.7"/>
<path class="st2" d="M46.5-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-48.7,46.5-48.8,46.5-48.7
C46.5-48.7,46.5-48.7,46.5-48.7"/>
<path class="st2" d="M38.8-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-48.7,38.8-48.8,38.8-48.7
C38.8-48.7,38.8-48.7,38.8-48.7"/>
<path class="st2" d="M31.1-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-48.7,31.1-48.8,31.1-48.7
C31.1-48.7,31.1-48.7,31.1-48.7"/>
<path class="st2" d="M23.5-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-48.7,23.5-48.8,23.5-48.7
C23.5-48.7,23.5-48.7,23.5-48.7"/>
<path class="st2" d="M15.8-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-48.7,15.8-48.8,15.8-48.7
C15.8-48.7,15.8-48.7,15.8-48.7"/>
<path class="st2" d="M8.2-48.7c0,0.1,0,0.1,0,0.2C8.1-48.4,8-48.4,8-48.4c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C8.5-46.4,8.7-46,8.9-46c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.2-48.7,8.2-48.8,8.2-48.7
C8.1-48.7,8.1-48.7,8.2-48.7"/>
<path class="st2" d="M0.5-48.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C0.9-46.4,1-46,1.3-46c0.2,0,0.4-0.1,0.5-0.1c0.2,0,0.4,0,0.6-0.1
c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2c0-0.1,0.1-0.2,0.1-0.3
c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8c-0.2,0-0.3,0.1-0.4,0.2
c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-48.7,0.5-48.8,0.5-48.7C0.5-48.7,0.5-48.7,0.5-48.7"/>
</g>
<g>
<path class="st2" d="M69.4-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-41.1,69.4-41.1,69.4-41C69.4-41,69.4-41,69.4-41
"/>
<path class="st2" d="M61.8-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-41.1,61.8-41.1,61.8-41C61.8-41,61.8-41,61.8-41
"/>
<path class="st2" d="M54.1-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-41.1,54.1-41.1,54.1-41C54.1-41,54.1-41,54.1-41
"/>
<path class="st2" d="M46.5-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-41.1,46.5-41.1,46.5-41C46.5-41,46.5-41,46.5-41
"/>
<path class="st2" d="M38.8-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-41.1,38.8-41.1,38.8-41C38.8-41,38.8-41,38.8-41
"/>
<path class="st2" d="M31.1-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-41.1,31.1-41.1,31.1-41C31.1-41,31.1-41,31.1-41
"/>
<path class="st2" d="M23.5-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-41.1,23.5-41.1,23.5-41C23.5-41,23.5-41,23.5-41
"/>
<path class="st2" d="M15.8-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-41.1,15.8-41.1,15.8-41C15.8-41,15.8-41,15.8-41
"/>
<path class="st2" d="M8.2-41c0,0.1,0,0.1,0,0.2C8.1-40.8,8-40.8,8-40.7c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.2-41.1,8.2-41.1,8.2-41C8.1-41,8.1-41,8.2-41"/>
<path class="st2" d="M0.5-41c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5C2.8-39,3-39,3.1-39c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-41.1,0.5-41.1,0.5-41C0.5-41,0.5-41,0.5-41"/>
</g>
<g>
<path class="st2" d="M69.4-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-33.4,69.4-33.5,69.4-33.4
C69.4-33.4,69.4-33.4,69.4-33.4"/>
<path class="st2" d="M61.8-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-33.4,61.8-33.5,61.8-33.4
C61.8-33.4,61.8-33.4,61.8-33.4"/>
<path class="st2" d="M54.1-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-33.4,54.1-33.5,54.1-33.4
C54.1-33.4,54.1-33.4,54.1-33.4"/>
<path class="st2" d="M46.5-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-33.4,46.5-33.5,46.5-33.4
C46.5-33.4,46.5-33.4,46.5-33.4"/>
<path class="st2" d="M38.8-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-33.4,38.8-33.5,38.8-33.4
C38.8-33.4,38.8-33.4,38.8-33.4"/>
<path class="st2" d="M31.1-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-33.4,31.1-33.5,31.1-33.4
C31.1-33.4,31.1-33.4,31.1-33.4"/>
<path class="st2" d="M23.5-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-33.4,23.5-33.5,23.5-33.4
C23.5-33.4,23.5-33.4,23.5-33.4"/>
<path class="st2" d="M15.8-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-33.4,15.8-33.5,15.8-33.4
C15.8-33.4,15.8-33.4,15.8-33.4"/>
<path class="st2" d="M8.2-33.4c0,0.1,0,0.1,0,0.2C8.1-33.1,8-33.1,8-33.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.2-33.4,8.2-33.5,8.2-33.4
C8.1-33.4,8.1-33.4,8.2-33.4"/>
<path class="st2" d="M0.5-33.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-33.4,0.5-33.5,0.5-33.4
C0.5-33.4,0.5-33.4,0.5-33.4"/>
</g>
<g>
<path class="st2" d="M69.4-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-25.8,69.4-25.8,69.4-25.7
C69.4-25.7,69.4-25.7,69.4-25.7"/>
<path class="st2" d="M61.8-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-25.8,61.8-25.8,61.8-25.7
C61.8-25.7,61.8-25.7,61.8-25.7"/>
<path class="st2" d="M54.1-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-25.8,54.1-25.8,54.1-25.7
C54.1-25.7,54.1-25.7,54.1-25.7"/>
<path class="st2" d="M46.5-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-25.8,46.5-25.8,46.5-25.7
C46.5-25.7,46.5-25.7,46.5-25.7"/>
<path class="st2" d="M38.8-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-25.8,38.8-25.8,38.8-25.7
C38.8-25.7,38.8-25.7,38.8-25.7"/>
<path class="st2" d="M31.1-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-25.8,31.1-25.8,31.1-25.7
C31.1-25.7,31.1-25.7,31.1-25.7"/>
<path class="st2" d="M23.5-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-25.8,23.5-25.8,23.5-25.7
C23.5-25.7,23.5-25.7,23.5-25.7"/>
<path class="st2" d="M15.8-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-25.8,15.8-25.8,15.8-25.7
C15.8-25.7,15.8-25.7,15.8-25.7"/>
<path class="st2" d="M8.2-25.7c0,0.1,0,0.1,0,0.2C8.1-25.4,8-25.5,8-25.4c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C8-24,8.2-23.8,8.3-23.6c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.2-25.8,8.2-25.8,8.2-25.7
C8.1-25.7,8.1-25.7,8.2-25.7"/>
<path class="st2" d="M0.5-25.7c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C0.9-23.5,1-23.1,1.3-23c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-25.8,0.5-25.8,0.5-25.7
C0.5-25.7,0.5-25.7,0.5-25.7"/>
</g>
<g>
<path class="st2" d="M69.4-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-18.1,69.4-18.2,69.4-18.1
C69.4-18,69.4-18.1,69.4-18.1"/>
<path class="st2" d="M61.8-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-18.1,61.8-18.2,61.8-18.1
C61.8-18,61.8-18.1,61.8-18.1"/>
<path class="st2" d="M54.1-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-18.1,54.1-18.2,54.1-18.1
C54.1-18,54.1-18.1,54.1-18.1"/>
<path class="st2" d="M46.5-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-18.1,46.5-18.2,46.5-18.1
C46.5-18,46.5-18.1,46.5-18.1"/>
<path class="st2" d="M38.8-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-18.1,38.8-18.2,38.8-18.1
C38.8-18,38.8-18.1,38.8-18.1"/>
<path class="st2" d="M31.1-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-18.1,31.1-18.2,31.1-18.1
C31.1-18,31.1-18.1,31.1-18.1"/>
<path class="st2" d="M23.5-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-18.1,23.5-18.2,23.5-18.1
C23.5-18,23.5-18.1,23.5-18.1"/>
<path class="st2" d="M15.8-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-18.1,15.8-18.2,15.8-18.1
C15.8-18,15.8-18.1,15.8-18.1"/>
<path class="st2" d="M8.2-18.1c0,0.1,0,0.1,0,0.2C8.1-17.8,8-17.8,8-17.8c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C8-16.3,8.2-16.1,8.3-16c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.2-18.1,8.2-18.2,8.2-18.1C8.1-18,8.1-18.1,8.2-18.1
"/>
<path class="st2" d="M0.5-18.1c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5C2.8-16.1,3-16,3.1-16c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-18.1,0.5-18.2,0.5-18.1C0.5-18,0.5-18.1,0.5-18.1
"/>
</g>
<g>
<path class="st2" d="M69.4-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-10.5,69.4-10.5,69.4-10.4
C69.4-10.4,69.4-10.4,69.4-10.4"/>
<path class="st2" d="M61.8-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1C63.9-8,63.8-8.2,64-8.3c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-10.5,61.8-10.5,61.8-10.4
C61.8-10.4,61.8-10.4,61.8-10.4"/>
<path class="st2" d="M54.1-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-10.5,54.1-10.5,54.1-10.4
C54.1-10.4,54.1-10.4,54.1-10.4"/>
<path class="st2" d="M46.5-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-10.5,46.5-10.5,46.5-10.4
C46.5-10.4,46.5-10.4,46.5-10.4"/>
<path class="st2" d="M38.8-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1C40.9-8,40.8-8.2,41-8.3c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-10.5,38.8-10.5,38.8-10.4
C38.8-10.4,38.8-10.4,38.8-10.4"/>
<path class="st2" d="M31.1-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-10.5,31.1-10.5,31.1-10.4
C31.1-10.4,31.1-10.4,31.1-10.4"/>
<path class="st2" d="M23.5-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-10.5,23.5-10.5,23.5-10.4
C23.5-10.4,23.5-10.4,23.5-10.4"/>
<path class="st2" d="M15.8-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1C17.9-8,17.8-8.2,18-8.3c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-10.5,15.8-10.5,15.8-10.4
C15.8-10.4,15.8-10.4,15.8-10.4"/>
<path class="st2" d="M8.2-10.4c0,0.1,0,0.1,0,0.2C8.1-10.1,8-10.2,8-10.1C7.9-10,7.9-9.8,7.9-9.8c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C8-8.7,8.2-8.5,8.3-8.3c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C8.2-10.5,8.2-10.5,8.2-10.4
C8.1-10.4,8.1-10.4,8.2-10.4"/>
<path class="st2" d="M0.5-10.4c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1C0.3-10,0.2-9.8,0.2-9.8c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C0.9-8.2,1-7.8,1.3-7.7c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1C2.6-8,2.5-8.2,2.7-8.3c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C0.5-10.5,0.5-10.5,0.5-10.4
C0.5-10.4,0.5-10.4,0.5-10.4"/>
</g>
</g>
<g>
<path class="st2" d="M69.4-2.8c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C69.8-0.5,70-0.1,70.2,0c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C69.4-2.8,69.4-2.9,69.4-2.8
C69.4-2.7,69.4-2.8,69.4-2.8"/>
<path class="st2" d="M61.8-2.8c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C61.6-1,61.8-0.8,62-0.7c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C61.8-2.8,61.8-2.9,61.8-2.8
C61.8-2.7,61.8-2.8,61.8-2.8"/>
<path class="st2" d="M54.1-2.8c0,0.1,0,0.1,0,0.2C54-2.5,54-2.5,53.9-2.5c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C54-1,54.1-0.8,54.3-0.7c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1C56.9-0.8,57-1,57.1-1.2c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C54.1-2.8,54.1-2.9,54.1-2.8
C54.1-2.7,54.1-2.8,54.1-2.8"/>
<path class="st2" d="M46.5-2.8c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C46.8-0.5,47-0.1,47.2,0c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C46.5-2.8,46.5-2.9,46.5-2.8
C46.5-2.7,46.5-2.8,46.5-2.8"/>
<path class="st2" d="M38.8-2.8c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C38.6-1,38.8-0.8,39-0.7c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C38.8-2.8,38.8-2.9,38.8-2.8
C38.8-2.7,38.8-2.8,38.8-2.8"/>
<path class="st2" d="M31.1-2.8c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C31-1,31.1-0.8,31.3-0.7c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C31.1-2.8,31.1-2.9,31.1-2.8
C31.1-2.7,31.1-2.8,31.1-2.8"/>
<path class="st2" d="M23.5-2.8c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4c0.1,0.2,0.3,0.4,0.4,0.5C23.8-0.5,24-0.1,24.3,0c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C23.5-2.8,23.5-2.9,23.5-2.8
C23.5-2.7,23.5-2.8,23.5-2.8"/>
<path class="st2" d="M15.8-2.8c0,0.1,0,0.1,0,0.2c-0.1,0.1-0.1,0.1-0.2,0.1c-0.1,0.1-0.1,0.3-0.1,0.4c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C15.7-1,15.8-0.8,16-0.7c0.2,0.1,0.4,0.6,0.6,0.6c0.2,0,0.4-0.1,0.5-0.1
c0.2,0,0.4,0,0.6-0.1c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2
c0-0.1,0.1-0.2,0.1-0.3c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8
c-0.2,0-0.3,0.1-0.4,0.2c-0.2,0.1-0.1,0.2-0.3,0.2c-0.1,0-0.2,0.1-0.2,0.2C15.8-2.8,15.8-2.9,15.8-2.8
C15.8-2.7,15.8-2.8,15.8-2.8"/>
<path class="st2" d="M8.2-2.8c0,0.1,0,0.1,0,0.2C8.1-2.5,8-2.5,8-2.5C7.9-2.4,7.9-2.2,7.9-2.1c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C8-1,8.2-0.8,8.3-0.7C8.5-0.5,8.7-0.1,8.9,0c0.2,0,0.4-0.1,0.5-0.1c0.2,0,0.4,0,0.6-0.1
c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1c0.2-0.1,0.3-0.3,0.4-0.5c0-0.1,0-0.1,0-0.2c0-0.1,0.1-0.2,0.1-0.3
c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8C9-3.5,8.8-3.4,8.7-3.4
C8.5-3.3,8.6-3.2,8.4-3.1C8.3-3.1,8.2-3,8.2-2.9C8.2-2.8,8.2-2.9,8.2-2.8C8.1-2.7,8.1-2.8,8.2-2.8"/>
<path class="st2" d="M0.5-2.8c0,0.1,0,0.1,0,0.2C0.4-2.5,0.4-2.5,0.3-2.5C0.3-2.4,0.2-2.2,0.2-2.1c-0.2,0.1,0,0.2,0,0.3
c0,0,0,0.1,0,0.2c0,0.1,0,0.3,0.1,0.4C0.3-1,0.5-0.8,0.7-0.7C0.9-0.5,1-0.1,1.3,0c0.2,0,0.4-0.1,0.5-0.1c0.2,0,0.4,0,0.6-0.1
c0.2-0.1,0.1-0.3,0.3-0.5c0.1-0.1,0.3,0,0.4-0.1C3.3-0.8,3.4-1,3.5-1.2c0-0.1,0-0.1,0-0.2c0-0.1,0.1-0.2,0.1-0.3
c0-0.1-0.1-0.1-0.1-0.2c0-0.1,0-0.2,0-0.3c0-0.2,0-0.4-0.1-0.5c-0.4-0.7-1.2-0.9-2-0.8C1.3-3.5,1.2-3.4,1-3.4
C0.9-3.3,0.9-3.2,0.7-3.1C0.6-3.1,0.5-3,0.5-2.9C0.5-2.8,0.5-2.9,0.5-2.8C0.5-2.7,0.5-2.8,0.5-2.8"/>
</g>
</g> </g>
</pattern>
<g>
<rect x="29" y="28.5" class="st0" width="223" height="53.3"/>
<path class="st2" d="M41.8,36.6h-9.1v-8.1h9.1V36.6z M41.8,73h-9.1V40.4h9.1V73z"/>
<path class="st2" d="M49.3,40.4h16.2c4.9,0,8.4,0.9,10.5,2.8c2.1,1.8,3.1,4.9,3.1,9.2V73h-8.6V53.4c0-2.4-0.4-4-1.1-4.8
s-2.3-1.1-4.6-1.1h-6.9V73h-8.6V40.4z"/>
<path class="st2" d="M83.2,40.4h6.1V28.5h8.6v11.8h9.1v6.5h-9.1v13.2c0,2.4,0.4,4.1,1.2,5c0.8,0.9,2.3,1.4,4.3,1.4h3.5V73h-7.9
c-3.2,0-5.6-0.9-7.3-2.6c-1.7-1.8-2.5-4.3-2.5-7.6V46.9h-6.1V40.4z"/>
<path class="st2" d="M126.7,73c-5.4,0-9.5-1.4-12.3-4.1c-2.8-2.8-4.2-6.8-4.2-12.2c0-5.4,1.4-9.4,4.2-12.2
c2.8-2.8,6.9-4.1,12.3-4.1h12.6v6.8h-11.4c-3.1,0-5.2,0.4-6.3,1.3c-1.1,0.9-1.7,2.5-1.7,4.8h19.5v6.8h-19.5
c0.1,2.3,0.6,3.9,1.6,4.8c1,0.9,3.1,1.3,6.4,1.3h11.5V73H126.7z"/>
<path class="st2" d="M175.4,71.9c0,4.5-1,7.8-3,9.9c-2,2.1-5.1,3.1-9.4,3.1h-16.9v-6.6h15.4c1.7,0,2.9-0.4,3.8-1.2
c0.9-0.8,1.3-2,1.3-3.5V73h-7c-3.6,0-6.2-0.3-7.8-0.8c-1.6-0.5-3.1-1.5-4.4-2.8c-1.6-1.5-2.8-3.3-3.6-5.5c-0.8-2.2-1.3-4.6-1.3-7.1
c0-2.5,0.4-4.9,1.3-7.1c0.8-2.2,2-4,3.6-5.5c1.4-1.4,3-2.4,4.9-3c1.9-0.6,4.3-0.9,7.4-0.9h15.7V71.9z M162.3,66.3h4.5V47.4h-4.5
c-2.2,0-3.7,0.1-4.5,0.2c-0.9,0.2-1.6,0.4-2.3,0.8c-1.3,0.8-2.3,1.9-2.9,3.2c-0.6,1.3-0.9,3-0.9,5.2c0,3.5,0.8,5.9,2.3,7.4
C155.5,65.6,158.3,66.3,162.3,66.3z"/>
<path class="st2" d="M182.6,40.4h14.5c3.4,0,5.8,0.6,7.1,1.8c1.4,1.2,2,3.4,2,6.4v5.4h-8.2v-4.2c0-1.3-0.2-2.1-0.7-2.6
c-0.5-0.4-1.5-0.7-3.1-0.7h-3V73h-8.6V40.4z"/>
<path class="st2" d="M225.8,65.8h6.9V40.4h8.6v31.8c0,4.3-1,7.5-3,9.6c-2,2.1-5.1,3.1-9.3,3.1h-16.9v-6.6h15.4
c1.7,0,2.9-0.4,3.8-1.2c0.9-0.8,1.3-2,1.3-3.5V73h-7.6c-4.9,0-8.4-1-10.4-2.9c-2.1-1.9-3.1-5.1-3.1-9.6V40.4h8.5v19.5
c0,2.5,0.4,4.1,1.1,4.8C221.9,65.4,223.4,65.8,225.8,65.8z"/>
</g>
<g>
<path class="st3" d="M35.3,7.8"/>
<path class="st2" d="M84.3,24.8c-7.3-8-17.8-13-29.5-13c-5.5,0-10.7,1.1-15.5,3.1l-3.9-7.2c6-2.7,12.6-4.1,19.5-4.1
c14.3,0,27.1,6.2,35.9,16.1L84.3,24.8z"/>
<path class="st2" d="M93,80.8c-8.7,11.4-22.4,18.7-37.8,18.8l0-8.1c12.8-0.1,24.1-6.3,31.3-15.7L93,80.8z"/>
<path class="st3" d="M19.8,84.4"/>
<path class="st2" d="M16.5,80.5c-6.1-8-9.7-18.1-9.7-28.9c0-17.6,9.5-33.1,23.7-41.4l3.9,7.2c-11.7,6.9-19.5,19.7-19.5,34.3
c0,8.9,2.9,17.2,7.9,23.8L16.5,80.5z"/>
<path class="st3" d="M39.3,15"/>
<path class="st2" d="M19.8,84.4l6.1-5.2c6.3,6.6,14.7,11,24.2,12.1l0,8.1C38.1,98.2,27.5,92.7,19.8,84.4"/>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g>
<g>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -44,7 +44,7 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<gson.version>2.9.1</gson.version> <gson.version>2.9.1</gson.version>
<httpclient.version>4.3.6</httpclient.version> <httpclient.version>4.3.6</httpclient.version>
<jaspersoft.version>6.20.6</jaspersoft.version> <jaspersoft.version>6.21.3</jaspersoft.version>
</properties> </properties>
<modules> <modules>