Merge branch 'dev' into 3771-ticket.expedition
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Joan Sanchez 2022-05-13 13:05:08 +00:00
commit 9cbee7a38a
28 changed files with 10066 additions and 10104 deletions

View File

@ -1,35 +0,0 @@
module.exports = Self => {
Self.remoteMethod('collectionFaults', {
description: 'Update sale of a collection',
accessType: 'WRITE',
accepts: [{
arg: 'shelvingFk',
type: 'String',
required: true,
description: 'The shalving id'
}, {
arg: 'quantity',
type: 'Number',
required: true,
description: 'The quantity to sale'
}, {
arg: 'itemFk',
type: 'Number',
required: true,
description: 'The ticket id'
}],
returns: {
type: 'Object',
root: true
},
http: {
path: `/collectionFaults`,
verb: 'POST'
}
});
Self.collectionFaults = async(shelvingFk, quantity, itemFk) => {
query = `CALL vn.collection_faults(?,?,?)`;
return await Self.rawSql(query, [shelvingFk, quantity, itemFk]);
};
};

View File

@ -1,9 +0,0 @@
const app = require('vn-loopback/server/server');
describe('collectionFaults()', () => {
it('return shelving afected', async() => {
let response = await app.models.Collection.collectionFaults('UXN', 0, 1);
expect(response.length).toBeGreaterThan(0);
expect(response[0][0].shelvingFk).toEqual('UXN');
});
});

View File

@ -0,0 +1,57 @@
const fs = require('fs-extra');
const path = require('path');
module.exports = Self => {
Self.remoteMethod('deleteTrashFiles', {
description: 'Deletes files that have trash type',
accessType: 'WRITE',
returns: {
type: 'object',
root: true
},
http: {
path: `/deleteTrashFiles`,
verb: 'POST'
}
});
Self.deleteTrashFiles = async(options) => {
const tx = await Self.beginTransaction({});
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction)
myOptions.transaction = tx;
try {
const models = Self.app.models;
const DmsContainer = models.DmsContainer;
const trashDmsType = await models.DmsType.findOne({
where: {code: 'trash'}
}, myOptions);
const dmsToDelete = await models.Dms.find({
where: {
dmsTypeFk: trashDmsType.id
}
}, myOptions);
for (let dms of dmsToDelete) {
const pathHash = DmsContainer.getHash(dms.id);
const dmsContainer = await DmsContainer.container(pathHash);
const dstFile = path.join(dmsContainer.client.root, pathHash, dms.file);
await fs.unlink(dstFile);
await dms.destroy(myOptions);
}
if (tx) await tx.commit();
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -12,9 +12,9 @@ describe('docuware download()', () => {
} }
}; };
const fileCabinetName = 'deliveryClientTest'; const fileCabinetName = 'deliveryClient';
const dialogDisplayName = 'find'; const dialogDisplayName = 'find';
const dialogName = 'findTest'; const dialogName = 'findTicket';
const gotGetResponse = { const gotGetResponse = {
body: JSON.stringify( body: JSON.stringify(

View File

@ -14,9 +14,9 @@ describe('docuware download()', () => {
}; };
it('should return the downloaded file name', async() => { it('should return the downloaded file name', async() => {
const fileCabinetName = 'deliveryClientTest'; const fileCabinetName = 'deliveryClient';
const dialogDisplayName = 'find'; const dialogDisplayName = 'find';
const dialogName = 'findTest'; const dialogName = 'findTicket';
const gotGetResponse = { const gotGetResponse = {
body: JSON.stringify( body: JSON.stringify(
{ {

View File

@ -3,5 +3,4 @@ module.exports = Self => {
require('../methods/collection/newCollection')(Self); require('../methods/collection/newCollection')(Self);
require('../methods/collection/getSectors')(Self); require('../methods/collection/getSectors')(Self);
require('../methods/collection/setSaleQuantity')(Self); require('../methods/collection/setSaleQuantity')(Self);
require('../methods/collection/collectionFaults')(Self);
}; };

View File

@ -5,6 +5,7 @@ module.exports = Self => {
require('../methods/dms/uploadFile')(Self); require('../methods/dms/uploadFile')(Self);
require('../methods/dms/removeFile')(Self); require('../methods/dms/removeFile')(Self);
require('../methods/dms/updateFile')(Self); require('../methods/dms/updateFile')(Self);
require('../methods/dms/deleteTrashFiles')(Self);
Self.checkRole = async function(ctx, id) { Self.checkRole = async function(ctx, id) {
const models = Self.app.models; const models = Self.app.models;

View File

@ -0,0 +1,5 @@
INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('Expense', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES('Expense', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');

View File

@ -0,0 +1,8 @@
ALTER TABLE vn.propertyDms DROP FOREIGN KEY propertyDms_FK;
ALTER TABLE vn.propertyDms ADD CONSTRAINT propertyDms_FK FOREIGN KEY (dmsFk) REFERENCES vn.dms(id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE vn.clientDms DROP FOREIGN KEY clientDms_ibfk_2;
ALTER TABLE vn.clientDms ADD CONSTRAINT clientDms_ibfk_2 FOREIGN KEY (dmsFk) REFERENCES vn.dms(id) ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE vn.workerDocument DROP FOREIGN KEY workerDocument_ibfk_2;
ALTER TABLE vn.workerDocument ADD CONSTRAINT workerDocument_ibfk_2 FOREIGN KEY (document) REFERENCES vn.dms(id) ON DELETE CASCADE ON UPDATE CASCADE;

View File

@ -0,0 +1,5 @@
ALTER TABLE vn.dmsType ADD monthToDelete INT UNSIGNED DEFAULT NULL NULL;
ALTER TABLE vn.dmsType MODIFY COLUMN monthToDelete int(10) unsigned DEFAULT NULL NULL COMMENT 'Meses en el pasado para ir borrando registros, dejar a null para no borrarlos nunca';
UPDATE vn.dmsType
SET monthToDelete=6
WHERE id=20;

View File

@ -0,0 +1,18 @@
DELIMITER $$
$$
CREATE TRIGGER dms_beforeDelete
BEFORE DELETE
ON dms FOR EACH ROW
BEGIN
DECLARE vCanNotBeDeleted INT;
SELECT COUNT(*) INTO vCanNotBeDeleted
FROM dmsType dt
WHERE NOT (code <=> 'trash')
AND dt.id = OLD.dmsTypeFk;
IF vCanNotBeDeleted THEN
CALL util.throw('A dms can not be deleted');
END IF;
END$$
DELIMITER ;

View File

@ -0,0 +1,175 @@
DROP PROCEDURE IF EXISTS vn.clean;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`clean`()
BEGIN
DECLARE vDateShort DATETIME;
DECLARE vOneYearAgo DATE;
DECLARE vFourYearsAgo DATE;
DECLARE v18Month DATE;
DECLARE v26Month DATE;
DECLARE v3Month DATE;
DECLARE vTrashId varchar(15);
SET vDateShort = TIMESTAMPADD(MONTH, -2, CURDATE());
SET vOneYearAgo = TIMESTAMPADD(YEAR,-1,CURDATE());
SET vFourYearsAgo = TIMESTAMPADD(YEAR,-4,CURDATE());
SET v18Month = TIMESTAMPADD(MONTH, -18,CURDATE());
SET v26Month = TIMESTAMPADD(MONTH, -26,CURDATE());
SET v3Month = TIMESTAMPADD(MONTH, -3, CURDATE());
DELETE FROM ticketParking WHERE created < vDateShort;
DELETE FROM routesMonitor WHERE dated < vDateShort;
DELETE FROM workerTimeControlLog WHERE created < vDateShort;
DELETE FROM `message` WHERE sendDate < vDateShort;
DELETE FROM messageInbox WHERE sendDate < vDateShort;
DELETE FROM messageInbox WHERE sendDate < vDateShort;
DELETE FROM workerTimeControl WHERE timed < vFourYearsAgo;
DELETE FROM itemShelving WHERE created < CURDATE() AND visible = 0;
DELETE FROM ticketDown WHERE created < TIMESTAMPADD(DAY,-1,CURDATE());
DELETE FROM entryLog WHERE creationDate < vDateShort;
DELETE IGNORE FROM expedition WHERE created < v26Month;
DELETE FROM sms WHERE created < v18Month;
DELETE FROM saleTracking WHERE created < vOneYearAgo;
DELETE tobs FROM ticketObservation tobs
JOIN ticket t ON tobs.ticketFk = t.id WHERE t.shipped < TIMESTAMPADD(YEAR,-2,CURDATE());
DELETE sc.* FROM saleCloned sc JOIN sale s ON s.id = sc.saleClonedFk JOIN ticket t ON t.id = s.ticketFk WHERE t.shipped < vOneYearAgo;
DELETE FROM sharingCart where ended < vDateShort;
DELETE FROM sharingClient where ended < vDateShort;
DELETE tw.* FROM ticketWeekly tw
LEFT JOIN sale s ON s.ticketFk = tw.ticketFk WHERE s.itemFk IS NULL;
DELETE FROM claim WHERE ticketCreated < vFourYearsAgo;
DELETE FROM message WHERE sendDate < vDateShort;
-- Robert ubicacion anterior de trevelLog comentario para debug
DELETE sc FROM saleChecked sc
JOIN sale s ON sc.saleFk = s.id WHERE s.created < vDateShort;
DELETE FROM zoneEvent WHERE `type` = 'day' AND dated < v3Month;
DELETE bm
FROM buyMark bm
JOIN buy b ON b.id = bm.id
JOIN entry e ON e.id = b.entryFk
JOIN travel t ON t.id = e.travelFk
WHERE t.landed <= vDateShort;
DELETE FROM stowaway WHERE created < v3Month;
DELETE FROM vn.buy WHERE created < vDateShort AND entryFk = 9200;
DELETE FROM vn.itemShelvingLog WHERE created < vDateShort;
DELETE FROM vn.stockBuyed WHERE creationDate < vDateShort;
-- Equipos duplicados
DELETE w.*
FROM workerTeam w
JOIN (SELECT id, team, workerFk, COUNT(*) - 1 as duplicated
FROM workerTeam
GROUP BY team,workerFk
HAVING duplicated
) d ON d.team = w.team AND d.workerFk = w.workerFk AND d.id != w.id;
DELETE sc
FROM saleComponent sc
JOIN sale s ON s.id= sc.saleFk
JOIN ticket t ON t.id= s.ticketFk
WHERE t.shipped < v18Month;
DELETE c
FROM vn.claim c
JOIN vn.claimState cs ON cs.id = c.claimStateFk
WHERE cs.description = "Anulado" AND
c.created < vDateShort;
DELETE
FROM vn.expeditionTruck
WHERE ETD < v3Month;
-- borrar travels sin entradas
DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete;
CREATE TEMPORARY TABLE tmp.thermographToDelete
SELECT th.id,th.dmsFk
FROM vn.travel t
LEFT JOIN vn.entry e ON e.travelFk = t.id
JOIN vn.travelThermograph th ON th.travelFk = t.id
WHERE t.shipped < TIMESTAMPADD(MONTH, -3, CURDATE()) AND e.travelFk IS NULL;
SELECT dt.id into vTrashId
FROM vn.dmsType dt
WHERE dt.code = 'trash';
UPDATE tmp.thermographToDelete th
JOIN vn.dms d ON d.id = th.dmsFk
SET d.dmsTypeFk = vTrashId;
DELETE th
FROM tmp.thermographToDelete tmp
JOIN vn.travelThermograph th ON th.id = tmp.id;
DELETE t
FROM vn.travel t
LEFT JOIN vn.entry e ON e.travelFk = t.id
WHERE t.shipped < TIMESTAMPADD(MONTH, -3, CURDATE()) AND e.travelFk IS NULL;
UPDATE dms d
JOIN dmsType dt ON dt.id = d.dmsTypeFk
SET d.dmsTypeFk = vTrashId
WHERE created < TIMESTAMPADD(MONTH, -dt.monthToDelete, CURDATE());
-- borrar entradas sin compras
DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete;
CREATE TEMPORARY TABLE tmp.entryToDelete
SELECT e.*
FROM vn.entry e
LEFT JOIN vn.buy b ON b.entryFk = e.id
JOIN vn.entryConfig ec ON e.id != ec.defaultEntry
WHERE e.dated < TIMESTAMPADD(MONTH, -3, CURDATE()) AND b.entryFK IS NULL;
DELETE e
FROM vn.entry e
JOIN tmp.entryToDelete tmp ON tmp.id = e.id;
-- borrar de route registros menores a 4 años
DROP TEMPORARY TABLE IF EXISTS tmp.routeToDelete;
CREATE TEMPORARY TABLE tmp.routeToDelete
SELECT *
FROM vn.route r
WHERE created < TIMESTAMPADD(YEAR,-4,CURDATE());
UPDATE tmp.routeToDelete tmp
JOIN vn.dms d ON d.id = tmp.gestdocFk
SET d.dmsTypeFk = vTrashId;
DELETE r
FROM tmp.routeToDelete tmp
JOIN vn.route r ON r.id = tmp.id;
-- borrar registros de dua y awb menores a 2 años
DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete;
CREATE TEMPORARY TABLE tmp.duaToDelete
SELECT *
FROM vn.dua
WHERE operated < TIMESTAMPADD(YEAR,-2,CURDATE());
UPDATE tmp.duaToDelete tm
JOIN vn.dms d ON d.id = tm.gestdocFk
SET d.dmsTypeFk = vTrashId;
DELETE d
FROM tmp.duaToDelete tmp
JOIN vn.dua d ON d.id = tmp.id;
DELETE FROM vn.awb WHERE created < TIMESTAMPADD(YEAR,-2,CURDATE());
-- Borra los ficheros gestDoc
INSERT INTO vn.printServerQueue(priorityFk, labelReportFk)VALUES(1,11);
-- Borra los registros de collection y ticketcollection
DELETE FROM vn.collection WHERE created < vDateShort;
DROP TEMPORARY TABLE IF EXISTS tmp.thermographToDelete;
DROP TEMPORARY TABLE IF EXISTS tmp.entryToDelete;
DROP TEMPORARY TABLE IF EXISTS tmp.duaToDelete;
DELETE FROM travelLog WHERE creationDate < v3Month;
CALL shelving_clean;
END$$
DELIMITER ;

View File

@ -0,0 +1,2 @@
INSERT INTO salix.ACL (model,property,accessType,permission,principalType,principalId)
VALUES ('Dms','deleteTrashFiles','WRITE','ALLOW','ROLE','employee')

File diff suppressed because one or more lines are too long

View File

@ -54,28 +54,7 @@ INSERT INTO `vn`.`educationLevel` (`id`, `name`)
INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`) INSERT INTO `vn`.`worker`(`id`,`code`, `firstName`, `lastName`, `userFk`, `bossFk`)
SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9 SELECT id,UPPER(LPAD(role, 3, '0')), name, name, id, 9
FROM `vn`.`user`; FROM `vn`.`user`;
ALTER TABLE `vn`.`worker` ADD `originCountryFk` mediumint(8) unsigned NULL COMMENT 'País de origen';
ALTER TABLE `vn`.`worker` ADD `educationLevelFk` SMALLINT NULL;
ALTER TABLE `vn`.`worker` ADD `SSN` varchar(15) NULL;
ALTER TABLE `vn`.`worker` CHANGE `maritalStatus__` `maritalStatus` enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
ALTER TABLE `vn`.`worker` MODIFY COLUMN `maritalStatus` enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
ALTER TABLE `vn`.`worker` CHANGE `maritalStatus` maritalStatus enum('S','M') CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL AFTER sectorFk;
ALTER TABLE `vn`.`worker` ADD CONSTRAINT `worker_FK_2` FOREIGN KEY (`educationLevelFk`) REFERENCES `vn`.`educationLevel`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE `vn`.`worker` ADD CONSTRAINT `worker_FK_1` FOREIGN KEY (`originCountryFk`) REFERENCES `vn`.`country`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
UPDATE `vn`.`worker` `w`
SET `maritalStatus` = 'S';
UPDATE `vn`.`worker` `w`
SET `originCountryFk` = '1';
UPDATE `vn`.`worker` `w`
SET `educationLevelFk` = '2';
UPDATE `vn`.`worker` `w`
SET `SSN` = '123456789123';
UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20; UPDATE `vn`.`worker` SET bossFk = NULL WHERE id = 20;
UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9; UPDATE `vn`.`worker` SET bossFk = 20 WHERE id = 1 OR id = 9;
@ -147,15 +126,6 @@ INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`,
(19,'Francia', 1, 'FR', 1, 27, 4, 0, 1), (19,'Francia', 1, 'FR', 1, 27, 4, 0, 1),
(30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2); (30,'Canarias', 1, 'IC', 1, 24, 4, 1, 2);
INSERT INTO `hedera`.`language` (`code`, `name`, `orgName`, `isActive`)
VALUES
('ca', 'Català' , 'Catalan' , TRUE),
('en', 'English' , 'English' , TRUE),
('es', 'Español' , 'Spanish' , TRUE),
('fr', 'Français' , 'French' , TRUE),
('mn', 'Португалий', 'Mongolian' , TRUE),
('pt', 'Português' , 'Portuguese', TRUE);
INSERT INTO `vn`.`warehouseAlias`(`id`, `name`) INSERT INTO `vn`.`warehouseAlias`(`id`, `name`)
VALUES VALUES
(1, 'Main Warehouse'), (1, 'Main Warehouse'),
@ -182,8 +152,9 @@ INSERT INTO `vn`.`parking` (`id`, `column`, `row`, `sectorFk`, `code`, `pickingO
INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `parked`, `userFk`) INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `parked`, `userFk`)
VALUES VALUES
('GVC', '1', '0', '1', '0', '1106'), ('GVC', 1, 0, 1, 0, 1106),
('HEJ', '2', '0', '1', '0', '1106'); ('HEJ', 2, 0, 1, 0, 1106),
('UXN', 1, 0, 1, 0, 1106);
INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`code`, `maxAmount`) INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`,`code`, `maxAmount`)
VALUES VALUES
@ -1095,10 +1066,11 @@ INSERT INTO `vn`.`saleComponent`(`saleFk`, `componentFk`, `value`)
(32, 36, -92.324), (32, 36, -92.324),
(32, 39, 0.994); (32, 39, 0.994);
INSERT INTO `vn`.`itemShelving` (`id`, `itemFk`, `shelvingFk`, `shelve`, `deep`, `quantity`, `visible`, `available`, `grouping`, `packing`, `level`, `userFk`) INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `shelve`, `visible`, `grouping`, `packing`, `userFk`)
VALUES VALUES
('1', '2', 'GVC', 'A', '0', '1', '1', '1', '1', '1', '1', '1106'), (2, 'GVC', 'A', 1, 1, 1, 1106),
('2', '4', 'HEJ', 'A', '0', '2', '1', '1', '1', '1', '1', '1106'); (4, 'HEJ', 'A', 1, 1, 1, 1106),
(1, 'UXN', 'A', 2, 12, 12, 1106);
INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`) INSERT INTO `vn`.`itemShelvingSale` (`itemShelvingFk`, `saleFk`, `quantity`, `created`, `userFk`)
VALUES VALUES
@ -1152,14 +1124,6 @@ INSERT INTO `vn`.`parking` (`column`, `row`, `sectorFk`, `code`, `pickingOrder`)
VALUES VALUES
('100', '01', 1, '100-01', 1); ('100', '01', 1, '100-01', 1);
INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `priority`, `userFk`)
VALUES
('UXN', 1, 1, 1106);
INSERT INTO `vn`.`itemShelving` (`itemFk`, `shelvingFk`, `shelve`, `deep`, `quantity`, `visible`, `available`, `grouping`, `packing`, `level`, `userFk`)
VALUES
(1, 'UXN', 'A', 2, 12, 12, 12, 12, 12, 1, 1106);
INSERT INTO `vn`.`ticketCollection` (`ticketFk`, `collectionFk`, `level`) INSERT INTO `vn`.`ticketCollection` (`ticketFk`, `collectionFk`, `level`)
VALUES VALUES
(1, 1, 1); (1, 1, 1);
@ -2555,7 +2519,7 @@ INSERT INTO `bs`.`sale` (`saleFk`, `amount`, `dated`, `typeFk`, `clientFk`)
INSERT INTO `vn`.`docuware` (`code`, `fileCabinetName`, `dialogName` , `find`) INSERT INTO `vn`.`docuware` (`code`, `fileCabinetName`, `dialogName` , `find`)
VALUES VALUES
('deliveryClientTest', 'deliveryClientTest', 'findTest', 'word'); ('deliveryClient', 'deliveryClient', 'findTicket', 'word');
INSERT INTO `vn`.`docuwareConfig` (`url`) INSERT INTO `vn`.`docuwareConfig` (`url`)
VALUES VALUES

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,8 @@ echo "" > "$DUMPED_FILE"
TABLES=( TABLES=(
util util
config config
version
versionLog
) )
dump_tables ${TABLES[@]} dump_tables ${TABLES[@]}
@ -74,10 +76,20 @@ dump_tables ${TABLES[@]}
TABLES=( TABLES=(
hedera hedera
browser
imageCollection imageCollection
imageCollectionSize
language
link
location
menu
message
metatag
newsTag
restPriv
social
tpvError tpvError
tpvResponse tpvResponse
imageCollectionSize
) )
dump_tables ${TABLES[@]} dump_tables ${TABLES[@]}

View File

@ -49,6 +49,7 @@ IGNORETABLES=(
--ignore-table=vn.grantGroup --ignore-table=vn.grantGroup
--ignore-table=vn.invoiceCorrection__ --ignore-table=vn.invoiceCorrection__
--ignore-table=vn.itemTaxCountrySpain --ignore-table=vn.itemTaxCountrySpain
--ignore-table=vn.itemShelvingPlacementSupplyStock__
--ignore-table=vn.itemFreeNumber__ --ignore-table=vn.itemFreeNumber__
--ignore-table=vn.mail__ --ignore-table=vn.mail__
--ignore-table=vn.manaSpellers --ignore-table=vn.manaSpellers

View File

@ -982,7 +982,7 @@ export default {
save: 'vn-invoice-in-basic-data button[type=submit]' save: 'vn-invoice-in-basic-data button[type=submit]'
}, },
invoiceInTax: { invoiceInTax: {
addTaxButton: 'vn-invoice-in-tax vn-icon-button[icon="add_circle"]', addTaxButton: 'vn-invoice-in-tax vn-icon-button[vn-tooltip="Add tax"]',
thirdExpence: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.expenseFk"]', thirdExpence: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.expenseFk"]',
thirdTaxableBase: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-input-number[ng-model="invoiceInTax.taxableBase"]', thirdTaxableBase: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-input-number[ng-model="invoiceInTax.taxableBase"]',
thirdTaxType: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.taxTypeSageFk"]', thirdTaxType: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.taxTypeSageFk"]',

View File

@ -25,6 +25,9 @@
ng-model="invoiceInDueDay.bankFk" ng-model="invoiceInDueDay.bankFk"
url="Banks" url="Banks"
show-field="bank" show-field="bank"
select-fields="['id','bank']"
order="id"
search-function="$ctrl.bankSearchFunc($search)"
rule> rule>
<tpl-item>{{id}}: {{bank}}</tpl-item> <tpl-item>{{id}}: {{bank}}</tpl-item>
</vn-autocomplete> </vn-autocomplete>

View File

@ -17,6 +17,12 @@ class Controller extends Section {
this.card.reload(); this.card.reload();
}); });
} }
bankSearchFunc($search) {
return /^\d+$/.test($search)
? {id: $search}
: {bank: {like: '%' + $search + '%'}};
}
} }
ngModule.vnComponent('vnInvoiceInDueDay', { ngModule.vnComponent('vnInvoiceInDueDay', {

View File

@ -33,6 +33,13 @@
show-field="id" show-field="id"
rule> rule>
<tpl-item>{{id}}: {{name}}</tpl-item> <tpl-item>{{id}}: {{name}}</tpl-item>
<append>
<vn-icon-button
vn-tooltip="Create expense"
icon="add_circle"
vn-click-stop="createExpense.show()">
</vn-icon-button>
</append>
</vn-autocomplete> </vn-autocomplete>
<vn-input-number vn-one <vn-input-number vn-one
disabled="$ctrl.invoiceIn.currency.code != 'EUR'" disabled="$ctrl.invoiceIn.currency.code != 'EUR'"
@ -96,4 +103,41 @@
label="Save"> label="Save">
</vn-submit> </vn-submit>
</vn-button-bar> </vn-button-bar>
</form> </form>
<!-- Dialog of create expense-->
<vn-dialog
vn-id="createExpense"
on-accept="$ctrl.onResponse()">
<tpl-body>
<section>
<h5 class="vn-py-sm">{{$ctrl.$t('New expense')}}</h5>
<vn-horizontal>
<vn-textfield vn-one
vn-id="code"
label="Code"
ng-model="$ctrl.expense.code"
required="true"
vn-focus>
</vn-textfield>
<vn-check
vn-one
label="It's a withholding"
ng-model="$ctrl.expense.isWithheld">
</vn-check>
</vn-horizontal>
<vn-horizontal>
<vn-textfield vn-one
vn-id="description"
label="Description"
ng-model="$ctrl.expense.description"
required="true">
</vn-textfield>
</vn-horizontal>
</section>
</tpl-body>
<tpl-buttons>
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
<button response="accept" translate>Save</button>
</tpl-buttons>
</vn-dialog>

View File

@ -1,7 +1,12 @@
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 { class Controller extends Section {
constructor($element, $, vnWeekDays) {
super($element, $);
this.expense = {};
}
taxRate(invoiceInTax, taxRateSelection) { taxRate(invoiceInTax, taxRateSelection) {
const taxTypeSage = taxRateSelection && taxRateSelection.rate; const taxTypeSage = taxRateSelection && taxRateSelection.rate;
const taxableBase = invoiceInTax && invoiceInTax.taxableBase; const taxableBase = invoiceInTax && invoiceInTax.taxableBase;
@ -26,6 +31,27 @@ class Controller extends Section {
this.card.reload(); this.card.reload();
}); });
} }
onResponse() {
try {
if (!this.expense.code)
throw new Error(`The code can't be empty`);
if (!this.expense.description)
throw new UserError(`The description can't be empty`);
const data = [{
id: this.expense.code,
isWithheld: this.expense.isWithheld,
name: this.expense.description
}];
this.$http.post(`Expenses`, data) .then(() => {
this.vnApp.showSuccess(this.$t('Expense saved!'));
});
} catch (e) {
this.vnApp.showError(this.$t(e.message));
}
}
} }
ngModule.vnComponent('vnInvoiceInTax', { ngModule.vnComponent('vnInvoiceInTax', {

View File

@ -1,16 +1,19 @@
import './index.js'; import './index.js';
import watcher from 'core/mocks/watcher'; import watcher from 'core/mocks/watcher';
import crudModel from 'core/mocks/crud-model'; import crudModel from 'core/mocks/crud-model';
const UserError = require('vn-loopback/util/user-error');
describe('InvoiceIn', () => { describe('InvoiceIn', () => {
describe('Component tax', () => { describe('Component tax', () => {
let controller; let controller;
let $scope; let $scope;
let vnApp; let vnApp;
let $httpBackend;
beforeEach(ngModule('invoiceIn')); beforeEach(ngModule('invoiceIn'));
beforeEach(inject(($componentController, $rootScope, _vnApp_) => { beforeEach(inject(($componentController, $rootScope, _vnApp_, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
vnApp = _vnApp_; vnApp = _vnApp_;
jest.spyOn(vnApp, 'showError'); jest.spyOn(vnApp, 'showError');
$scope = $rootScope.$new(); $scope = $rootScope.$new();
@ -19,6 +22,7 @@ describe('InvoiceIn', () => {
const $element = angular.element('<vn-invoice-in-tax></vn-invoice-in-tax>'); const $element = angular.element('<vn-invoice-in-tax></vn-invoice-in-tax>');
controller = $componentController('vnInvoiceInTax', {$element, $scope}); controller = $componentController('vnInvoiceInTax', {$element, $scope});
controller.$.model = crudModel;
controller.invoiceIn = {id: 1}; controller.invoiceIn = {id: 1};
})); }));
@ -55,5 +59,56 @@ describe('InvoiceIn', () => {
expect(controller.card.reload).toHaveBeenCalledWith(); expect(controller.card.reload).toHaveBeenCalledWith();
}); });
}); });
describe('onResponse()', () => {
it('should return success message', () => {
controller.expense = {
code: 7050000005,
isWithheld: 0,
description: 'Test'
};
const data = [{
id: controller.expense.code,
isWithheld: controller.expense.isWithheld,
name: controller.expense.description
}];
jest.spyOn(controller.vnApp, 'showSuccess');
$httpBackend.expect('POST', `Expenses`, data).respond();
controller.onResponse();
$httpBackend.flush();
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Expense saved!');
});
it('should return an error if code is empty', () => {
controller.expense = {
code: null,
isWithheld: 0,
description: 'Test'
};
jest.spyOn(controller.vnApp, 'showError');
controller.onResponse();
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The code can't be empty`);
});
it('should return an error if description is empty', () => {
controller.expense = {
code: 7050000005,
isWithheld: 0,
description: null
};
jest.spyOn(controller.vnApp, 'showError');
controller.onResponse();
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The description can't be empty`);
});
});
}); });
}); });

View File

@ -0,0 +1,7 @@
Create expense: Crear gasto
New expense: Nuevo gasto
It's a withholding: Es una retención
The fields can't be empty: Los campos no pueden estar vacíos
The code can't be empty: El código no puede estar vacío
The description can't be empty: La descripción no puede estar vacía
Expense saved!: Gasto guardado!

View File

@ -17,9 +17,6 @@
}, },
"isWithheld": { "isWithheld": {
"type": "number" "type": "number"
},
"taxTypeFk": {
"type": "number"
} }
}, },
"relations": { "relations": {
@ -28,13 +25,5 @@
"model": "TaxType", "model": "TaxType",
"foreignKey": "taxTypeFk" "foreignKey": "taxTypeFk"
} }
}, }
"acls": [
{
"accessType": "READ",
"principalType": "ROLE",
"principalId": "$everyone",
"permission": "ALLOW"
}
]
} }

View File

@ -12,12 +12,12 @@
{"state": "supplier.card.basicData", "icon": "settings"}, {"state": "supplier.card.basicData", "icon": "settings"},
{"state": "supplier.card.fiscalData", "icon": "account_balance"}, {"state": "supplier.card.fiscalData", "icon": "account_balance"},
{"state": "supplier.card.billingData", "icon": "icon-payment"}, {"state": "supplier.card.billingData", "icon": "icon-payment"},
{"state": "supplier.card.address.index", "icon": "icon-delivery"}, {"state": "supplier.card.log", "icon": "history"},
{"state": "supplier.card.account", "icon": "icon-account"}, {"state": "supplier.card.account", "icon": "icon-account"},
{"state": "supplier.card.contact", "icon": "contact_phone"}, {"state": "supplier.card.contact", "icon": "contact_phone"},
{"state": "supplier.card.agencyTerm.index", "icon": "icon-agency-term"}, {"state": "supplier.card.address.index", "icon": "icon-delivery"},
{"state": "supplier.card.log", "icon": "history"}, {"state": "supplier.card.consumption", "icon": "show_chart"},
{"state": "supplier.card.consumption", "icon": "show_chart"} {"state": "supplier.card.agencyTerm.index", "icon": "icon-agency-term"}
] ]
}, },
"keybindings": [ "keybindings": [
@ -97,7 +97,7 @@
"url": "/index", "url": "/index",
"state": "supplier.card.agencyTerm.index", "state": "supplier.card.agencyTerm.index",
"component": "vn-supplier-agency-term-index", "component": "vn-supplier-agency-term-index",
"description": "Autonomous", "description": "Agency Agreement",
"params": { "params": {
"supplier": "$ctrl.supplier" "supplier": "$ctrl.supplier"
} }

View File

@ -35,8 +35,8 @@
</div> </div>
<p v-html="$t('redmineLink')"></p> <p v-html="$t('redmineLink')"></p>
<div class="external-link vn-pa-sm vn-m-md"> <div class="external-link vn-pa-sm vn-m-md">
<a href="https://redmine.verdnatura.es/projects/refactor/issues?query_id=112" target="_blank"> <a href="https://redmine.verdnatura.es/projects/desarrollo/issues?query_id=112" target="_blank">
https://redmine.verdnatura.es/projects/refactor/issues?query_id=112 https://redmine.verdnatura.es/projects/desarrollo/issues?query_id=112
</a> </a>
</div> </div>
</div> </div>