Skip to content
Snippets Groups Projects
Commit a4892097 authored by Johannes Hörmann's avatar Johannes Hörmann
Browse files

Chart fixed

parent 331dea9c
No related branches found
No related tags found
No related merge requests found
<?xml version="1.0" encoding="UTF-8"?>
<entity xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/entity/1.1.0">
<name>Turnover_entity</name>
<title>Turnover</title>
<majorModelMode>DISTRIBUTED</majorModelMode>
<recordContainer>jdito</recordContainer>
<entityFields>
......@@ -12,10 +13,22 @@
<title>Year</title>
</entityField>
<entityField>
<name>VALUE</name>
<name>Y</name>
<title>Turnover</title>
</entityField>
<entityField>
<name>PARENT</name>
<title>Parent</title>
</entityField>
<entityField>
<name>CATEGORY</name>
<title>Category</title>
</entityField>
<entityField>
<name>X</name>
<title>Year</title>
<contentType>NUMBER</contentType>
<outputFormat>0.00#.##</outputFormat>
</entityField>
</entityFields>
<recordContainers>
......@@ -26,7 +39,9 @@
<recordFields>
<element>UID.value</element>
<element>PARENT.value</element>
<element>VALUE.value</element>
<element>CATEGORY.value</element>
<element>Y.value</element>
<element>X.value</element>
</recordFields>
</jDitoRecordContainer>
</recordContainers>
......
import("system.logging");
import("system.datetime");
import("system.db");
import("system.result");
import("system.translate");
var sumOfMonthTurnover = db.table("select year(SALESORDERDATE) yearNum, 'turnover', month(SALESORDERDATE) monthNum, sum(NET + VAT) from SALESORDER group by year(SALESORDERDATE), month(SALESORDERDATE) order by yearNum, monthNum");
var sumOfMonthForecast = db.table("select year(DATE_START) yearNum, 'forecast', month(DATE_START) monthNum, sum(VOLUME) from SALESPROJECT_FORECAST group by year(DATE_START), month(DATE_START) order by yearNum, monthNum");
var turnoverData = db.table("select year(SALESORDERDATE) yearNum, 0 monthNum, sum(NET + VAT) from SALESORDER group by year(SALESORDERDATE) "
+ " union "
+ " select year(SALESORDERDATE) yearNum, month(SALESORDERDATE) monthNum, sum(NET + VAT) from SALESORDER group by year(SALESORDERDATE), month(SALESORDERDATE) "
+ " order by yearNum, monthNum");
logging.log(turnoverData.toSource())
var chartData = [];
var turnoverSkippedCount = 0;
var forecastSkippedCount = 0;
var chartData = [];
turnoverData.forEach(function(rowData)
for (let i = 0; i < 4; i++)
{
var parent = (rowData[1] == 0) ? "" : rowData[0] + "0";
var year = i + 2016;
_addMonthRows(year);
}
chartData.push([rowData[0] + rowData[1], parent, parseFloat(rowData[2])]);
})
result.object(chartData);
logging.log(chartData.toSource())
result.object(chartData);
\ No newline at end of file
function _addRow(pRow)
{
//logging.log(pRow.toSource())
// month = 0 --> sum of the whole year
var parent = "";
var dateDisplay = pRow[0];
if (pRow[2] != 0)
{
parent = pRow[0] + "0" + pRow[1].trim();
var rowDate = new Date(pRow[0], pRow[2]-1);
dateDisplay = datetime.toDate(rowDate.getTime(), "MMM yyyy", "UTC")
}
chartData.push([pRow[0] + pRow[2] + pRow[1].trim(), parent,
((pRow[1].trim() == "turnover") ? translate.text("Turnover") : translate.text("Forecast")), parseFloat(pRow[3]), dateDisplay]);
}
function _addMonthRows(pYear)
{
var turnoverSkippedCount = 0;
var forecastSkippedCount = 0;
var turnoverYearSum = 0;
var forecastYearSum = 0;
var filteredTurnover = sumOfMonthTurnover.filter(function(row)
{
return row[0] == pYear
});
var filteredForecast = sumOfMonthForecast.filter(function(row)
{
return row[0] == pYear
});
for (let i = 1; i <= 12; i++)
{
var turnoverSum = filteredTurnover[i - turnoverSkippedCount - 1];
var forecastSum = filteredForecast[i - forecastSkippedCount - 1];
if (turnoverSum != undefined && turnoverSum[0] == pYear && turnoverSum[2] == i.toString())
{
_addRow(turnoverSum);
turnoverYearSum += turnoverSum[3];
}
else
{
_addRow([year.toString(), 'turnover', i, 0.0]);
turnoverSkippedCount++;
}
if (forecastSum != undefined && forecastSum[0] == pYear && forecastSum[2] == i)
{
_addRow(forecastSum);
forecastYearSum += forecastSum[3];
}
else
{
_addRow([year.toString(), 'forecast', i, 0.0]);
forecastSkippedCount++;
}
}
_addRow([year.toString(), 'turnover', 0, turnoverYearSum]);
_addRow([year.toString(), 'forecast', 0, forecastYearSum]);
}
......@@ -1257,6 +1257,75 @@
<entry>
<key>Receipt</key>
</entry>
<entry>
<key>Receipt number</key>
</entry>
<entry>
<key>Year</key>
</entry>
<entry>
<key>New receipt version</key>
</entry>
<entry>
<key>Orderitems</key>
</entry>
<entry>
<key>Nur Eigene anzeigen</key>
</entry>
<entry>
<key>Sent receipts</key>
</entry>
<entry>
<key>asdfgsdfg</key>
</entry>
<entry>
<key>Copy receipt</key>
</entry>
<entry>
<key>Orderitem</key>
</entry>
<entry>
<key>The order number already exists!</key>
</entry>
<entry>
<key>July</key>
</entry>
<entry>
<key>June</key>
</entry>
<entry>
<key>October</key>
</entry>
<entry>
<key>November</key>
</entry>
<entry>
<key>December</key>
</entry>
<entry>
<key>Turnover</key>
</entry>
<entry>
<key>May</key>
</entry>
<entry>
<key>April</key>
</entry>
<entry>
<key>January</key>
</entry>
<entry>
<key>March</key>
</entry>
<entry>
<key>September</key>
</entry>
<entry>
<key>August</key>
</entry>
<entry>
<key>February</key>
</entry>
</keyValueMap>
<font name="Dialog" style="0" size="11" />
<sqlModels>
......
......@@ -14,6 +14,10 @@
<key>German (Austria)</key>
<value>Deutsch (Österreich)</value>
</entry>
<entry>
<key>Turnover</key>
<value>Umsatz</value>
</entry>
<entry>
<key>E-Mail</key>
<value>E-Mail</value>
......@@ -1106,7 +1110,7 @@
</entry>
<entry>
<key>Forecast</key>
<value>Vorhersage</value>
<value>Forecast</value>
</entry>
<entry>
<key>Vorschau</key>
......@@ -1554,6 +1558,70 @@
<entry>
<key>My histories</key>
</entry>
<entry>
<key>Year</key>
<value>Jahr</value>
</entry>
<entry>
<key>New receipt version</key>
</entry>
<entry>
<key>Orderitems</key>
</entry>
<entry>
<key>Nur Eigene anzeigen</key>
</entry>
<entry>
<key>Sent receipts</key>
</entry>
<entry>
<key>asdfgsdfg</key>
</entry>
<entry>
<key>Copy receipt</key>
</entry>
<entry>
<key>Orderitem</key>
</entry>
<entry>
<key>The order number already exists!</key>
</entry>
<entry>
<key>July</key>
</entry>
<entry>
<key>June</key>
</entry>
<entry>
<key>October</key>
</entry>
<entry>
<key>November</key>
</entry>
<entry>
<key>December</key>
</entry>
<entry>
<key>May</key>
</entry>
<entry>
<key>April</key>
</entry>
<entry>
<key>January</key>
</entry>
<entry>
<key>March</key>
</entry>
<entry>
<key>September</key>
</entry>
<entry>
<key>August</key>
</entry>
<entry>
<key>February</key>
</entry>
</keyValueMap>
<font name="Dialog" style="0" size="11" />
</language>
......@@ -1274,6 +1274,76 @@
<entry>
<key>Receipt</key>
</entry>
<entry>
<key>Receipt number</key>
</entry>
<entry>
<key>Year</key>
</entry>
<entry>
<key>New receipt version</key>
</entry>
<entry>
<key>Orderitems</key>
</entry>
<entry>
<key>Nur Eigene anzeigen</key>
</entry>
<entry>
<key>Sent receipts</key>
</entry>
<entry>
<key>asdfgsdfg</key>
</entry>
<entry>
<key>Copy receipt</key>
</entry>
<entry>
<key>Orderitem</key>
</entry>
<entry>
<key>Turnover</key>
<value></value>
</entry>
<entry>
<key>The order number already exists!</key>
</entry>
<entry>
<key>July</key>
</entry>
<entry>
<key>June</key>
</entry>
<entry>
<key>October</key>
</entry>
<entry>
<key>November</key>
</entry>
<entry>
<key>December</key>
</entry>
<entry>
<key>May</key>
</entry>
<entry>
<key>April</key>
</entry>
<entry>
<key>January</key>
</entry>
<entry>
<key>March</key>
</entry>
<entry>
<key>September</key>
</entry>
<entry>
<key>August</key>
</entry>
<entry>
<key>February</key>
</entry>
</keyValueMap>
<font name="Dialog" style="0" size="11" />
</language>
<?xml version="1.0" encoding="UTF-8"?>
<neonContext xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.0.0" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/neonContext/1.0.0">
<name>Turnover_context</name>
<title>Turnover</title>
<majorModelMode>DISTRIBUTED</majorModelMode>
<mainview>TurnoverChart_view</mainview>
<entity>Turnover_entity</entity>
......
......@@ -10,10 +10,22 @@
<children>
<multiDataChartViewTemplate>
<name>TurnoverChart_template</name>
<chartTitle>Turnover</chartTitle>
<chartType>COLUMN</chartType>
<xAxis>UID</xAxis>
<yAxis>VALUE</yAxis>
<xAxis>X</xAxis>
<yAxis>Y</yAxis>
<parentField>PARENT</parentField>
<categoryField>CATEGORY</categoryField>
<entityField>#ENTITY</entityField>
</multiDataChartViewTemplate>
<multiDataChartViewTemplate>
<name>TurnoverLinesChart_template</name>
<chartTitle>Turnover</chartTitle>
<chartType>SPLINE</chartType>
<xAxis>X</xAxis>
<yAxis>Y</yAxis>
<parentField>PARENT</parentField>
<categoryField>CATEGORY</categoryField>
<entityField>#ENTITY</entityField>
</multiDataChartViewTemplate>
</children>
......
......@@ -4,7 +4,7 @@
<insert tableName="SALESPROJECT">
<column name="SALESPROJECTID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
<column name="PROJECTCODE" valueNumeric="1000"/>
<column name="PROJECTTITLE" value="GfK"/>
<column name="RELATION_ID" value="b219b58a-f120-42d8-9a64-0b176501eac7"/>
......@@ -23,7 +23,7 @@
<insert tableName="SALESPROJECT_SOURCE">
<column name="SALESPROJECT_SOURCEID" value="1c1f83ad-9e4b-4d0f-b820-98e724e34aec"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
<column name="ENTRYDATE" valueDate="2017-08-21T09:03:43"/>
<column name="INFO" value="Initialeintrag"/>
<column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
......@@ -33,12 +33,12 @@
<insert tableName="SALESPROJECT_CYCLE">
<column name="SALESPROJECT_CYCLEID" value="c1eb7a04-666f-4bb0-8021-3feadff5d5df"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
<column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
<column name="TYPE" valueNumeric="1"/>
<column name="VALUE" valueNumeric="1"/>
<column name="DATE_START" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_END" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_START" valueDate="2016-06-13T09:03:43"/>
<column name="DATE_END" valueDate="2016-06-13T09:03:43"/>
</insert>
<insert tableName="SALESPROJECT_FORECAST">
......@@ -53,15 +53,60 @@
<column name="INFO" value="grob abgeschätzt, da große Unsicherheit"/>
<column name="DATE_START" valueDate="2018-06-13T09:03:43"/>
<column name="VOLUME" valueNumeric="15"/>
<column name="VOLUME" valueNumeric="100"/>
</insert>
<insert tableName="SALESPROJECT_FORECAST">
<column name="SALESPROJECT_FORECASTID" value="35f5f997-cc23-4850-8e71-b497bb7d12d6"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
<column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
<column name="RELATION_ID" value="b219b58a-f120-42d8-9a64-0b176501eac7"/>
<column name="TYPE" value="PLAN"/>
<column name="GROUPCODE" valueNumeric="1"/>
<column name="INFO" value="grob abgeschätzt, da große Unsicherheit"/>
<column name="DATE_START" valueDate="2016-06-13T09:03:43"/>
<column name="VOLUME" valueNumeric="150"/>
</insert>
<insert tableName="SALESPROJECT_FORECAST">
<column name="SALESPROJECT_FORECASTID" value="625dd1eb-3d60-4818-8e9a-c55650d7fd87"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2017-06-13T09:03:43"/>
<column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
<column name="RELATION_ID" value="b219b58a-f120-42d8-9a64-0b176501eac7"/>
<column name="TYPE" value="PLAN"/>
<column name="GROUPCODE" valueNumeric="1"/>
<column name="INFO" value="grob abgeschätzt, da große Unsicherheit"/>
<column name="DATE_START" valueDate="2017-06-13T09:03:43"/>
<column name="VOLUME" valueNumeric="500"/>
</insert>
<insert tableName="SALESPROJECT_FORECAST">
<column name="SALESPROJECT_FORECASTID" value="c2b3303e-4a11-455c-b214-16400f9d8c16"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2017-05-13T09:03:43"/>
<column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
<column name="RELATION_ID" value="b219b58a-f120-42d8-9a64-0b176501eac7"/>
<column name="TYPE" value="PLAN"/>
<column name="GROUPCODE" valueNumeric="1"/>
<column name="INFO" value="grob abgeschätzt, da große Unsicherheit"/>
<column name="DATE_START" valueDate="2017-05-13T09:03:43"/>
<column name="VOLUME" valueNumeric="600"/>
</insert>
<insert tableName="SALESPROJECT_COMPETITION">
<column name="SALESPROJECT_COMPETITIONID" value="a3ae9702-a3da-4d5f-a3ab-e386c8a0ac40"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
<column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
<column name="DATE_CANCELLED" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_CANCELLED" valueDate="2016-06-13T09:03:43"/>
<column name="INFO" value="starkes Prozess Know-How, wird gefährlich für uns. Dazu private Verbindungen"/>
<column name="RELATION_ID" value="eda61ea6-35ed-4a92-a93c-6118fc67d533"/>
<column name="STATUS" valueNumeric="1"/>
......@@ -70,7 +115,7 @@
<insert tableName="SALESPROJECT_MEMBER">
<column name="SALESPROJECT_MEMBERID" value="f9dc15c0-91b8-43d3-ba98-80ca581db3a3"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
<column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
<column name="RELATION_ID" value="73d731a2-e7f5-11e8-9f32-f2801f1b9fd1"/>
<column name="SALESPROJECT_ROLE" valueNumeric="1"/>
......@@ -79,7 +124,7 @@
<insert tableName="SALESPROJECT_CLASSIFICATION">
<column name="SALESPROJECT_CLASSIFICATIONID" value="77da9dcb-b49a-4608-9c7d-68545b0ec29b"/>
<column name="USER_NEW" value="admin"/>
<column name="DATE_NEW" valueDate="2018-06-13T09:03:43"/>
<column name="DATE_NEW" valueDate="2016-06-13T09:03:43"/>
<column name="SALESPROJECT_ID" value="0833465c-8851-4fbb-b7e3-8c1d73c903da"/>
<column name="CLASS" valueNumeric="1"/>
......
<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://www.adito.de/2018/ao/Model" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" VERSION="1.1.7" xsi:schemaLocation="http://www.adito.de/2018/ao/Model adito://models/xsd/process/1.1.7">
<name>Chart_lib</name>
<majorModelMode>DISTRIBUTED</majorModelMode>
<process>%aditoprj%/process/Chart_lib/process.js</process>
</process>
import("system.util");
import("system.report");
import("system.neon");
import("system.vars");
var sumOfMonthTurnover = db.table("select year(SALESORDERDATE) yearNum, 'turnover', month(SALESORDERDATE) monthNum, sum(NET + VAT) from SALESORDER group by year(SALESORDERDATE), month(SALESORDERDATE) order by yearNum, monthNum");
var sumOfMonthForecast = db.table("select year(DATE_START) yearNum, 'forecast', month(DATE_START) monthNum, sum(VOLUME) from SALESPROJECT_FORECAST group by year(DATE_START), month(DATE_START) order by yearNum, monthNum");
var chartData = [];
var turnoverSkippedCount = 0;
var forecastSkippedCount = 0;
for (let i = 0; i < 4; i++)
{
var year = i + 2016;
_addMonthRows(year);
}
result.object(chartData);
function _addRow(pRow)
{
//logging.log(pRow.toSource())
// month = 0 --> sum of the whole year
var parent = "";
var dateDisplay = pRow[0];
if (pRow[2] != 0)
{
parent = pRow[0] + "0" + pRow[1].trim();
var rowDate = new Date(pRow[0], pRow[2]-1);
dateDisplay = datetime.toDate(rowDate.getTime(), "MMM yyyy", "UTC")
}
chartData.push([pRow[0] + pRow[2] + pRow[1].trim(), parent,
((pRow[1].trim() == "turnover") ? translate.text("Turnover") : translate.text("Forecast")), parseFloat(pRow[3]), dateDisplay]);
}
function _addMonthRows(pYear)
{
var turnoverSkippedCount = 0;
// var turnoverNotCorrectYearCount = 0;
var forecastSkippedCount = 0;
var forecastNotCorrectYearCount = 0;
var turnoverYearSum = 0;
var forecastYearSum = 0;
var filteredTurnover = sumOfMonthTurnover.filter(function(row)
{
return row[0] == pYear
});
var filteredForecast = sumOfMonthForecast.filter(function(row)
{
return row[0] == pYear
});
for (let i = 1; i <= 12; i++)
{
var turnoverSum = filteredTurnover[i - turnoverSkippedCount - 1];
var forecastSum = filteredForecast[i - forecastSkippedCount - 1];
if (turnoverSum != undefined && turnoverSum[0] == pYear && turnoverSum[2] == i.toString())
{
_addRow(turnoverSum);
turnoverYearSum += turnoverSum[3];
}
else
{
_addRow([year.toString(), 'turnover', i, 0.0]);
turnoverSkippedCount++;
}
if (forecastSum != undefined && forecastSum[0] == pYear && forecastSum[2] == i)
{
_addRow(forecastSum);
forecastYearSum += forecastSum[3];
}
else
{
_addRow([year.toString(), 'forecast', i, 0.0]);
forecastSkippedCount++;
}
}
_addRow([year.toString(), 'turnover', 0, turnoverYearSum]);
_addRow([year.toString(), 'forecast', 0, forecastYearSum]);
}
/**
*
* @class
*/
function MultiDataChart()
{
this._ID = 0;
this._GROUP = 1;
this._X = 2;
this._Y = 3;
this.dataSources = {};
this.drilldowns = {};
this._resultData = [];
}
MultiDataChart.begin = function()
{
var chart = new MultiDataChart();
return chart;
}
/**
* Add a new datasource
* Has to be an array with [[id, x, y, ...], [id, x, y, ...]]
* ... means you can add additional columns, used as identification and naming of drilldowns
*/
MultiDataChart.prototype.addDataSource = function(pName, pData)
{
this.dataSources[pName] = pData;
return this;
}
/**
*
*/
MultiDataChart.prototype.addCumulativeDrillDown = function(pDataSourceName, pGetParentXCallback, pGetCummulationCallback)
{
if (this.dataSources[pDataSourceName] != undefined)
{
this.drilldowns[pDataSourceName].type = "cumulative";
this.drilldowns[pDataSourceName].dataSource = pDataSourceName;
this.drilldowns[pDataSourceName].getParentX = pGetParentXCallback;
this.drilldowns[pDataSourceName].getCumulation = pGetCummulationCallback;
}
else
{
throw Error("MultiDataChart::addCumulativeDrillDown: Data source " + pDataSourceName + " doesn't exist!");
}
return this;
}
/**
*
*/
MultiDataChart.prototype.build = function()
{
for (dataSource in this.dataSources)
{
for (let i = 0; i < dataSources[dataSource].length; i++)
{
var dataRow = dataSources[dataSource][i];
var rowId = util.getNewUUID();
// id, parent, group, x, y
this._resultData.push([rowId, "", dataSource, dataRow[this._X], dataRow[this._Y]]);
}
}
}
MultiDataChart.prototype._processDrilldowns = function()
{
for (drilldown in this.drilldowns)
{
if (drilldown.type == "cumulative")
{
this._processCumulativeDrilldown(drilldown);
}
}
}
MultiDataChart.prototype._processCumulativeDrilldown = function(pDrilldown)
{
var parentId = util.getNewUUID();
var data = this.dataSources[pDrilldown.dataSource];
}
\ No newline at end of file
......@@ -47,4 +47,31 @@ DateUtils.getDateIncrementedByYears = function(pDate, pYears) {
var dateObj = new Date(pDate);
return dateObj.setFullYear(dateObj.getFullYear() + pYears);
}
/**
* get Month name
*
* @param pMonth {Number} starting with 0 as Janur
*
* @result {String} translated name
*/
DateUtils.getDateIncrementedByYears = function(pDate, pYears) {
var monthNames = [
translate.text("January"),
translate.text("February"),
translate.text("March"),
translate.text("April"),
translate.text("May"),
translate.text("June"),
translate.text("July"),
translate.text("August"),
translate.text("September"),
translate.text("October"),
translate.text("November"),
translate.text("December")
];
return
}
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment