Commit 2e2f2d5b authored by d.arizona's avatar d.arizona

update

parent 38b87002
......@@ -5915,6 +5915,31 @@
"safer-buffer": "^2.1.0"
}
},
"echarts": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.0.2.tgz",
"integrity": "sha512-En0VYpc96nw2/2AZoBWPHsGi471zMublttj50kfFpYAeR4geup0Tj9iVgEXh7QYZFPnRiruDJEjcB5PXZ+BYzQ==",
"requires": {
"tslib": "2.0.3",
"zrender": "5.0.4"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
},
"echarts-for-react": {
"version": "3.0.0-beta.2",
"resolved": "https://registry.npmjs.org/echarts-for-react/-/echarts-for-react-3.0.0-beta.2.tgz",
"integrity": "sha512-ZBd5KTOoL5HYAUMPLhSeX7U7ibvMj2Bj9THvboEwLbH1Ve5Fcxl/orkC+eFn/tPxcPJYC3+onP/Zw1SQ+AFEIg==",
"requires": {
"fast-deep-equal": "^3.1.3",
"size-sensor": "^1.0.0"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
......@@ -17197,6 +17222,11 @@
"resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz",
"integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="
},
"size-sensor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/size-sensor/-/size-sensor-1.0.1.tgz",
"integrity": "sha512-QTy7MnuugCFXIedXRpUSk9gUnyNiaxIdxGfUjr8xxXOqIB3QvBUYP9+b51oCg2C4dnhaeNk/h57TxjbvoJrJUA=="
},
"slash": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
......@@ -19732,6 +19762,21 @@
"camelcase": "^5.0.0",
"decamelize": "^1.2.0"
}
},
"zrender": {
"version": "5.0.4",
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.0.4.tgz",
"integrity": "sha512-DJpy0yrHYY5CuH6vhb9IINWbjvBUe/56J8aH86Jb7O8rRPAYZ3M2E469Qf5B3EOIfM3o3aUrO5edRQfLJ+l1Qw==",
"requires": {
"tslib": "2.0.3"
},
"dependencies": {
"tslib": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.0.3.tgz",
"integrity": "sha512-uZtkfKblCEQtZKBF6EBXVZeQNl82yqtDQdv+eck8u7tdPxjLu2/lp5/uPW+um2tpuxINHWy3GhiccY7QgEaVHQ=="
}
}
}
}
}
......@@ -22,6 +22,8 @@
"bootstrap": "^4.5.2",
"date-fns": "^2.15.0",
"dotenv": "^8.2.0",
"echarts": "^5.0.2",
"echarts-for-react": "^3.0.0-beta.2",
"font-awesome": "^4.7.0",
"install": "^0.13.0",
"moment": "^2.27.0",
......
......@@ -365,6 +365,14 @@ const create = (type = "") => {
const getListUserSubcoMB = (periode) => api.get(`transaction/get_dashboard_sub_co/master_budget/${periode}`)
const getListUserSubcoMR = (months,periode) => api.get(`transaction/get_dashboard_sub_co/monthly_report/${periode}/${months}`)
// Cronjob
const getHierarkiCronJobMBPL = () => api.get('/transaction/report/get_hierarki_master_budget/profit_loss')
const getHierarkiCronJobMBCF = () => api.get('/transaction/report/get_hierarki_master_budget/cash_flow')
const getHierarkiCronJobMBRatio = () => api.get('/transaction/report/get_hierarki_master_budget/ratio')
const getHierarkiCronJobMRPL = () => api.get('/transaction/report/get_hierarki_monthly_report/profit_loss')
const getHierarkiCronJobMRCF = () => api.get('/transaction/report/get_hierarki_monthly_report/cash_flow')
const getHierarkiCronJobMRRatio = () => api.get('/transaction/report/get_hierarki_monthly_report/ratio')
// MonthlyPL
// const getHierarkiMontlyReportPL = (body) => api.post('transaction/monthly_report_pl/get_report_hierarki', body)
// const createMonthlyReportPL = (body) => api.post('transaction/monthly_report_pl/create_monthly_report', body)
......@@ -663,7 +671,13 @@ const create = (type = "") => {
createReportFRMR,
getFullApproveMB,
getFullApproveMonthly,
getDashboardFinancial
getDashboardFinancial,
getHierarkiCronJobMBPL,
getHierarkiCronJobMBCF,
getHierarkiCronJobMBRatio,
getHierarkiCronJobMRPL,
getHierarkiCronJobMRCF,
getHierarkiCronJobMRRatio
}
}
......
......@@ -10,6 +10,7 @@ import api from '../../api';
import Constant from '../../library/Constant';
import { format } from 'date-fns';
import { PropagateLoader } from 'react-spinners';
import ReactECharts from 'echarts-for-react';
const Alert = withStyles({
})((props) => <MuiAlert elevation={6} variant="filled" {...props} />);
......@@ -57,56 +58,23 @@ export default class DashboardFinancial extends React.Component {
listMonth2: null,
month2: null,
loading: false,
tpat: null,
companyRev: [],
mbRev: [],
mrRev: [],
minRev: 0,
maxRev: 0,
companyTPAT: [],
mbTPAT: [],
mrTPAT: [],
minTPAT: 0,
maxTPAT: 0,
companyEBITDA: [],
mbEBITDA: [],
mrEBITDA: [],
minEBITDA: 0,
maxEBITDA: 0,
data: [
// {
// "country": "AD",
// "hot dog": 6,
// "hot dogColor": "hsl(228, 70%, 50%)",
// "burger": 53,
// "burgerColor": "hsl(29, 70%, 50%)"
// },
// {
// "country": "AE",
// "hot dog": 167,
// "hot dogColor": "hsl(340, 70%, 50%)",
// "burger": 133,
// "burgerColor": "hsl(160, 70%, 50%)"
// },
// {
// "country": "AF",
// "hot dog": 60,
// "hot dogColor": "hsl(188, 70%, 50%)",
// "burger": 120,
// "burgerColor": "hsl(252, 70%, 50%)"
// },
// {
// "country": "AG",
// "hot dog": 38000,
// "hot dogColor": "hsl(356, 70%, 50%)",
// "burger": 28700,
// "burgerColor": "hsl(161, 70%, 50%)"
// },
// {
// "country": "AI",
// "hot dog": 4000,
// "hot dogColor": "hsl(102, 70%, 50%)",
// "burger": 25000,
// "burgerColor": "hsl(308, 70%, 50%)"
// },
// {
// "country": "AL",
// "hot dog": 1000000,
// "hot dogColor": "hsl(288, 70%, 50%)",
// "burger": 50000,
// "burgerColor": "hsl(288, 70%, 50%)"
// },
// {
// "country": "AM",
// "hot dog": 35000,
// "hot dogColor": "hsl(239, 70%, 50%)",
// "burger": 150,
// "burgerColor": "hsl(306, 70%, 50%)"
// }
],
};
}
......@@ -299,6 +267,82 @@ export default class DashboardFinancial extends React.Component {
})
}
getOption() {
let option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
toolbox: {
feature: {
dataView: {show: true, readOnly: false},
magicType: {show: true, type: ['line', 'bar']},
restore: {show: true},
saveAsImage: {show: true}
}
},
legend: {
data: ['蒸发量', '降水量', '平均温度']
},
xAxis: [
{
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
name: '水量',
min: 0,
max: 250,
interval: 50,
axisLabel: {
formatter: '{value} ml'
}
},
{
type: 'value',
name: '温度',
min: 0,
max: 25,
interval: 5,
axisLabel: {
formatter: '{value} °C'
}
}
],
series: [
{
name: '蒸发量',
type: 'bar',
data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
},
{
name: '降水量',
type: 'bar',
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
},
{
name: '平均温度',
type: 'line',
yAxisIndex: 1,
data: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
}
]
};
return option
}
getDashboardFinancial() {
let payload = {
"report_type": this.state.report.value,
......@@ -341,42 +385,63 @@ export default class DashboardFinancial extends React.Component {
api.create().getDashboardFinancial(payload).then((res) => {
console.log(res)
if (res.data) {
this.setState({loading: false})
let response = res.data.data.ytd != null? res.data.data.ytd : (res.data.data.mtd != null? res.data.data.mtd : res.data.data.summary)
let revenue = []
let tpat = []
let ebitda = []
let totalAssets = []
response.revenue.nodes.map((item,index) => {
revenue.push({
"company": handleName(item.company),
"MB": item.value_mb,
"MBColor": "hsl(212, 64%, 46%)",
"MR": item.value_mr,
"MRColor": "hsl(212, 78%, 62%)",
})
let companyRev = []
let mbRev = []
let mrRev = []
let maxRev = response.revenue.vertical_pointing[0]
let minRev = response.revenue.vertical_pointing[1]
let companyTPAT = []
let mbTPAT = []
let mrTPAT = []
let maxTPAT = response.tpat.vertical_pointing[0]
let minTPAT = response.tpat.vertical_pointing[1]
let companyEBITDA = []
let mbEBITDA = []
let mrEBITDA = []
let maxEBITDA = response.ebitda.vertical_pointing[0]
let minEBITDA = response.ebitda.vertical_pointing[1]
response.revenue.nodes.map((item,index) => {
if (this.state.report.value == 'summary') {
companyRev.push(item.periode)
mbRev.push(item.value)
mrRev.push(item.gp_margin)
} else {
companyRev.push(handleName(item.company))
mbRev.push(item.value_mb)
mrRev.push(item.value_mr)
}
})
response.tpat.nodes.map((item,index) => {
tpat.push({
"company": handleName(item.company),
"MB": item.value_mb,
"MBColor": "hsl(212, 64%, 46%)",
"MR": item.value_mr,
"MRColor": "hsl(212, 78%, 62%)",
})
if (this.state.report.value == 'summary') {
companyTPAT.push(item.periode)
mbTPAT.push(item.value)
mrTPAT.push(item.gp_margin)
} else {
companyTPAT.push(handleName(item.company))
mbTPAT.push(item.value_mb)
mrTPAT.push(item.value_mr)
}
})
response.ebitda.nodes.map((item,index) => {
ebitda.push({
"company": handleName(item.company),
"MB": item.value_mb,
"MBColor": "hsl(212, 64%, 46%)",
"MR": item.value_mr,
"MRColor": "hsl(212, 78%, 62%)",
})
if (this.state.report.value == 'summary') {
companyEBITDA.push(item.periode)
mbEBITDA.push(item.value)
mrEBITDA.push(item.gp_margin)
} else {
companyEBITDA.push(handleName(item.company))
mbEBITDA.push(item.value_mb)
mrEBITDA.push(item.value_mr)
}
})
if (this.state.report.value == 'summary') {
......@@ -391,8 +456,10 @@ export default class DashboardFinancial extends React.Component {
})
})
}
console.log(revenue)
this.setState({revenue, ebitda, tpat, totalAssets})
this.setState({companyRev, mbRev, mrRev, minRev, maxRev, companyTPAT, mbTPAT, mrTPAT, minTPAT, maxTPAT, companyEBITDA, mbEBITDA, mrEBITDA, minEBITDA, maxEBITDA}, () => {
console.log(companyTPAT)
this.setState({loading: false})
})
}
})
}
......@@ -569,323 +636,357 @@ export default class DashboardFinancial extends React.Component {
<Typography style={{ fontSize: '16px', color: 'black' }}>in IDR mn</Typography>
</div>
<div style={{ height: Number(0.5 * this.props.height), border: '1px solid black', marginTop: 25, paddingBottom: 50}}>
<div style={{ height: Number(0.6 * this.props.height), border: '1px solid black', marginTop: 25, paddingBottom: 50}}>
{this.state.businessUnit != null && <Typography style={{ fontSize: '16px', color: 'black', textAlign: 'center', marginTop: 10, marginBottom: 10 }}>{`Revenue ${this.state.report.value == 'mtd' || this.state.report.value == 'ytd'? String(this.state.report.value).toLocaleUpperCase() : ''} - ${this.state.report.value == 'mtd' || this.state.report.value == 'ytd'? titleCase(this.state.businessUnit.business_unit_name) : this.state.company.company_name}`}</Typography>}
{!this.state.loading && <ResponsiveBar
data={this.state.revenue}
keys={['MB', 'MR']}
indexBy="company"
margin={{ top: 50, right: 50, bottom: 100, left: 75 }}
padding={0.3}
groupMode="grouped"
valueScale={{ type: 'linear' }}
indexScale={{ type: 'band', round: true }}
colors={['#2a70c0','#5399ea']}
// defs={[
// {
// id: 'dots',
// type: 'patternDots',
// background: 'inherit',
// color: '#5399ea',
// size: 4,
// padding: 1,
// stagger: true
// },
// {
// id: 'lines',
// type: 'patternLines',
// background: 'inherit',
// color: '#2a70c0',
// rotation: -45,
// lineWidth: 6,
// spacing: 10
// }
// ]}
// fill={[
// {
// match: {
// id: 'MB'
// },
// id: 'dots'
// },
// {
// match: {
// id: 'MR'
// },
// id: 'lines'
// }
// ]}
borderColor={{ from: 'color', modifiers: [['darker', 1.6]] }}
axisTop={null}
axisRight={null}
axisBottom={{
tickSize: 20,
tickPadding: 0,
tickRotation: 0,
legend: 'Company',
legendPosition: 'middle',
// legendOffset: 32,
// renderTick: CustomTick,
// lineStyle: { stroke: '#f47560', strokeWidth: 1 },
// textStyle: { fill: '#e25c3b' },
// legend: 'Company',
// legendPosition: 'middle',
// legendOrientation: 'vertical',
legendOffset: 50,
}}
axisLeft={{
tickSize: 5,
tickPadding: 5,
tickRotation: 0,
legend: '(Rp bn)',
legendPosition: 'middle',
legendOffset: -60
}}
// axisRight={{ format: v => `${v}%`, legend: '(%)', legendOffset: 52 }}
labelSkipWidth={12}
labelSkipHeight={12}
labelTextColor={{ from: 'color', modifiers: [['darker', 1.6]] }}
legends={[
{
dataFrom: 'keys',
anchor: 'bottom',
direction: 'row',
justify: false,
translateX: 30,
translateY: 85,
itemsSpacing: 7,
itemWidth: 109,
itemHeight: 10,
itemDirection: 'left-to-right',
itemOpacity: 0.85,
symbolSize: 25,
effects: [
{
on: 'hover',
style: {
itemOpacity: 1
}
{!this.state.loading && <ReactECharts
style={{height: 500, width: '100%', marginTop: 20}}
option={{
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
]
}
]}
animate={true}
motionStiffness={90}
motionDamping={15}
}
},
toolbox: {
feature: {
restore: {show: true},
saveAsImage: {show: true}
}
},
legend: {
data: ['Revenue', 'GP Margin']
},
xAxis: [
{
type: 'category',
data: this.state.companyRev,
axisPointer: {
type: 'shadow'
}
}
],
yAxis: this.state.report.value != 'summary'?
[
{
type: 'value',
name: '(Rp bn)',
min: this.state.minRev,
max: this.state.maxRev,
interval: 1000
}
] :
[
{
type: 'value',
name: '(Rp bn)',
min: this.state.minRev,
max: this.state.maxRev,
interval: 1000
},
{
type: 'value',
name: '(%)',
min: 0,
max: 100,
interval: 20,
axisLabel: {
formatter: '{value}%'
}
}
]
,
series: this.state.report.value != 'summary'?
[
{
name: 'MB',
type: 'bar',
data: this.state.mbRev
},
{
name: 'MR',
type: 'bar',
data: this.state.mrRev
}
] :
[
{
name: 'Revenue',
type: 'bar',
data: this.state.mbRev
},
{
name: 'GP Margin',
type: 'line',
yAxisIndex: 1,
data: this.state.mrRev
}
]
}}
/>}
</div>
<div style={{ height: Number(0.5 * this.props.height), border: '1px solid black', marginTop: 50, paddingBottom: 50}}>
<div style={{ height: Number(0.6 * this.props.height), border: '1px solid black', marginTop: 50, paddingBottom: 50}}>
{this.state.businessUnit != null && <Typography style={{ fontSize: '16px', color: 'black', textAlign: 'center', marginTop: 10, marginBottom: 10 }}>{`TPAT ${this.state.report.value == 'mtd' || this.state.report.value == 'ytd'? String(this.state.report.value).toLocaleUpperCase() : ''} - ${this.state.report.value == 'mtd' || this.state.report.value == 'ytd'? titleCase(this.state.businessUnit.business_unit_name) : this.state.company.company_name}`}</Typography>}
{!this.state.loading && <ResponsiveBar
data={this.state.tpat}
keys={['MB', 'MR']}
indexBy="company"
margin={{ top: 50, right: 50, bottom: 100, left: 75 }}
padding={0.3}
groupMode="grouped"
valueScale={{ type: 'linear' }}
indexScale={{ type: 'band', round: true }}
colors={['#2a70c0','#5399ea']}
// defs={[
// {
// id: 'dots',
// type: 'patternDots',
// background: 'inherit',
// color: '#5399ea',
// size: 4,
// padding: 1,
// stagger: true
// },
// {
// id: 'lines',
// type: 'patternLines',
// background: 'inherit',
// color: '#2a70c0',
// rotation: -45,
// lineWidth: 6,
// spacing: 10
// }
// ]}
// fill={[
// {
// match: {
// id: 'MB'
// },
// id: 'dots'
// },
// {
// match: {
// id: 'MR'
// },
// id: 'lines'
// }
// ]}
borderColor={{ from: 'color', modifiers: [['darker', 1.6]] }}
axisTop={null}
axisRight={null}
axisBottom={{
tickSize: 20,
tickPadding: 0,
tickRotation: 0,
legend: 'Company',
legendPosition: 'middle',
// legendOffset: 32,
// renderTick: CustomTick,
// lineStyle: { stroke: '#f47560', strokeWidth: 1 },
// textStyle: { fill: '#e25c3b' },
// legend: 'Company',
// legendPosition: 'middle',
// legendOrientation: 'vertical',
legendOffset: 50,
}}
// axisLeft={{
// tickSize: 5,
// tickPadding: 5,
// tickRotation: 0,
// legend: 'food',
// legendPosition: 'middle',
// legendOffset: -40
// }}
labelSkipWidth={12}
labelSkipHeight={12}
labelTextColor={{ from: 'color', modifiers: [['darker', 1.6]] }}
legends={[
{
dataFrom: 'keys',
anchor: 'bottom',
direction: 'row',
justify: false,
translateX: 30,
translateY: 85,
itemsSpacing: 7,
itemWidth: 109,
itemHeight: 10,
itemDirection: 'left-to-right',
itemOpacity: 0.85,
symbolSize: 25,
effects: [
{
on: 'hover',
style: {
itemOpacity: 1
}
{!this.state.loading && <ReactECharts
style={{height: 500, width: '100%', marginTop: 20}}
option={{
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
]
}
]}
animate={true}
motionStiffness={90}
motionDamping={15}
}
},
toolbox: {
feature: {
restore: {show: true},
saveAsImage: {show: true}
}
},
legend: {
data: ['TPAT', 'TPAT Margin']
},
xAxis: [
{
type: 'category',
data: this.state.companyTPAT,
axisPointer: {
type: 'shadow'
}
}
],
yAxis: this.state.report.value != 'summary'?
[
{
type: 'value',
name: '(Rp bn)',
min: this.state.minTPAT,
max: this.state.maxTPAT,
interval: 1000
}
] :
[
{
type: 'value',
name: '(Rp bn)',
min: this.state.minTPAT,
max: this.state.maxTPAT,
interval: 1000
},
{
type: 'value',
name: '(%)',
min: 0,
max: 100,
interval: 20,
axisLabel: {
formatter: '{value}%'
}
}
]
,
series: this.state.report.value != 'summary'?
[
{
name: 'MB',
type: 'bar',
data: this.state.mbTPAT
},
{
name: 'MR',
type: 'bar',
data: this.state.mrTPAT
}
] :
[
{
name: 'TPAT',
type: 'bar',
data: this.state.mbTPAT
},
{
name: 'TPAT Margin',
type: 'line',
yAxisIndex: 1,
data: this.state.mrTPAT
}
]
}}
/>}
{/* <ReactECharts
style={{height: 500, width: '100%'}}
option={{
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
}
},
toolbox: {
feature: {
dataView: {show: true, readOnly: false},
magicType: {show: true, type: ['line', 'bar']},
restore: {show: true},
saveAsImage: {show: true}
}
},
legend: {
data: ['蒸发量', '降水量', '平均温度']
},
xAxis: [
{
type: 'category',
data: ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],
axisPointer: {
type: 'shadow'
}
}
],
yAxis: [
{
type: 'value',
name: '水量',
min: 0,
max: 250,
interval: 50,
axisLabel: {
formatter: '{value} ml'
}
},
{
type: 'value',
name: '温度',
min: 0,
max: 25,
interval: 5,
axisLabel: {
formatter: '{value} °C'
}
}
],
series: [
{
name: '蒸发量',
type: 'bar',
data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3]
},
{
name: '降水量',
type: 'bar',
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3]
},
{
name: '平均温度',
type: 'line',
yAxisIndex: 1,
data: [2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2]
}
]
}}
/> */}
</div>
<div style={{ height: Number(0.5 * this.props.height), border: '1px solid black', marginTop: 50, paddingBottom: 50}}>
<div style={{ height: Number(0.6 * this.props.height), border: '1px solid black', marginTop: 50, paddingBottom: 50}}>
{this.state.businessUnit != null && <Typography style={{ fontSize: '16px', color: 'black', textAlign: 'center', marginTop: 10, marginBottom: 10 }}>{`EBITDA ${this.state.report.value == 'mtd' || this.state.report.value == 'ytd'? String(this.state.report.value).toLocaleUpperCase() : ''} - ${this.state.report.value == 'mtd' || this.state.report.value == 'ytd'? titleCase(this.state.businessUnit.business_unit_name) : this.state.company.company_name}`}</Typography>}
{!this.state.loading && <ResponsiveBar
data={this.state.ebitda}
keys={['MB', 'MR']}
indexBy="company"
margin={{ top: 50, right: 50, bottom: 100, left: 75 }}
padding={0.3}
groupMode="grouped"
valueScale={{ type: 'linear' }}
indexScale={{ type: 'band', round: true }}
colors={['#2a70c0','#5399ea']}
// defs={[
// {
// id: 'dots',
// type: 'patternDots',
// background: 'inherit',
// color: '#5399ea',
// size: 4,
// padding: 1,
// stagger: true
// },
// {
// id: 'lines',
// type: 'patternLines',
// background: 'inherit',
// color: '#2a70c0',
// rotation: -45,
// lineWidth: 6,
// spacing: 10
// }
// ]}
// fill={[
// {
// match: {
// id: 'MB'
// },
// id: 'dots'
// },
// {
// match: {
// id: 'MR'
// },
// id: 'lines'
// }
// ]}
borderColor={{ from: 'color', modifiers: [['darker', 1.6]] }}
axisTop={null}
axisRight={null}
axisBottom={{
tickSize: 20,
tickPadding: 0,
tickRotation: 0,
legend: 'Company',
legendPosition: 'middle',
// legendOffset: 32,
// renderTick: CustomTick,
// lineStyle: { stroke: '#f47560', strokeWidth: 1 },
// textStyle: { fill: '#e25c3b' },
// legend: 'Company',
// legendPosition: 'middle',
// legendOrientation: 'vertical',
legendOffset: 50,
}}
// axisLeft={{
// tickSize: 5,
// tickPadding: 5,
// tickRotation: 0,
// legend: 'food',
// legendPosition: 'middle',
// legendOffset: -40
// }}
labelSkipWidth={12}
labelSkipHeight={12}
labelTextColor={{ from: 'color', modifiers: [['darker', 1.6]] }}
legends={[
{
dataFrom: 'keys',
anchor: 'bottom',
direction: 'row',
justify: false,
translateX: 30,
translateY: 85,
itemsSpacing: 7,
itemWidth: 109,
itemHeight: 10,
itemDirection: 'left-to-right',
itemOpacity: 0.85,
symbolSize: 25,
effects: [
{
on: 'hover',
style: {
itemOpacity: 1
}
{!this.state.loading && <ReactECharts
style={{height: 500, width: '100%', marginTop: 20}}
option={{
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
crossStyle: {
color: '#999'
}
]
}
]}
animate={true}
motionStiffness={90}
motionDamping={15}
}
},
toolbox: {
feature: {
restore: {show: true},
saveAsImage: {show: true}
}
},
legend: {
data: ['EBITDA', 'EBITDA Margin']
},
xAxis: [
{
type: 'category',
data: this.state.companyEBITDA,
axisPointer: {
type: 'shadow'
}
}
],
yAxis: this.state.report.value != 'summary'?
[
{
type: 'value',
name: '(Rp bn)',
min: this.state.minEBITDA,
max: this.state.maxEBITDA,
interval: 1000
}
] :
[
{
type: 'value',
name: '(Rp bn)',
min: this.state.minEBITDA,
max: this.state.maxEBITDA,
interval: 1000
},
{
type: 'value',
name: '(%)',
min: 0,
max: 100,
interval: 20,
axisLabel: {
formatter: '{value}%'
}
}
]
,
series: this.state.report.value != 'summary'?
[
{
name: 'MB',
type: 'bar',
data: this.state.mbEBITDA
},
{
name: 'MR',
type: 'bar',
data: this.state.mrEBITDA
}
] :
[
{
name: 'EBITDA',
type: 'bar',
data: this.state.mbEBITDA
},
{
name: 'EBITDA Margin',
type: 'line',
yAxisIndex: 1,
data: this.state.mrEBITDA
}
]
}}
/>}
</div>
{this.state.report.value == 'summary' && <div style={{ height: Number(0.5 * this.props.height), border: '1px solid black', marginTop: 50, paddingBottom: 50}}>
{/* {this.state.report.value == 'summary' && <div style={{ height: Number(0.5 * this.props.height), border: '1px solid black', marginTop: 50, paddingBottom: 50}}>
<Typography style={{ fontSize: '16px', color: 'black', textAlign: 'center', marginTop: 10, marginBottom: 10 }}>{`Total Assets - ${this.state.company.company_name}`}</Typography>
<ResponsiveBar
data={this.state.totalAssets}
......@@ -988,7 +1089,7 @@ export default class DashboardFinancial extends React.Component {
motionStiffness={90}
motionDamping={15}
/>
</div>}
</div>} */}
</div>
</Paper>
</div>
......
import React, { Component } from 'react'
import api from '../api'
import * as R from 'ramda'
export default class ShadwoScreen extends Component {
constructor(props) {
super(props)
this.state = {
dataCompPL: [],
dataCompCF: [],
dataCompRatio: [],
dbPL: [],
dbCF: [],
dbFR: [],
PLID: null,
FRID: null
}
}
componentDidMount() {
if (this.props.match.params.type == 'mb' || this.props.match.params.type == 'mr') {
this.getHierarki(this.props.match.params.type)
}
}
getHierarki(){
if (this.props.match.params.type == 'mb') {
api.create().getHierarkiCronJobMBPL().then((res) => {
if (res.data) {
this.setState({dataCompPL: res.data.data.master_budget}, () => {
this.state.dataCompPL.map((item,index) => {
this.getPL(item)
})
})
}
})
api.create().getHierarkiCronJobMBCF().then((res) => {
if (res.data) {
this.setState({dataCompCF: res.data.data})
}
})
api.create().getHierarkiCronJobMBRatio().then((res) => {
if (res.data) {
this.setState({dataCompRatio: res.data.data})
}
})
} else {
api.create().getHierarkiCronJobMRPL().then((res) => {
if (res.data) {
this.setState({dataCompPL: res.data.data})
}
})
api.create().getHierarkiCronJobMRCF().then((res) => {
if (res.data) {
this.setState({dataCompCF: res.data.data})
}
})
api.create().getHierarkiCronJobMRRatio().then((res) => {
if (res.data) {
this.setState({dataCompRatio: res.data.data})
}
})
}
}
getPL(value) {
console.log(value)
let PLID = null
let payloadID = {
"periode": value.periode,
"company_id": value.company_id
}
// console.log(payloadID);
api.create().getPLID(payloadID).then(response => {
// console.log(response);
if (response) {
PLID = response.data.data == null ? null : response.data.data.profit_loss_id
} else {
PLID = null
}
// this.setState({ PLID }, () => {
let payload = {
"report_id": value.report_id,
"revision": value.revision,
"periode": value.periode,
"company_id": value.company_id,
"submission_id": PLID,
"months": 0,
"quarter": 0,
}
api.create().getHierarkiCreateReportPLMB(payload).then(response => {
// console.log(response);
let dataTable = []
if (response.data) {
// let dataTable = []
// console.log(response)
let res = response.data.data
const handlePushChild = (item) => {
dataTable.push([
item.type_report_id,
item.id,
item.parent,
item.formula,
item.level,
item.description,
item.profit_detail.total_actual_before === null ? "0" : item.profit_detail.total_actual_before === "" ? "0" : item.profit_detail.total_actual_before,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.january, formula: item.profit_detail.january_formula } : item.profit_detail.january,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.february, formula: item.profit_detail.february_formula } : item.profit_detail.february,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.march, formula: item.profit_detail.march_formula } : item.profit_detail.march,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.april, formula: item.profit_detail.april_formula } : item.profit_detail.april,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.may, formula: item.profit_detail.may_formula } : item.profit_detail.may,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.june, formula: item.profit_detail.june_formula } : item.profit_detail.june,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.july, formula: item.profit_detail.july_formula } : item.profit_detail.july,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.august, formula: item.profit_detail.august_formula } : item.profit_detail.august,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.september, formula: item.profit_detail.september_formula } : item.profit_detail.september,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.october, formula: item.profit_detail.october_formula } : item.profit_detail.october,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.november, formula: item.profit_detail.november_formula } : item.profit_detail.november,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.december, formula: item.profit_detail.december_formula } : item.profit_detail.december,
item.profit_detail.total_current_year,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? 0 : item.profit_detail.total_next_year,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? 0 : item.profit_detail.total_more_year,
item.order,
item.condition_it_should_be,
item.condition_if_wrong,
item.profit_detail.forecast_formula == null ? [] : item.profit_detail.forecast_formula,
item.profit_detail.notes
])
if (item.children !== null) {
if (item.children.length > 0) {
item.children.map((items, indexs) => {
handlePushChild(items)
})
}
}
}
res.map((item, index) => {
dataTable.push([
item.type_report_id,
item.id,
item.parent,
item.formula,
item.level,
item.description,
item.profit_detail.total_actual_before === null ? "0" : item.profit_detail.total_actual_before === "" ? "0" : item.profit_detail.total_actual_before,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.january, formula: item.profit_detail.january_formula } : item.profit_detail.january,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.february, formula: item.profit_detail.february_formula } : item.profit_detail.february,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.march, formula: item.profit_detail.march_formula } : item.profit_detail.march,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.april, formula: item.profit_detail.april_formula } : item.profit_detail.april,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.may, formula: item.profit_detail.may_formula } : item.profit_detail.may,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.june, formula: item.profit_detail.june_formula } : item.profit_detail.june,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.july, formula: item.profit_detail.july_formula } : item.profit_detail.july,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.august, formula: item.profit_detail.august_formula } : item.profit_detail.august,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.september, formula: item.profit_detail.september_formula } : item.profit_detail.september,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.october, formula: item.profit_detail.october_formula } : item.profit_detail.october,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.november, formula: item.profit_detail.november_formula } : item.profit_detail.november,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? { value: item.profit_detail.december, formula: item.profit_detail.december_formula } : item.profit_detail.december,
item.profit_detail.total_current_year,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? 0 : item.profit_detail.total_next_year,
item.type_report_id == 5 || item.type_report_id == 6 || item.type_report_id == 7 ? 0 : item.profit_detail.total_more_year,
item.order,
item.condition_it_should_be,
item.condition_if_wrong,
item.profit_detail.forecast_formula == null ? [] : item.profit_detail.forecast_formula,
item.profit_detail.notes
])
if (item.children !== null) {
if (item.children.length > 0) {
item.children.map((items, indexs) => {
handlePushChild(items)
})
}
}
})
// console.log(dataTable)
// this.setState({ dbPL: dataTable }, () => {
this.olahDataPL(dataTable, value, PLID)
// })
} else {
// this.setState({ dbPL: [] })
}
})
// })
})
}
handleValueFormulaDBPL = (valueItem, datatable, value, tableMeta, column, periode, forecast) => {
let splitFormula = String(tableMeta[3]).split(/([()@])/)
let baru = []
let anjay = []
let dataTable2 = datatable
// console.log(datatable)
splitFormula.map((item, index) => {
let items = String(item).substr(Number(String(item).length) - 1, 1)
let subForm = String(item).substr(0, Number(String(item).length) - 1)
let re = /^[a-zA-Z0-9_]+$/;
let asd = ''
if (item !== "") {
if (!re.test(items)) {
baru.push(subForm)
baru.push(items)
} else {
baru.push(String(item))
}
}
})
baru.map((item, index) => {
if (item == '-' || item == '+' || item == '/' || item == '*' || item == '(' || item == ')') {
anjay.push(item)
} else {
if (String(item).includes('#')) {
if (forecast !== undefined) {
let forecastt = 0
forecast.map((items, index) => {
if (items.periode == periode) {
forecastt += Number(items.value)
}
})
anjay.push(forecastt)
} else {
if (String(item).includes('[M-1]')) {
let tst = String(item).replace('[M-1]', '')
let data = column == 7 ? 18 : column - 1
let period = data == 18 ? Number(valueItem.periode) - 1 : valueItem.periode
let indexID = tableMeta.rowData[data].formula.findIndex((val) => val.item_formula == String(`@${tst}`) && val.periode == period)
if (indexID !== -1) {
let valuezz = tableMeta.rowData[data].formula[indexID].value
anjay.push(valuezz == "" ? 0 : valuezz)
}
} else {
let indexID = value.formula.findIndex((val) => val.item_formula == String(`@${item}`) && val.periode == Number(valueItem.periode))
if (indexID !== -1) {
let valuezz = value.formula[indexID].value
anjay.push(valuezz == "" ? 0 : valuezz)
}
}
}
} else {
let indexID = dataTable2.findIndex((val) => val[22] == item)
if (indexID !== -1) {
if (forecast != undefined) {
// console.log(dataTable2[indexID][column])
}
let valuezz = dataTable2[indexID][column].value == undefined ? dataTable2[indexID][column] : dataTable2[indexID][column].value
anjay.push(valuezz == "" ? 0 : valuezz)
} else {
if (item === '(-1)') {
anjay.push(-1)
}
}
}
}
})
let anjay2 = []
let kurung = false
let item1 = []
anjay.map((item, index) => {
if (item == "(") {
kurung = true
} else if (item == ")") {
kurung = false
anjay2.push(item1)
item1 = []
} else {
if (kurung) {
item1.push(item)
} else {
anjay2.push(item)
}
}
})
let total = 0
let opt = ""
let totalPrio = 0
let optPrio = ""
let prio = false
anjay2.map((item, index) => {
if (Array.isArray(item)) {
prio = true
item.map((items, indexs) => {
if (items == "+") {
optPrio = "tambah"
} else if (items == "-") {
optPrio = "kurang"
} else if (items == "*") {
optPrio = "kali"
} else if (items == "/") {
optPrio = "bagi"
} else {
if (optPrio == "tambah") {
totalPrio = Number(totalPrio) + Number(items)
} else if (optPrio == "kurang") {
totalPrio = Number(totalPrio) - Number(items)
} else if (optPrio == "kali") {
totalPrio = Number(totalPrio) * Number(items)
} else if (optPrio == "bagi") {
totalPrio = Number(totalPrio) / Number(items) == NaN ? 0 : Number(totalPrio) / Number(items)
} else {
totalPrio += Number(items)
}
}
})
if (index == anjay2.length - 1) {
if (opt == "tambah") {
total = Number(total) + Number(totalPrio)
} else if (opt == "kurang") {
total = Number(total) - Number(totalPrio)
} else if (opt == "kali") {
total = Number(total) * Number(totalPrio)
} else if (opt == "bagi") {
total = Number(total) / Number(totalPrio) == NaN ? 0 : Number(total) / Number(totalPrio)
} else {
total += Number(totalPrio)
}
}
} else {
if (item == "+") {
opt = "tambah"
if (prio) {
total = Number(Number(totalPrio) + Number(total))
prio = false
totalPrio = 0
optPrio = ""
}
} else if (item == "-") {
opt = "kurang"
if (prio) {
total = Number(Number(totalPrio) + Number(total))
prio = false
totalPrio = 0
optPrio = ""
}
} else if (item == "*") {
opt = "kali"
if (prio) {
total = Number(Number(totalPrio) + Number(total))
prio = false
totalPrio = 0
optPrio = ""
}
} else if (item == "/") {
opt = "bagi"
if (prio) {
total = Number(Number(totalPrio) + Number(total))
prio = false
totalPrio = 0
optPrio = ""
}
} else {
if (opt == "tambah") {
total = Number(total) + Number(item)
} else if (opt == "kurang") {
total = Number(total) - Number(item)
} else if (opt == "kali") {
total = Number(total) * Number(item)
} else if (opt == "bagi") {
total = Number(total) / Number(item) == NaN ? 0 : Number(total) / Number(item)
} else {
total += Number(item)
}
}
}
})
total = R.equals(total, NaN) ? "0.0" : total
return total
}
handleForecastDBPL = (value, datatable, index, tableMeta, periode, column) => {
let total = 0
let dataTable2 = datatable
if (tableMeta[3].includes('#PL')) {
dataTable2[index][25].map((item, index) => {
if (item.periode == periode) {
total += Number(item.value)
}
})
} else {
total = this.handleValueFormulaDBPL(value, dataTable2, tableMeta, column, periode, dataTable2[index][25])
}
return total
}
olahDataPL(dbPL, value, PLID) {
console.log('masuk')
dbPL.map((item,index) => {
if(item[0] == 5 || item[0] == 6 || item[0] == 7) {
item[7].value = this.handleValueFormulaDBPL(value,dbPL,item[7],item,7)
item[8].value = this.handleValueFormulaDBPL(value,dbPL,item[8],item,8)
item[9].value = this.handleValueFormulaDBPL(value,dbPL,item[9],item,9)
item[10].value = this.handleValueFormulaDBPL(value,dbPL,item[10],item,10)
item[12].value = this.handleValueFormulaDBPL(value,dbPL,item[12],item,12)
item[13].value = this.handleValueFormulaDBPL(value,dbPL,item[13],item,13)
item[14].value = this.handleValueFormulaDBPL(value,dbPL,item[14],item,14)
item[11].value = this.handleValueFormulaDBPL(value,dbPL,item[11],item,11)
item[15].value = this.handleValueFormulaDBPL(value,dbPL,item[15],item,15)
item[16].value = this.handleValueFormulaDBPL(value,dbPL,item[16],item,16)
item[17].value = this.handleValueFormulaDBPL(value,dbPL,item[17],item,17)
item[18].value = this.handleValueFormulaDBPL(value,dbPL,item[18],item,18)
item[20] = this.handleForecastDBPL(value, dbPL, index, item, `${Number(value.periode) + 1}`, 20)
item[21] = this.handleForecastDBPL(value, dbPL, index, item, `${Number(value.periode) + 2}`, 21)
}
})
// this.setState({dbPL}, () => {
this.payloadPL(dbPL, value, PLID)
// })
}
payloadPL(dbPL, value, PLID) {
let listPL = []
// console.log(dbPL)
dbPL.map((item,index) => {
if (item[0] == 5 || item[0] == 6 || item[0] == 7) {
item[7].value = this.handleValueFormulaDBPL(value,dbPL,item[7],item,7)
item[8].value = this.handleValueFormulaDBPL(value,dbPL,item[8],item,8)
item[9].value = this.handleValueFormulaDBPL(value,dbPL,item[9],item,9)
item[10].value = this.handleValueFormulaDBPL(value,dbPL,item[10],item,10)
item[11].value = this.handleValueFormulaDBPL(value,dbPL,item[11],item,11)
item[12].value = this.handleValueFormulaDBPL(value,dbPL,item[12],item,12)
item[13].value = this.handleValueFormulaDBPL(value,dbPL,item[13],item,13)
item[14].value = this.handleValueFormulaDBPL(value,dbPL,item[14],item,14)
item[15].value = this.handleValueFormulaDBPL(value,dbPL,item[15],item,15)
item[16].value = this.handleValueFormulaDBPL(value,dbPL,item[16],item,16)
item[17].value = this.handleValueFormulaDBPL(value,dbPL,item[17],item,17)
item[18].value = this.handleValueFormulaDBPL(value,dbPL,item[18],item,18)
item[20] = this.handleForecastDBPL(value, dbPL, index, item, `${Number(value.periode) + 1}`, 20)
item[21] = this.handleForecastDBPL(value, dbPL, index, item, `${Number(value.periode) + 2}`, 21)
}
listPL.push(
{
"item_report_id": item[1],
"january": String(item[7].value == undefined? item[7] : Number(item[7].value).toFixed(1)),
"february": String(item[8].value == undefined? item[8] : Number(item[8].value).toFixed(1)),
"march": String(item[9].value == undefined? item[9] : Number(item[9].value).toFixed(1)),
"april": String(item[10].value == undefined? item[10] : Number(item[10].value).toFixed(1)),
"may": String(item[11].value == undefined? item[11] : Number(item[11].value).toFixed(1)),
"june": String(item[12].value == undefined? item[12] : Number(item[12].value).toFixed(1)),
"july": String(item[13].value == undefined? item[13] : Number(item[13].value).toFixed(1)),
"august": String(item[14].value == undefined? item[14] : Number(item[14].value).toFixed(1)),
"september": String(item[15].value == undefined? item[15] : Number(item[15].value).toFixed(1)),
"october": String(item[16].value == undefined? item[16] : Number(item[16].value).toFixed(1)),
"november": String(item[17].value == undefined? item[17] : Number(item[17].value).toFixed(1)),
"december": String(item[18].value == undefined? item[18] : Number(item[18].value).toFixed(1)),
"total_current_year": String(item[19]),
"total_next_year": String(item[20] != ''? Number(item[20]).toFixed(1) : item[20]),
"total_more_year": String(item[21] != ''? Number(item[21]).toFixed(1) : item[21]),
"notes": String(item[26]),
}
)
})
// this.setState({dbPL: listPL} , () => {
this.createDBPL(value, listPL, PLID)
// })
}
createDBPL(value, listPL, PLID) {
// console.log('masuk', value)
let payload = {
"company_id": value.company_id,
"periode": value.periode,
"report_id": value.report_id,
"status": "submitted",
"profit_loss_id": PLID,
"profit_loss_mb": listPL,
"months": 0,
}
// console.log(JSON.stringify(payload))
api.create().createReportPLMB(payload).then((res) => {
// console.log(res)
})
}
render() {
return (
<div></div>
)
}
}
\ No newline at end of file
......@@ -16,6 +16,7 @@ import ResetPassword from '../container/ResetPassword'
import SetPassword from '../container/SetPassword'
import EmailVerification from "../container/EmailVerification";
import Constant from "../library/Constant";
import ShadowScreen from "../container/ShadowScreen";
// This site has 3 pages, all of which are rendered
// dynamically in the browser (not server rendered).
//
......@@ -46,6 +47,7 @@ export default function BasicExample() {
<Route path="/set-password/:id" component={SetPassword} />
<Route path="/email-verification" component={EmailVerification} />
<Route path="/register" component={Register}/>
<Route path="/cronjob/:type" component={ShadowScreen}/>
<PrivateRoute path="/home">
<Home/>
</PrivateRoute>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment