Merge branch 'dev' into #288-traducir-state-i18n
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
a34c006dc9
|
@ -0,0 +1,12 @@
|
||||||
|
CREATE TABLE `vn`.`invoiceInConfig` (
|
||||||
|
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||||
|
`retentionRate` int(3) NOT NULL,
|
||||||
|
`retentionName` varchar(25) NOT NULL,
|
||||||
|
`sageWithholdingFk` smallint(6) NOT NULL,
|
||||||
|
PRIMARY KEY (`id`),
|
||||||
|
CONSTRAINT `invoiceInConfig_sageWithholdingFk` FOREIGN KEY (`sageWithholdingFk`) REFERENCES `sage`.`TiposRetencion`(`CodigoRetencion`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||||
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3 COLLATE=utf8mb3_unicode_ci;
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`invoiceInConfig` (`id`, `retentionRate`, `retentionName`, `sageWithholdingFk`)
|
||||||
|
VALUES
|
||||||
|
(1, -2, 'Retención 2%', 2);
|
|
@ -2,7 +2,7 @@
|
||||||
"InvoiceIn": {
|
"InvoiceIn": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"InvoiceInTax": {
|
"InvoiceInConfig": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
"InvoiceInDueDay": {
|
"InvoiceInDueDay": {
|
||||||
|
@ -13,5 +13,8 @@
|
||||||
},
|
},
|
||||||
"InvoiceInLog": {
|
"InvoiceInLog": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
|
"InvoiceInTax": {
|
||||||
|
"dataSource": "vn"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
{
|
||||||
|
"name": "InvoiceInConfig",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "invoiceInConfig"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"id": true,
|
||||||
|
"type": "number",
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"retentionRate": {
|
||||||
|
"type": "number"
|
||||||
|
},
|
||||||
|
"retentionName": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"sageWithholding": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "SageWithholding",
|
||||||
|
"foreignKey": "sageWithholdingFk"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [{
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}]
|
||||||
|
}
|
|
@ -1,3 +1,10 @@
|
||||||
|
<vn-crud-model
|
||||||
|
url="InvoiceInConfigs"
|
||||||
|
data="$ctrl.config"
|
||||||
|
filter="{fields: ['sageWithholdingFk']}"
|
||||||
|
id-value="1"
|
||||||
|
auto-load="true">
|
||||||
|
</vn-crud-model>
|
||||||
<vn-descriptor-content
|
<vn-descriptor-content
|
||||||
module="invoiceIn"
|
module="invoiceIn"
|
||||||
description="$ctrl.invoiceIn.supplierRef"
|
description="$ctrl.invoiceIn.supplierRef"
|
||||||
|
@ -26,13 +33,13 @@
|
||||||
Clone Invoice
|
Clone Invoice
|
||||||
</vn-item>
|
</vn-item>
|
||||||
<vn-item
|
<vn-item
|
||||||
ng-if="false"
|
ng-if="$ctrl.isAgricultural()"
|
||||||
ng-click="$ctrl.showPdfInvoice()"
|
ng-click="$ctrl.showPdfInvoice()"
|
||||||
translate>
|
translate>
|
||||||
Show agricultural invoice as PDF
|
Show agricultural invoice as PDF
|
||||||
</vn-item>
|
</vn-item>
|
||||||
<vn-item
|
<vn-item
|
||||||
ng-if="false"
|
ng-if="$ctrl.isAgricultural()"
|
||||||
ng-click="sendPdfConfirmation.show({email: $ctrl.entity.supplierContact[0].email})"
|
ng-click="sendPdfConfirmation.show({email: $ctrl.entity.supplierContact[0].email})"
|
||||||
translate>
|
translate>
|
||||||
Send agricultural invoice as PDF
|
Send agricultural invoice as PDF
|
||||||
|
|
|
@ -110,6 +110,10 @@ class Controller extends Descriptor {
|
||||||
recipientId: this.entity.supplier.id
|
recipientId: this.entity.supplier.id
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isAgricultural() {
|
||||||
|
return this.invoiceIn.supplier.sageWithholdingFk == this.config[0].sageWithholdingFk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnInvoiceInDescriptor', {
|
ngModule.vnComponent('vnInvoiceInDescriptor', {
|
||||||
|
|
|
@ -13,6 +13,7 @@ describe('InvoiceOut downloadZip()', () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
it('should return part of link to dowloand the zip', async() => {
|
it('should return part of link to dowloand the zip', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4875');
|
||||||
const tx = await models.InvoiceOut.beginTransaction({});
|
const tx = await models.InvoiceOut.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -256,7 +256,7 @@ class Controller extends Section {
|
||||||
this.$http.post(`NotificationQueues`, {
|
this.$http.post(`NotificationQueues`, {
|
||||||
notificationFk: 'invoiceElectronic',
|
notificationFk: 'invoiceElectronic',
|
||||||
authorFk: client.id,
|
authorFk: client.id,
|
||||||
}).then(a => {
|
}).then(() => {
|
||||||
this.vnApp.showSuccess(this.$t('Invoice sent'));
|
this.vnApp.showSuccess(this.$t('Invoice sent'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="font gray uppercase">{{$t('ref')}}</td>
|
<td class="font gray uppercase">{{$t('ref')}}</td>
|
||||||
<th>{{entry.ref}}</th>
|
<th>{{entry.invoiceNumber}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
SELECT
|
SELECT
|
||||||
e.id,
|
e.id,
|
||||||
e.ref,
|
e.invoiceNumber,
|
||||||
e.notes,
|
e.notes,
|
||||||
c.code companyCode,
|
c.code companyCode,
|
||||||
t.landed
|
t.landed
|
||||||
|
|
|
@ -49,7 +49,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="entry in travel.entries">
|
<tr v-for="entry in travel.entries">
|
||||||
<td>{{entry.supplierName}}</td>
|
<td>{{entry.supplierName}}</td>
|
||||||
<td>{{entry.ref}}</td>
|
<td>{{entry.reference}}</td>
|
||||||
<td class="number">{{entry.volumeKg | number($i18n.locale)}}</td>
|
<td class="number">{{entry.volumeKg | number($i18n.locale)}}</td>
|
||||||
<td class="number">{{entry.loadedKg | number($i18n.locale)}}</td>
|
<td class="number">{{entry.loadedKg | number($i18n.locale)}}</td>
|
||||||
<td class="number">{{entry.stickers}}</td>
|
<td class="number">{{entry.stickers}}</td>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
SELECT
|
SELECT
|
||||||
e.id,
|
e.id,
|
||||||
e.travelFk,
|
e.travelFk,
|
||||||
e.ref,
|
e.reference,
|
||||||
s.name AS supplierName,
|
s.name AS supplierName,
|
||||||
SUM(b.stickers) AS stickers,
|
SUM(b.stickers) AS stickers,
|
||||||
CAST(SUM(b.weight * b.stickers) as DECIMAL(10,0)) as loadedKg,
|
CAST(SUM(b.weight * b.stickers) as DECIMAL(10,0)) as loadedKg,
|
||||||
|
|
|
@ -5,9 +5,8 @@
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
<div class="grid-block">
|
<div class="grid-block">
|
||||||
<div class="columns vn-mb-lg">
|
<div class="columns vn-mb-lg">
|
||||||
<div class="size50">
|
<div class="size75">
|
||||||
<div class="size75 vn-mt-ml">
|
<div class="size100 vn-mt-ml">
|
||||||
<h1 class="title uppercase">{{$t('title')}}</h1>
|
|
||||||
<table class="row-oriented ticket-info">
|
<table class="row-oriented ticket-info">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -16,7 +15,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="font gray uppercase">{{$t('invoiceId')}}</td>
|
<td class="font gray uppercase">{{$t('invoiceId')}}</td>
|
||||||
<th>{{invoice.id}}</th>
|
<th>{{invoice.supplierRef}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td class="font gray uppercase">{{$t('date')}}</td>
|
<td class="font gray uppercase">{{$t('date')}}</td>
|
||||||
|
@ -26,7 +25,7 @@
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="size50">
|
<div class="size25">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<div class="header">{{$t('invoiceData')}}</div>
|
<div class="header">{{$t('invoiceData')}}</div>
|
||||||
<div class="body">
|
<div class="body">
|
||||||
|
@ -43,7 +42,7 @@
|
||||||
<div class="vn-mt-lg" v-for="entry in entries">
|
<div class="vn-mt-lg" v-for="entry in entries">
|
||||||
<div class="table-title clearfix">
|
<div class="table-title clearfix">
|
||||||
<div class="pull-left">
|
<div class="pull-left">
|
||||||
<h2>{{$t('invoiceId')}}</h2>
|
<h2>{{$t('entry')}}</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-left vn-mr-md">
|
<div class="pull-left vn-mr-md">
|
||||||
<div class="field rectangle">
|
<div class="field rectangle">
|
||||||
|
@ -64,7 +63,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="pull-left">
|
<div class="pull-left">
|
||||||
<div class="field rectangle">
|
<div class="field rectangle">
|
||||||
<span>{{entry.ref}}</span>
|
<span>{{entry.reference}}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</span>
|
</span>
|
||||||
|
@ -82,7 +81,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td width="50%">{{buy.name}}</td>
|
<td width="50%">{{buy.name}}</td>
|
||||||
<td class="number">{{buy.quantity}}</td>
|
<td class="number">{{buy.quantity}}</td>
|
||||||
<td class="number">{{buy.buyingValue}}</td>
|
<td class="number">{{buy.buyingValue | currency('EUR', $i18n.locale)}}</td>
|
||||||
<td class="number">{{buyImport(buy) | currency('EUR', $i18n.locale)}}</td>
|
<td class="number">{{buyImport(buy) | currency('EUR', $i18n.locale)}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="description font light-gray">
|
<tr class="description font light-gray">
|
||||||
|
@ -103,27 +102,31 @@
|
||||||
</tfoot>
|
</tfoot>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="columns vn-mt-xl">
|
<div class="columns vn-mt-xl">
|
||||||
<div id="taxes" class="size50 pull-right no-page-break" v-if="taxes">
|
<div id="signature" class="size50 pull-left no-page-break vn-pr-xs">
|
||||||
|
<div class="panel">
|
||||||
|
<div class="header">{{$t('payMethod')}}: {{invoice.payMethod}}</div>
|
||||||
|
<div class="body">
|
||||||
|
<div class="vn-mt-md">{{$t('signer.received')}}:</div>
|
||||||
|
<div class="vn-my-md">{{$t('signer.signed')}}:</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="taxes" class="size50 pull-right no-page-break vn-pl-xs vn-mt-md" v-if="taxes">
|
||||||
<table class="column-oriented">
|
<table class="column-oriented">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="4">{{$t('taxBreakdown')}}</th>
|
<th colspan="4">{{$t('taxBreakdown')}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<thead class="light">
|
|
||||||
<tr>
|
|
||||||
<th width="45%">{{$t('type')}}</th>
|
|
||||||
<th width="25%" class="number">{{$t('taxBase')}}</th>
|
|
||||||
<th>{{$t('tax')}}</th>
|
|
||||||
<th class="number">{{$t('fee')}}</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr v-for="tax in taxes">
|
<tr v-for="tax in taxes">
|
||||||
<td width="45%">{{tax.name}}</td>
|
<td width="45%">{{tax.name}}</td>
|
||||||
<td width="25%" class="number">{{tax.taxableBase | currency('EUR', $i18n.locale)}}</td>
|
<td width="25%" class="number">{{tax.taxableBase | currency('EUR', $i18n.locale)}}
|
||||||
<td>{{tax.rate | percentage}}</td>
|
</td>
|
||||||
|
<td>{{(tax.rate / 100) | percentage}}</td>
|
||||||
<td class="number">{{tax.vat | currency('EUR', $i18n.locale)}}</td>
|
<td class="number">{{tax.vat | currency('EUR', $i18n.locale)}}</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -150,28 +153,16 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="columns vn-mt-xl">
|
</div>
|
||||||
<div class="size50 pull-left no-page-break">
|
|
||||||
<div class="panel">
|
<div id="footer" class="vn-mt-xl">
|
||||||
<div class="header">{{$t('observations')}}</div>
|
<h2 class="centered bold">{{$t('footer')}}</h2>
|
||||||
<div class="body">
|
|
||||||
<div>{{$t('payMethod')}}</div>
|
|
||||||
<div>{{invoice.payMethod}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-slot:footer>
|
<template v-slot:footer>
|
||||||
<report-footer
|
<report-footer id="pageFooter" v-bind:company-code="invoice.companyCode" v-bind:left-text="$t('invoiceId')"
|
||||||
id="pageFooter"
|
v-bind:center-text="invoice.name" v-bind="$props">
|
||||||
v-bind:company-code="invoice.companyCode"
|
|
||||||
v-bind:left-text="$t('invoiceId')"
|
|
||||||
v-bind:center-text="invoice.name"
|
|
||||||
v-bind="$props"
|
|
||||||
>
|
|
||||||
</report-footer>
|
</report-footer>
|
||||||
</template>
|
</template>
|
||||||
</report-body>
|
</report-body>
|
||||||
|
|
|
@ -9,6 +9,16 @@ module.exports = {
|
||||||
this.invoice = await this.fetchInvoice(this.id);
|
this.invoice = await this.fetchInvoice(this.id);
|
||||||
this.taxes = await this.fetchTaxes(this.id);
|
this.taxes = await this.fetchTaxes(this.id);
|
||||||
|
|
||||||
|
let defaultTax = await this.fetchDefaultTax();
|
||||||
|
|
||||||
|
if (defaultTax) {
|
||||||
|
defaultTax = Object.assign(defaultTax, {
|
||||||
|
taxableBase: 0,
|
||||||
|
vat: (this.taxTotal() * defaultTax.rate / 100)
|
||||||
|
});
|
||||||
|
this.taxes.push(defaultTax);
|
||||||
|
}
|
||||||
|
|
||||||
if (!this.invoice)
|
if (!this.invoice)
|
||||||
throw new Error('Something went wrong');
|
throw new Error('Something went wrong');
|
||||||
|
|
||||||
|
@ -43,6 +53,9 @@ module.exports = {
|
||||||
fetchBuy(id) {
|
fetchBuy(id) {
|
||||||
return this.rawSqlFromDef('buy', [id]);
|
return this.rawSqlFromDef('buy', [id]);
|
||||||
},
|
},
|
||||||
|
fetchDefaultTax() {
|
||||||
|
return this.findOneFromDef('defaultTax');
|
||||||
|
},
|
||||||
async fetchTaxes(id) {
|
async fetchTaxes(id) {
|
||||||
const taxes = await this.rawSqlFromDef(`taxes`, [id]);
|
const taxes = await this.rawSqlFromDef(`taxes`, [id]);
|
||||||
return this.taxVat(taxes);
|
return this.taxVat(taxes);
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
reportName: invoice
|
reportName: agricultural receip
|
||||||
title: Agricultural invoice
|
title: Agricultural receip
|
||||||
invoiceId: Agricultural invoice
|
invoiceId: Agricultural receip
|
||||||
supplierId: Proveedor
|
supplierId: Proveedor
|
||||||
invoiceData: Invoice data
|
invoiceData: Invoice data
|
||||||
reference: Reference
|
reference: Reference
|
||||||
|
@ -23,3 +23,8 @@ subtotal: Subtotal
|
||||||
taxBreakdown: Tax breakdown
|
taxBreakdown: Tax breakdown
|
||||||
observations: Observations
|
observations: Observations
|
||||||
payMethod: Pay method
|
payMethod: Pay method
|
||||||
|
entry: Entry
|
||||||
|
signer:
|
||||||
|
received: Received
|
||||||
|
signed: Signature
|
||||||
|
footer: Passive subject covered by the special agrarian regime. Please send this duly signed and sealed copy. Thanks.
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
reportName: factura
|
reportName: recibo agrícola
|
||||||
title: Factura Agrícola
|
title: Recibo Agrícola
|
||||||
invoiceId: Factura Agrícola
|
invoiceId: Recibo Agrícola
|
||||||
supplierId: Proveedor
|
supplierId: Proveedor
|
||||||
invoiceData: Datos de facturación
|
invoiceData: Datos de facturación
|
||||||
reference: Referencia
|
reference: Referencia
|
||||||
|
@ -23,3 +23,8 @@ subtotal: Subtotal
|
||||||
taxBreakdown: Desglose impositivo
|
taxBreakdown: Desglose impositivo
|
||||||
observations: Observaciones
|
observations: Observaciones
|
||||||
payMethod: Método de pago
|
payMethod: Método de pago
|
||||||
|
entry: Entrada
|
||||||
|
signer:
|
||||||
|
received: Recibí
|
||||||
|
signed: Firma y sello
|
||||||
|
footer: Sujeto pasivo acogido al régimen especial agrario. Les rogamos remitan esta copia debidamente firmada y sellada. Gracias.
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
retentionRate rate,
|
||||||
|
retentionName name
|
||||||
|
FROM invoiceInConfig;
|
|
@ -1,7 +1,7 @@
|
||||||
SELECT
|
SELECT
|
||||||
e.id,
|
e.id,
|
||||||
t.landed,
|
t.landed,
|
||||||
e.ref
|
e.reference
|
||||||
FROM entry e
|
FROM entry e
|
||||||
JOIN invoiceIn i ON i.id = e.invoiceInFk
|
JOIN invoiceIn i ON i.id = e.invoiceInFk
|
||||||
JOIN travel t ON t.id = e.travelFk
|
JOIN travel t ON t.id = e.travelFk
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
SELECT
|
SELECT
|
||||||
i.id,
|
i.supplierRef,
|
||||||
s.id supplierId,
|
s.id supplierId,
|
||||||
i.created,
|
i.created,
|
||||||
s.name,
|
s.name,
|
||||||
|
|
|
@ -5,4 +5,5 @@ SELECT
|
||||||
FROM invoiceIn ii
|
FROM invoiceIn ii
|
||||||
JOIN invoiceInTax iit ON ii.id = iit.invoiceInFk
|
JOIN invoiceInTax iit ON ii.id = iit.invoiceInFk
|
||||||
JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
|
JOIN sage.TiposIva ti ON ti.CodigoIva = iit.taxTypeSageFk
|
||||||
WHERE ii.id = ?;
|
WHERE ii.id = ?
|
||||||
|
ORDER BY name DESC;
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
SELECT
|
SELECT
|
||||||
e.id,
|
e.id,
|
||||||
e.ref,
|
e.reference,
|
||||||
e.supplierFk,
|
e.supplierFk,
|
||||||
t.shipped
|
t.shipped
|
||||||
FROM vn.entry e
|
FROM vn.entry e
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
<h2>
|
<h2>
|
||||||
<span>{{$t('entry')}} {{entry.id}}</span>
|
<span>{{$t('entry')}} {{entry.id}}</span>
|
||||||
<span>{{$t('dated')}} {{entry.shipped | date('%d-%m-%Y')}}</span>
|
<span>{{$t('dated')}} {{entry.shipped | date('%d-%m-%Y')}}</span>
|
||||||
<span class="pull-right">{{$t('reference')}} {{entry.ref}}</span>
|
<span class="pull-right">{{$t('reference')}} {{entry.reference}}</span>
|
||||||
</h2>
|
</h2>
|
||||||
<table class="column-oriented repeatable">
|
<table class="column-oriented repeatable">
|
||||||
<thead>
|
<thead>
|
||||||
|
|
Loading…
Reference in New Issue