Merge branch 'dev' into 4793-models_translation
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
927b5a63ec
|
@ -0,0 +1,4 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||||
|
VALUES
|
||||||
|
('Receipt', 'balanceCompensationEmail', 'WRITE', 'ALLOW', 'ROLE', 'employee'),
|
||||||
|
('Receipt', 'balanceCompensationPdf', 'READ', 'ALLOW', 'ROLE', 'employee');
|
|
@ -1859,7 +1859,8 @@ INSERT INTO `vn`.`receipt`(`id`, `invoiceFk`, `amountPaid`, `payed`, `workerFk`,
|
||||||
(1, 'Cobro web', 100.50, util.VN_CURDATE(), 9, 1, 1101, util.VN_CURDATE(), 442, 1),
|
(1, 'Cobro web', 100.50, util.VN_CURDATE(), 9, 1, 1101, util.VN_CURDATE(), 442, 1),
|
||||||
(2, 'Cobro web', 200.50, DATE_ADD(util.VN_CURDATE(), INTERVAL -5 DAY), 9, 1, 1101, DATE_ADD(util.VN_CURDATE(), INTERVAL -5 DAY), 442, 1),
|
(2, 'Cobro web', 200.50, DATE_ADD(util.VN_CURDATE(), INTERVAL -5 DAY), 9, 1, 1101, DATE_ADD(util.VN_CURDATE(), INTERVAL -5 DAY), 442, 1),
|
||||||
(3, 'Cobro en efectivo', 300.00, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 DAY), 9, 1, 1102, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 DAY), 442, 0),
|
(3, 'Cobro en efectivo', 300.00, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 DAY), 9, 1, 1102, DATE_ADD(util.VN_CURDATE(), INTERVAL -10 DAY), 442, 0),
|
||||||
(4, 'Cobro en efectivo', 400.00, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), 9, 1, 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), 442, 0);
|
(4, 'Cobro en efectivo', 400.00, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), 9, 1, 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), 442, 0),
|
||||||
|
(5, 'Compensación', 400.00, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), 9, 3, 1103, DATE_ADD(util.VN_CURDATE(), INTERVAL -15 DAY), 442, 0);
|
||||||
|
|
||||||
INSERT INTO `vn`.`workerTeam`(`id`, `team`, `workerFk`)
|
INSERT INTO `vn`.`workerTeam`(`id`, `team`, `workerFk`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
|
@ -324,7 +324,8 @@ export default {
|
||||||
anyBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr',
|
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)',
|
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',
|
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'
|
firstLineReferenceInput: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable > div > field > vn-textfield',
|
||||||
|
compensationButton: 'vn-client-balance-index vn-icon-button[vn-dialog="send_compensation"]'
|
||||||
},
|
},
|
||||||
webPayment: {
|
webPayment: {
|
||||||
confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]',
|
confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]',
|
||||||
|
@ -1038,6 +1039,17 @@ export default {
|
||||||
booked: 'vn-invoice-in-basic-data vn-date-picker[ng-model="$ctrl.invoiceIn.booked"]',
|
booked: 'vn-invoice-in-basic-data vn-date-picker[ng-model="$ctrl.invoiceIn.booked"]',
|
||||||
currency: 'vn-invoice-in-basic-data vn-autocomplete[ng-model="$ctrl.invoiceIn.currencyFk"]',
|
currency: 'vn-invoice-in-basic-data vn-autocomplete[ng-model="$ctrl.invoiceIn.currencyFk"]',
|
||||||
company: 'vn-invoice-in-basic-data vn-autocomplete[ng-model="$ctrl.invoiceIn.companyFk"]',
|
company: 'vn-invoice-in-basic-data vn-autocomplete[ng-model="$ctrl.invoiceIn.companyFk"]',
|
||||||
|
dms: 'vn-invoice-in-basic-data vn-textfield[ng-model="$ctrl.invoiceIn.dmsFk"]',
|
||||||
|
download: 'vn-invoice-in-basic-data vn-textfield[ng-model="$ctrl.invoiceIn.dmsFk"] > div.container > div.prepend > prepend > vn-icon-button',
|
||||||
|
edit: 'vn-invoice-in-basic-data vn-textfield[ng-model="$ctrl.invoiceIn.dmsFk"] > div.container > div.append > append > vn-icon-button[icon="edit"]',
|
||||||
|
create: 'vn-invoice-in-basic-data vn-textfield[ng-model="$ctrl.invoiceIn.dmsFk"] > div.container > div.append > append > vn-icon-button[icon="add_circle"]',
|
||||||
|
reference: 'vn-textfield[ng-model="$ctrl.dms.reference"]',
|
||||||
|
companyId: 'vn-autocomplete[ng-model="$ctrl.dms.companyId"]',
|
||||||
|
warehouseId: 'vn-autocomplete[ng-model="$ctrl.dms.warehouseId"]',
|
||||||
|
dmsTypeId: 'vn-autocomplete[ng-model="$ctrl.dms.dmsTypeId"]',
|
||||||
|
description: 'vn-textarea[ng-model="$ctrl.dms.description"]',
|
||||||
|
inputFile: 'vn-input-file[ng-model="$ctrl.dms.files"]',
|
||||||
|
confirm: 'button[response="accept"]',
|
||||||
save: 'vn-invoice-in-basic-data button[type=submit]'
|
save: 'vn-invoice-in-basic-data button[type=submit]'
|
||||||
},
|
},
|
||||||
invoiceInTax: {
|
invoiceInTax: {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import selectors from '../../helpers/selectors';
|
||||||
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
|
describe('Client Send balance compensation', () => {
|
||||||
|
let browser;
|
||||||
|
let page;
|
||||||
|
beforeAll(async() => {
|
||||||
|
browser = await getBrowser();
|
||||||
|
page = browser.page;
|
||||||
|
await page.loginAndModule('employee', 'client');
|
||||||
|
await page.accessToSearchResult('Clark Kent');
|
||||||
|
await page.accessToSection('client.card.balance.index');
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async() => {
|
||||||
|
await browser.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should click on send compensation button`, async() => {
|
||||||
|
await page.autocompleteSearch(selectors.clientBalance.company, 'VNL');
|
||||||
|
await page.waitToClick(selectors.clientBalance.compensationButton);
|
||||||
|
await page.waitToClick(selectors.clientBalance.saveButton);
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Notification sent!');
|
||||||
|
});
|
||||||
|
});
|
|
@ -4,6 +4,7 @@ import getBrowser from '../../helpers/puppeteer';
|
||||||
describe('InvoiceIn basic data path', () => {
|
describe('InvoiceIn basic data path', () => {
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
|
let newDms;
|
||||||
|
|
||||||
beforeAll(async() => {
|
beforeAll(async() => {
|
||||||
browser = await getBrowser();
|
browser = await getBrowser();
|
||||||
|
@ -24,6 +25,8 @@ describe('InvoiceIn basic data path', () => {
|
||||||
await page.autocompleteSearch(selectors.invoiceInBasicData.supplier, 'Verdnatura');
|
await page.autocompleteSearch(selectors.invoiceInBasicData.supplier, 'Verdnatura');
|
||||||
await page.clearInput(selectors.invoiceInBasicData.supplierRef);
|
await page.clearInput(selectors.invoiceInBasicData.supplierRef);
|
||||||
await page.write(selectors.invoiceInBasicData.supplierRef, '9999');
|
await page.write(selectors.invoiceInBasicData.supplierRef, '9999');
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.dms);
|
||||||
|
await page.write(selectors.invoiceInBasicData.dms, '2');
|
||||||
await page.pickDate(selectors.invoiceInBasicData.bookEntried, now);
|
await page.pickDate(selectors.invoiceInBasicData.bookEntried, now);
|
||||||
await page.pickDate(selectors.invoiceInBasicData.booked, now);
|
await page.pickDate(selectors.invoiceInBasicData.booked, now);
|
||||||
await page.autocompleteSearch(selectors.invoiceInBasicData.currency, 'USD');
|
await page.autocompleteSearch(selectors.invoiceInBasicData.currency, 'USD');
|
||||||
|
@ -61,4 +64,141 @@ describe('InvoiceIn basic data path', () => {
|
||||||
|
|
||||||
expect(result).toEqual('ORN');
|
expect(result).toEqual('ORN');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it(`should confirm the invoiceIn dms was edited`, async() => {
|
||||||
|
const result = await page
|
||||||
|
.waitToGetProperty(selectors.invoiceInBasicData.dms, 'value');
|
||||||
|
|
||||||
|
expect(result).toEqual('2');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should create a new invoiceIn dms and save the changes`, async() => {
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.dms);
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.create);
|
||||||
|
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.reference);
|
||||||
|
await page.write(selectors.invoiceInBasicData.reference, 'New Dms');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||||
|
let message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('The company can\'t be empty');
|
||||||
|
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.companyId);
|
||||||
|
await page.autocompleteSearch(selectors.invoiceInBasicData.companyId, 'VNL');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||||
|
message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('The warehouse can\'t be empty');
|
||||||
|
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.warehouseId);
|
||||||
|
await page.autocompleteSearch(selectors.invoiceInBasicData.warehouseId, 'Warehouse One');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||||
|
message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('The DMS Type can\'t be empty');
|
||||||
|
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.dmsTypeId);
|
||||||
|
await page.autocompleteSearch(selectors.invoiceInBasicData.dmsTypeId, 'Ticket');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||||
|
message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('The description can\'t be empty');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.description);
|
||||||
|
await page.write(selectors.invoiceInBasicData.description, 'Dms without edition.');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||||
|
message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('The files can\'t be empty');
|
||||||
|
|
||||||
|
let currentDir = process.cwd();
|
||||||
|
let filePath = `${currentDir}/e2e/assets/thermograph.jpeg`;
|
||||||
|
|
||||||
|
const [fileChooser] = await Promise.all([
|
||||||
|
page.waitForFileChooser(),
|
||||||
|
page.waitToClick(selectors.invoiceInBasicData.inputFile)
|
||||||
|
]);
|
||||||
|
await fileChooser.accept([filePath]);
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||||
|
message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Data saved!');
|
||||||
|
|
||||||
|
newDms = await page
|
||||||
|
.waitToGetProperty(selectors.invoiceInBasicData.dms, 'value');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should confirm the invoiceIn was edited with the new dms`, async() => {
|
||||||
|
await page.reloadSection('invoiceIn.card.basicData');
|
||||||
|
const result = await page
|
||||||
|
.waitToGetProperty(selectors.invoiceInBasicData.dms, 'value');
|
||||||
|
|
||||||
|
expect(result).toEqual(newDms);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should edit the invoiceIn`, async() => {
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.edit);
|
||||||
|
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.reference);
|
||||||
|
await page.write(selectors.invoiceInBasicData.reference, 'Dms Edited');
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.companyId);
|
||||||
|
await page.autocompleteSearch(selectors.invoiceInBasicData.companyId, 'CCs');
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.warehouseId);
|
||||||
|
await page.autocompleteSearch(selectors.invoiceInBasicData.warehouseId, 'Algemesi');
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.dmsTypeId);
|
||||||
|
await page.autocompleteSearch(selectors.invoiceInBasicData.dmsTypeId, 'Basura');
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.description);
|
||||||
|
await page.write(selectors.invoiceInBasicData.description, ' Nevermind, now is edited.');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||||
|
let message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Data saved!');
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should confirm the new dms has been edited`, async() => {
|
||||||
|
await page.reloadSection('invoiceIn.card.basicData');
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.edit);
|
||||||
|
|
||||||
|
const reference = await page
|
||||||
|
.waitToGetProperty(selectors.invoiceInBasicData.reference, 'value');
|
||||||
|
const companyId = await page
|
||||||
|
.waitToGetProperty(selectors.invoiceInBasicData.companyId, 'value');
|
||||||
|
const warehouseId = await page
|
||||||
|
.waitToGetProperty(selectors.invoiceInBasicData.warehouseId, 'value');
|
||||||
|
const dmsTypeId = await page
|
||||||
|
.waitToGetProperty(selectors.invoiceInBasicData.dmsTypeId, 'value');
|
||||||
|
const description = await page
|
||||||
|
.waitToGetProperty(selectors.invoiceInBasicData.description, 'value');
|
||||||
|
|
||||||
|
expect(reference).toEqual('Dms Edited');
|
||||||
|
expect(companyId).toEqual('CCs');
|
||||||
|
expect(warehouseId).toEqual('Algemesi');
|
||||||
|
expect(dmsTypeId).toEqual('Basura');
|
||||||
|
expect(description).toEqual('Dms without edition. Nevermind, now is edited.');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.confirm);
|
||||||
|
});
|
||||||
|
|
||||||
|
it(`should disable edit and download if dms doesn't exists, and set back the original dms`, async() => {
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.dms);
|
||||||
|
await page.write(selectors.invoiceInBasicData.dms, '9999');
|
||||||
|
|
||||||
|
await page.waitForSelector(`${selectors.invoiceInBasicData.download}.disabled`);
|
||||||
|
await page.waitForSelector(`${selectors.invoiceInBasicData.edit}.disabled`);
|
||||||
|
|
||||||
|
await page.clearInput(selectors.invoiceInBasicData.dms);
|
||||||
|
await page.write(selectors.invoiceInBasicData.dms, '1');
|
||||||
|
|
||||||
|
await page.waitToClick(selectors.invoiceInBasicData.save);
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.text).toContain('Data saved!');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -138,5 +138,8 @@
|
||||||
"You don't have grant privilege": "You don't have grant privilege",
|
"You don't have grant privilege": "You don't have grant privilege",
|
||||||
"You don't own the role and you can't assign it to another user": "You don't own the role and you can't assign it to another user",
|
"You don't own the role and you can't assign it to another user": "You don't own the role and you can't assign it to another user",
|
||||||
"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) merged with [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})",
|
"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) merged with [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})",
|
||||||
"Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production"
|
"Sale(s) blocked, please contact production": "Sale(s) blocked, please contact production",
|
||||||
|
"Receipt's bank was not found": "Receipt's bank was not found",
|
||||||
|
"This receipt was not compensated": "This receipt was not compensated",
|
||||||
|
"Client's email was not found": "Client's email was not found"
|
||||||
}
|
}
|
||||||
|
|
|
@ -244,5 +244,8 @@
|
||||||
"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) fusionado con [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})",
|
"Ticket merged": "Ticket [{{id}}]({{{fullPath}}}) ({{{originDated}}}) fusionado con [{{tfId}}]({{{fullPathFuture}}}) ({{{futureDated}}})",
|
||||||
"Already has this status": "Ya tiene este estado",
|
"Already has this status": "Ya tiene este estado",
|
||||||
"There aren't records for this week": "No existen registros para esta semana",
|
"There aren't records for this week": "No existen registros para esta semana",
|
||||||
"Empty data source": "Origen de datos vacio"
|
"Empty data source": "Origen de datos vacio",
|
||||||
|
"Receipt's bank was not found": "No se encontró el banco del recibo",
|
||||||
|
"This receipt was not compensated": "Este recibo no ha sido compensado",
|
||||||
|
"Client's email was not found": "No se encontró el email del cliente"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
const {Email} = require('vn-print');
|
const {Email} = require('vn-print');
|
||||||
|
const UserError = require('vn-loopback/util/user-error');
|
||||||
|
|
||||||
module.exports = Self => {
|
module.exports = Self => {
|
||||||
Self.remoteMethodCtx('balanceCompensationEmail', {
|
Self.remoteMethodCtx('balanceCompensationEmail', {
|
||||||
|
@ -10,7 +11,7 @@ module.exports = Self => {
|
||||||
type: 'Number',
|
type: 'Number',
|
||||||
required: true,
|
required: true,
|
||||||
description: 'The receipt id',
|
description: 'The receipt id',
|
||||||
http: { source: 'path' }
|
http: {source: 'path'}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -23,18 +24,29 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.balanceCompensationEmail = async (ctx, id) => {
|
Self.balanceCompensationEmail = async(ctx, id) => {
|
||||||
|
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const receipt = await models.Receipt.findById(id, {fields: ['clientFk']});
|
const receipt = await models.Receipt.findById(id, {fields: ['clientFk', 'bankFk']});
|
||||||
const client = await models.Client.findById(receipt.clientFk, {fields:['email']});
|
|
||||||
|
|
||||||
const email = new Email('balance-compensation', {
|
const bank = await models.Bank.findById(receipt.bankFk);
|
||||||
lang: ctx.req.getLocale(),
|
if (!bank)
|
||||||
recipient: client.email+',administracion@verdnatura.es',
|
throw new UserError(`Receipt's bank was not found`);
|
||||||
id
|
|
||||||
});
|
|
||||||
|
|
||||||
return email.send();
|
const accountingType = await models.AccountingType.findById(bank.accountingTypeFk);
|
||||||
|
if (!(accountingType && accountingType.code == 'compensation'))
|
||||||
|
throw new UserError(`This receipt was not compensated`);
|
||||||
|
|
||||||
|
const client = await models.Client.findById(receipt.clientFk, {fields: ['email']});
|
||||||
|
|
||||||
|
if (!client.email)
|
||||||
|
throw new UserError(`Client's email was not found`);
|
||||||
|
else {
|
||||||
|
const email = new Email('balance-compensation', {
|
||||||
|
lang: ctx.req.getLocale(),
|
||||||
|
recipient: client.email + ',administracion@verdnatura.es',
|
||||||
|
id
|
||||||
|
});
|
||||||
|
return email.send();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -56,11 +56,14 @@ module.exports = Self => {
|
||||||
u.name userName,
|
u.name userName,
|
||||||
r.clientFk,
|
r.clientFk,
|
||||||
FALSE hasPdf,
|
FALSE hasPdf,
|
||||||
FALSE isInvoice
|
FALSE isInvoice,
|
||||||
|
CASE WHEN at2.code LIKE 'compensation' THEN True ELSE False END as isCompensation
|
||||||
FROM vn.receipt r
|
FROM vn.receipt r
|
||||||
LEFT JOIN vn.worker w ON w.id = r.workerFk
|
LEFT JOIN vn.worker w ON w.id = r.workerFk
|
||||||
LEFT JOIN account.user u ON u.id = w.userFk
|
LEFT JOIN account.user u ON u.id = w.userFk
|
||||||
JOIN vn.company c ON c.id = r.companyFk
|
JOIN vn.company c ON c.id = r.companyFk
|
||||||
|
JOIN vn.accounting a ON a.id = r.bankFk
|
||||||
|
JOIN vn.accountingType at2 ON at2.id = a.accountingTypeFk
|
||||||
WHERE r.clientFk = ? AND r.companyFk = ?
|
WHERE r.clientFk = ? AND r.companyFk = ?
|
||||||
UNION ALL
|
UNION ALL
|
||||||
SELECT
|
SELECT
|
||||||
|
@ -77,9 +80,12 @@ module.exports = Self => {
|
||||||
NULL,
|
NULL,
|
||||||
i.clientFk,
|
i.clientFk,
|
||||||
i.hasPdf,
|
i.hasPdf,
|
||||||
TRUE isInvoice
|
TRUE isInvoice,
|
||||||
|
CASE WHEN at2.code LIKE 'compensation' THEN True ELSE False END as isCompensation
|
||||||
FROM vn.invoiceOut i
|
FROM vn.invoiceOut i
|
||||||
JOIN vn.company c ON c.id = i.companyFk
|
JOIN vn.company c ON c.id = i.companyFk
|
||||||
|
JOIN vn.accounting a ON a.id = i.bankFk
|
||||||
|
JOIN vn.accountingType at2 ON at2.id = a.accountingTypeFk
|
||||||
WHERE i.clientFk = ? AND i.companyFk = ?
|
WHERE i.clientFk = ? AND i.companyFk = ?
|
||||||
ORDER BY payed DESC, created DESC
|
ORDER BY payed DESC, created DESC
|
||||||
) t ORDER BY payed DESC, created DESC`,
|
) t ORDER BY payed DESC, created DESC`,
|
||||||
|
|
|
@ -121,7 +121,7 @@
|
||||||
</vn-icon-button>
|
</vn-icon-button>
|
||||||
</a>
|
</a>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td center shrink ng-if="!balance.isInvoice">
|
<vn-td center shrink ng-if="balance.isCompensation">
|
||||||
<vn-icon-button
|
<vn-icon-button
|
||||||
vn-dialog="send_compensation"
|
vn-dialog="send_compensation"
|
||||||
icon="outgoing_mail"
|
icon="outgoing_mail"
|
||||||
|
|
|
@ -70,7 +70,7 @@ class Controller extends Section {
|
||||||
const balances = this.$.model.data;
|
const balances = this.$.model.data;
|
||||||
balances.forEach((balance, index) => {
|
balances.forEach((balance, index) => {
|
||||||
if (index === 0)
|
if (index === 0)
|
||||||
balance.balance = this.getCurrentBalance();
|
balance.balance = this.getCurrentBalance();
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
let previousBalance = balances[index - 1];
|
let previousBalance = balances[index - 1];
|
||||||
balance.balance = previousBalance.balance - (previousBalance.debit - previousBalance.credit);
|
balance.balance = previousBalance.balance - (previousBalance.debit - previousBalance.credit);
|
||||||
|
@ -89,7 +89,7 @@ class Controller extends Section {
|
||||||
const params = {description: balance.description};
|
const params = {description: balance.description};
|
||||||
const endpoint = `Receipts/${balance.id}`;
|
const endpoint = `Receipts/${balance.id}`;
|
||||||
this.$http.patch(endpoint, params)
|
this.$http.patch(endpoint, params)
|
||||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
||||||
}
|
}
|
||||||
|
|
||||||
sendEmail(balance) {
|
sendEmail(balance) {
|
||||||
|
|
|
@ -151,5 +151,19 @@ describe('Client', () => {
|
||||||
$httpBackend.flush();
|
$httpBackend.flush();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('sendEmail()', () => {
|
||||||
|
it('should send an email', () => {
|
||||||
|
jest.spyOn(controller.vnEmail, 'send');
|
||||||
|
|
||||||
|
const $data = {id: 1103};
|
||||||
|
|
||||||
|
controller.sendEmail($data);
|
||||||
|
|
||||||
|
const expectedPath = `Receipts/${$data.id}/balance-compensation-email`;
|
||||||
|
|
||||||
|
expect(controller.vnEmail.send).toHaveBeenCalledWith(expectedPath);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
BILL: N/INV {{ref}}
|
BILL: N/INV {{ref}}
|
||||||
|
Notify compensation: Do you want to report compensation to the client by mail?
|
||||||
|
Send compensation: Send compensation
|
||||||
|
|
|
@ -5,6 +5,24 @@
|
||||||
form="form"
|
form="form"
|
||||||
save="patch">
|
save="patch">
|
||||||
</vn-watcher>
|
</vn-watcher>
|
||||||
|
<vn-crud-model
|
||||||
|
auto-load="true"
|
||||||
|
url="Companies"
|
||||||
|
data="companies"
|
||||||
|
order="code">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-crud-model
|
||||||
|
auto-load="true"
|
||||||
|
url="Warehouses"
|
||||||
|
data="warehouses"
|
||||||
|
order="name">
|
||||||
|
</vn-crud-model>
|
||||||
|
<vn-crud-model
|
||||||
|
auto-load="true"
|
||||||
|
url="DmsTypes"
|
||||||
|
data="dmsTypes"
|
||||||
|
order="name">
|
||||||
|
</vn-crud-model>
|
||||||
<form name="form" ng-submit="watcher.submit()" class="vn-w-md">
|
<form name="form" ng-submit="watcher.submit()" class="vn-w-md">
|
||||||
<vn-card class="vn-pa-lg">
|
<vn-card class="vn-pa-lg">
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
|
@ -57,6 +75,36 @@
|
||||||
{{id}} - {{name}}
|
{{id}} - {{name}}
|
||||||
</tpl-item>
|
</tpl-item>
|
||||||
</vn-datalist>
|
</vn-datalist>
|
||||||
|
<vn-textfield
|
||||||
|
label="Document"
|
||||||
|
ng-model="$ctrl.invoiceIn.dmsFk"
|
||||||
|
ng-change="$ctrl.checkFileExists($ctrl.invoiceIn.dmsFk)"
|
||||||
|
rule>
|
||||||
|
<prepend>
|
||||||
|
<vn-icon-button
|
||||||
|
disabled="$ctrl.editDownloadDisabled"
|
||||||
|
ng-if="$ctrl.invoiceIn.dmsFk"
|
||||||
|
title="{{'Download file' | translate}}"
|
||||||
|
icon="cloud_download"
|
||||||
|
ng-click="$ctrl.downloadFile($ctrl.invoiceIn.dmsFk)">
|
||||||
|
</vn-icon-button>
|
||||||
|
</prepend>
|
||||||
|
<append>
|
||||||
|
<vn-icon-button
|
||||||
|
disabled="$ctrl.editDownloadDisabled"
|
||||||
|
ng-if="$ctrl.invoiceIn.dmsFk"
|
||||||
|
ng-click="$ctrl.openEditDialog($ctrl.invoiceIn.dmsFk)"
|
||||||
|
icon="edit"
|
||||||
|
title="{{'Edit document' | translate}}">
|
||||||
|
</vn-icon-button>
|
||||||
|
<vn-icon-button
|
||||||
|
ng-if="!$ctrl.invoiceIn.dmsFk"
|
||||||
|
ng-click="$ctrl.openCreateDialog()"
|
||||||
|
icon="add_circle"
|
||||||
|
title="{{'Create document' | translate}}">
|
||||||
|
</vn-icon-button>
|
||||||
|
</append>
|
||||||
|
</vn-textfield>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-date-picker
|
<vn-date-picker
|
||||||
|
@ -105,3 +153,163 @@
|
||||||
</vn-button>
|
</vn-button>
|
||||||
</vn-button-bar>
|
</vn-button-bar>
|
||||||
</form>
|
</form>
|
||||||
|
<!-- Create edit dms dialog -->
|
||||||
|
<vn-dialog
|
||||||
|
vn-id="dmsEditDialog"
|
||||||
|
message="Edit document"
|
||||||
|
on-accept="$ctrl.onEdit()">
|
||||||
|
<tpl-body>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield
|
||||||
|
vn-one
|
||||||
|
vn-focus
|
||||||
|
label="Reference"
|
||||||
|
ng-model="$ctrl.dms.reference"
|
||||||
|
rule>
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Company"
|
||||||
|
ng-model="$ctrl.dms.companyId"
|
||||||
|
url="Companies"
|
||||||
|
show-field="code"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Warehouse"
|
||||||
|
ng-model="$ctrl.dms.warehouseId"
|
||||||
|
url="Warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete vn-one required="true"
|
||||||
|
label="Type"
|
||||||
|
ng-model="$ctrl.dms.dmsTypeId"
|
||||||
|
url="DmsTypes"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textarea
|
||||||
|
vn-one
|
||||||
|
required="true"
|
||||||
|
label="Description"
|
||||||
|
ng-model="$ctrl.dms.description"
|
||||||
|
rule>
|
||||||
|
</vn-textarea>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-file
|
||||||
|
vn-one
|
||||||
|
label="File"
|
||||||
|
ng-model="$ctrl.dms.files"
|
||||||
|
on-change="$ctrl.onFileChange($files)"
|
||||||
|
accept="{{$ctrl.allowedContentTypes}}"
|
||||||
|
required="false"
|
||||||
|
multiple="true">
|
||||||
|
<append>
|
||||||
|
<vn-icon vn-none
|
||||||
|
color-marginal
|
||||||
|
title="{{$ctrl.contentTypesInfo}}"
|
||||||
|
icon="info">
|
||||||
|
</vn-icon>
|
||||||
|
</append>
|
||||||
|
</vn-input-file>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-vertical>
|
||||||
|
<vn-check disabled="true"
|
||||||
|
label="Generate identifier for original file"
|
||||||
|
ng-model="$ctrl.dms.hasFile">
|
||||||
|
</vn-check>
|
||||||
|
</vn-vertical>
|
||||||
|
</tpl-body>
|
||||||
|
<tpl-buttons>
|
||||||
|
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||||
|
<button response="accept" translate>Save</button>
|
||||||
|
</tpl-buttons>
|
||||||
|
</vn-dialog>
|
||||||
|
<!-- Create new dms dialog -->
|
||||||
|
<vn-dialog
|
||||||
|
vn-id="dmsCreateDialog"
|
||||||
|
message="Create document"
|
||||||
|
on-accept="$ctrl.onCreate()">
|
||||||
|
<tpl-body>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield
|
||||||
|
vn-one
|
||||||
|
vn-focus
|
||||||
|
label="Reference"
|
||||||
|
ng-model="$ctrl.dms.reference"
|
||||||
|
rule>
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
label="Company"
|
||||||
|
ng-model="$ctrl.dms.companyId"
|
||||||
|
data="companies"
|
||||||
|
show-field="code"
|
||||||
|
value-field="id"
|
||||||
|
required="true">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
label="Warehouse"
|
||||||
|
ng-model="$ctrl.dms.warehouseId"
|
||||||
|
data="warehouses"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
required="true">
|
||||||
|
</vn-autocomplete>
|
||||||
|
<vn-autocomplete
|
||||||
|
vn-one
|
||||||
|
label="Type"
|
||||||
|
ng-model="$ctrl.dms.dmsTypeId"
|
||||||
|
data="dmsTypes"
|
||||||
|
show-field="name"
|
||||||
|
value-field="id"
|
||||||
|
required="true">
|
||||||
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textarea
|
||||||
|
vn-one
|
||||||
|
label="Description"
|
||||||
|
ng-model="$ctrl.dms.description"
|
||||||
|
required="true"
|
||||||
|
rule>
|
||||||
|
</vn-textarea>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-input-file
|
||||||
|
vn-one
|
||||||
|
label="File"
|
||||||
|
ng-model="$ctrl.dms.files"
|
||||||
|
on-change="$ctrl.onFileChange($files)"
|
||||||
|
accept="{{$ctrl.allowedContentTypes}}"
|
||||||
|
required="true"
|
||||||
|
multiple="true">
|
||||||
|
<append>
|
||||||
|
<vn-icon vn-none
|
||||||
|
color-marginal
|
||||||
|
title="{{$ctrl.contentTypesInfo}}"
|
||||||
|
icon="info">
|
||||||
|
</vn-icon>
|
||||||
|
</append>
|
||||||
|
</vn-input-file>
|
||||||
|
</vn-horizontal>
|
||||||
|
<vn-vertical>
|
||||||
|
<vn-check
|
||||||
|
label="Generate identifier for original file"
|
||||||
|
ng-model="$ctrl.dms.hasFile">
|
||||||
|
</vn-check>
|
||||||
|
</vn-vertical>
|
||||||
|
</tpl-body>
|
||||||
|
<tpl-buttons>
|
||||||
|
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||||
|
<button response="accept" translate>Create</button>
|
||||||
|
</tpl-buttons>
|
||||||
|
</vn-dialog>
|
||||||
|
|
|
@ -1,9 +1,181 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import Section from 'salix/components/section';
|
import Section from 'salix/components/section';
|
||||||
|
import UserError from 'core/lib/user-error';
|
||||||
|
|
||||||
|
class Controller extends Section {
|
||||||
|
constructor($element, $, vnFile) {
|
||||||
|
super($element, $, vnFile);
|
||||||
|
this.dms = {
|
||||||
|
files: [],
|
||||||
|
hasFile: false,
|
||||||
|
hasFileAttached: false
|
||||||
|
};
|
||||||
|
this.vnFile = vnFile;
|
||||||
|
this.getAllowedContentTypes();
|
||||||
|
this._editDownloadDisabled = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
get contentTypesInfo() {
|
||||||
|
return this.$t('ContentTypesInfo', {
|
||||||
|
allowedContentTypes: this.allowedContentTypes
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
get editDownloadDisabled() {
|
||||||
|
return this._editDownloadDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkFileExists(dmsId) {
|
||||||
|
if (!dmsId) return;
|
||||||
|
let filter = {
|
||||||
|
fields: ['id']
|
||||||
|
};
|
||||||
|
await this.$http.get(`Dms/${dmsId}`, {filter})
|
||||||
|
.then(() => this._editDownloadDisabled = false)
|
||||||
|
.catch(() => this._editDownloadDisabled = true);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getFile(dmsId) {
|
||||||
|
const path = `Dms/${dmsId}`;
|
||||||
|
await this.$http.get(path).then(res => {
|
||||||
|
const dms = res.data && res.data;
|
||||||
|
this.dms = {
|
||||||
|
dmsId: dms.id,
|
||||||
|
reference: dms.reference,
|
||||||
|
warehouseId: dms.warehouseFk,
|
||||||
|
companyId: dms.companyFk,
|
||||||
|
dmsTypeId: dms.dmsTypeFk,
|
||||||
|
description: dms.description,
|
||||||
|
hasFile: dms.hasFile,
|
||||||
|
hasFileAttached: false,
|
||||||
|
files: []
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
getAllowedContentTypes() {
|
||||||
|
this.$http.get('DmsContainers/allowedContentTypes').then(res => {
|
||||||
|
if (res.data.length > 0) {
|
||||||
|
const contentTypes = res.data.join(', ');
|
||||||
|
this.allowedContentTypes = contentTypes;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
openEditDialog(dmsId) {
|
||||||
|
this.getFile(dmsId).then(() => this.$.dmsEditDialog.show());
|
||||||
|
}
|
||||||
|
|
||||||
|
openCreateDialog() {
|
||||||
|
this.dms = {
|
||||||
|
reference: null,
|
||||||
|
warehouseId: null,
|
||||||
|
companyId: null,
|
||||||
|
dmsTypeId: null,
|
||||||
|
description: null,
|
||||||
|
hasFile: true,
|
||||||
|
hasFileAttached: true,
|
||||||
|
files: null
|
||||||
|
};
|
||||||
|
this.$.dmsCreateDialog.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
downloadFile(dmsId) {
|
||||||
|
this.vnFile.download(`api/dms/${dmsId}/downloadFile`);
|
||||||
|
}
|
||||||
|
|
||||||
|
onFileChange(files) {
|
||||||
|
let hasFileAttached = false;
|
||||||
|
if (files.length > 0)
|
||||||
|
hasFileAttached = true;
|
||||||
|
|
||||||
|
this.$.$applyAsync(() => {
|
||||||
|
this.dms.hasFileAttached = hasFileAttached;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onEdit() {
|
||||||
|
if (!this.dms.companyId)
|
||||||
|
throw new UserError(`The company can't be empty`);
|
||||||
|
if (!this.dms.warehouseId)
|
||||||
|
throw new UserError(`The warehouse can't be empty`);
|
||||||
|
if (!this.dms.dmsTypeId)
|
||||||
|
throw new UserError(`The DMS Type can't be empty`);
|
||||||
|
if (!this.dms.description)
|
||||||
|
throw new UserError(`The description can't be empty`);
|
||||||
|
|
||||||
|
const query = `dms/${this.dms.dmsId}/updateFile`;
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: query,
|
||||||
|
params: this.dms,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': undefined
|
||||||
|
},
|
||||||
|
transformRequest: files => {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++)
|
||||||
|
formData.append(files[i].name, files[i]);
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
},
|
||||||
|
data: this.dms.files
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$http(options).then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||||
|
if (res.data.length > 0) this.invoiceIn.dmsFk = res.data[0].id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onCreate() {
|
||||||
|
if (!this.dms.companyId)
|
||||||
|
throw new UserError(`The company can't be empty`);
|
||||||
|
if (!this.dms.warehouseId)
|
||||||
|
throw new UserError(`The warehouse can't be empty`);
|
||||||
|
if (!this.dms.dmsTypeId)
|
||||||
|
throw new UserError(`The DMS Type can't be empty`);
|
||||||
|
if (!this.dms.description)
|
||||||
|
throw new UserError(`The description can't be empty`);
|
||||||
|
if (!this.dms.files)
|
||||||
|
throw new UserError(`The files can't be empty`);
|
||||||
|
|
||||||
|
const query = `Dms/uploadFile`;
|
||||||
|
const options = {
|
||||||
|
method: 'POST',
|
||||||
|
url: query,
|
||||||
|
params: this.dms,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': undefined
|
||||||
|
},
|
||||||
|
transformRequest: files => {
|
||||||
|
const formData = new FormData();
|
||||||
|
|
||||||
|
for (let i = 0; i < files.length; i++)
|
||||||
|
formData.append(files[i].name, files[i]);
|
||||||
|
|
||||||
|
return formData;
|
||||||
|
},
|
||||||
|
data: this.dms.files
|
||||||
|
};
|
||||||
|
|
||||||
|
this.$http(options).then(res => {
|
||||||
|
if (res) {
|
||||||
|
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||||
|
if (res.data.length > 0) this.invoiceIn.dmsFk = res.data[0].id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller.$inject = ['$element', '$scope', 'vnFile'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnInvoiceInBasicData', {
|
ngModule.vnComponent('vnInvoiceInBasicData', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Section,
|
controller: Controller,
|
||||||
bindings: {
|
bindings: {
|
||||||
invoiceIn: '<'
|
invoiceIn: '<'
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
import './index.js';
|
||||||
|
import watcher from 'core/mocks/watcher';
|
||||||
|
|
||||||
|
describe('InvoiceIn', () => {
|
||||||
|
describe('Component vnInvoiceInBasicData', () => {
|
||||||
|
let controller;
|
||||||
|
let $scope;
|
||||||
|
let $httpBackend;
|
||||||
|
let $httpParamSerializer;
|
||||||
|
|
||||||
|
beforeEach(ngModule('invoiceIn'));
|
||||||
|
|
||||||
|
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
||||||
|
$scope = $rootScope.$new();
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$httpParamSerializer = _$httpParamSerializer_;
|
||||||
|
const $element = angular.element('<vn-invoice-in-basic-data></vn-invoice-in-basic-data>');
|
||||||
|
controller = $componentController('vnInvoiceInBasicData', {$element, $scope});
|
||||||
|
controller.$.watcher = watcher;
|
||||||
|
$httpBackend.expect('GET', `DmsContainers/allowedContentTypes`).respond({});
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('onFileChange()', () => {
|
||||||
|
it('should set dms hasFileAttached property to true if has any files', () => {
|
||||||
|
const files = [{id: 1, name: 'MyFile'}];
|
||||||
|
controller.onFileChange(files);
|
||||||
|
|
||||||
|
$scope.$apply();
|
||||||
|
|
||||||
|
expect(controller.dms.hasFileAttached).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('checkFileExists()', () => {
|
||||||
|
it(`should return false if a file exists`, () => {
|
||||||
|
const fileIdExists = 1;
|
||||||
|
controller.checkFileExists(fileIdExists);
|
||||||
|
|
||||||
|
expect(controller.editDownloadDisabled).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onEdit()', () => {
|
||||||
|
it(`should perform a POST query to edit the dms properties`, () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
|
||||||
|
const dms = {
|
||||||
|
dmsId: 1,
|
||||||
|
reference: 'Ref1',
|
||||||
|
warehouseId: 1,
|
||||||
|
companyId: 442,
|
||||||
|
dmsTypeId: 20,
|
||||||
|
description: 'This is a description',
|
||||||
|
files: []
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.dms = dms;
|
||||||
|
const serializedParams = $httpParamSerializer(controller.dms);
|
||||||
|
const query = `dms/${controller.dms.dmsId}/updateFile?${serializedParams}`;
|
||||||
|
|
||||||
|
$httpBackend.expectPOST(query).respond({});
|
||||||
|
controller.onEdit();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('onCreate()', () => {
|
||||||
|
it(`should perform a POST query to create a new dms`, () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
|
||||||
|
const dms = {
|
||||||
|
reference: 'Ref1',
|
||||||
|
warehouseId: 1,
|
||||||
|
companyId: 442,
|
||||||
|
dmsTypeId: 20,
|
||||||
|
description: 'This is a description',
|
||||||
|
files: [{
|
||||||
|
lastModified: 1668673957761,
|
||||||
|
lastModifiedDate: new Date(),
|
||||||
|
name: 'file-example.png',
|
||||||
|
size: 19653,
|
||||||
|
type: 'image/png',
|
||||||
|
webkitRelativePath: ''
|
||||||
|
}]
|
||||||
|
};
|
||||||
|
|
||||||
|
controller.dms = dms;
|
||||||
|
const serializedParams = $httpParamSerializer(controller.dms);
|
||||||
|
const query = `Dms/uploadFile?${serializedParams}`;
|
||||||
|
|
||||||
|
$httpBackend.expectPOST(query).respond({});
|
||||||
|
controller.onCreate();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
ContentTypesInfo: Allowed file types {{allowedContentTypes}}
|
|
@ -0,0 +1,15 @@
|
||||||
|
Upload file: Subir fichero
|
||||||
|
Edit file: Editar fichero
|
||||||
|
Upload: Subir
|
||||||
|
Document: Documento
|
||||||
|
ContentTypesInfo: "Tipos de archivo permitidos: {{allowedContentTypes}}"
|
||||||
|
Generate identifier for original file: Generar identificador para archivo original
|
||||||
|
File management: Gestión documental
|
||||||
|
Hard copy: Copia
|
||||||
|
This file will be deleted: Este fichero va a ser borrado
|
||||||
|
Are you sure?: Estas seguro?
|
||||||
|
File deleted: Fichero eliminado
|
||||||
|
Remove file: Eliminar fichero
|
||||||
|
Download file: Descargar fichero
|
||||||
|
Edit document: Editar documento
|
||||||
|
Create document: Crear documento
|
Loading…
Reference in New Issue