refs #3963 autoload fixed

This commit is contained in:
Alexandre Riera 2022-12-20 11:36:37 +01:00
parent 284f9f418b
commit b356839148
8 changed files with 110 additions and 256 deletions

View File

@ -2,12 +2,13 @@ DROP PROCEDURE IF EXISTS `vn`.`ticket_canAdvance`;
DELIMITER $$
$$
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canAdvance`(vShipped DATE, vWarehouseFk INT)
CREATE DEFINER=`root`@`localhost` PROCEDURE `vn`.`ticket_canAdvance`(vDateFuture DATE, vDateToAdvance DATE, vWarehouseFk INT)
BEGIN
/**
* Devuelve los tickets y la cantidad de lineas de venta que se pueden adelantar.
*
* @param vShipped Fecha de los tickets que se quieren adelantar.
* @param vDateFuture Fecha de los tickets que se quieren adelantar.
* @param vDateToAdvance Fecha a cuando se quiere adelantar.
* @param vWarehouseFk Almacén
*/
@ -16,7 +17,7 @@ BEGIN
SELECT inventoried INTO vDateInventory FROM vn.config;
SET vDateToAdvance = TIMESTAMPADD(DAY,-1,vShipped);
-- SET vDateToAdvance = TIMESTAMPADD(DAY,-1,vDateFuture);
DROP TEMPORARY TABLE IF EXISTS tmp.stock;
CREATE TEMPORARY TABLE tmp.stock
@ -30,20 +31,20 @@ BEGIN
SELECT itemFk, quantity
FROM vn.itemTicketOut
WHERE shipped >= vDateInventory
AND shipped < vShipped
AND shipped < vDateFuture
AND warehouseFk = vWarehouseFk
UNION ALL
SELECT itemFk, quantity
FROM vn.itemEntryIn
WHERE landed >= vDateInventory
AND landed < vShipped
AND landed < vDateFuture
AND isVirtualStock = FALSE
AND warehouseInFk = vWarehouseFk
UNION ALL
SELECT itemFk, quantity
FROM vn.itemEntryOut
WHERE shipped >= vDateInventory
AND shipped < vShipped
AND shipped < vDateFuture
AND warehouseOutFk = vWarehouseFk
) t
GROUP BY itemFk HAVING amount != 0;
@ -55,7 +56,7 @@ BEGIN
sum((s.quantity <= IFNULL(st.amount,0))) hasStock,
count(DISTINCT s.id) saleCount,
st.name tfState,
GROUP_CONCAT(DISTINCT ipt.description ORDER BY ipt.description) tfIpt,
GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) tfIpt,
t2.ticketFk id,
t2.state,
t2.ipt,
@ -65,8 +66,7 @@ BEGIN
t2.shipped,
t.shipped tfShipped,
t2.totalWithVat,
t.totalWithVat tfTotalWithVat,
t.landed destETD
t.totalWithVat tfTotalWithVat
FROM vn.ticket t
JOIN vn.ticketState ts ON ts.ticketFk = t.id
JOIN vn.state st ON st.id = ts.stateFk
@ -75,7 +75,7 @@ BEGIN
t2.id ticketFk,
t2.addressFk,
st.name state,
GROUP_CONCAT(DISTINCT ipt.description ORDER BY ipt.description) ipt,
GROUP_CONCAT(DISTINCT ipt.code ORDER BY ipt.code) ipt,
t2.shipped,
t2.totalWithVat
FROM vn.ticket t2
@ -91,7 +91,7 @@ BEGIN
JOIN vn.item i ON i.id = s.itemFk
LEFT JOIN vn.itemPackingType ipt ON ipt.code = i.itemPackingTypeFk
LEFT JOIN tmp.stock st ON st.itemFk = s.itemFk
WHERE t.shipped BETWEEN vShipped AND util.dayend(vShipped)
WHERE t.shipped BETWEEN vDateFuture AND util.dayend(vDateFuture)
AND t.warehouseFk = vWarehouseFk
GROUP BY t.id;

View File

@ -1,177 +0,0 @@
import selectors from '../../helpers/selectors.js';
import getBrowser from '../../helpers/puppeteer';
describe('Ticket Advance path', () => {
let browser;
let page;
beforeAll(async() => {
browser = await getBrowser();
page = browser.page;
await page.loginAndModule('employee', 'ticket');
await page.accessToSection('ticket.advance');
});
afterAll(async() => {
await browser.close();
});
let tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);
const ticket = {
shipped: tomorrow,
warehouseFk: 'Warehouse One'
};
it('should show errors snackbar because of the required data', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.warehouseFk);
await page.waitToClick(selectors.ticketAdvance.submit);
let message = await page.waitForSnackbar();
expect(message.text).toContain('warehouseFk is a required argument');
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.shipped);
await page.waitToClick(selectors.ticketAdvance.submit);
message = await page.waitForSnackbar();
expect(message.text).toContain('shipped is a required argument');
});
it('should search with the required data', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.pickDate(selectors.ticketAdvance.shipped, ticket.shipped);
await page.autocompleteSearch(selectors.ticketAdvance.warehouseFk, ticket.warehouseFk);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the destination shipped', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.pickDate(selectors.ticketAdvance.tfShipped, tomorrow);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.tfShipped);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the origin IPT', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.ipt, 'Horizontal');
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.ipt);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the destination IPT', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.tfIpt, 'Horizontal');
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.tfIpt);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the origin grouped state', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.state, 'Free');
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 0);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.state);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search with the destination grouped state', async() => {
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.autocompleteSearch(selectors.ticketAdvance.tfState, 'Free');
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.clearInput(selectors.ticketAdvance.tfState);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with an IPT Origin', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.autocompleteSearch(selectors.ticketAdvance.tableIpt, 'Vertical');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with an IPT Destination', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.autocompleteSearch(selectors.ticketAdvance.tableTfIpt, 'Vertical');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with stock', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.write(selectors.ticketAdvance.tableStock, '5');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 2);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with especified Lines', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.write(selectors.ticketAdvance.tableLines, '0');
await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should search in smart-table with especified Liters', async() => {
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.write(selectors.ticketAdvance.tableLiters, '0');
await page.keyboard.press('Enter');
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
await page.waitToClick(selectors.ticketAdvance.tableButtonSearch);
await page.waitToClick(selectors.ticketAdvance.openAdvancedSearchButton);
await page.waitToClick(selectors.ticketAdvance.submit);
await page.waitForNumberOfElements(selectors.ticketAdvance.table, 1);
});
it('should check the three last tickets and move to the future', async() => {
await page.waitToClick(selectors.ticketAdvance.multiCheck);
await page.waitToClick(selectors.ticketAdvance.moveButton);
await page.waitToClick(selectors.ticketAdvance.acceptButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Tickets moved successfully!');
});
});

View File

@ -14,16 +14,16 @@ module.exports = Self => {
required: true
},
{
arg: 'shipped',
arg: 'dateFuture',
type: 'date',
description: 'Origin shipped',
description: 'Date of the tickets that you want to advance',
required: true
},
{
arg: 'ticketFutureShipped',
arg: 'dateToAdvance',
type: 'date',
description: 'Destination shipped',
required: false
description: 'Date to when you want to advance',
required: true
},
{
arg: 'ipt',
@ -87,11 +87,17 @@ module.exports = Self => {
const where = buildFilter(ctx.args, (param, value) => {
switch (param) {
case 'ticketFutureShipped':
return {'f.tfShipped': value};
// case 'dateFuture':
// return {'f.shipped': value};
// case 'dateToAdvance':
// return {'f.tfShipped': value};
case 'id':
return {'f.id': value};
case 'ticketFuture':
return {'f.ticketFuture': value};
case 'ipt':
return {'f.ipt': value};
case 'ticketFutureIpt':
case 'tfIpt':
return {'f.tfIpt': value};
case 'state':
return {'f.state': {like: `%${value}%`}};
@ -105,8 +111,8 @@ module.exports = Self => {
let stmt;
stmt = new ParameterizedSQL(
`CALL vn.ticket_canAdvance(?,?)`,
[args.shipped, args.warehouseFk]);
`CALL vn.ticket_canAdvance(?,?,?)`,
[args.dateFuture, args.dateToAdvance, args.warehouseFk]);
stmts.push(stmt);

View File

@ -4,36 +4,37 @@
<vn-date-picker
vn-one
label="Origin date"
ng-model="filter.shipped"
ng-model="filter.dateFuture"
required="true">
</vn-date-picker>
<vn-date-picker
vn-one
label="Destination date"
ng-model="filter.ticketFutureShipped">
ng-model="filter.dateToAdvance"
required="true">
</vn-date-picker>
</vn-horizontal>
<vn-horizontal class="vn-px-lg">
<vn-autocomplete vn-one
data="$ctrl.itemPackingTypes"
label="Origin IPT"
value-field="name"
show-field="name"
ng-model="filter.ipt"
value-field="code"
show-field="description"
ng-model="filter.ticketFutureIpt"
info="IPT">
<tpl-item>
{{name}}
{{description}}
</tpl-item>
</vn-autocomplete>
<vn-autocomplete vn-one
data="$ctrl.itemPackingTypes"
label="Destination IPT"
value-field="name"
show-field="name"
ng-model="filter.ticketFutureIpt"
value-field="code"
show-field="description"
ng-model="filter.ipt"
info="IPT">
<tpl-item>
{{name}}
{{description}}
</tpl-item>
</vn-autocomplete>
</vn-horizontal>
@ -41,7 +42,7 @@
<vn-autocomplete vn-one
data="$ctrl.groupedStates"
label="Origin Grouped State"
value-field="name"
value-field="code"
show-field="name"
ng-model="filter.state">
<tpl-item>
@ -51,7 +52,7 @@
<vn-autocomplete vn-one
data="$ctrl.groupedStates"
label="Destination Grouped State"
value-field="name"
value-field="code"
show-field="name"
ng-model="filter.ticketFutureState">
<tpl-item>

View File

@ -28,9 +28,8 @@ class Controller extends SearchPanel {
this.$http.get('ItemPackingTypes').then(res => {
for (let ipt of res.data) {
itemPackingTypes.push({
id: ipt.id,
code: ipt.code,
name: this.$t(ipt.code)
description: this.$t(ipt.description)
});
}
this.itemPackingTypes = itemPackingTypes;

View File

@ -1,6 +1,8 @@
<vn-crud-model
vn-id="model"
url="Tickets/getTicketsAdvance">
url="Tickets/getTicketsAdvance"
auto-load="true"
params="model.params">
</vn-crud-model>
<vn-portal slot="topbar">
<vn-searchbar
@ -29,6 +31,11 @@
<slot-table>
<table>
<thead>
<tr second-header>
<td></td>
<th colspan="5" translate>Origin</th>
<th colspan="8" translate>Destination</th>
</tr>
<tr>
<th shrink>
<vn-multi-check
@ -37,40 +44,43 @@
check-field="checked">
</vn-multi-check>
</th>
<th field="ticketFk">
<span translate>Origin ID</span>
<th field="ticketFuture">
<span translate>ID</span>
</th>
<th field="state">
<span translate>Origin State</span>
<th field="tfShipped">
<span translate>Date</span>
</th>
<th field="ipt" title="Item Packing Type">
<th field="tfIpt" title="Item Packing Type">
<span>IPT</span>
</th>
<th field="tfState">
<span translate>State</span>
</th>
<th field="totalWithVat">
<span translate>Import</span>
</th>
<th field="ticketFuture">
<span translate>Destination ID</span>
<th separator field="id">
<span translate>ID</span>
</th>
<th field="destEstimatedTimeDelivery" title="Estimated Time Delivery">
<span translate>Destination ETD</span>
<th field="shipped">
<span translate>Date</span>
</th>
<th field="ticketFutureState">
<span translate>Destination State</span>
<th field="ipt" title="Item Packing Type">
<span>IPT</span>
</th>
<th field="state">
<span translate>State</span>
</th>
<th field="liters">
<span translate>Liters</span>
</th>
<th field="lines">
<span translate>Lines</span>
</th>
<th field="hasStock">
<span>Stock</span>
</th>
<th field="ticketFutureIpt" title="Item Packing Type">
<span>IPT</span>
<th field="lines">
<span translate>Lines</span>
</th>
<th field="ticketFutureTotalWithVat">
<th field="tfTotalWithVat">
<span translate>Import</span>
</th>
</tr>
@ -87,46 +97,51 @@
<span
ng-click="ticketDescriptor.show($event, ticket.id)"
class="link">
{{::ticket.id | dashIfEmpty}}
{{::ticket.ticketFuture | dashIfEmpty}}
</span>
</td>
<td shrink-date>
<span class="chip {{$ctrl.compareDate(ticket.tfShipped)}}">
{{::ticket.tfShipped | date: 'dd/MM/yyyy'}}
</span>
</td>
<td>{{::ticket.tfIpt | dashIfEmpty}}</td>
<td>
<span
class="chip {{$ctrl.stateColor(ticket.state)}}">
{{::ticket.state | dashIfEmpty}}
{{::ticket.tfState | dashIfEmpty}}
</span>
</td>
<td>{{::ticket.ipt | dashIfEmpty}}</td>
<td>
<span class="chip {{$ctrl.totalPriceColor(ticket.totalWithVat)}}">
{{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}}
<span class="chip {{$ctrl.totalPriceColor(ticket.tfTotalWithVat)}}">
{{::(ticket.tfTotalWithVat ? ticket.tfTotalWithVat : 0) | currency: 'EUR': 2}}
</span>
</td>
<td>
<span
ng-click="ticketDescriptor.show($event, ticket.ticketFuture)"
class="link">
{{::ticket.ticketFuture | dashIfEmpty}}
{{::ticket.id | dashIfEmpty}}
</span>
</td>
<td shrink-date>
<span class="chip {{$ctrl.compareDate(ticket.destETD)}}">
{{::ticket.destETD | date: 'dd/MM/yyyy'}}
<span class="chip {{$ctrl.compareDate(ticket.shipped)}}">
{{::ticket.shipped | date: 'dd/MM/yyyy'}}
</span>
</td>
<td>{{::ticket.ipt | dashIfEmpty}}</td>
<td>
<span
class="chip {{$ctrl.stateColor(ticket.tfState)}}">
{{::ticket.tfState | dashIfEmpty}}
class="chip {{$ctrl.stateColor(ticket.state)}}">
{{::ticket.state | dashIfEmpty}}
</span>
</td>
<td>{{::ticket.liters | dashIfEmpty}}</td>
<td>{{::ticket.lines | dashIfEmpty}}</td>
<td>{{::ticket.hasStock | dashIfEmpty}}</td>
<td>{{::ticket.tfIpt | dashIfEmpty}}</td>
<td>{{::ticket.lines | dashIfEmpty}}</td>
<td>
<span class="chip {{$ctrl.totalPriceColor(ticket.tfTotalWithVat)}}">
{{::(ticket.tfTotalWithVat ? ticket.tfTotalWithVat : 0) | currency: 'EUR': 2}}
<span class="chip {{$ctrl.totalPriceColor(ticket.totalWithVat)}}">
{{::(ticket.totalWithVat ? ticket.totalWithVat : 0) | currency: 'EUR': 2}}
</span>
</td>
</tr>

View File

@ -16,7 +16,7 @@ export default class Controller extends Section {
searchable: false
},
{
field: 'ticketFutureState',
field: 'tfState',
searchable: false
},
{
@ -24,11 +24,15 @@ export default class Controller extends Section {
searchable: false
},
{
field: 'ticketFutureTotalWithVat',
field: 'tfTotalWithVat',
searchable: false
},
{
field: 'destEstimatedTimeDelivery',
field: 'shipped',
searchable: false
},
{
field: 'tfShipped',
searchable: false
},
{
@ -36,15 +40,15 @@ export default class Controller extends Section {
autocomplete: {
url: 'ItemPackingTypes',
showField: 'description',
valueField: 'description'
valueField: 'code'
}
},
{
field: 'ticketFutureIpt',
field: 'tfIpt',
autocomplete: {
url: 'ItemPackingTypes',
showField: 'description',
valueField: 'description'
valueField: 'code'
}
},
]
@ -53,12 +57,17 @@ export default class Controller extends Section {
}
setDefaultFilter() {
const tomorrow = new Date();
let today = new Date();
const tomorrow = new Date(today);
tomorrow.setDate(tomorrow.getDate() + 1);
this.filterParams = {
shipped: tomorrow,
dateFuture: tomorrow,
dateToAdvance: today,
warehouseFk: this.vnConfig.warehouseFk
};
this.$.model = {
params: this.filterParams
};
}
compareDate(date) {
@ -123,7 +132,6 @@ export default class Controller extends Section {
arr[index].ticketFuture = arr[index].id;
arr[index].id = aux;
});
const params = {tickets: ticketsToAdvance};
return this.$http.post('Tickets/merge', params)
.then(() => {

View File

@ -13,16 +13,16 @@ describe('Component vnTicketAdvance', () => {
$httpBackend = _$httpBackend_;
$window = _$window_;
const $element = angular.element('<vn-ticket-advance></vn-ticket-advance>');
controller = $componentController('vnTicketAdvance', { $element });
controller = $componentController('vnTicketAdvance', {$element});
controller.$.model = crudModel;
controller.$.model.data = [{
id: 1,
checked: true,
state: "OK"
state: 'OK'
}, {
id: 2,
checked: true,
state: "Libre"
state: 'Libre'
}];
}));
@ -67,6 +67,7 @@ describe('Component vnTicketAdvance', () => {
it('should return success to the OK tickets', () => {
const ok = controller.stateColor(controller.$.model.data[0].state);
const notOk = controller.stateColor(controller.$.model.data[1].state);
expect(ok).toEqual('success');
expect(notOk).not.toEqual('success');
});
@ -74,6 +75,7 @@ describe('Component vnTicketAdvance', () => {
it('should return success to the FREE tickets', () => {
const notFree = controller.stateColor(controller.$.model.data[0].state);
const free = controller.stateColor(controller.$.model.data[1].state);
expect(free).toEqual('notice');
expect(notFree).not.toEqual('notice');
});