2569 - Section changes
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:
parent
f4e9fc83ec
commit
7693a1c449
|
@ -20,6 +20,9 @@
|
|||
"Container": {
|
||||
"dataSource": "storage"
|
||||
},
|
||||
"Continent": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Collection": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "Continent",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "continent"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "number"
|
||||
},
|
||||
"name": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"id": true,
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"acls": [{
|
||||
"accessType": "READ",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}]
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
CREATE TABLE `vn`.continent
|
||||
(
|
||||
id TINYINT(4) AUTO_INCREMENT,
|
||||
name VARCHAR(50) NOT NULL,
|
||||
code VARCHAR(2) NOT NULL COLLATE utf8_general_ci,
|
||||
CONSTRAINT continent_pk
|
||||
PRIMARY KEY (id)
|
||||
)
|
||||
COMMENT 'World continents';
|
||||
|
||||
CREATE UNIQUE INDEX continent_name_uindex
|
||||
ON `vn`.continent (name);
|
||||
|
||||
INSERT IGNORE INTO `vn`.continent (`name`, `code`)
|
||||
VALUES
|
||||
('Asia', 'AS'),
|
||||
('América', 'AM'),
|
||||
('África', 'AF'),
|
||||
('Europa', 'EU'),
|
||||
('Oceanía', 'OC');
|
|
@ -0,0 +1,13 @@
|
|||
ALTER TABLE `vn`.`country`
|
||||
ADD COLUMN `continentFk` TINYINT(4) NULL AFTER `ibanLength`,
|
||||
ADD INDEX `continent_id_fk_idx` (`continentFk` ASC);
|
||||
|
||||
ALTER TABLE `vn`.`country`
|
||||
ADD CONSTRAINT `continent_id_fk`
|
||||
FOREIGN KEY (`continentFk`)
|
||||
REFERENCES `vn`.`continent` (`id`)
|
||||
ON DELETE NO ACTION
|
||||
ON UPDATE CASCADE;
|
||||
|
||||
UPDATE `vn`.`country` SET `continentFk` = '2' WHERE (`id` = '11');
|
||||
UPDATE `vn`.`country` SET `continentFk` = '2' WHERE (`id` = '13');
|
|
@ -3,3 +3,4 @@ host = localhost
|
|||
port = 3306
|
||||
user = root
|
||||
password = root
|
||||
default-character-set=utf8
|
||||
|
|
|
@ -92,17 +92,17 @@ INSERT INTO `vn`.`worker`(`id`, `code`, `firstName`, `lastName`, `userFk`,`bossF
|
|||
(109, 'HLK', 'Bruce' , 'Banner', 109, 19, 432978109),
|
||||
(110, 'JJJ', 'Jessica' , 'Jones' , 110, 19, 432978110);
|
||||
|
||||
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`)
|
||||
INSERT INTO `vn`.`country`(`id`, `country`, `isUeeMember`, `code`, `currencyFk`, `ibanLength`, `continentFk`)
|
||||
VALUES
|
||||
(1, 'España', 1, 'ES', 1, 24),
|
||||
(2, 'Italia', 1, 'IT', 1, 27),
|
||||
(3, 'Alemania', 1, 'DE', 1, 22),
|
||||
(4, 'Rumania', 1, 'RO', 1, 24),
|
||||
(5, 'Holanda', 1, 'NL', 1, 18),
|
||||
(8, 'Portugal', 1, 'PT', 1, 27),
|
||||
(13,'Ecuador', 0, 'EC', 1, 24),
|
||||
(19,'Francia', 1, 'FR', 1, 27),
|
||||
(30,'Canarias', 1, 'IC', 1, 24);
|
||||
(1, 'España', 1, 'ES', 1, 24, 4),
|
||||
(2, 'Italia', 1, 'IT', 1, 27, 4),
|
||||
(3, 'Alemania', 1, 'DE', 1, 22, 4),
|
||||
(4, 'Rumania', 1, 'RO', 1, 24, 4),
|
||||
(5, 'Holanda', 1, 'NL', 1, 18, 4),
|
||||
(8, 'Portugal', 1, 'PT', 1, 27, 4),
|
||||
(13,'Ecuador', 0, 'EC', 1, 24, 2),
|
||||
(19,'Francia', 1, 'FR', 1, 27, 4),
|
||||
(30,'Canarias', 1, 'IC', 1, 24, 4);
|
||||
|
||||
INSERT INTO `hedera`.`language` (`code`, `name`, `orgName`, `isActive`)
|
||||
VALUES
|
||||
|
@ -118,13 +118,13 @@ INSERT INTO `vn`.`warehouseAlias`(`id`, `name`)
|
|||
(1, 'Main Warehouse'),
|
||||
(2, 'Silla');
|
||||
|
||||
INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasStowaway`, `hasDms`, `hasComission`, `aliasFk`)
|
||||
INSERT INTO `vn`.`warehouse`(`id`, `name`, `isComparative`, `isInventory`, `hasAvailable`, `isManaged`, `hasStowaway`, `hasDms`, `hasComission`, `aliasFk`, `countryFk`)
|
||||
VALUES
|
||||
(1, 'Warehouse One', 1, 1, 1, 1, 1, 1, 1, 2),
|
||||
(2, 'Warehouse Two', 1, 1, 1, 1, 0, 0, 1, 2),
|
||||
(3, 'Warehouse Three', 1, 1, 1, 1, 0, 0, 0, 2),
|
||||
(4, 'Warehouse Four', 1, 1, 1, 1, 0, 0, 0, 2),
|
||||
(5, 'Warehouse Five', 1, 1, 1, 1, 0, 0, 0, 2);
|
||||
(1, 'Warehouse One', 1, 1, 1, 1, 1, 1, 1, 2, 1),
|
||||
(2, 'Warehouse Two', 1, 1, 1, 1, 0, 0, 1, 2, 13),
|
||||
(3, 'Warehouse Three', 1, 1, 1, 1, 0, 0, 0, 2, 1),
|
||||
(4, 'Warehouse Four', 1, 1, 1, 1, 0, 0, 0, 2, 1),
|
||||
(5, 'Warehouse Five', 1, 1, 1, 1, 0, 0, 0, 2, 1);
|
||||
|
||||
INSERT INTO `vn`.`sector`(`id`, `description`, `warehouseFk`, `isPreviousPreparedByPacking`, `code`, `pickingPlacement`, `path`)
|
||||
VALUES
|
||||
|
@ -1250,11 +1250,11 @@ INSERT INTO `vn`.`travel`(`id`,`shipped`, `landed`, `warehouseInFk`, `warehouseO
|
|||
(1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 2, 1, 100.00, 1000, 'first travel', 1, 1),
|
||||
(2, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 150, 2000, 'second travel', 2, 2),
|
||||
(3, CURDATE(), CURDATE(), 1, 2, 1, 0.00, 0.00, 'third travel', 1, 1),
|
||||
(4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 50.00, 500, 'fourth travel', 0, 2),
|
||||
(5, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 2, 1, 50.00, 500, 'fifth travel', 1, 1),
|
||||
(6, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 2, 1, 50.00, 500, 'sixth travel', 1, 2),
|
||||
(7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500, 'seventh travel', 2, 1),
|
||||
(8, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 2, 1, 50.00, 500, 'eight travel', 1, 2);
|
||||
(4, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 3, 1, 50.00, 500, 'fourth travel', 0, 2),
|
||||
(5, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 3, 3, 1, 50.00, 500, 'fifth travel', 1, 1),
|
||||
(6, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 50.00, 500, 'sixth travel', 1, 2),
|
||||
(7, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 4, 1, 50.00, 500, 'seventh travel', 2, 1),
|
||||
(8, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 5, 1, 1, 50.00, 500, 'eight travel', 1, 2);
|
||||
|
||||
INSERT INTO `vn`.`entry`(`id`, `supplierFk`, `created`, `travelFk`, `isConfirmed`, `companyFk`, `ref`,`isInventory`, `isRaid`, `notes`, `evaNotes`)
|
||||
VALUES
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
<div></div>
|
||||
<div translate>
|
||||
<ng-transclude></ng-transclude>
|
||||
</div>
|
|
@ -1,19 +1,10 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from '../../lib/component';
|
||||
import './style.scss';
|
||||
|
||||
export default class Th extends Component {
|
||||
constructor($element, $, $transclude) {
|
||||
super($element, $);
|
||||
|
||||
export default class Th {
|
||||
constructor($element) {
|
||||
this._order = 'ASC';
|
||||
this.column = $element[0];
|
||||
$element.on('click', () => this.onToggleOrder());
|
||||
|
||||
$transclude($clone => {
|
||||
const text = this.$t($clone.text()); // Not updating translations
|
||||
$element.append(text ? text : $clone);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -81,9 +72,10 @@ export default class Th extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
Th.$inject = ['$element', '$scope', '$transclude'];
|
||||
Th.$inject = ['$element'];
|
||||
|
||||
ngModule.vnComponent('vnTh', {
|
||||
template: require('./index.html'),
|
||||
transclude: true,
|
||||
controller: Th,
|
||||
bindings: {
|
||||
|
|
|
@ -6,18 +6,18 @@ vn-th {
|
|||
}
|
||||
|
||||
vn-th[field] {
|
||||
&.active:after {
|
||||
&.active > :after {
|
||||
color: $color-font;
|
||||
opacity: 1;
|
||||
}
|
||||
&.desc:after {
|
||||
&.desc > :after {
|
||||
content: 'arrow_drop_down';
|
||||
}
|
||||
&.asc:after {
|
||||
&.asc > :after {
|
||||
content: 'arrow_drop_up';
|
||||
}
|
||||
|
||||
&:after {
|
||||
& > :after {
|
||||
font-family: 'Material Icons';
|
||||
content: 'arrow_drop_down';
|
||||
position: absolute;
|
||||
|
@ -27,7 +27,7 @@ vn-th[field] {
|
|||
opacity: 0
|
||||
|
||||
}
|
||||
&:hover:after {
|
||||
&:hover > :after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
|
@ -17,7 +17,7 @@
|
|||
ui-sref="{{::$ctrl.summaryState}}({id: $ctrl.descriptor.id})">
|
||||
<vn-icon icon="desktop_windows"></vn-icon>
|
||||
</a>
|
||||
<vn-icon-button ng-if="$ctrl.$transclude.isSlotFilled('menu')"
|
||||
<vn-icon-button ng-if="!$ctrl.$transclude.isSlotFilled('dotMenu')"
|
||||
ng-class="::{invisible: !$ctrl.$transclude.isSlotFilled('menu')}"
|
||||
icon="more_vert"
|
||||
vn-popover="menu">
|
||||
|
|
|
@ -84,6 +84,32 @@ class VnMySQL extends MySQL {
|
|||
return wrappedConnector.buildWhere(null, where);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs SQL GROUP BY clause from Loopback filter.
|
||||
*
|
||||
* @param {Object} group The group by definition
|
||||
* @return {String} Built SQL group by
|
||||
*/
|
||||
makeGroupBy(group) {
|
||||
if (!group)
|
||||
return '';
|
||||
if (typeof group === 'string')
|
||||
group = [group];
|
||||
|
||||
let clauses = [];
|
||||
|
||||
for (let clause of group) {
|
||||
let sqlGroup = '';
|
||||
let t = clause.split(/[\s,]+/);
|
||||
|
||||
sqlGroup += this.escapeName(t[0]);
|
||||
|
||||
clauses.push(sqlGroup);
|
||||
}
|
||||
|
||||
return `GROUP BY ${clauses.join(', ')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs SQL order clause from Loopback filter.
|
||||
*
|
||||
|
|
|
@ -5,10 +5,8 @@ describe('item getBalance()', () => {
|
|||
let params = {where: {itemFk: 1, warehouseFk: 2}};
|
||||
let result = await app.models.Item.getBalance(params);
|
||||
|
||||
expect(result.length).toBe(4);
|
||||
expect(result.length).toBe(2);
|
||||
expect(result[0].balance).toBe(-100);
|
||||
expect(result[1].balance).toBe(-110);
|
||||
expect(result[2].balance).toBe(-110);
|
||||
expect(result[3].balance).toBe(-210);
|
||||
expect(result[1].balance).toBe(-200);
|
||||
});
|
||||
});
|
||||
|
|
|
@ -67,6 +67,10 @@ module.exports = Self => {
|
|||
arg: 'ref',
|
||||
type: 'string',
|
||||
description: 'The reference'
|
||||
}, {
|
||||
arg: 'continent',
|
||||
type: 'string',
|
||||
description: 'The continent code'
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
|
@ -97,6 +101,8 @@ module.exports = Self => {
|
|||
return {'t.landed': {gte: value}};
|
||||
case 'landedTo':
|
||||
return {'t.landed': {lte: value}};
|
||||
case 'continent':
|
||||
return {'cnt.code': value};
|
||||
case 'id':
|
||||
case 'agencyFk':
|
||||
case 'warehouseOutFk':
|
||||
|
@ -107,17 +113,21 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
filter = mergeFilters(ctx.args.filter, {where});
|
||||
filter = mergeFilters(filter, {where});
|
||||
|
||||
let stmts = [];
|
||||
let stmt;
|
||||
stmts.push('DROP TEMPORARY TABLE IF EXISTS tmp.travel');
|
||||
stmt = new ParameterizedSQL(
|
||||
`SELECT
|
||||
tr.id,
|
||||
tr.ref,
|
||||
tr.shipped,
|
||||
tr.landed,
|
||||
tr.kg,
|
||||
`CREATE TEMPORARY TABLE tmp.travel
|
||||
(INDEX (id))
|
||||
ENGINE = MEMORY
|
||||
SELECT
|
||||
t.id,
|
||||
t.ref,
|
||||
t.shipped,
|
||||
t.landed,
|
||||
t.kg,
|
||||
am.id AS agencyModeFk,
|
||||
am.name AS agencyModeName,
|
||||
wo.id AS warehouseOutFk,
|
||||
|
@ -126,102 +136,78 @@ module.exports = Self => {
|
|||
w.name AS warehouseInName,
|
||||
SUM(b.stickers) AS stickers,
|
||||
s.id AS supplierFk,
|
||||
s.nickname AS supplierNickname
|
||||
FROM travel tr
|
||||
LEFT JOIN supplier s ON s.id = tr.cargoSupplierFk
|
||||
LEFT JOIN entry e ON e.travelFk = tr.id
|
||||
s.nickname AS cargoSupplierNickname,
|
||||
CAST(SUM(i.density * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as loadedKg,
|
||||
CAST(SUM(167.5 * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as volumeKg
|
||||
FROM travel t
|
||||
LEFT JOIN supplier s ON s.id = t.cargoSupplierFk
|
||||
LEFT JOIN entry e ON e.travelFk = t.id
|
||||
LEFT JOIN buy b ON b.entryFk = e.id
|
||||
LEFT JOIN packaging p ON p.id = b.packageFk
|
||||
LEFT JOIN packaging pkg ON pkg.id = b.packageFk
|
||||
LEFT JOIN item i ON i.id = b.itemFk
|
||||
LEFT JOIN itemType it ON it.id = i.typeFk
|
||||
JOIN warehouse w ON w.id = tr.warehouseInFk
|
||||
JOIN warehouse wo ON wo.id = tr.warehouseOutFk
|
||||
JOIN agencyMode am ON am.id = tr.agencyFk`
|
||||
JOIN warehouse w ON w.id = t.warehouseInFk
|
||||
JOIN warehouse wo ON wo.id = t.warehouseOutFk
|
||||
JOIN country c ON c.id = wo.countryFk
|
||||
LEFT JOIN continent cnt ON cnt.id = c.continentFk
|
||||
JOIN agencyMode am ON am.id = t.agencyFk`
|
||||
);
|
||||
|
||||
/* cast(sum(a.density * c.Etiquetas * IF(cb.Volumen, cb.Volumen, cb.X * cb.Y * cb.Z) / 1000000 ) as DECIMAL(10,0)) as loadedKg,
|
||||
cast(sum(167.5 * c.Etiquetas * IF(cb.Volumen, cb.Volumen, cb.X * cb.Y * cb.Z) / 1000000 ) as DECIMAL(10,0)) as volumeKg,
|
||||
pc.Alias as Carguera */
|
||||
stmt.merge(conn.makeWhere(filter.where));
|
||||
stmt.merge(conn.makeGroupBy('t.id'));
|
||||
stmt.merge(conn.makeLimit(filter));
|
||||
stmts.push(stmt);
|
||||
|
||||
// WHERE tr.landing >= @vDateFrom AND (wo.name="Colombia" OR wo.name="Ecuador")
|
||||
const travelsIndex = stmts.push('SELECT * FROM tmp.travel') - 1;
|
||||
|
||||
stmt.merge('GROUP BY tr.id');
|
||||
// stmt.merge(conn.makeSuffix(filter));
|
||||
const itemsIndex = stmts.push(stmt) - 1;
|
||||
stmt = new ParameterizedSQL(
|
||||
`SELECT
|
||||
e.id,
|
||||
e.travelFk,
|
||||
e.ref,
|
||||
e.loadPriority,
|
||||
s.name AS supplierName,
|
||||
SUM(b.stickers) AS stickers,
|
||||
e.evaNotes,
|
||||
e.notes,
|
||||
CAST(SUM(i.density * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as loadedkg,
|
||||
CAST(SUM(167.5 * b.stickers * IF(pkg.volume, pkg.volume, pkg.width * pkg.depth * pkg.height) / 1000000 ) as DECIMAL(10,0)) as volumeKg
|
||||
FROM entry e
|
||||
JOIN tmp.travel tr ON tr.id = e.travelFk
|
||||
JOIN buy b ON b.entryFk = e.id
|
||||
JOIN packaging pkg ON pkg.id = b.packageFk
|
||||
JOIN item i ON i.id = b.itemFk
|
||||
JOIN itemType it ON it.id = i.typeFk
|
||||
JOIN supplier s ON s.id = e.supplierFk`
|
||||
);
|
||||
|
||||
stmt.merge(conn.makeGroupBy('e.id'));
|
||||
stmt.merge(conn.makeOrderBy(filter.order));
|
||||
const entriesIndex = stmts.push(stmt) - 1;
|
||||
|
||||
stmts.push(`DROP TEMPORARY TABLE tmp.travel`);
|
||||
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const result = await conn.executeStmt(sql);
|
||||
return itemsIndex === 0 ? result : result[itemsIndex];
|
||||
|
||||
/*
|
||||
SET @vDateFrom:= TIMESTAMPADD(WEEK,-12,CURDATE());
|
||||
const travels = result[travelsIndex];
|
||||
const entries = result[entriesIndex];
|
||||
|
||||
SELECT
|
||||
1 as IsTravel,
|
||||
tr.id as travel,
|
||||
NULL as Entrada,
|
||||
ag.Agencia,
|
||||
tr.ref,
|
||||
tr.shipment,
|
||||
wo.name as OrigenCajas,
|
||||
tr.landing,
|
||||
w.name as Destino,
|
||||
sum(c.Etiquetas) as Etiquetas,
|
||||
NULL as Notas_Eva,
|
||||
kg,
|
||||
cast(sum(a.density * c.Etiquetas * IF(cb.Volumen, cb.Volumen, cb.X * cb.Y * cb.Z) / 1000000 ) as DECIMAL(10,0)) as loadedKg,
|
||||
cast(sum(167.5 * c.Etiquetas * IF(cb.Volumen, cb.Volumen, cb.X * cb.Y * cb.Z) / 1000000 ) as DECIMAL(10,0)) as volumeKg,
|
||||
NULL as loadPriority,
|
||||
NULL as Notas,
|
||||
pc.Alias as Carguera
|
||||
FROM travel tr
|
||||
LEFT JOIN Proveedores pc ON pc.Id_Proveedor = tr.cargoSupplierFk
|
||||
LEFT JOIN Entradas e ON e.travel_id = tr.id
|
||||
LEFT JOIN Compres c ON c.Id_Entrada = e.Id_Entrada
|
||||
LEFT JOIN Cubos cb ON cb.Id_Cubo = c.Id_Cubo
|
||||
LEFT JOIN Articles a ON a.Id_Article = c.Id_Article
|
||||
LEFT JOIN Tipos tp ON tp.tipo_id = a.tipo_id
|
||||
JOIN warehouse w ON w.id = tr.warehouse_id
|
||||
JOIN warehouse wo ON wo.id = tr.warehouse_id_out
|
||||
JOIN Agencias ag ON ag.Id_Agencia = tr.agency_id
|
||||
WHERE tr.landing >= @vDateFrom AND (wo.name="Colombia" OR wo.name="Ecuador")
|
||||
GROUP BY tr.id
|
||||
const travelsMap = new Map();
|
||||
for (let travel of travels)
|
||||
travelsMap.set(travel.id, travel);
|
||||
|
||||
UNION ALL
|
||||
for (let entry of entries) {
|
||||
const travel = travelsMap.get(entry.travelFk);
|
||||
|
||||
SELECT
|
||||
0 as IsTravel,
|
||||
e.travel_id as travel,
|
||||
e.Id_Entrada,
|
||||
p.Proveedor,
|
||||
e.Referencia,
|
||||
tr.shipment,
|
||||
wo.name as OrigenCajas,
|
||||
tr.landing,
|
||||
w.name as Destino,
|
||||
sum(Etiquetas) as Etiquetas,
|
||||
e.Notas_Eva,
|
||||
NULL as kg,
|
||||
cast(sum(a.density * c.Etiquetas * IF(cb.Volumen, cb.Volumen, cb.X * cb.Y * cb.Z) / 1000000 ) as DECIMAL(10,0)) as loadedkg,
|
||||
cast(sum(167.5 * c.Etiquetas * IF(cb.Volumen, cb.Volumen, cb.X * cb.Y * cb.Z) / 1000000 ) as DECIMAL(10,0)) as volumeKg,
|
||||
loadPriority,
|
||||
e.Notas,
|
||||
pc.Alias as carguera
|
||||
if (travel) {
|
||||
if (!travel.entries) travel.entries = [];
|
||||
|
||||
FROM Entradas e
|
||||
JOIN Compres c ON c.Id_Entrada = e.Id_Entrada
|
||||
JOIN Cubos cb ON cb.Id_Cubo = c.Id_Cubo
|
||||
JOIN Articles a ON a.Id_Article = c.Id_Article
|
||||
JOIN Tipos tp ON tp.tipo_id = a.tipo_id
|
||||
JOIN Proveedores p ON p.Id_Proveedor = e.Id_Proveedor
|
||||
JOIN travel tr ON tr.id = e.travel_id
|
||||
LEFT JOIN Proveedores pc ON pc.Id_Proveedor = tr.cargoSupplierFk
|
||||
JOIN warehouse w ON w.id = tr.warehouse_id
|
||||
JOIN warehouse wo ON wo.id = tr.warehouse_id_out
|
||||
WHERE tr.landing >= @vDateFrom AND (wo.name="Colombia" OR wo.name="Ecuador")
|
||||
GROUP BY e.Id_Entrada
|
||||
) sub
|
||||
ORDER BY landing ASC, shipment ASC,travel, IsTravel DESC, (loadPriority > 0) DESC,loadPriority, Agencia, Notas_Eva ; */
|
||||
travel.entries.push(entry);
|
||||
}
|
||||
}
|
||||
|
||||
return travels;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('Travel extraCommunityFilter()', () => {
|
||||
const filter = {
|
||||
order: 'landed ASC, shipped ASC, travelFk, loadPriority, agencyModeFk, evaNotes',
|
||||
};
|
||||
it('should return the travel matching "search"', async() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
search: 2
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
const firstRow = result[0];
|
||||
const entries = firstRow.entries;
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
expect(firstRow.id).toEqual(2);
|
||||
expect(entries.length).toEqual(2);
|
||||
});
|
||||
|
||||
it('should return the travel matching "search" by ref', async() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
search: 'third'
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
const firstRow = result[0];
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
expect(firstRow.id).toEqual(3);
|
||||
});
|
||||
|
||||
it('should return the travel matching "warehouse out"', async() => {
|
||||
const ctx = {
|
||||
args: {
|
||||
warehouseOutFk: 2
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
});
|
||||
|
||||
it('should return the routes matching "landed from" and "landed to"', async() => {
|
||||
const from = new Date();
|
||||
const to = new Date();
|
||||
from.setHours(0, 0, 0, 0);
|
||||
to.setHours(23, 59, 59, 999);
|
||||
to.setDate(to.getDate() + 14);
|
||||
const ctx = {
|
||||
args: {
|
||||
landedFrom: from,
|
||||
landedTo: to
|
||||
}
|
||||
};
|
||||
|
||||
const result = await app.models.Travel.extraCommunityFilter(ctx, filter);
|
||||
|
||||
expect(result.length).toEqual(1);
|
||||
});
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
Reference: Referencia
|
||||
Wh. In: Almacén entrada
|
||||
Wh. Out: Almacén salida
|
||||
Wh. In: Alm. entrada
|
||||
Wh. Out: Alm. salida
|
||||
Shipped: F. envío
|
||||
Landed: F. entrega
|
||||
Total entries: Entradas totales
|
|
@ -0,0 +1,91 @@
|
|||
<div class="search-panel">
|
||||
<form ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="General search"
|
||||
ng-model="filter.search"
|
||||
info="Search travels by id"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Reference"
|
||||
ng-model="filter.ref">
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Total entries"
|
||||
ng-model="filter.totalEntries">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Travel id"
|
||||
ng-model="filter.id">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete vn-one
|
||||
label="Agency"
|
||||
ng-model="filter.agencyFk"
|
||||
url="AgencyModes"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Shipped from"
|
||||
ng-model="filter.shippedFrom">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Shipped to"
|
||||
ng-model="filter.shippedTo">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Landed from"
|
||||
ng-model="filter.landedFrom">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="Landed to"
|
||||
ng-model="filter.landedTo">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
label="Warehouse In"
|
||||
ng-model="filter.warehouseInFk"
|
||||
url="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
label="Warehouse Out"
|
||||
ng-model="filter.warehouseOutFk"
|
||||
url="Warehouses"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
label="Continent Out"
|
||||
ng-model="filter.continent"
|
||||
url="Continents"
|
||||
show-field="name"
|
||||
value-field="code">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-mt-lg">
|
||||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
</form>
|
||||
</div>
|
|
@ -0,0 +1,7 @@
|
|||
import ngModule from '../module';
|
||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||
|
||||
ngModule.vnComponent('vnExtraCommunitySearchPanel', {
|
||||
template: require('./index.html'),
|
||||
controller: SearchPanel
|
||||
});
|
|
@ -1,49 +1,111 @@
|
|||
<vn-crud-model auto-load="true"
|
||||
vn-id="model"
|
||||
url="Travels/extraCommunityFilter"
|
||||
data="travels">
|
||||
data="travels"
|
||||
order="landed ASC, shipped ASC, travelFk, loadPriority, agencyModeFk, evaNotes"
|
||||
limit="20">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
vn-focus
|
||||
placeholder="Search by travel id"
|
||||
info="Search by travel id"
|
||||
panel="vn-extra-community-search-panel"
|
||||
suggested-filter="$ctrl.defaultFilter"
|
||||
filter="$ctrl.defaultFilter"
|
||||
info="Search by travel id or reference"
|
||||
auto-state="false"
|
||||
model="model">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<vn-data-viewer model="model">
|
||||
<vn-card>
|
||||
<section ng-repeat="travel in travels" class="vn-pa-md">
|
||||
<vn-horizontal class="header">
|
||||
<vn-table>
|
||||
<vn-data-viewer model="model" class="travel-list">
|
||||
<vn-card ng-repeat="travel in travels" class="vn-mb-md">
|
||||
<section class="vn-pa-md">
|
||||
<vn-table vn-droppable="$ctrl.onDrop($event)" ng-attr-id="{{::travel.id}}">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th>{{travel.id}}</vn-th>
|
||||
<vn-th>{{travel.supplierNickname}}</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
</vn-table>
|
||||
<!-- <h5><span></span></h5> -->
|
||||
</vn-horizontal>
|
||||
<!-- <vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th class="waste-family">Family</vn-th>
|
||||
<vn-th number>Percentage</vn-th>
|
||||
<vn-th number>Dwindle</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
<vn-tr ng-if="$index == 0">
|
||||
<vn-th shrink>Id</vn-th>
|
||||
<vn-th expand>Supplier</vn-th>
|
||||
<vn-th expand>Freighter</vn-th>
|
||||
<vn-th>Reference</vn-th>
|
||||
<vn-th number>Packages</vn-th>
|
||||
<vn-th number>Bl. KG</vn-th>
|
||||
<vn-th number>Phy. KG</vn-th>
|
||||
<vn-th number>Vol. KG</vn-th>
|
||||
<vn-th expand translate-attr="{title: 'Warehouse Out'}">
|
||||
Wh. Out
|
||||
</vn-th>
|
||||
<vn-th expand>Shipped</vn-th>
|
||||
<vn-th expand translate-attr="{title: 'Warehouse In'}">
|
||||
Wh. In
|
||||
</vn-th>
|
||||
<vn-th expand>Landed</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="waste in detail.lines">
|
||||
<vn-td class="waste-family">{{::waste.family}}</vn-td>
|
||||
<vn-td number>{{::(waste.percentage / 100) | percentage: 2}}</vn-td>
|
||||
<vn-td number>{{::waste.dwindle | currency: 'EUR'}}</vn-td>
|
||||
<vn-td number>{{::waste.total | currency: 'EUR'}}</vn-td>
|
||||
<vn-tr class="header">
|
||||
<vn-td>
|
||||
<span class="link"
|
||||
ng-click="travelDescriptor.show($event, travel.id)">
|
||||
{{::travel.id}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td expand>{{::travel.agencyModeName}}</vn-td>
|
||||
<vn-td expand>{{::travel.cargoSupplierNickname}}</vn-td>
|
||||
<vn-td-editable expand>
|
||||
<text>{{travel.ref}}</text>
|
||||
<field>
|
||||
<vn-textfield class="dense" vn-focus
|
||||
ng-model="travel.ref"
|
||||
on-change="$ctrl.changeReference(travel)">
|
||||
</vn-textfield>
|
||||
</field>
|
||||
</vn-td-editable>
|
||||
<vn-td number>{{::travel.stickers}}</vn-td>
|
||||
<vn-td number>{{::travel.kg}}</vn-td>
|
||||
<vn-td number>{{::travel.loadedKg}}</vn-td>
|
||||
<vn-td number>{{::travel.volumeKg}}</vn-td>
|
||||
<vn-td expand>{{::travel.warehouseOutName}}</vn-td>
|
||||
<vn-td expand>{{::travel.shipped | date: 'dd/MM/yyyy'}}</vn-td>
|
||||
<vn-td expand>{{::travel.warehouseInName}}</vn-td>
|
||||
<vn-td expand>{{::travel.landed | date: 'dd/MM/yyyy'}}</vn-td>
|
||||
</vn-tr>
|
||||
<a href="#" ng-repeat="entry in travel.entries" class="vn-tr" draggable
|
||||
ng-attr-id="{{::entry.id}}"
|
||||
ng-click="$event.preventDefault()">
|
||||
<vn-td>
|
||||
<span class="link"
|
||||
ng-click="entryDescriptor.show($event, entry.id)">
|
||||
{{::entry.id}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{::entry.supplierName}}</vn-td>
|
||||
<vn-td></vn-td>
|
||||
<vn-td expand>{{::entry.ref}}</vn-td>
|
||||
<vn-th number>{{::entry.stickers}}</vn-th>
|
||||
<vn-td number></vn-td>
|
||||
<vn-td number>{{::entry.loadedkg}}</vn-td>
|
||||
<vn-td number>{{::entry.volumeKg}}</vn-td>
|
||||
<vn-td>
|
||||
<span nf-if="::entry.notes" vn-tooltip="{{::entry.notes}}">
|
||||
{{::entry.notes}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>
|
||||
<span nf-if="::entry.evaNotes" vn-tooltip="{{::entry.evaNotes}}">
|
||||
{{::entry.evaNotes}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td></vn-td>
|
||||
<vn-td></vn-td>
|
||||
</a>
|
||||
</vn-tbody>
|
||||
</vn-table> -->
|
||||
</vn-table>
|
||||
</section>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<vn-travel-descriptor-popover
|
||||
vn-id="travelDescriptor">
|
||||
</vn-travel-descriptor-popover>
|
||||
<vn-entry-descriptor-popover
|
||||
vn-id="entryDescriptor">
|
||||
</vn-entry-descriptor-popover>
|
||||
|
||||
|
|
|
@ -2,7 +2,90 @@ import ngModule from '../module';
|
|||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
const draggable = this.element.querySelector('.travel-list');
|
||||
draggable.addEventListener('dragstart',
|
||||
event => this.dragStart(event));
|
||||
draggable.addEventListener('dragend',
|
||||
event => this.dragEnd(event));
|
||||
|
||||
this.draggableElement = 'a[draggable]';
|
||||
this.droppableElement = 'vn-table[vn-droppable]';
|
||||
|
||||
const scopeDays = 14;
|
||||
const landedFrom = new Date();
|
||||
landedFrom.setHours(0, 0, 0, 0);
|
||||
|
||||
const landedTo = new Date();
|
||||
landedTo.setDate(landedTo.getDate() + scopeDays);
|
||||
landedTo.setHours(23, 59, 59, 59);
|
||||
|
||||
this.defaultFilter = {
|
||||
landedFrom: landedFrom,
|
||||
landedTo: landedTo,
|
||||
continent: 'AM'
|
||||
};
|
||||
}
|
||||
|
||||
findDraggable($event) {
|
||||
const target = $event.target;
|
||||
const draggable = target.closest(this.draggableElement);
|
||||
|
||||
return draggable;
|
||||
}
|
||||
|
||||
findDroppable($event) {
|
||||
const target = $event.target;
|
||||
const droppable = target.closest(this.droppableElement);
|
||||
|
||||
return droppable;
|
||||
}
|
||||
|
||||
dragStart($event) {
|
||||
const draggable = this.findDraggable($event);
|
||||
draggable.classList.add('dragging');
|
||||
|
||||
const id = draggable.getAttribute('id');
|
||||
this.entryId = id;
|
||||
this.entry = draggable;
|
||||
}
|
||||
|
||||
dragEnd($event) {
|
||||
const draggable = this.findDraggable($event);
|
||||
draggable.classList.remove('dragging');
|
||||
this.entryId = null;
|
||||
this.entry = null;
|
||||
}
|
||||
|
||||
onDrop($event) {
|
||||
const model = this.$.model;
|
||||
const droppable = this.findDroppable($event);
|
||||
const travelId = droppable.getAttribute('id');
|
||||
|
||||
const currentDroppable = this.entry.closest(this.droppableElement);
|
||||
|
||||
if (currentDroppable == droppable) return;
|
||||
|
||||
if (this.entryId && travelId) {
|
||||
const path = `Entries/${this.entryId}`;
|
||||
this.$http.patch(path, {travelFk: travelId})
|
||||
.then(() => model.refresh())
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
||||
}
|
||||
}
|
||||
|
||||
changeReference(travel) {
|
||||
const params = {ref: travel.ref};
|
||||
const endpoint = `Travels/${travel.id}`;
|
||||
this.$http.patch(endpoint, params)
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnTravelExtraCommunity', {
|
||||
template: require('./index.html'),
|
||||
controller: Section
|
||||
controller: Controller
|
||||
});
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Travel Component vnTravelExtraCommunity', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let travel = {
|
||||
id: 1,
|
||||
warehouseInFk: 1,
|
||||
totalEntries: 3,
|
||||
isDelivered: false
|
||||
};
|
||||
|
||||
beforeEach(ngModule('travel'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
const $element = angular.element('<vn-travel-extra-community></vn-travel-extra-community>');
|
||||
controller = $componentController('vnTravelExtraCommunity', {$element});
|
||||
controller.$.summary = {show: jasmine.createSpy('show')};
|
||||
}));
|
||||
|
||||
describe('changeReference()', () => {
|
||||
it('should make an HTTP query', () => {
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
|
||||
const travel = {id: 1, ref: 'New reference'};
|
||||
const expectedData = {ref: 'New reference'};
|
||||
$httpBackend.expect('PATCH', `Travels/${travel.id}`, expectedData).respond(200);
|
||||
controller.changeReference(travel);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
||||
});
|
||||
});
|
||||
|
||||
xdescribe('changeReference()', () => {
|
||||
it('should make an HTTP query', () => {
|
||||
let event = new MouseEvent('click', {
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
controller.preview(event, travel);
|
||||
|
||||
expect(controller.$.summary.show).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1 +1,8 @@
|
|||
Family: Familia
|
||||
Extra community: Extra comunitarios
|
||||
Freighter: Transitario
|
||||
Bl. KG: KG Bloq.
|
||||
Phy. KG: KG físico
|
||||
Vol. KG: KG Vol.
|
||||
Search by travel id or reference: Buscar por id travel o referencia
|
||||
Continent Out: Continente salida
|
|
@ -3,7 +3,6 @@
|
|||
vn-travel-extra-community {
|
||||
.header {
|
||||
margin-bottom: 16px;
|
||||
text-transform: uppercase;
|
||||
font-size: 1.25rem;
|
||||
line-height: 1;
|
||||
padding: 7px;
|
||||
|
@ -11,15 +10,46 @@ vn-travel-extra-community {
|
|||
padding-bottom: 4px;
|
||||
font-weight: lighter;
|
||||
background-color: #fde6ca;
|
||||
color: $color-font-light;
|
||||
border-bottom: 1px solid #f7931e;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
vn-table vn-th.waste-family,
|
||||
vn-table vn-td.waste-family {
|
||||
max-width: 64px;
|
||||
width: 64px
|
||||
vn-td-editable text {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
border: 0;
|
||||
border-bottom: 1px dashed $color-active;
|
||||
border-radius: 0;
|
||||
color: $color-active
|
||||
}
|
||||
|
||||
vn-td-editable text:after {
|
||||
font-family: 'Material Icons';
|
||||
content: 'edit';
|
||||
position: absolute;
|
||||
margin-left: 5px;
|
||||
color: $color-spacer
|
||||
}
|
||||
|
||||
vn-table[vn-droppable] {
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
a[draggable] {
|
||||
transition: all .5s;
|
||||
cursor: move;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
a[draggable]:hover {
|
||||
background-color: $color-hover-cd
|
||||
}
|
||||
|
||||
a[draggable].dragging {
|
||||
background-color: $color-success-light;
|
||||
font-weight:bold
|
||||
}
|
||||
}
|
|
@ -14,3 +14,4 @@ import './thermograph/create/';
|
|||
import './thermograph/edit/';
|
||||
import './descriptor-popover';
|
||||
import './extra-community';
|
||||
import './extra-community-search-panel';
|
||||
|
|
|
@ -93,7 +93,7 @@
|
|||
"acl": ["buyer"]
|
||||
},
|
||||
{
|
||||
"url": "/extra-community",
|
||||
"url": "/extra-community?q",
|
||||
"state": "travel.extraCommunity",
|
||||
"component": "vn-travel-extra-community",
|
||||
"description": "Extra community",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
Reference: Referencia
|
||||
Warehouse In: Almacen entrada
|
||||
Warehouse Out: Almacen salida
|
||||
Warehouse In: Almacén entrada
|
||||
Warehouse Out: Almacén salida
|
||||
Shipped: F. envío
|
||||
Landed: F. entrega
|
||||
Total entries: Entradas totales
|
||||
|
|
Loading…
Reference in New Issue