7129-fixFilter #2766
|
@ -1,5 +1,10 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`expeditionPallet_build`(IN vExpeditions JSON, IN vArcId INT, IN vWorkerFk INT, OUT vPalletFk INT)
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`expeditionPallet_build`(
|
||||
vExpeditions JSON,
|
||||
vArcId INT,
|
||||
vWorkerFk INT,
|
||||
OUT vPalletFk INT
|
||||
)
|
||||
BEGIN
|
||||
/** Construye un pallet de expediciones.
|
||||
*
|
||||
|
@ -7,28 +12,22 @@ BEGIN
|
|||
* en cuyo caso actualiza ese pallet.
|
||||
*
|
||||
* @param vExpeditions JSON_ARRAY con esta estructura [exp1, exp2, exp3, ...]
|
||||
* @param vArcId INT Identificador de vn.arcRead
|
||||
* @param vWorkerFk INT Identificador de vn.worker
|
||||
* @param out vPalletFk Identificador de vn.expeditionPallet
|
||||
* @param vArcId INT Identificador de arcRead
|
||||
* @param vWorkerFk INT Identificador de worker
|
||||
* @param out vPalletFk Identificador de expeditionPallet
|
||||
*/
|
||||
DECLARE vCounter INT;
|
||||
DECLARE vExpeditionFk INT;
|
||||
DECLARE vTruckFk INT;
|
||||
DECLARE vPrinterFk INT;
|
||||
DECLARE vExpeditionStateTypeFk INT;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tExpedition;
|
||||
CREATE TEMPORARY TABLE tExpedition
|
||||
SELECT
|
||||
e.id expeditionFk,
|
||||
r.id routeFk,
|
||||
ep.id palletFk
|
||||
FROM
|
||||
vn.expedition e,
|
||||
vn.route r,
|
||||
vn.expeditionPallet ep
|
||||
LIMIT 0;
|
||||
|
||||
ALTER TABLE tExpedition ADD PRIMARY KEY (expeditionFk);
|
||||
CREATE OR REPLACE TEMPORARY TABLE tExpedition (
|
||||
expeditionFk INT,
|
||||
routeFk INT,
|
||||
palletFk INT,
|
||||
PRIMARY KEY (expeditionFk)
|
||||
);
|
||||
|
||||
SET vCounter = JSON_LENGTH(vExpeditions);
|
||||
|
||||
|
@ -39,53 +38,58 @@ BEGIN
|
|||
|
||||
INSERT IGNORE INTO tExpedition(expeditionFk, routeFk, palletFk)
|
||||
SELECT vExpeditionFk, t.routeFk, es.palletFk
|
||||
FROM vn.expedition e
|
||||
LEFT JOIN vn.ticket t ON t.id = e.ticketFk
|
||||
LEFT JOIN vn.expeditionScan es ON es.expeditionFk = e.id
|
||||
FROM expedition e
|
||||
LEFT JOIN ticket t ON t.id = e.ticketFk
|
||||
LEFT JOIN expeditionScan es ON es.expeditionFk = e.id
|
||||
WHERE e.id = vExpeditionFk;
|
||||
END WHILE;
|
||||
|
||||
SELECT palletFk INTO vPalletFk
|
||||
FROM (
|
||||
SELECT palletFk, count(*) n
|
||||
FROM tExpedition
|
||||
WHERE palletFk > 0
|
||||
GROUP BY palletFk
|
||||
ORDER BY n DESC
|
||||
LIMIT 100 ) sub
|
||||
SELECT palletFk, count(*) n
|
||||
FROM tExpedition
|
||||
WHERE palletFk > 0
|
||||
GROUP BY palletFk
|
||||
ORDER BY n DESC
|
||||
LIMIT 100
|
||||
) sub
|
||||
LIMIT 1;
|
||||
|
||||
IF vPalletFk IS NULL THEN
|
||||
SELECT roadmapStopFk
|
||||
INTO vTruckFk
|
||||
FROM (
|
||||
SELECT rm.roadmapStopFk, count(*) n
|
||||
FROM vn.routesMonitor rm
|
||||
JOIN tExpedition e ON e.routeFk = rm.routeFk
|
||||
GROUP BY roadmapStopFk
|
||||
ORDER BY n DESC
|
||||
LIMIT 1) sub;
|
||||
SELECT roadmapStopFk INTO vTruckFk
|
||||
FROM (
|
||||
SELECT rm.roadmapStopFk, count(*) n
|
||||
FROM routesMonitor rm
|
||||
JOIN tExpedition e ON e.routeFk = rm.routeFk
|
||||
GROUP BY roadmapStopFk
|
||||
ORDER BY n DESC
|
||||
LIMIT 1
|
||||
) sub;
|
||||
|
||||
IF vTruckFk IS NULL THEN
|
||||
CALL util.throw ('TRUCK_NOT_AVAILABLE');
|
||||
END IF;
|
||||
|
||||
INSERT INTO vn.expeditionPallet(truckFk)
|
||||
VALUES(vTruckFk);
|
||||
INSERT INTO expeditionPallet SET truckFk = vTruckFk;
|
||||
|
||||
SET vPalletFk = LAST_INSERT_ID();
|
||||
END IF;
|
||||
|
||||
INSERT INTO vn.expeditionScan(expeditionFk, palletFk, workerFk)
|
||||
INSERT INTO expeditionScan(expeditionFk, palletFk, workerFk)
|
||||
SELECT expeditionFk, vPalletFk, vWorkerFk
|
||||
FROM tExpedition
|
||||
ON DUPLICATE KEY UPDATE palletFk = vPalletFk, workerFk = vWorkerFk;
|
||||
|
||||
SELECT printerFk INTO vPrinterFk
|
||||
FROM vn.arcRead
|
||||
WHERE id = vArcId;
|
||||
SELECT id INTO vExpeditionStateTypeFk
|
||||
FROM expeditionStateType
|
||||
WHERE code = 'PALLETIZED';
|
||||
|
||||
CALL vn.report_print(
|
||||
INSERT INTO expeditionState(expeditionFk, typeFk)
|
||||
SELECT expeditionFk, vExpeditionStateTypeFk FROM tExpedition;
|
||||
|
||||
SELECT printerFk INTO vPrinterFk FROM arcRead WHERE id = vArcId;
|
||||
|
||||
CALL report_print(
|
||||
'LabelPalletExpedition',
|
||||
vPrinterFk,
|
||||
account.myUser_getId(),
|
||||
|
@ -93,7 +97,7 @@ BEGIN
|
|||
'high'
|
||||
);
|
||||
|
||||
UPDATE vn.expeditionPallet SET isPrint = TRUE WHERE id = vPalletFk;
|
||||
UPDATE expeditionPallet SET isPrint = TRUE WHERE id = vPalletFk;
|
||||
|
||||
DROP TEMPORARY TABLE tExpedition;
|
||||
END$$
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
DELIMITER $$
|
||||
CREATE OR REPLACE DEFINER=`root`@`localhost` PROCEDURE `vn`.`itemMinimumQuantity_check`(
|
||||
vSelf INT,
|
||||
vItemFk INT,
|
||||
vStarted DATE,
|
||||
vEnded DATE,
|
||||
vWarehouseFk INT
|
||||
)
|
||||
BEGIN
|
||||
DECLARE vHasCollision BOOL;
|
||||
|
||||
IF vStarted IS NULL THEN
|
||||
CALL util.throw('The field "started" cannot be null');
|
||||
END IF;
|
||||
|
||||
SELECT COUNT(*) INTO vHasCollision
|
||||
FROM itemMinimumQuantity
|
||||
WHERE vItemFk = itemFk
|
||||
AND ((vStarted <= ended OR ended IS NULL)
|
||||
AND (vStarted >= `started` OR vEnded IS NULL))
|
||||
AND (vWarehouseFk <=> warehouseFk)
|
||||
AND vSelf <> id;
|
||||
|
||||
IF vHasCollision THEN
|
||||
CALL util.throw('A line with the same configuration already exists');
|
||||
END IF;
|
||||
END$$
|
||||
DELIMITER ;
|
|
@ -4,5 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`itemMinimumQuantity_b
|
|||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
CALL itemMinimumQuantity_check(NEW.id, NEW.itemFk, NEW.started, NEW.ended, NEW.warehouseFk);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -4,5 +4,6 @@ CREATE OR REPLACE DEFINER=`root`@`localhost` TRIGGER `vn`.`itemMinimumQuantity_b
|
|||
FOR EACH ROW
|
||||
BEGIN
|
||||
SET NEW.editorFk = account.myUser_getId();
|
||||
CALL itemMinimumQuantity_check(NEW.id, NEW.itemFk, NEW.started, NEW.ended, NEW.warehouseFk);
|
||||
END$$
|
||||
DELIMITER ;
|
||||
|
|
|
@ -16,6 +16,4 @@ INSERT IGNORE INTO account.roleInherit (`role`,`inheritsFrom`)
|
|||
|
||||
UPDATE salix.ACL
|
||||
SET principalId='$authenticated'
|
||||
WHERE id=264;
|
||||
|
||||
|
||||
WHERE id=(SELECT id FROM salix.ACL WHERE model='StarredModule' and property='*' and `accessType`='*');
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||
|
||||
module.exports = Self => {
|
||||
|
|
|
@ -2,9 +2,10 @@ const {models} = require('vn-loopback/server/server');
|
|||
|
||||
describe('itemMinimumQuantity model', () => {
|
||||
const itemFk = 5;
|
||||
const quantity = 100;
|
||||
const warehouseFk = 60;
|
||||
|
||||
beforeAll(async() => {
|
||||
beforeEach(async() => {
|
||||
await models.ItemMinimumQuantity.destroyAll({where: {itemFk: itemFk}});
|
||||
});
|
||||
|
||||
|
@ -12,7 +13,7 @@ describe('itemMinimumQuantity model', () => {
|
|||
it('should create a new itemMinimumQuantity record', async() => {
|
||||
const newRecord = {
|
||||
itemFk: itemFk,
|
||||
quantity: 100,
|
||||
quantity: quantity,
|
||||
started: Date.vnNew(),
|
||||
ended: new Date(Date.vnNew().setFullYear(Date.vnNew().getFullYear() + 1)),
|
||||
warehouseFk: warehouseFk
|
||||
|
@ -27,7 +28,7 @@ describe('itemMinimumQuantity model', () => {
|
|||
it('should read an existing itemMinimumQuantity record', async() => {
|
||||
const newRecord = {
|
||||
itemFk: itemFk,
|
||||
quantity: 100,
|
||||
quantity: quantity,
|
||||
started: Date.vnNew(),
|
||||
ended: new Date(Date.vnNew().setFullYear(Date.vnNew().getFullYear() + 2)),
|
||||
warehouseFk: warehouseFk
|
||||
|
@ -44,7 +45,7 @@ describe('itemMinimumQuantity model', () => {
|
|||
it('should update an existing itemMinimumQuantity record', async() => {
|
||||
const newRecord = {
|
||||
itemFk: itemFk,
|
||||
quantity: 100,
|
||||
quantity: quantity,
|
||||
started: Date.vnNew(),
|
||||
ended: new Date(Date.vnNew().setFullYear(Date.vnNew().getFullYear() + 3)),
|
||||
warehouseFk: warehouseFk
|
||||
|
@ -67,7 +68,7 @@ describe('itemMinimumQuantity model', () => {
|
|||
it('should enforce unique constraint on itemFk, started, ended, and warehouseFk', async() => {
|
||||
const newRecord = {
|
||||
itemFk: itemFk,
|
||||
quantity: 100,
|
||||
quantity: quantity,
|
||||
started: Date.vnNew(),
|
||||
ended: Date.vnNew().setFullYear(Date.vnNew().getFullYear() + 5),
|
||||
warehouseFk: warehouseFk
|
||||
|
@ -78,14 +79,14 @@ describe('itemMinimumQuantity model', () => {
|
|||
await models.ItemMinimumQuantity.create(newRecord);
|
||||
} catch (e) {
|
||||
expect(e).toBeDefined();
|
||||
expect(e.code).toContain('ER_DUP_ENTRY');
|
||||
expect(e.code).toContain('ER_SIGNAL_EXCEPTION');
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow null values for ended and warehouseFk', async() => {
|
||||
const newRecord = {
|
||||
itemFk: itemFk,
|
||||
quantity: 100,
|
||||
quantity: quantity,
|
||||
started: Date.vnNew(),
|
||||
ended: null,
|
||||
warehouseFk: null
|
||||
|
|
|
@ -1,121 +1,2 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="Items/getBalance"
|
||||
filter="$ctrl.filter"
|
||||
data="sales"
|
||||
auto-load="false">
|
||||
</vn-crud-model>
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses"
|
||||
order="name"
|
||||
vn-id="warehouse-model">
|
||||
</vn-crud-model>
|
||||
<vn-vertical>
|
||||
<vn-card class="vn-pa-lg vn-w-lg">
|
||||
<vn-vertical>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-focus
|
||||
data="warehouses"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
initial-data="$ctrl.warehouseFk"
|
||||
ng-model="$ctrl.warehouseFk"
|
||||
label="Select warehouse">
|
||||
</vn-autocomplete>
|
||||
<vn-check
|
||||
ng-class="{'table-check':$ctrl.showOld}"
|
||||
label="Show what's before the inventory"
|
||||
ng-model="$ctrl.showOld">
|
||||
</vn-check>
|
||||
<vn-date-picker
|
||||
label="Since"
|
||||
ng-model="$ctrl.date"
|
||||
ng-show="$ctrl.showOld">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th shrink></vn-th>
|
||||
<vn-th expand>Date</vn-th>
|
||||
<vn-th number order="DESC" shrink>Id</vn-th>
|
||||
<vn-th>State</vn-th>
|
||||
<vn-th>Reference</vn-th>
|
||||
<vn-th expand>Client</vn-th>
|
||||
<vn-th number>In</vn-th>
|
||||
<vn-th number>Out</vn-th>
|
||||
<vn-th number>Balance</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr
|
||||
ng-class="::{
|
||||
'isIn': sale.invalue,
|
||||
'balanceNegative': sale.balance < 0}"
|
||||
ng-repeat="sale in sales"
|
||||
vn-repeat-last
|
||||
on-last="$ctrl.scrollToLine(sale.lastPreparedLineFk)"
|
||||
ng-attr-id="vnItemDiary-{{::sale.lineFk}}">
|
||||
<vn-td shrink>
|
||||
<a ui-sref="claim.card.summary({id: sale.claimFk})">
|
||||
<vn-icon icon="icon-claims"
|
||||
ng-show="sale.claimFk"
|
||||
vn-tooltip="{{::$ctrl.$t('Claim')}}: {{::sale.claimFk}}">
|
||||
</vn-icon>
|
||||
</a>
|
||||
</vn-td>
|
||||
<vn-td expand>
|
||||
<span class="chip"
|
||||
ng-class="::{warning: $ctrl.today == sale.shipped}">
|
||||
{{::sale.shipped | date:'dd/MM/yyyy' }}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number shrink>
|
||||
<span class="link"
|
||||
ng-click="$ctrl.showDescriptor($event, sale)"
|
||||
name="origin">
|
||||
{{::sale.origin | dashIfEmpty}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td>{{::sale.stateName | dashIfEmpty}}</vn-td>
|
||||
<vn-td>{{::sale.reference | dashIfEmpty}}</vn-td>
|
||||
<vn-td class="truncate" expand>
|
||||
<span ng-class="::{'warning chip': sale.highlighted}">
|
||||
<span ng-if="::!sale.isTicket">
|
||||
{{::sale.name | dashIfEmpty}}
|
||||
</span>
|
||||
<span
|
||||
ng-if="::sale.isTicket"
|
||||
vn-click-stop="clientDescriptor.show($event, sale.clientFk)"
|
||||
class="link">
|
||||
{{::sale.name | dashIfEmpty}}
|
||||
</span>
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number class="in">{{::sale.invalue | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{::sale.out | dashIfEmpty}}</vn-td>
|
||||
<vn-td number class="balance">
|
||||
<span class="chip balanceSpan"
|
||||
ng-class="::{message: sale.lineFk == sale.lastPreparedLineFk}">
|
||||
{{::sale.balance | dashIfEmpty}}
|
||||
</span>
|
||||
</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
</vn-vertical>
|
||||
<vn-ticket-descriptor-popover
|
||||
vn-id="ticket-descriptor">
|
||||
</vn-ticket-descriptor-popover>
|
||||
<vn-client-descriptor-popover
|
||||
vn-id="clientDescriptor">
|
||||
</vn-client-descriptor-popover>
|
||||
<vn-entry-descriptor-popover
|
||||
vn-id="entryDescriptor">
|
||||
</vn-entry-descriptor-popover>
|
||||
|
||||
<vn-card>
|
||||
</vn-card>
|
||||
|
|
|
@ -1,107 +1,21 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $scope, $anchorScroll, $location) {
|
||||
super($element, $scope);
|
||||
this.$anchorScroll = $anchorScroll;
|
||||
this.$location = $location;
|
||||
let today = Date.vnNew();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
this.today = today.toJSON();
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
}
|
||||
|
||||
get item() {
|
||||
return this._item;
|
||||
}
|
||||
|
||||
set item(value) {
|
||||
this._item = value;
|
||||
|
||||
this.filter = {
|
||||
where: {itemFk: this.$params.id}
|
||||
};
|
||||
|
||||
this.$.$applyAsync(() => {
|
||||
if (this.$params.warehouseFk)
|
||||
this.warehouseFk = this.$params.warehouseFk;
|
||||
else if (value)
|
||||
this.warehouseFk = this.vnConfig.warehouseFk;
|
||||
|
||||
if (this.$params.lineFk)
|
||||
this.lineFk = this.$params.lineFk;
|
||||
});
|
||||
}
|
||||
|
||||
set warehouseFk(value) {
|
||||
if (value && value != this._warehouseFk) {
|
||||
this._warehouseFk = value;
|
||||
this.card.warehouseFk = value;
|
||||
this.filter.where.warehouseFk = this.warehouseFk;
|
||||
|
||||
this.$.model.refresh();
|
||||
}
|
||||
}
|
||||
|
||||
get warehouseFk() {
|
||||
return this._warehouseFk;
|
||||
}
|
||||
|
||||
set date(value) {
|
||||
this._date = value;
|
||||
this.filter.where.date = value;
|
||||
this.filter.where.warehouseFk = this.warehouseFk;
|
||||
|
||||
this.$.model.refresh();
|
||||
}
|
||||
|
||||
get date() {
|
||||
return this._date;
|
||||
}
|
||||
|
||||
set showOld(value) {
|
||||
this._showOld = value;
|
||||
if (!this._showOld) this.date = null;
|
||||
else this.date = new Date();
|
||||
}
|
||||
|
||||
get showOld() {
|
||||
return this._showOld;
|
||||
}
|
||||
|
||||
scrollToLine(lineFk) {
|
||||
this.$.$applyAsync(() => {
|
||||
const hashFk = this.lineFk || lineFk;
|
||||
const hash = `vnItemDiary-${hashFk}`;
|
||||
this.$location.hash(hash);
|
||||
this.$anchorScroll();
|
||||
});
|
||||
}
|
||||
|
||||
showDescriptor(event, sale) {
|
||||
let descriptor = 'entryDescriptor';
|
||||
if (sale.isTicket)
|
||||
descriptor = 'ticketDescriptor';
|
||||
|
||||
this.$[descriptor].show(event.target, sale.origin);
|
||||
}
|
||||
|
||||
$onDestroy() {
|
||||
if (this.$state.getCurrentPath()[2].state.name === 'item')
|
||||
this.card.reload();
|
||||
async $onInit() {
|
||||
this.$state.go('item.card.summary', {id: this.$params.id});
|
||||
window.location.href = await this.vnApp.getUrl(`item/${this.$params.id}/diary`);
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', '$anchorScroll', '$location'];
|
||||
|
||||
ngModule.vnComponent('vnItemDiary', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
item: '<'
|
||||
},
|
||||
require: {
|
||||
card: '?^vnItemCard'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1,99 +0,0 @@
|
|||
import './index.js';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Item', () => {
|
||||
describe('Component vnItemDiary', () => {
|
||||
let $scope;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('item'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope) => {
|
||||
$scope = $rootScope.$new();
|
||||
const $element = angular.element('<vn-item-diary></vn-item-diary>');
|
||||
controller = $componentController('vnItemDiary', {$element, $scope});
|
||||
controller.$.model = crudModel;
|
||||
controller.$params = {id: 1};
|
||||
controller.card = {};
|
||||
}));
|
||||
|
||||
describe('set item()', () => {
|
||||
it('should set warehouseFk property based on itemType warehouseFk', () => {
|
||||
jest.spyOn(controller.$, '$applyAsync');
|
||||
controller.vnConfig = {warehouseFk: 1};
|
||||
controller.item = {id: 1};
|
||||
|
||||
expect(controller.$.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.warehouseFk).toEqual(1);
|
||||
expect(controller.item.id).toEqual(1);
|
||||
});
|
||||
|
||||
it(`should set warehouseFk property based on url query warehouseFk`, () => {
|
||||
jest.spyOn(controller.$, '$applyAsync');
|
||||
controller.$params.warehouseFk = 4;
|
||||
controller.item = {id: 1, itemType: {warehouseFk: 1}};
|
||||
|
||||
expect(controller.$.$applyAsync).toHaveBeenCalledWith(jasmine.any(Function));
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.warehouseFk).toEqual(4);
|
||||
expect(controller.item.id).toEqual(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('scrollToLine ()', () => {
|
||||
it('should assign $location then call anchorScroll using controller value', () => {
|
||||
jest.spyOn(controller, '$anchorScroll');
|
||||
controller.lineFk = 1;
|
||||
controller.scrollToLine('invalidValue');
|
||||
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.$location.hash()).toEqual(`vnItemDiary-${1}`);
|
||||
expect(controller.$anchorScroll).toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it('should assign $location then call anchorScroll using received value', () => {
|
||||
jest.spyOn(controller, '$anchorScroll');
|
||||
controller.lineFk = undefined;
|
||||
controller.scrollToLine(1);
|
||||
|
||||
$scope.$apply();
|
||||
|
||||
expect(controller.$location.hash()).toEqual(`vnItemDiary-${1}`);
|
||||
expect(controller.$anchorScroll).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('showDescriptor ()', () => {
|
||||
it('should call to the entryDescriptor show() method', () => {
|
||||
controller.$.entryDescriptor = {};
|
||||
controller.$.entryDescriptor.show = jest.fn();
|
||||
|
||||
const $event = new Event('click');
|
||||
const target = document.createElement('div');
|
||||
target.dispatchEvent($event);
|
||||
const data = {id: 1, origin: 1};
|
||||
controller.showDescriptor($event, data);
|
||||
|
||||
expect(controller.$.entryDescriptor.show).toHaveBeenCalledWith($event.target, data.origin);
|
||||
});
|
||||
|
||||
it('should call to the ticketDescriptor show() method', () => {
|
||||
controller.$.ticketDescriptor = {};
|
||||
controller.$.ticketDescriptor.show = jest.fn();
|
||||
|
||||
const $event = new Event('click');
|
||||
const target = document.createElement('div');
|
||||
target.dispatchEvent($event);
|
||||
const data = {id: 1, origin: 1, isTicket: true};
|
||||
controller.showDescriptor($event, data);
|
||||
|
||||
expect(controller.$.ticketDescriptor.show).toHaveBeenCalledWith($event.target, data.origin);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
In: Entrada
|
||||
Out: Salida
|
||||
Visible quantity: Cantidad visible
|
||||
Ticket/Entry: Ticket/Entrada
|
||||
Show what's before the inventory: Mostrar lo anterior al inventario
|
|
@ -1,33 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
vn-item-diary {
|
||||
& > vn-vertical {
|
||||
display: block;
|
||||
}
|
||||
vn-horizontal {
|
||||
justify-content: center;
|
||||
}
|
||||
vn-autocomplete > div {
|
||||
width: 400px;
|
||||
}
|
||||
.balanceNegative .balance {
|
||||
color: $color-alert;
|
||||
}
|
||||
.isIn .in {
|
||||
color: $color-success;
|
||||
font-weight: bold;
|
||||
}
|
||||
.isToday .date {
|
||||
color: white;
|
||||
background-color: $color-main;
|
||||
}
|
||||
.truncate {
|
||||
max-width: 250px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.table-check{
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
subject: Bank Direct Debit Request
|
||||
title: SEPA CORE Direct Debit
|
||||
description:
|
||||
dear: Dear Customer
|
||||
instructions: <p>Given the excellent relationship between our two companies
|
||||
and to facilitate the payment processes of our invoices, we suggest the use
|
||||
of the SEPA CORE direct debit system.</p>
|
||||
<p>This service involves issuing our receipts to your company in an automated
|
||||
and electronic manner, which represents a substantial reduction in costs for you
|
||||
in terms of fees and bank charges.</p>
|
||||
<p>If you accept our proposal, on the due date of each payment, it will be automatically
|
||||
debited from your account through your bank.</p>
|
||||
<p>This system is based on the electronic transmission of data; the handling of
|
||||
physical documents has been eliminated.</p>
|
||||
<p>We appreciate your cooperation,</p>
|
||||
conclusion: Thank you for your attention!
|
|
@ -9,9 +9,7 @@ description:
|
|||
forma automatizada y electrónicamente, lo que supone para usted una reducción
|
||||
sustancial de costos en términos de honorarios y gastos bancarios.</p>
|
||||
<p>En caso de que acepte nuestra propuesta, a la fecha de vencimiento de cada efecto,
|
||||
se debitará a su cuenta automáticamente a través de su entidad bancaria.
|
||||
Por tanto, le pedimos que firme y envíe a su banco la autorización original adjunta,
|
||||
debidamente cumplimentada, y nos devuelva una fotocopia de dicha autorización.</p>
|
||||
se debitará a su cuenta automáticamente a través de su entidad bancaria.</p>
|
||||
<p>Este sistema se basa en la transmisión electrónica de datos;
|
||||
el manejo de documentos físicos ha sido eliminado.</p>
|
||||
<p>Le agradecemos su cooperación,</p>
|
||||
|
|
|
@ -14,11 +14,7 @@ description:
|
|||
et commissions bancaires.</p>
|
||||
<p>Dans le cas où vous accepteriez notre proposition, à
|
||||
l’échéance de chaque effet, votre compte sera débité
|
||||
automatiquement par votre Banque.
|
||||
Ainsi, nous vous demandons de signer et envoyer à votre
|
||||
Banque l'original de l'autorisation pour débit en annexe,
|
||||
dûment remplie, et de nous retourner une photocopie de la
|
||||
dite autorisation.</p>
|
||||
automatiquement par votre Banque.</p>
|
||||
<p>Ce système étant basé sur la transmission de données de
|
||||
manière électronique, le maniement de documents
|
||||
physiques á été éliminé</p>
|
||||
|
|
|
@ -28,4 +28,4 @@ SELECT ROW_NUMBER() OVER(ORDER BY b.id, num.n) labelNum,
|
|||
LEFT JOIN origin o ON o.id = i.originFk
|
||||
JOIN numbers num
|
||||
WHERE b.entryFk = ?
|
||||
AND num.n <= b.stickers
|
||||
AND num.n <= b.stickers
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
reportName: direct-debit-order
|
||||
title: SEPA CORE Direct Debit Order
|
||||
description: By signing this direct debit order, the debtor authorizes (A) the creditor
|
||||
to send instructions to the debtor's bank to debit their account and (B) the bank to debit
|
||||
their account according to the creditor's instructions. As part of their rights,
|
||||
the debtor is entitled to a refund by their bank under the terms and conditions
|
||||
of the contract signed with the bank. The refund request must be made within
|
||||
eight weeks of the debit. You can obtain additional information about your rights
|
||||
from your financial institution.
|
||||
documentCopy: You must take a signed copy of this document to your Bank for registration to avoid returns.
|
||||
mandatoryFields: ALL FIELDS MUST BE COMPLETED.
|
||||
sendOrder: ONCE THIS DIRECT DEBIT ORDER IS SIGNED, IT MUST BE SENT TO THE CREDITOR
|
||||
FOR SAFEGUARDING AND IT IS RECOMMENDED TO PROVIDE A COPY TO YOUR BANK.
|
||||
supplier:
|
||||
toCompleteBySupplier: To be completed by the creditor
|
||||
orderReference: Direct debit order reference
|
||||
identifier: Creditor identifier
|
||||
name: Creditor's name
|
||||
street: Address
|
||||
location: Postal Code - City - Province
|
||||
country: Country
|
||||
client:
|
||||
toCompleteByClient: To be completed by the debtor
|
||||
name: Debtor's name(s)
|
||||
fiscalId: NIF
|
||||
street: Debtor's address
|
||||
location: Postal Code - City - Province
|
||||
country: Debtor's country
|
||||
swift: Swift BIC
|
||||
accountNumber: IBAN
|
||||
accountHolder: "(Account holder(s))"
|
||||
accountNumberFormat: In {0}, the IBAN consists of {1} characters always starting with {2}
|
||||
paymentType: Payment type
|
||||
recurrent: Recurrent
|
||||
unique: Unique
|
||||
signLocation: Date - City
|
||||
sign: Debtor's signature and stamp
|
||||
order: Direct Debit Order {0}
|
||||
Francia: France
|
||||
España: Spain
|
||||
Portugal: Portugal
|
||||
instructions:
|
||||
title: Instructions
|
||||
accountFields: Fill in the fields related to the bank account
|
||||
signDocument: Sign and stamp the document. For it to be valid, the stamp must show the CIF/NIF. If not, the request must be accompanied by an account ownership certificate.
|
||||
thanks: Thank you for your cooperation!
|
|
@ -1,13 +1,12 @@
|
|||
const vnReport = require('../../../core/mixins/vn-report.js');
|
||||
const db = require('../../../core/database');
|
||||
|
||||
module.exports = {
|
||||
name: 'sepa-core',
|
||||
mixins: [vnReport],
|
||||
async serverPrefetch() {
|
||||
this.client = await this.findOneFromDef('client', [this.companyId, this.companyId, this.id]);
|
||||
this.client = await this.findOneFromDef('client', [this.id]);
|
||||
this.checkMainEntity(this.client);
|
||||
const suppliers = await this.rawSqlFromDef('supplier', [this.companyId, this.companyId, this.id]);
|
||||
const suppliers = await this.rawSqlFromDef('supplier', [this.companyId, this.id]);
|
||||
this.supplier = {
|
||||
...suppliers[0],
|
||||
accountDetailValue: suppliers.map(val => val?.accountDetailValue)
|
||||
|
@ -23,16 +22,5 @@ module.exports = {
|
|||
type: Number,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getSupplierCif() {
|
||||
return db.findOne(`
|
||||
SELECT DISTINCT ad.value
|
||||
FROM supplierAccount sa
|
||||
JOIN accountDetail ad ON ad.supplierAccountFk = sa.id
|
||||
JOIN accountDetailType adt ON adt.id = ad.accountDetailTypeFk AND adt.id = 3
|
||||
WHERE sa.supplierFk = ?`) [this.companyId];
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
SELECT
|
||||
c.id,
|
||||
m.code mandateCode,
|
||||
SELECT c.id,
|
||||
c.socialName,
|
||||
c.street,
|
||||
c.postcode,
|
||||
c.city,
|
||||
c.fi,
|
||||
p.name AS province,
|
||||
p.name province,
|
||||
ct.name country,
|
||||
ct.code AS countryCode,
|
||||
ct.ibanLength AS ibanLength
|
||||
FROM client c
|
||||
JOIN country ct ON ct.id = c.countryFk
|
||||
LEFT JOIN mandate m ON m.clientFk = c.id
|
||||
AND m.companyFk = ? AND m.finished IS NULL
|
||||
LEFT JOIN province p ON p.id = c.provinceFk
|
||||
WHERE (m.companyFk = ? OR m.companyFk IS NULL) AND c.id = ?
|
||||
ORDER BY m.created DESC LIMIT 1
|
||||
ct.code countryCode,
|
||||
ct.ibanLength ibanLength
|
||||
FROM client c
|
||||
JOIN country ct ON ct.id = c.countryFk
|
||||
JOIN province p ON p.id = c.provinceFk
|
||||
WHERE c.id = ?
|
|
@ -1,29 +1,24 @@
|
|||
SELECT
|
||||
m.code mandateCode,
|
||||
s.name,
|
||||
s.street,
|
||||
sc.name country,
|
||||
s.postCode,
|
||||
s.city,
|
||||
sp.name province,
|
||||
s.nif,
|
||||
sa.supplierFk,
|
||||
be.name bankName,
|
||||
ad.value accountDetailValue
|
||||
FROM
|
||||
client c
|
||||
LEFT JOIN mandate m ON m.clientFk = c.id AND m.companyFk = ? AND m.finished IS NULL
|
||||
LEFT JOIN supplier s ON s.id = m.companyFk
|
||||
LEFT JOIN country sc ON sc.id = s.countryFk
|
||||
LEFT JOIN province sp ON sp.id = s.provinceFk
|
||||
LEFT JOIN province p ON p.id = c.provinceFk
|
||||
LEFT JOIN supplierAccount sa ON sa.supplierFk = s.id
|
||||
LEFT JOIN bankEntity be ON sa.bankEntityFk = be.id
|
||||
LEFT JOIN accountDetail ad ON ad.supplierAccountFk = sa.id
|
||||
JOIN accountDetailType adt ON adt.id = ad.accountDetailTypeFk AND adt.id = 3
|
||||
WHERE
|
||||
(m.companyFk = ? OR m.companyFk IS NULL)
|
||||
AND (c.id = ? OR (c.id IS NULL AND c.countryFk = sa.countryFk))
|
||||
GROUP BY ad.value
|
||||
ORDER BY
|
||||
m.created DESC;
|
||||
SELECT m.code mandateCode,
|
||||
s.name,
|
||||
s.street,
|
||||
sc.name country,
|
||||
s.postCode,
|
||||
s.city,
|
||||
sp.name province,
|
||||
ad.value accountDetailValue
|
||||
FROM client c
|
||||
JOIN mandate m ON m.clientFk = c.id
|
||||
JOIN mandateType mt ON mt.id = m.mandateTypeFk
|
||||
JOIN supplier s ON s.id = m.companyFk
|
||||
LEFT JOIN country sc ON sc.id = s.countryFk
|
||||
LEFT JOIN province sp ON sp.id = s.provinceFk
|
||||
JOIN supplierAccount sa ON sa.supplierFk = s.id
|
||||
JOIN accountDetail ad ON ad.supplierAccountFk = sa.id
|
||||
JOIN accountDetailType adt ON adt.id = ad.accountDetailTypeFk
|
||||
WHERE m.companyFk = ?
|
||||
AND m.finished IS NULL
|
||||
AND c.id = ?
|
||||
AND mt.name = 'CORE'
|
||||
AND adt.description = 'Referencia Remesas'
|
||||
GROUP BY m.id, ad.value
|
||||
ORDER BY m.created DESC
|
Loading…
Reference in New Issue