Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 3256-order_transactions
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Carlos Jimenez Ruiz 2021-11-12 17:32:03 +01:00
commit 266b1c8073
61 changed files with 2901 additions and 1628 deletions

View File

@ -25,6 +25,9 @@
},
"isAutoConciliated": {
"type": "boolean"
},
"maxAmount": {
"type": "number"
}
},
"acls": [{

View File

@ -0,0 +1,3 @@
ALTER TABLE vn.accountingType ADD maxAmount INT DEFAULT NULL NULL;
UPDATE vn.accountingType SET maxAmount = 1000 WHERE code = 'cash';

View File

@ -19,7 +19,7 @@ USE `util`;
--
-- Dumping data for table `config`
--
LOCK TABLES `config` WRITE;
/*!40000 ALTER TABLE `config` DISABLE KEYS */;
INSERT INTO `config` VALUES (1,'10360',0,'production',NULL);
@ -34,7 +34,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-10-20 8:38:20
-- Dump completed on 2021-11-08 8:19:54
USE `account`;
-- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64)
--
@ -72,7 +72,7 @@ INSERT INTO `roleInherit` VALUES (1,1,2),(2,1,3),(3,1,70),(4,2,11),(5,3,11),(6,5
/*!40000 ALTER TABLE `roleInherit` ENABLE KEYS */;
UNLOCK TABLES;
--
--
-- Dumping data for table `roleRole`
--
@ -120,7 +120,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-10-20 8:38:22
-- Dump completed on 2021-11-08 8:19:55
USE `salix`;
-- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64)
--
@ -176,7 +176,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-10-20 8:38:23
-- Dump completed on 2021-11-08 8:19:56
USE `vn`;
-- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64)
--
@ -432,7 +432,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-10-20 8:38:27
-- Dump completed on 2021-11-08 8:20:01
USE `cache`;
-- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64)
--
@ -468,7 +468,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-10-20 8:38:28
-- Dump completed on 2021-11-08 8:20:02
USE `hedera`;
-- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64)
--
@ -534,7 +534,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-10-20 8:38:29
-- Dump completed on 2021-11-08 8:20:03
USE `postgresql`;
-- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64)
--
@ -608,7 +608,7 @@ UNLOCK TABLES;
LOCK TABLES `workcenter` WRITE;
/*!40000 ALTER TABLE `workcenter` DISABLE KEYS */;
INSERT INTO `workcenter` VALUES (1,'Silla',20,NULL,1,'Av espioca 100',552703),(2,'Mercaflor',19,NULL,NULL,NULL,NULL),(3,'Marjales',26,20008,NULL,NULL,NULL),(4,'VNH',NULL,NULL,3,NULL,NULL),(5,'Madrid',28,2867,5,'Av constitución 3',554145),(6,'Vilassar',88,88038,2,'Cami del Crist, 33',556412),(7,'Tenerife',NULL,NULL,10,NULL,NULL),(8,NULL,NULL,NULL,NULL,NULL,NULL),(9,'Algemesi',20,1348,60,'Fenollars, 2',523549),(10,NULL,NULL,NULL,NULL,NULL,NULL);
INSERT INTO `workcenter` VALUES (1,'Silla',20,NULL,1,'Av espioca 100',552703),(2,'Mercaflor',19,NULL,NULL,NULL,NULL),(3,'Marjales',26,20008,NULL,NULL,NULL),(4,'VNH',NULL,NULL,3,NULL,NULL),(5,'Madrid',28,2868,5,'Av constitución 3',554145),(6,'Vilassar',88,88038,2,'Cami del Crist, 33',556412),(7,'Tenerife',NULL,NULL,10,NULL,NULL),(8,NULL,NULL,NULL,NULL,NULL,NULL),(9,'Algemesi',20,1351,60,'Fenollars, 2',523549),(10,NULL,NULL,NULL,NULL,NULL,NULL);
/*!40000 ALTER TABLE `workcenter` ENABLE KEYS */;
UNLOCK TABLES;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
@ -620,7 +620,7 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-10-20 8:38:30
-- Dump completed on 2021-11-08 8:20:05
USE `sage`;
-- MariaDB dump 10.19 Distrib 10.6.4-MariaDB, for Linux (x86_64)
--
@ -676,4 +676,4 @@ UNLOCK TABLES;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2021-10-20 8:38:31
-- Dump completed on 2021-11-08 8:20:06

View File

@ -7,7 +7,7 @@ ALTER TABLE `vn`.`zoneGeo` AUTO_INCREMENT = 1;
ALTER TABLE `vn`.`ticket` AUTO_INCREMENT = 1;
INSERT INTO `salix`.`AccessToken` (`id`, `ttl`, `created`, `userId`)
VALUES
VALUES
('TOTALLY_SECURE_TOKEN', '1209600', CURDATE(), 66);
@ -154,16 +154,16 @@ INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `park
('GVC', '1', '0', '1', '0', '1106'),
('HEJ', '2', '0', '1', '0', '1106');
INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`code`)
INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`code`, `maxAmount`)
VALUES
(1, 'CC y Polizas de crédito', NULL, NULL),
(2, 'Cash', 'Cash', 'cash'),
(3, 'Credit card', 'Credit Card', 'creditCard'),
(4, 'Finalcial lines', NULL, NULL),
(5, 'Other products', NULL, NULL),
(6, 'Loans', NULL, NULL),
(7, 'Leasing', NULL, NULL),
(8, 'Compensations', 'Compensations', 'compensation');
(1, 'CC y Polizas de crédito', NULL, NULL, NULL),
(2, 'Cash', 'Cash', 'cash', 1000),
(3, 'Credit card', 'Credit Card', 'creditCard', NULL),
(4, 'Finalcial lines', NULL, NULL, NULL),
(5, 'Other products', NULL, NULL, NULL),
(6, 'Loans', NULL, NULL, NULL),
(7, 'Leasing', NULL, NULL, NULL),
(8, 'Compensations', 'Compensations', 'compensation', NULL);
INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`)
VALUES
@ -1285,11 +1285,11 @@ INSERT INTO `vn`.`supplierAddress`(`id`, `supplierFk`, `nickname`, `street`, `pr
(5, 442, 'GCR building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222'),
(6, 442, 'The Gotham Tonight building', 'Bristol district', 1, '46000', 'Gotham', '111111111', '222222222');
INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`,`isFarmer`,`commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`)
INSERT INTO `vn`.`supplier`(`id`, `name`, `nickname`,`account`,`countryFk`,`nif`,`isFarmer`,`commission`, `created`, `isActive`, `street`, `city`, `provinceFk`, `postCode`, `payMethodFk`, `payDemFk`, `payDay`, `taxTypeSageFk`, `withholdingSageFk`, `transactionTypeSageFk`, `workerFk`, `supplierActivityFk`, `isPayMethodChecked`)
VALUES
(1, 'Plants SL', 'Plants nick', 4100000001, 1, '06089160W', 0, 0, CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants'),
(2, 'Farmer King', 'The farmer', 4000020002, 1, '87945234L', 1, 0, CURDATE(), 1, 'supplier address 2', 'SILLA', 2, 43022, 1, 2, 10, 93, 2, 8, 18, 'animals'),
(442, 'Verdnatura Levante SL', 'Verdnatura', 5115000442, 1, '06815934E', 0, 0, CURDATE(), 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'flowerPlants');
(1, 'Plants SL', 'Plants nick', 4100000001, 1, '06089160W', 0, 0, CURDATE(), 1, 'supplier address 1', 'PONTEVEDRA', 1, 15214, 1, 1, 15, 4, 1, 1, 18, 'flowerPlants', 1),
(2, 'Farmer King', 'The farmer', 4000020002, 1, '87945234L', 1, 0, CURDATE(), 1, 'supplier address 2', 'SILLA', 2, 43022, 1, 2, 10, 93, 2, 8, 18, 'animals', 1),
(442, 'Verdnatura Levante SL', 'Verdnatura', 5115000442, 1, '06815934E', 0, 0, CURDATE(), 1, 'supplier address 3', 'SILLA', 1, 43022, 1, 2, 15, 6, 9, 3, 18, 'flowerPlants', 1);
INSERT INTO `vn`.`supplierContact`(`id`, `supplierFk`, `phone`, `mobile`, `email`, `observation`, `name`)
VALUES

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,4 @@
/* eslint max-len: ["error", { "ignoreStrings": true }]*/
export default {
globalItems: {
@ -273,6 +274,7 @@ export default {
deliveredAmount: '.vn-dialog vn-input-number[ng-model="$ctrl.deliveredAmount"]',
refundAmount: '.vn-dialog vn-input-number[ng-model="$ctrl.amountToReturn"]',
saveButton: '.vn-dialog.shown [response="accept"]',
anyBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr',
firstLineBalance: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)',
firstLineReference: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable',
firstLineReferenceInput: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable > div > field > vn-textfield'
@ -470,6 +472,7 @@ export default {
firstTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1) > vn-check',
secondTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(2) > vn-td:nth-child(1) > vn-check',
thirdTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(3) > vn-td:nth-child(1) > vn-check',
fifthTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(5) > vn-td:nth-child(1) > vn-check',
sixthTicketCheckbox: 'vn-ticket-index vn-tbody > a:nth-child(6) > vn-td:nth-child(1) > vn-check',
payoutButton: 'vn-ticket-index vn-button[icon="icon-recovery"]',
payoutCompany: '.vn-dialog vn-autocomplete[ng-model="$ctrl.companyFk"]',
@ -1144,6 +1147,7 @@ export default {
alias: 'vn-supplier-basic-data vn-textfield[ng-model="$ctrl.supplier.nickname"]',
isSerious: 'vn-supplier-basic-data vn-check[ng-model="$ctrl.supplier.isSerious"]',
isActive: 'vn-supplier-basic-data vn-check[ng-model="$ctrl.supplier.isActive"]',
isPayMethodChecked: 'vn-supplier-basic-data vn-check[ng-model="$ctrl.supplier.isPayMethodChecked"]',
notes: 'vn-supplier-basic-data vn-textarea[ng-model="$ctrl.supplier.note"]',
saveButton: 'vn-supplier-basic-data button[type="submit"]',
},

View File

@ -105,7 +105,23 @@ describe('Client balance path', () => {
expect(result).toContain('-€100.00');
});
it('should create a new payment and check the cash exceeded the maximum', async() => {
const amountPaid = '1001';
await page.closePopup();
await page.waitToClick(selectors.clientBalance.newPaymentButton);
await page.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Cash');
await page.write(selectors.clientBalance.newPaymentAmount, amountPaid);
await page.clearInput(selectors.clientBalance.newDescription);
await page.write(selectors.clientBalance.newDescription, 'Payment');
await page.waitToClick(selectors.clientBalance.saveButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Amount exceeded');
});
it('should create a new payment that sets the balance back to the original negative value', async() => {
await page.closePopup();
await page.waitToClick(selectors.clientBalance.newPaymentButton);
await page.autocompleteSearch(selectors.clientBalance.newPaymentBank, 'Pay on receipt');
await page.overwrite(selectors.clientBalance.newPaymentAmount, '-150');

View File

@ -21,8 +21,8 @@ describe('Ticket index payout path', () => {
it('should check the second ticket from a client and 1 of another', async() => {
await page.waitToClick(selectors.globalItems.searchButton);
await page.waitToClick(selectors.ticketsIndex.secondTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.thirdTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.fifthTicketCheckbox);
await page.waitToClick(selectors.ticketsIndex.payoutButton);
const message = await page.waitForSnackbar();
@ -58,9 +58,11 @@ describe('Ticket index payout path', () => {
await page.selectModule('client');
await page.accessToSearchResult('1101');
await page.accessToSection('client.card.balance.index');
await page.waitForSelector('vn-client-balance-index vn-tbody > vn-tr');
let result = await page.countElement('vn-client-balance-index vn-tbody > vn-tr');
await page.waitForSelector(selectors.clientBalance.anyBalanceLine);
const count = await page.countElement(selectors.clientBalance.anyBalanceLine);
const reference = await page.waitToGetProperty(selectors.clientBalance.firstLineReference, 'innerText');
expect(result).toEqual(4);
expect(count).toEqual(4);
expect(reference).toContain('Cash, Albaran: 7, 8Payment');
});
});

View File

@ -22,6 +22,7 @@ describe('Supplier basic data path', () => {
await page.write(selectors.supplierBasicData.alias, 'Plants Nick SL');
await page.waitToClick(selectors.supplierBasicData.isSerious);
await page.waitToClick(selectors.supplierBasicData.isActive);
await page.waitToClick(selectors.supplierBasicData.isPayMethodChecked);
await page.write(selectors.supplierBasicData.notes, 'Some notes');
await page.waitToClick(selectors.supplierBasicData.saveButton);
@ -52,6 +53,12 @@ describe('Supplier basic data path', () => {
expect(result).toBe('unchecked');
});
it('should check the isPayMethodChecked checkbox is now unchecked', async() => {
const result = await page.checkboxState(selectors.supplierBasicData.isPayMethodChecked);
expect(result).toBe('unchecked');
});
it('should check the notes were edited', async() => {
const result = await page.waitToGetProperty(selectors.supplierBasicData.notes, 'value');

View File

@ -9,19 +9,19 @@
"properties": {
"id": {
"id": true,
"type": "Number"
"type": "number"
},
"sender": {
"type": "String"
"receiver": {
"type": "string"
},
"replyTo": {
"type": "String"
"type": "string"
},
"subject": {
"type": "String"
"type": "string"
},
"body": {
"type": "String"
"type": "string"
}
},
"acls": [

View File

@ -28,7 +28,7 @@
url="Workers/activeWithRole"
search-function="{firstName: $search}"
value-field="id"
where="{role: 'salesPerson'}"
where="{role: {inq: ['salesPerson', 'officeBoss']}}"
label="Salesperson">
<tpl-item>{{firstName}} {{name}}</tpl-item>
</vn-autocomplete>

View File

@ -44,7 +44,8 @@
label="Amount"
ng-model="$ctrl.amountPaid"
step="0.01"
required="true">
required="true"
max="$ctrl.maxAmount">
</vn-input-number>
</vn-horizontal>
<vn-horizontal>

View File

@ -45,6 +45,7 @@ class Controller extends Dialog {
set description(value) {
this.receipt.description = value;
this.originalDescription = value;
}
get description() {
@ -60,7 +61,14 @@ class Controller extends Dialog {
if (value) {
const accountingType = value.accountingType;
this.receipt.description = accountingType && accountingType.receiptDescription;
if (this.originalDescription) {
this.receipt.description =
`${accountingType && accountingType.receiptDescription}, ${this.originalDescription}`;
} else {
this.receipt.description =
`${accountingType && accountingType.receiptDescription}`;
}
this.maxAmount = accountingType && accountingType.maxAmount;
}
}
@ -121,6 +129,11 @@ class Controller extends Dialog {
if (response !== 'accept')
return super.responseHandler(response);
const exceededAmount = this.receipt.amountPaid > this.maxAmount;
if (this.bankSelection.accountingType.code == 'cash' && exceededAmount)
return this.vnApp.showError(this.$t('Amount exceeded', {maxAmount: this.maxAmount}));
let receiptId;
return this.$http.post(`Clients/${this.clientFk}/createReceipt`, this.receipt)
.then(res => {

View File

@ -23,10 +23,12 @@ describe('Client', () => {
clientFk: 1101,
companyFk: 442
};
controller.bankSelection = {accountingType: {code: 'myCode'}};
}));
describe('bankSelection() setter', () => {
it('should set the receipt description property', () => {
controller.originalDescription = 'Albaran: 1, 2';
controller.bankSelection = {
id: 1,
bank: 'Cash',
@ -36,7 +38,7 @@ describe('Client', () => {
}
};
expect(controller.receipt.description).toEqual('Cash');
expect(controller.receipt.description).toEqual('Cash, Albaran: 1, 2');
});
});

View File

@ -1 +1,2 @@
View receipt: Ver recibo
View receipt: Ver recibo
Amount exceeded: Según ley contra el fraude no se puede recibir cobros por importe igual o superior a {{maxAmount}}

View File

@ -34,13 +34,20 @@
</div>
<div class="quicklinks">
<div ng-transclude="btnOne">
<vn-quick-link
tooltip="Supplier card"
state="['supplier.card.summary', {id: $ctrl.entry.supplier.id}]"
icon="icon-supplier">
</vn-quick-link>
</div>
<div ng-transclude="btnTwo">
<vn-quick-link
tooltip="All travels with current agency"
state="['travel.index', {q: $ctrl.travelFilter}]"
icon="local_airport">
</vn-quick-link>
</div>
<div ng-transclude="btnTwo">
<div ng-transclude="btnThree">
<vn-quick-link
tooltip="All entries with current supplier"
state="['entry.index', {q: $ctrl.entryFilter}]"

View File

@ -1,4 +1,5 @@
Reference: Referencia
Supplier card: Ficha del proveedor
All travels with current agency: Todos los envios con la agencia actual
All entries with current supplier: Todas las entradas con el proveedor actual
Show entry report: Ver informe del pedido

View File

@ -8,6 +8,7 @@ class Controller extends ModuleCard {
'id',
'ref',
'issued',
'serial',
'amount',
'clientFk',
'companyFk',

View File

@ -69,6 +69,12 @@
translate>
{{!$ctrl.invoiceOut.hasPdf ? 'Generate PDF invoice': 'Regenerate PDF invoice'}}
</vn-item>
<vn-item
ng-click="$ctrl.showExportationLetter()"
ng-show="$ctrl.invoiceOut.serial == 'E'"
translate>
Show CIES letter
</vn-item>
</slot-menu>
<slot-body>
<div class="attributes">

View File

@ -98,6 +98,13 @@ class Controller extends Descriptor {
invoiceId: this.id
});
}
showExportationLetter() {
this.vnReport.show('exportation', {
recipientId: this.invoiceOut.client.id,
invoiceId: this.id,
});
}
}
ngModule.vnComponent('vnInvoiceOutDescriptor', {

View File

@ -8,12 +8,13 @@ Send PDF invoice: Enviar factura en PDF
Send CSV invoice: Enviar factura en CSV
Delete Invoice: Eliminar factura
Clone Invoice: Clonar factura
Book invoice: Asentar factura
Generate PDF invoice: Generar PDF factura
Show CIES letter: Ver carta CIES
InvoiceOut deleted: Factura eliminada
Are you sure you want to delete this invoice?: Estas seguro de eliminar esta factura?
Are you sure you want to clone this invoice?: Estas seguro de clonar esta factura?
Book invoice: Asentar factura
InvoiceOut booked: Factura asentada
Are you sure you want to book this invoice?: Estas seguro de querer asentar esta factura?
Generate PDF invoice: Generar PDF factura
Regenerate PDF invoice: Regenerar PDF factura
The invoice PDF document has been regenerated: El documento PDF de la factura ha sido regenerado

View File

@ -6,7 +6,7 @@ class Controller extends Section {
super($element, $);
const from = new Date();
from.setDate(from.getDate());
from.setDate(from.getDate() - 75);
from.setHours(0, 0, 0, 0);
const to = new Date();

View File

@ -20,7 +20,7 @@
url="Workers/activeWithRole"
search-function="{firstName: $search}"
value-field="id"
wwhere="{role: {inq: ['logistic', 'buyer']}}"
where="{role: {inq: ['logistic', 'buyer']}}"
label="Atender">
<tpl-item>{{nickname}}</tpl-item>
</vn-autocomplete>

View File

@ -180,11 +180,11 @@ module.exports = Self => {
LEFT JOIN zoneEstimatedDelivery zed ON zed.zoneFk = t.zoneFk`);
stmt.merge(conn.makeWhere(filter.where));
stmt.merge(`GROUP BY id`);
stmt.merge(conn.makePagination(filter));
stmts.push(stmt);
stmt = new ParameterizedSQL(`SELECT * FROM tmp.filter`);
stmt.merge(`GROUP BY id`);
stmt.merge(conn.makeOrderBy(filter.order));
const ordersIndex = stmts.push(stmt) - 1;

View File

@ -26,7 +26,7 @@ module.exports = Self => {
const user = await models.user.findById(loopBackContext.active.accessToken.userId);
const bankEntity = await models.BankEntity.findById(ctx.instance.bankEntityFk);
await Self.app.models.Mail.create({
sender: 'finanzas@verdnatura.es',
receiver: 'finanzas@verdnatura.es',
subject: 'Añadida cuenta bancaria al proveedor' + ctx.instance.supplierFk,
body: user.username + ' ha añadido: ' +
ctx.instance.iban + ', entidad: ' + bankEntity.name + ', bic: ' + bankEntity.bic

View File

@ -101,7 +101,10 @@
"mysql": {
"columnName": "withholdingSageFk"
}
}
},
"isPayMethodChecked": {
"type": "boolean"
}
},
"relations": {
"payMethod": {
@ -160,13 +163,5 @@
"model": "SupplierAddress",
"foreignKey": "supplierFk"
}
},
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}
]
}
}

View File

@ -36,6 +36,10 @@
label="Active"
ng-model="$ctrl.supplier.isActive">
</vn-check>
<vn-check
label="PayMethodChecked"
ng-model="$ctrl.supplier.isPayMethodChecked">
</vn-check>
</vn-horizontal>
<vn-horizontal>
<vn-textarea

View File

@ -1,4 +1,5 @@
Notes: Notas
Active: Activo
Verified: Verificado
PayMethodChecked: Método de pago validado
Responsible for approving invoices: Responsable de aprobar las facturas

View File

@ -174,7 +174,7 @@ module.exports = Self => {
const emailSubject = subject + ' ' + user.name;
await Self.app.models.Mail.create({
sender: sendTo,
receiver: sendTo,
subject: emailSubject,
body: emailBody
});

View File

@ -87,7 +87,7 @@ module.exports = Self => {
await models.Mail.create({
subject: $t('Absence change notification on the labour calendar'),
body: body,
sender: department.notificationEmail
receiver: department.notificationEmail
}, myOptions);
}

View File

@ -71,7 +71,7 @@ module.exports = Self => {
await models.Mail.create({
subject: $t('Absence change notification on the labour calendar'),
body: body,
sender: department.notificationEmail
receiver: department.notificationEmail
}, myOptions);
}

View File

@ -42,27 +42,21 @@ module.exports = Self => {
const stmts = [];
const startedMinusOne = new Date(started);
startedMinusOne.setDate(started.getDate() - 1);
const endedPlusOne = new Date(ended);
endedPlusOne.setDate(ended.getDate() + 1);
stmts.push(`
DROP TEMPORARY TABLE IF EXISTS
tmp.timeControlCalculate,
tmp.timeBusinessCalculate
`);
stmts.push(new ParameterizedSQL('CALL vn.timeControl_calculateByUser(?, ?, ?)', [userId, startedMinusOne, endedPlusOne]));
stmts.push(new ParameterizedSQL('CALL vn.timeControl_calculateByUser(?, ?, ?)', [userId, started, ended]));
stmts.push(new ParameterizedSQL('CALL vn.timeBusiness_calculateByUser(?, ?, ?)', [userId, startedMinusOne, endedPlusOne]));
stmts.push(new ParameterizedSQL('CALL vn.timeBusiness_calculateByUser(?, ?, ?)', [userId, started, ended]));
const resultIndex = stmts.push(new ParameterizedSQL(`
SELECT tbc.dated, tbc.timeWorkSeconds expectedHours, tcc.timeWorkSeconds workedHours
FROM tmp.timeBusinessCalculate tbc
LEFT JOIN tmp.timeControlCalculate tcc ON tcc.dated = tbc.dated
WHERE tbc.dated BETWEEN ? AND ?
SELECT tcc.dated, tbc.timeWorkSeconds expectedHours, tcc.timeWorkSeconds workedHours
FROM tmp.timeControlCalculate tcc
LEFT JOIN tmp.timeBusinessCalculate tbc ON tcc.dated = tbc.dated
WHERE tcc.dated BETWEEN DATE(?) AND DATE(?)
`, [started, ended])) - 1;
stmts.push(`

View File

@ -1,17 +1,17 @@
const app = require('vn-loopback/server/server');
const models = require('vn-loopback/server/server').models;
describe('Worker getWorkedHours()', () => {
it(`should return the expected hours and the worked hours of a given date`, async() => {
const workerID = 1106;
let started = new Date();
const started = new Date();
started.setHours(0, 0, 0, 0);
let ended = new Date();
ended.setHours(0, 0, 0, 0);
const ended = new Date();
ended.setHours(23, 59, 59, 999);
const [result] = await app.models.Worker.getWorkedHours(workerID, started, ended);
const [result] = await models.Worker.getWorkedHours(workerID, started, ended);
expect(result.expectedHours).toEqual(28800); // 8:00 hours seconds
expect(result.expectedHours).toEqual(28800); // 8:00 hours in seconds
expect(result.workedHours).toEqual(29400); // 8:10 hours in seconds
});
});

View File

@ -171,7 +171,6 @@ class Controller extends Section {
from: from,
to: to
};
const query = `Workers/${this.$params.id}/getWorkedHours`;
return this.$http.get(query, {params}).then(res => {
const workDays = res.data;
@ -212,7 +211,8 @@ class Controller extends Section {
let todayInWeek = this.weekDays.find(day => day.dated.getTime() === today.getTime());
if (todayInWeek && todayInWeek.hours && todayInWeek.hours.length) {
const remainingTime = todayInWeek.workedHours ? ((todayInWeek.expectedHours - todayInWeek.workedHours) * 1000) : null;
const remainingTime = todayInWeek.workedHours ?
((todayInWeek.expectedHours - todayInWeek.workedHours) * 1000) : null;
const lastKnownEntry = todayInWeek.hours[todayInWeek.hours.length - 1];
const lastKnownTime = new Date(lastKnownEntry.timed).getTime();
const finishTimeStamp = lastKnownTime && remainingTime ? lastKnownTime + remainingTime : null;

View File

@ -0,0 +1,63 @@
module.exports = Self => {
Self.remoteMethod('getEventsFiltered', {
description: 'Get events filtered for zone and date',
accepts: [
{
arg: 'zoneFk',
type: 'number',
description: 'The zone id',
required: true
},
{
arg: 'started',
type: 'date',
description: 'The date calendar start',
},
{
arg: 'ended',
type: 'date',
description: 'The date calendar end',
}
],
returns: {
type: 'object',
root: true
},
http: {
path: `/getEventsFiltered`,
verb: 'GET'
}
});
Self.getEventsFiltered = async(zoneFk, started, ended, options) => {
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
query = `
SELECT *
FROM vn.zoneEvent
WHERE zoneFk = ?
AND ((type = 'indefinitely')
OR (type = 'day' AND dated BETWEEN ? AND ?)
OR (type = 'range'
AND (
(started BETWEEN ? AND ?)
OR (ended BETWEEN ? AND ?)
)
)
)
ORDER BY type='indefinitely' DESC, type='range' DESC, type='day' DESC;`;
const events = await Self.rawSql(query, [zoneFk, started, ended, started, ended, started, ended], myOptions);
query = `
SELECT *
FROM vn.zoneExclusion
WHERE zoneFk = ?
AND dated BETWEEN ? AND ?;`;
const exclusions = await Self.rawSql(query, [zoneFk, started, ended], myOptions);
return {events, exclusions};
};
};

View File

@ -1,12 +1,12 @@
const app = require('vn-loopback/server/server');
const models = require('vn-loopback/server/server').models;
describe('agency clone()', () => {
it('should clone a zone', async() => {
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
const newZone = await app.models.Zone.clone(1, options);
const newZone = await models.Zone.clone(1, options);
expect(newZone.name).toEqual('Zone pickup A');

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server');
const models = require('vn-loopback/server/server').models;
const LoopBackContext = require('loopback-context');
describe('zone deletezone()', () => {
@ -16,13 +16,13 @@ describe('zone deletezone()', () => {
active: activeCtx
});
try {
const originalTickets = await app.models.Ticket.find({
const originalTickets = await models.Ticket.find({
where: {
zoneFk: zoneId
}
});
ticketIDs = originalTickets.map(ticket => ticket.id);
originalTicketStates = await app.models.TicketState.find({where: {
originalTicketStates = await models.TicketState.find({where: {
ticketFk: {inq: ticketIDs},
code: 'FIXING'}});
} catch (error) {
@ -31,16 +31,16 @@ describe('zone deletezone()', () => {
});
it('should delete a zone and update their tickets', async() => {
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
await app.models.Zone.deleteZone(ctx, zoneId, options);
await models.Zone.deleteZone(ctx, zoneId, options);
const updatedZone = await app.models.Zone.findById(zoneId, null, options);
const anUpdatedTicket = await app.models.Ticket.findById(ticketIDs[0], null, options);
const updatedZone = await models.Zone.findById(zoneId, null, options);
const anUpdatedTicket = await models.Ticket.findById(ticketIDs[0], null, options);
const updatedTicketStates = await app.models.TicketState.find({
const updatedTicketStates = await models.TicketState.find({
where: {
ticketFk: {inq: ticketIDs},
code: 'FIXING'

View File

@ -1,13 +1,13 @@
const app = require('vn-loopback/server/server');
const models = require('vn-loopback/server/server').models;
describe('zone getEvents()', () => {
it('should return all events for the specified geo and agency mode', async() => {
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
let result = await app.models.Zone.getEvents(20, 1, options);
let result = await models.Zone.getEvents(20, 1, options);
expect(result.events.length).toEqual(10);

View File

@ -0,0 +1,21 @@
const models = require('vn-loopback/server/server').models;
describe('zone getEventsFiltered()', () => {
it('should return events and exclusions for the specified zoneFk in a range of dates', async() => {
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
let result = await models.Zone.getEventsFiltered(10, '2021-10-01', '2021-10-02', options);
expect(result.events.length).toEqual(1);
expect(result.exclusions.length).toEqual(0);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -1,13 +1,13 @@
const app = require('vn-loopback/server/server');
const models = require('vn-loopback/server/server').models;
describe('zone getLeaves()', () => {
it('should return the country and the childs containing the search value', async() => {
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
let result = await app.models.Zone.getLeaves(1, null, '46000', options);
let result = await models.Zone.getLeaves(1, null, '46000', options);
expect(result.length).toEqual(1);

View File

@ -1,4 +1,4 @@
const app = require('vn-loopback/server/server');
const models = require('vn-loopback/server/server').models;
describe('zone includingExpired()', () => {
const inhousePickupId = 1;
@ -6,14 +6,14 @@ describe('zone includingExpired()', () => {
const warehouseId = 1;
it('should return an array containing all zones', async() => {
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
const ctx = {req: {accessToken: {userId: 1}}};
const where = {};
try {
const options = {transaction: tx};
const result = await app.models.Zone.includingExpired(ctx, {where}, options);
const result = await models.Zone.includingExpired(ctx, {where}, options);
expect(result.length).toBeGreaterThan(2);
@ -28,12 +28,12 @@ describe('zone includingExpired()', () => {
const ctx = {req: {accessToken: {userId: 1}}};
const where = {agencyModeFk: inhousePickupId};
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
const result = await app.models.Zone.includingExpired(ctx, {where}, options);
const result = await models.Zone.includingExpired(ctx, {where}, options);
const validAgency = result.every(zone => zone.agencyModeFk = inhousePickupId);
@ -56,12 +56,12 @@ describe('zone includingExpired()', () => {
warehouseFk: warehouseId
};
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
const result = await app.models.Zone.includingExpired(ctx, {where}, options);
const result = await models.Zone.includingExpired(ctx, {where}, options);
const firstZone = result[0];
expect(firstZone.name).toEqual('Zone pickup A');

View File

@ -1,13 +1,13 @@
const app = require('vn-loopback/server/server');
const models = require('vn-loopback/server/server').models;
describe('zone toggleIsIncluded()', () => {
it('should return the created location with isIncluded true', async() => {
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
let result = await app.models.Zone.toggleIsIncluded(1, 20, true, options);
let result = await models.Zone.toggleIsIncluded(1, 20, true, options);
expect(result.isIncluded).toBeTrue();
@ -19,12 +19,12 @@ describe('zone toggleIsIncluded()', () => {
});
it('should return the created location with isIncluded false', async() => {
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
let result = await app.models.Zone.toggleIsIncluded(1, 20, false, options);
let result = await models.Zone.toggleIsIncluded(1, 20, false, options);
expect(result.isIncluded).toBeFalse();
@ -36,14 +36,14 @@ describe('zone toggleIsIncluded()', () => {
});
it('should return the amount of deleted locations', async() => {
const tx = await app.models.Zone.beginTransaction({});
const tx = await models.Zone.beginTransaction({});
try {
const options = {transaction: tx};
await app.models.Zone.toggleIsIncluded(1, 20, false, options);
await models.Zone.toggleIsIncluded(1, 20, false, options);
let result = await app.models.Zone.toggleIsIncluded(1, 20, undefined, options);
let result = await models.Zone.toggleIsIncluded(1, 20, undefined, options);
expect(result).toEqual({count: 1});

View File

@ -2,6 +2,7 @@ module.exports = Self => {
require('../methods/zone/clone')(Self);
require('../methods/zone/getLeaves')(Self);
require('../methods/zone/getEvents')(Self);
require('../methods/zone/getEventsFiltered')(Self);
require('../methods/zone/toggleIsIncluded')(Self);
require('../methods/zone/getUpcomingDeliveries')(Self);
require('../methods/zone/deleteZone')(Self);

View File

@ -1,5 +1,6 @@
<vn-zone-calendar
id="calendar"
vn-id="calendar"
data="data"
on-selection="$ctrl.onSelection($days, $type, $weekday, $events, $exclusions)"
class="vn-w-md">

View File

@ -21,14 +21,18 @@ class Controller extends Section {
}
refresh() {
let data = {};
this.$q.all([
this.$http.get(this.path)
.then(res => data.events = res.data),
this.$http.get(this.exclusionsPath)
.then(res => data.exclusions = res.data)
]).finally(() => {
this.$.data = data;
this.$.data = null;
this.$.$applyAsync(() => {
const params = {
zoneFk: this.$params.id,
started: this.$.calendar.firstDay,
ended: this.$.calendar.lastDay
};
this.$http.get(`Zones/getEventsFiltered`, {params}).then(res => {
const data = res.data;
this.$.data = data;
});
});
}

View File

@ -17,8 +17,26 @@ describe('component vnZoneEvents', () => {
describe('refresh()', () => {
it('should set the zone and then call both getSummary() and getWarehouses()', () => {
$httpBackend.expectGET(`Zones/1/events`).respond({id: 1});
$httpBackend.expectGET(`Zones/1/exclusions`).respond({id: 1});
const date = '2021-10-01';
controller.$params.id = 999;
controller.$.calendar = {
firstDay: date,
lastDay: date
};
const params = {
zoneFk: controller.$params.id,
started: date,
ended: date
};
const query = `Zones/getEventsFiltered?ended=${date}&started=${date}&zoneFk=${params.zoneFk}`;
const response = {
events: 'myEvents',
exclusions: 'myExclusions'
};
$httpBackend.whenGET(query).respond(response);
controller.refresh();
$httpBackend.flush();

View File

@ -256,17 +256,4 @@ table {
.line span {
background-color: #FFF;
padding: 5px
}
.signature {
width: 100%
}
.signature section {
height: 150px
}
.signature p {
margin-right: 50%;
margin-top: 140px
}
}

View File

@ -1,5 +1,6 @@
const db = require('../core/database');
const Email = require('../core/email');
const Report = require('../core/report');
const smtp = require('../core/smtp');
const config = require('../core/config');
@ -195,7 +196,8 @@ module.exports = app => {
if (!ticket.recipient) {
const body = `No se ha podido enviar el albarán <strong>${ticket.id}</strong>
al cliente <strong>${ticket.clientFk}</strong> porque no tiene un email especificado.<br/><br/>
Para dejar de recibir esta notificación, asígnale un email o desactiva la notificación por email para este cliente.`;
Para dejar de recibir esta notificación, asígnale un email o desactiva
la notificación por email para este cliente.`;
smtp.send({
to: ticket.salesPersonEmail,
subject: 'No se ha podido enviar el albarán',
@ -207,22 +209,37 @@ module.exports = app => {
const hasToInvoice = ticket.hasToInvoice && ticket.hasDailyInvoice;
if (hasToInvoice) {
const invoiceId = await db.findValue(`
SELECT io.id
const invoice = await db.findOne(`
SELECT io.id, io.ref, io.serial, cny.code companyCode
FROM ticket t
JOIN invoiceOut io ON io.ref = t.refFk
JOIN company cny ON cny.id = io.companyFk
WHERE t.id = ?
`, [ticket.id]);
const args = Object.assign({
invoiceId: invoiceId,
invoiceId: invoice.id,
recipientId: ticket.clientFk,
recipient: ticket.recipient,
replyTo: ticket.salesPersonEmail
}, reqArgs);
let mailOptions = {};
if (invoice.serial == 'E' && invoice.companyCode == 'VNL') {
const exportation = new Report('exportation', args);
const stream = await exportation.toPdfStream();
const fileName = `exportation-${invoice.ref}.pdf`;
mailOptions = {
overrideAttachments: false,
attachments: [{
filename: fileName,
content: stream
}]
};
}
const email = new Email('invoice', args);
await email.send();
await email.send(mailOptions);
} else {
const args = Object.assign({
ticketId: ticket.id,

View File

@ -10,4 +10,5 @@ closed: Cerrado
ticketSubject: Asunto
ticketDescription: Descripción
resolution: Resolución
grafanaLink: "Puedes ver la gráfica desde el siguiente enlace:"
grafanaLink: "Puedes ver la gráfica desde el siguiente enlace:"
redmineLink: "Desde el siguiente enlace puedes ver el resumen semanal de tareas de refactor:"

View File

@ -33,6 +33,12 @@
https://grafana.verdnatura.es/d/2kaHDi9Mk/osticket?orgId=1&from={{startedTime}}&to={{endedTime}}
</a>
</div>
<p v-html="$t('redmineLink')"></p>
<div class="external-link vn-pa-sm vn-m-md">
<a href="https://redmine.verdnatura.es/projects/refactor/issues?query_id=112" target="_blank">
https://redmine.verdnatura.es/projects/refactor/issues?query_id=112
</a>
</div>
</div>
</div>
<!-- Block -->

View File

@ -11,5 +11,5 @@ clientSignature: Firma del cliente
claim: Reclamación {0}
sections:
agency:
description: 'Para agilizar su recogida, por favor, póngase en contacto con la oficina
de integrados. <br/> Tlf: 96 166 77 88 - Ana Gómez (Ext. 2113) <em>(agomezf@integra2.com)</em>'
description: 'Para agilizar su recogida, por favor, póngase en contacto con la oficina
de Logista Parcel. <br/> Tlf: 96 166 77 88 - Ana Gómez (Ext. 2113) <em>(atcsalidas.i2valencia@integra2.es)</em>'

View File

@ -12,8 +12,9 @@ SELECT
FROM claim cl
JOIN client c ON c.id = cl.clientFk
JOIN account.user u ON u.id = c.id
JOIN country ct ON ct.id = c.countryFk
JOIN ticket t ON t.id = cl.ticketFk
JOIN address a ON a.id = t.addressFk
LEFT JOIN province p ON p.id = c.provinceFk
LEFT JOIN province p ON p.id = a.provinceFk
LEFT JOIN autonomy amy ON amy.id = p.autonomyFk
LEFT JOIN country ct ON ct.id = amy.countryFk
WHERE cl.id = ?

View File

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

View File

@ -0,0 +1,12 @@
.grid-block {
font-size: 1.2em
}
ul li {
margin-bottom: 20px;
text-align: justify;
}
.signature img {
width: 400px
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -0,0 +1,51 @@
<!DOCTYPE html>
<html v-bind:lang="$i18n.locale">
<body>
<table class="grid">
<tbody>
<tr>
<td>
<!-- Header block -->
<report-header v-bind="$props"></report-header>
<!-- Block -->
<div class="grid-row">
<div class="grid-block">
<h1 class="title centered uppercase">{{$t('title')}}</h1>
<p>{{$t('toAttention')}}</p>
<p v-html="$t('declaration', [invoice.ref, issued])"></p>
<p>
<ul>
<li v-for="responsibility in $t('responsibilities')">
{{responsibility}}
</li>
</ul>
</p>
<div class="signature">
<p>{{$t('issued', [
'Algemesí',
invoice.issued.getDate(),
$t('months')[invoice.issued.getMonth()],
invoice.issued.getFullYear()])
}}
</p>
<p><em>({{$t('signature')}})</em></p>
<img v-bind:src="getReportSrc('signature.png')">
<p>
<div>{{$t('signer.name')}}: JUAN VICENTE FERRER ROIG</div>
<div>{{$t('signer.ID')}}: 73943586N</div>
<div>{{$t('signer.position')}}: ADMINISTRADOR</div>
</p>
</div>
</div>
</div>
<!-- Footer block -->
<report-footer id="pageFooter"
v-bind:left-text="$t('invoice', [invoice.ref])"
v-bind="$props">
</report-footer>
</td>
</tr>
</tbody>
</table>
</body>
</html>

View File

@ -0,0 +1,34 @@
const Component = require(`${appPath}/core/component`);
const reportHeader = new Component('report-header');
const reportFooter = new Component('report-footer');
module.exports = {
name: 'exportation',
async serverPrefetch() {
this.invoice = await this.fetchInvoice(this.invoiceId);
if (!this.invoice)
throw new Error('Something went wrong');
},
methods: {
fetchInvoice(invoiceId) {
return this.findOneFromDef('invoice', [invoiceId]);
}
},
computed: {
issued: function() {
const filters = this.$options.filters;
return filters.date(this.invoice.issued, '%d-%m-%Y');
}
},
components: {
'report-header': reportHeader.build(),
'report-footer': reportFooter.build()
},
props: {
invoiceId: {
required: true
}
}
};

View File

@ -0,0 +1,50 @@
title: 'Carta CITES'
toAttention: 'A la atención del Sr. Administrador de la Aduana de la Farga de Moles.'
declaration: 'Por la presente DECLARO, bajo mi responsabilidad, que las mercancías detalladas en la factura
n° <strong>{0}</strong> de fecha <strong>{1}</strong>
asi como ninguno de sus componentes,'
issued: 'En {0}, a {1} de {2} de {3}'
invoice: 'Factura {0}'
responsibilities:
- 'NO están comprendidas en la Convención de Washington (CITES). Reglamento (CE) n° 338/1997
DO L61 de 3.3.1997 y sus últimas modificaciones, relativo a la protección de especies de fauna y
flora silvestres.'
- 'NO están incluidas en las listas del Anexo I del R/CE 428/2009 y sus posteriores modificaciones,
por lo que NO puede considerarse productos ni tecnologias de Doble Uso ni de uso militar.
No estando incluidas en la Relación de Material de Defensa del Anexo I del Real Decreto
679/2014, estando exentas a todos los efectos de autorizaciones administrativas para su comercio
exterior.'
- 'NO están incluidas los Anexos II, III y IV del R/UE 2019/125 L-30 de 31/01/2019
y sus modificaciones, sobre el comercio de determinados productos que pueden utilizarse para
aplicar la pena de muerte o infligir tortura u otros tratos o penas crueles, inhumanos o
degradantes.'
- 'NO están incluidas en el ANEXO ni en el ANEXO V del Reglamento (UE) N° 649/2012 y
sus modificaciones, relativo a la exportación e importación de productos químicos
peligrosos. ni tampoco contienen mercurio.'
- 'NO están sujetas al Reglamento/CE 1005/2009 L-286 de 30-10-2009 y sus
modificaciones, relativo a las mercancías que agotan la capa de ozono.'
- 'NO están afectadas por la prohibición a las importaciones de gases fluorados de
efecto invernadero, de acuerdo con el R/UE 517/2014.'
- 'NO están sujetas al Reglamento (CE) 116/2009 relativo a la exportación de bienes
culturales; y NO están sujetas a la Ley 16/1985, de 25 de junio, del Patrimonio
Histórico Español, estando exentas de Autorización Administrativa de Exportación.'
- 'NO están sujetos a las disposiciones del Reglamento (CE) Nº 1013/2006, relativo
a los traslados de residuos, y que en ningún modo pueden considerarse afectados por este control.'
signature: Firma y sello de la empresa
signer:
name: Nombre del firmante
ID: DNI del firmante
position: Cargo del firmante
months:
- 'Enero'
- 'Febrero'
- 'Marzo'
- 'Abril'
- 'Mayo'
- 'Junio'
- 'Julio'
- 'Agosto'
- 'Septiembre'
- 'Octubre'
- 'Noviembre'
- 'Diciembre'

View File

@ -0,0 +1,6 @@
SELECT
io.id,
io.ref,
io.issued
FROM invoiceOut io
WHERE io.id = ?

View File

@ -96,7 +96,7 @@
</div>
</div>
<div class="pull-left">
<h2>Shipped</h2>
<h2>{{$t('shipped')}}</h2>
</div>
<div class="pull-left">
<div class="field rectangle">

View File

@ -4,4 +4,5 @@ SELECT
t.nickname
FROM invoiceOut io
JOIN ticket t ON t.refFk = io.ref
WHERE io.id = ?
WHERE io.id = ?
ORDER BY t.shipped