Merge branch '1772-campaign_metrics' of verdnatura/salix into dev
gitea/salix/dev This commit looks good
Details
gitea/salix/dev This commit looks good
Details
This commit is contained in:
commit
3163dfa19e
|
@ -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%
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
// Import global filters
|
// Import global filters
|
||||||
require('./date');
|
require('./date');
|
||||||
|
require('./uppercase');
|
||||||
require('./currency');
|
require('./currency');
|
||||||
require('./percentage');
|
require('./percentage');
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
const Vue = require('vue');
|
||||||
|
|
||||||
|
Vue.filter('uppercase', function(value) {
|
||||||
|
return value.toUpperCase();
|
||||||
|
});
|
|
@ -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();
|
|
@ -0,0 +1,6 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"filename": "campaing-metrics",
|
||||||
|
"component": "campaign-metrics"
|
||||||
|
}
|
||||||
|
]
|
|
@ -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>
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -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.
|
|
@ -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();
|
|
@ -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;
|
||||||
|
}
|
|
@ -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>
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -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
|
Loading…
Reference in New Issue