Merge branch '1772-campaign_metrics' of verdnatura/salix into dev
gitea/salix/dev This commit looks good Details

This commit is contained in:
Carlos Jimenez Ruiz 2019-11-28 07:42:16 +00:00 committed by Gitea
commit 3163dfa19e
13 changed files with 306 additions and 1 deletions

View File

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

View File

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

View File

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

View File

@ -0,0 +1,8 @@
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/email.css`])
.mergeStyles();

View File

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

View File

@ -0,0 +1,46 @@
<!DOCTYPE html>
<html v-bind:lang="locale">
<head>
<meta name="viewport" content="width=device-width">
<meta name="format-detection" content="telephone=no">
<title>{{ $t('subject') }}</title>
</head>
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
<!-- Header block -->
<div class="grid-row">
<div class="grid-block">
<email-header v-bind="$props"></email-header>
</div>
</div>
<!-- Block -->
<div class="grid-row">
<div class="grid-block vn-pa-lg">
<h1>{{ $t('title') }}</h1>
<p>{{$t('dear')}},</p>
<p>{{$t('description')}}</p>
</div>
</div>
<!-- Footer block -->
<div class="grid-row">
<div class="grid-block">
<email-footer v-bind="$props"></email-footer>
</div>
</div>
<!-- Empty block -->
<div class="grid-row">
<div class="grid-block empty"></div>
</div>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,23 @@
const Component = require(`${appPath}/core/component`);
const emailHeader = new Component('email-header');
const emailFooter = new Component('email-footer');
module.exports = {
name: 'campaign-metrics',
components: {
'email-header': emailHeader.build(),
'email-footer': emailFooter.build()
},
props: {
clientId: {
required: true
},
from: {
required: true
},
to: {
required: true
}
}
};

View File

@ -0,0 +1,7 @@
subject: Informe consumo campaña
title: Informe consumo campaña
dear: Estimado cliente
description: Con motivo de esta próxima campaña, me complace
relacionarle a continuación el consumo que nos consta en su cuenta para las
mismas fechas del año pasado. Espero le sea de utilidad para preparar su pedido.
Al mismo tiempo aprovecho la ocasión para saludarle cordialmente.

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">
<h1 class="title uppercase">{{$t('title')}}</h1>
<div class="size75">
<table class="row-oriented">
<tbody>
<tr>
<td class="font gray">{{$t('Client')}}</td>
<th>{{client.id}}</th>
</tr>
<tr>
<td class="font gray">{{$t('From')}}</td>
<th>{{from | date('%d-%m-%Y')}}</th>
</tr>
<tr>
<td class="font gray">{{$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,78 @@
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() {
this.to = new Date(this.to);
this.from = new Date(this.from);
this.client = await this.fetchClient(this.clientId);
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,
type: Date
},
to: {
required: true,
type: Date
}
}
};

View File

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