#1903 informe consumo campaña

This commit is contained in:
Carlos Jimenez Ruiz 2019-11-27 16:00:42 +01:00
parent 74213ad880
commit 0c0ae14263
10 changed files with 230 additions and 1 deletions

View File

@ -4,7 +4,7 @@
*/ */
.grid { .grid {
font-family: Helvetica, Arial, sans-serif; font-family: Arial, sans-serif;
font-size: 16px !important; font-size: 16px !important;
width: 100% width: 100%
} }

View File

@ -2,5 +2,6 @@ const Vue = require('vue');
const strftime = require('strftime'); const strftime = require('strftime');
Vue.filter('date', function(value, specifiers) { Vue.filter('date', function(value, specifiers) {
console.log(value);
return strftime(specifiers, value); return strftime(specifiers, value);
}); });

View File

@ -1,4 +1,5 @@
// Import global filters // Import global filters
require('./date'); require('./date');
require('./uppercase');
require('./currency'); require('./currency');
require('./percentage'); require('./percentage');

View File

@ -0,0 +1,5 @@
const Vue = require('vue');
Vue.filter('uppercase', function(value) {
return value.toUpperCase();
});

View File

@ -1,2 +1,6 @@
[ [
{
"filename": "campaing-metrics",
"component": "campaign-metrics"
}
] ]

View File

@ -0,0 +1,9 @@
const Stylesheet = require(`${appPath}/core/stylesheet`);
module.exports = new Stylesheet([
`${appPath}/common/css/spacing.css`,
`${appPath}/common/css/misc.css`,
`${appPath}/common/css/layout.css`,
`${appPath}/common/css/report.css`,
`${__dirname}/style.css`])
.mergeStyles();

View File

@ -0,0 +1,11 @@
.column-oriented {
margin-top: 50px !important;
}
.bottom-line > tr {
border-bottom: 1px solid #ccc;
}
.bottom-line tr:nth-last-child() {
border-bottom: none;
}

View File

@ -0,0 +1,100 @@
<!DOCTYPE html>
<html v-bind:lang="locale">
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<report-header v-bind="$props"></report-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
<div class="columns">
<div class="size50">
<div class="size100">
<h1 class="title uppercase">{{$t('title')}}</h1>
<table class="row-oriented">
<tbody>
<tr>
<td class="font gray uppercase">{{$t('Client')}}</td>
<th>{{client.id}}</th>
</tr>
<tr>
<td class="font gray uppercase">{{$t('From')}}</td>
<th>{{from | date('%d-%m-%Y')}}</th>
</tr>
<tr>
<td class="font gray uppercase">{{$t('To')}}</td>
<th>{{to | date('%d-%m-%Y')}}</th>
</tr>
</tbody>
</table>
</div>
</div>
<div class="size50">
<div class="panel">
<div class="header">{{$t('clientData')}}</div>
<div class="body">
<h3 class="uppercase">{{client.socialName}}</h3>
<div>
{{client.street}}
</div>
<div>
{{client.postcode}}, {{client.city}} ({{client.province}})
</div>
<div>
{{client.country}}
</div>
</div>
</div>
</div>
</div>
<table class="column-oriented">
<thead>
<tr>
<th class="number">{{$t('Code')}}</th>
<th class="number">{{$t('Quantity')}}</th>
<th>{{$t('Concept')}}</th>
</tr>
</thead>
<tbody class="row-oriented bottom-line">
<tr v-for="sale in sales">
<td class="number">{{sale.itemFk}}</td>
<td class="number">{{Math.trunc(sale.subtotal)}}</td>
<td>
{{sale.concept}} <span class="font gray">{{sale.subName | uppercase}}</span>
<section>
<span class="font gray">{{sale.tag5}}</span>
<span>{{sale.value5}}</span>
<span class="font gray">{{sale.tag6}}</span>
<span>{{sale.value6}}</span>
<span class="font gray">{{sale.tag7}}</span>
<span>{{sale.value7}}</span>
</section>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<report-footer id="pageFooter"
v-bind:left-text="$t('client', [client.id])"
v-bind:center-text="client.socialName"
v-bind="$props">
</report-footer>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,85 @@
const Component = require(`${appPath}/core/component`);
const db = require(`${appPath}/core/database`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
module.exports = {
name: 'campaign-metrics',
async serverPrefetch() {
// // te delete once form inputs get date ranges
// this.from = new Date();
// this.from.setMonth(0);
// this.from.setDate(1);
// this.to = new Date();
// this.to.setMonth(11);
// this.to.setDate(31);
// this.clientId = 101;
// // end of delete
this.client = await this.fetchClient(this.clientId);
console.log(this.from, this.to);
this.sales = await this.fetchSales(this.clientId, this.from, this.to);
if (!this.client)
throw new Error('Something went wrong');
},
methods: {
fetchClient(clientId) {
return db.findOne(
`SELECT
c.street,
c.socialName,
c.city,
c.postcode,
c.id,
c.name AS clientName,
p.name AS province,
co.country
FROM client c
JOIN province p ON c.provinceFk = p.id
JOIN country co ON c.countryFk = co.id
WHERE
c.id = ?`, [clientId]);
},
fetchSales(clientId, from, to) {
return db.rawSql(
`SELECT
SUM(s.quantity) AS subtotal,
s.itemFk,
s.concept,
i.subName,
i.tag5,
i.value5,
i.tag6,
i.value6,
i.tag7,
i.value7
FROM sale s
JOIN ticket t ON t.id = s.ticketFk
JOIN item i ON i.id = s.itemFk
JOIN itemType it ON it.id = i.typeFk
WHERE
t.clientFk = ? AND it.isPackaging = FALSE
AND DATE(t.shipped) BETWEEN ? AND ?
GROUP BY s.itemFk
ORDER BY i.typeFk , i.name , i.size`, [clientId, from, to]);
},
},
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: {
clientId: {
required: true
},
from: {
required: true
},
to: {
required: true
}
}
};

View File

@ -0,0 +1,13 @@
title: Consumo de campaña
Client: Cliente
clientData: Datos del cliente
dated: Fecha
From: Desde
To: Hasta
concept: Concepto
client: Cliente {0}
Code: Código
Quantity: Cantidad
Stems: Tallos
Concept: Concepto
Tags: Etiquetas