#2913, #2914 - Changes to sales monitors
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Joan Sanchez 2021-05-18 08:41:36 +02:00
parent ea1ff3e5fa
commit 10387ee40b
13 changed files with 214 additions and 28 deletions

View File

@ -25,10 +25,12 @@ vn-table {
}
}
& > vn-tbody,
& > a.vn-tbody,
& > tbody {
display: table-row-group;
}
& > vn-tfoot,
& > .vn-tfoot,
& > tfoot {
border-top: 2px solid $color-spacer;
display: table-footer-group
@ -39,7 +41,9 @@ vn-table {
display: table-row;
height: 48px;
}
vn-thead, vn-tbody, vn-tfoot,
vn-thead, .vn-thead,
vn-tbody, .vn-tbody,
vn-tfoot, .vn-tfoot,
thead, tbody, tfoot {
& > * {
display: table-row;
@ -126,7 +130,13 @@ vn-table {
color: inherit;
}
}
a.vn-tbody {
&.clickable {
@extend %clickable;
}
}
vn-tbody > *,
.vn-tbody > *,
tbody > * {
border-bottom: 1px solid $color-spacer-light;
@ -206,6 +216,7 @@ vn-table.scrollable > .vn-table,
border-bottom: 2px solid $color-spacer;
background-color: #FFF;
position: sticky;
z-index: 9;
top: 0
}
}

View File

@ -0,0 +1,47 @@
module.exports = Self => {
Self.remoteMethod('deleteOrders', {
description: 'Deletes the selected orders',
accessType: 'WRITE',
accepts: [{
arg: 'deletes',
type: ['number'],
required: true,
description: 'The order ids to delete'
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/deleteOrders`,
verb: 'POST'
}
});
Self.deleteOrders = async(deletes, options) => {
const models = Self.app.models;
let tx;
let myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
if (!myOptions.transaction) {
tx = await Self.beginTransaction({});
myOptions.transaction = tx;
}
try {
const deleted = models.Order.destroyAll({
id: {inq: deletes}
}, myOptions);
if (tx) await tx.commit();
return deleted;
} catch (e) {
if (tx) await tx.rollback();
throw e;
}
};
};

View File

@ -0,0 +1,21 @@
const app = require('vn-loopback/server/server');
describe('SalesMonitor deleteOrders()', () => {
it('should return the deleted orders', async() => {
const tx = await app.models.Order.beginTransaction({});
try {
const options = {transaction: tx};
const deletes = [1, 2];
const result = await app.models.SalesMonitor.deleteOrders(deletes, options);
expect(result.count).toEqual(2);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -2,4 +2,5 @@ module.exports = Self => {
require('../methods/sales-monitor/salesFilter')(Self);
require('../methods/sales-monitor/clientsFilter')(Self);
require('../methods/sales-monitor/ordersFilter')(Self);
require('../methods/sales-monitor/deleteOrders')(Self);
};

View File

@ -1,8 +1,9 @@
<vn-crud-model auto-load="true"
<vn-crud-model
vn-id="model"
url="SalesMonitors/clientsFilter"
limit="6"
order="dated DESC">
order="dated DESC"
auto-load="true">
</vn-crud-model>
<vn-horizontal class="header">
<vn-one translate>

View File

@ -3,10 +3,8 @@
<vn-monitor-sales-tickets></vn-monitor-sales-tickets>
</vn-three>
<vn-one>
<vn-vertical class="vn-mb-sm">
<vn-monitor-sales-clients></vn-monitor-sales-clients>
</vn-vertical>
<vn-vertical>
<vn-monitor-sales-clients class="vn-mb-sm"></vn-monitor-sales-clients>
<vn-monitor-sales-orders></vn-monitor-sales-orders>
</vn-vertical>
</vn-one>

View File

@ -2,3 +2,5 @@ Tickets monitor: Monitor de tickets
Clients on website: Clientes activos en la web
Recent order actions: Acciones recientes en pedidos
Search tickets: Buscar tickets
Delete selected elements: Eliminar los elementos seleccionados
All the selected elements will be deleted. Are you sure you want to continue?: Todos los elementos seleccionados serán eliminados. ¿Seguro que quieres continuar?

View File

@ -9,6 +9,12 @@
Recent order actions
</vn-one>
<vn-none>
<vn-icon
icon="delete"
vn-tooltip="Delete"
ng-if="$ctrl.totalChecked > 0"
ng-click="delete.show()">
</vn-icon>
<vn-icon
icon="refresh"
vn-tooltip="Refresh"
@ -17,16 +23,29 @@
</vn-none>
</vn-horizontal>
<vn-card>
<vn-table model="model" class="scrollable sm">
<vn-table model="model" class="scrollable">
<vn-thead>
<vn-tr>
<vn-th shrink>
<vn-multi-check
model="model">
</vn-multi-check>
</vn-th>
<vn-th field="date_make" shrink-datetime default-order="DESC">Date</vn-th>
<vn-th field="clientFk">Client</vn-th>
<vn-th>Import</vn-th>
</vn-tr>
</vn-thead>
<vn-tbody ng-repeat="order in model.data">
<a ng-repeat="order in model.data"
class="clickable vn-tbody search-result"
ui-sref="order.card.summary({id: {{::order.id}}})" target="_blank">
<vn-tr>
<vn-td>
<vn-check
ng-model="order.checked"
vn-click-stop>
</vn-check>
</vn-td>
<vn-td>
<span class="chip success">
{{::order.date_send | date: 'dd/MM/yyyy'}}
@ -42,7 +61,8 @@
</vn-td>
<vn-td number>{{::order.import | currency: 'EUR':2}}</vn-td>
</vn-tr>
<vn-tr class="dark-row">
<vn-tr>
<vn-td></vn-td>
<vn-td shrink-datetime>
<span>
{{::order.date_make | date: 'dd/MM/yyyy HH:mm'}}
@ -62,7 +82,7 @@
</span>
</vn-td>
</vn-tr>
</vn-tbody>
</a>
</vn-table>
<div
ng-if="!model.data.length"
@ -83,3 +103,9 @@
<vn-client-descriptor-popover
vn-id="clientDescriptor">
</vn-client-descriptor-popover>
<vn-confirm
vn-id="delete"
on-accept="$ctrl.onDelete()"
question="All the selected elements will be deleted. Are you sure you want to continue?"
message="Delete selected elements">
</vn-confirm>

View File

@ -2,7 +2,31 @@ import ngModule from '../../module';
import Section from 'salix/components/section';
import './style.scss';
export default class Controller extends Section {
get checked() {
const rows = this.$.model.data || [];
const checkedRows = [];
for (let row of rows) {
if (row.checked)
checkedRows.push(row.id);
}
return checkedRows;
}
get totalChecked() {
return this.checked.length;
}
onDelete() {
const params = {deletes: this.checked};
const query = `SalesMonitors/deleteOrders`;
this.$http.post(query, params).then(
() => this.$.model.refresh());
}
}
ngModule.vnComponent('vnMonitorSalesOrders', {
template: require('./index.html'),
controller: Section
controller: Controller
});

View File

@ -0,0 +1,50 @@
import './index.js';
import crudModel from 'core/mocks/crud-model';
describe('Component vnMonitorSalesOrders', () => {
let controller;
let $httpBackend;
beforeEach(ngModule('monitor'));
beforeEach(inject(($componentController, _$httpBackend_) => {
$httpBackend = _$httpBackend_;
const $element = angular.element('<vn-monitor-sales-orders></vn-monitor-sales-orders>');
controller = $componentController('vnMonitorSalesOrders', {$element});
controller.$.model = crudModel;
controller.$.model.data = [
{id: 1, name: 'My item 1'},
{id: 2, name: 'My item 2'},
{id: 3, name: 'My item 3'}
];
}));
describe('checked() getter', () => {
it('should return a the selected rows', () => {
const modelData = controller.$.model.data;
modelData[0].checked = true;
modelData[1].checked = true;
const result = controller.checked;
expect(result).toEqual(expect.arrayContaining([1, 2]));
});
});
describe('onDelete()', () => {
it('should make a query and then call to the model refresh() method', () => {
jest.spyOn(controller.$.model, 'refresh');
const modelData = controller.$.model.data;
modelData[0].checked = true;
modelData[1].checked = true;
const expectedParams = {deletes: [1, 2]};
$httpBackend.expect('POST', 'SalesMonitors/deleteOrders', expectedParams).respond(200);
controller.onDelete();
$httpBackend.flush();
expect(controller.$.model.refresh).toHaveBeenCalledWith();
});
});
});

View File

@ -1,16 +1,18 @@
@import "variables";
vn-monitor-sales-orders {
.dark-row {
background-color: lighten($color-marginal, 15%);
color: gray;
vn-table.scrollable {
height: 350px
}
vn-td {
border-bottom: 2px solid $color-marginal
vn-table a.vn-tbody {
& > vn-tr:nth-child(2) {
color: gray;
& > vn-td {
border-bottom: 2px solid $color-marginal;
font-size: 13px;
}
}
}
vn-tbody vn-tr:nth-child(3) {
height: inherit
}
}

View File

@ -17,4 +17,9 @@ vn-monitor-index {
color: $color-font-secondary;
text-align: center;
}
vn-vertical {
position: fixed;
width: 400px
}
}

View File

@ -30,7 +30,7 @@
</vn-none>
</vn-horizontal>
<vn-card>
<vn-table model="model" class="scrollable lg">
<vn-table model="model" class="scrollable">
<vn-thead>
<vn-tr>
<vn-th class="icon-field"></vn-th>
@ -49,7 +49,7 @@
<vn-tbody>
<a ng-repeat="ticket in model.data"
class="clickable vn-tr search-result"
ui-sref="ticket.card.summary({id: {{::ticket.id}}})">
ui-sref="ticket.card.summary({id: {{::ticket.id}}})" target="_blank">
<vn-td class="icon-field">
<vn-icon
ng-show="::ticket.isTaxDataChecked === 0"
@ -155,9 +155,7 @@
</vn-table>
<vn-pagination
model="model"
class="vn-pt-xs"
scroll-selector="vn-monitor-sales-tickets vn-table"
scroll-offset="100">
class="vn-pt-xs">
</vn-pagination>
</vn-card>
<vn-worker-descriptor-popover