3352-docuware #880

Merged
joan merged 16 commits from 3352-docuware into dev 2022-02-28 13:44:49 +00:00
12 changed files with 157 additions and 36 deletions
Showing only changes of commit ab6b5aa803 - Show all commits

View File

@ -6,20 +6,23 @@ CREATE DEFINER=`root`@`%` PROCEDURE `vn`.`ticket_getMovable`(vTicketFk INT, vDat
BEGIN BEGIN
/** /**
* Cálcula el stock movible para los artículos de un ticket * Cálcula el stock movible para los artículos de un ticket
* vDatedNew debe ser menor que vDatedOld, en los otros casos se
* asume que siempre es posible
* *
* @param vTicketFk -> Ticket * @param vTicketFk -> Ticket
* @param vDatedNew -> Nueva fecha * @param vDatedNew -> Nueva fecha
* @return Sales con Movible * @return Sales con Movible
*/ */
DECLARE vDatedOld DATETIME; DECLARE vDatedOld DATETIME;
SET vDatedNew = DATE_ADD(vDatedNew, INTERVAL 1 DAY);
SELECT t.shipped INTO vDatedOld SELECT t.shipped INTO vDatedOld
FROM ticket t FROM ticket t
WHERE t.id = vTicketFk; WHERE t.id = vTicketFk;
CALL itemStock(vWarehouseFk, DATE_SUB(vDatedNew, INTERVAL 1 DAY), NULL); CALL itemStock(vWarehouseFk, vDatedNew, NULL);
CALL item_getMinacum(vWarehouseFk, vDatedNew, DATEDIFF(vDatedOld, vDatedNew), NULL); CALL item_getMinacum(vWarehouseFk, vDatedNew, DATEDIFF(DATE_SUB(vDatedOld, INTERVAL 1 DAY), vDatedNew), NULL);
SELECT s.id, SELECT s.id,
s.itemFk, s.itemFk,
s.quantity, s.quantity,

View File

@ -1,6 +1,10 @@
module.exports = Self => { module.exports = Self => {
Self.getSynchronizer = async function() { Self.getSynchronizer = async function() {
let NODE_ENV = process.env.NODE_ENV;
if (!NODE_ENV || NODE_ENV == 'development')
return null;
return await Self.findOne({ return await Self.findOne({
fields: ['id', 'rolePrefix', 'userPrefix', 'userHost'] fields: ['id', 'rolePrefix', 'userPrefix', 'userHost']
}); });

View File

@ -1,7 +1,8 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const soap = require('soap'); const soap = require('soap');
describe('client sendSms()', () => { // #3673 sendSms tests excluded
xdescribe('client sendSms()', () => {
it('should now send a message and log it', async() => { it('should now send a message and log it', async() => {
spyOn(soap, 'createClientAsync').and.returnValue('a so fake client'); spyOn(soap, 'createClientAsync').and.returnValue('a so fake client');
const tx = await models.Client.beginTransaction({}); const tx = await models.Client.beginTransaction({});

View File

@ -1,6 +1,7 @@
const app = require('vn-loopback/server/server'); const app = require('vn-loopback/server/server');
describe('sms send()', () => { // #3673 sendSms tests excluded
xdescribe('sms send()', () => {
it('should not return status error', async() => { it('should not return status error', async() => {
const ctx = {req: {accessToken: {userId: 1}}}; const ctx = {req: {accessToken: {userId: 1}}};
const result = await app.models.Sms.send(ctx, 1105, '123456789', 'My SMS Body'); const result = await app.models.Sms.send(ctx, 1105, '123456789', 'My SMS Body');

View File

@ -3,13 +3,21 @@
url="Items/getWasteByWorker" url="Items/getWasteByWorker"
data="details"> data="details">
</vn-crud-model> </vn-crud-model>
<vn-data-viewer model="model"> <vn-data-viewer model="model">
<vn-card> <section ng-repeat="detail in details" class="vn-pa-md">
<section ng-repeat="detail in details" class="vn-pa-md"> <vn-horizontal class="header">
<vn-horizontal class="header"> <h5><span translate>{{detail.buyer}}</span></h5>
<h5><span><span translate>{{detail.buyer}}</span></h5> <vn-none>
</vn-horizontal> <vn-icon
ng-class="{'hidden': !$ctrl.wasteConfig[detail.buyer].hidden}"
class="arrow pointer"
icon="keyboard_arrow_up"
vn-tooltip="Minimize/Maximize"
ng-click="$ctrl.toggleHidePanel(detail)">
</vn-icon>
</vn-none>
</vn-horizontal>
<vn-card ng-class="{'hidden': !$ctrl.wasteConfig[detail.buyer].hidden}">
<vn-table> <vn-table>
<vn-thead> <vn-thead>
<vn-tr> <vn-tr>
@ -21,7 +29,7 @@
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<a ng-repeat="waste in detail.lines" class="clickable vn-tr" <a ng-repeat="waste in detail.lines" class="clickable vn-tr"
ui-sref="item.waste.detail({buyer: waste.buyer, family: waste.family})" > ui-sref="item.waste.detail({buyer: waste.buyer, family: waste.family})">
<vn-td class="waste-family">{{::waste.family}}</vn-td> <vn-td class="waste-family">{{::waste.family}}</vn-td>
<vn-td number>{{::(waste.percentage / 100) | percentage: 2}}</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.dwindle | currency: 'EUR'}}</vn-td>
@ -29,6 +37,6 @@
</vn-tr> </vn-tr>
</vn-tbody> </vn-tbody>
</vn-table> </vn-table>
</section> </vn-card>
</vn-card> </section>
</vn-data-viewer> </vn-data-viewer>

View File

@ -2,7 +2,34 @@ import ngModule from '../../module';
import Section from 'salix/components/section'; import Section from 'salix/components/section';
import './style.scss'; import './style.scss';
export default class Controller extends Section {
constructor($element, $) {
super($element, $);
this.getWasteConfig();
}
getWasteConfig() {
return this.wasteConfig = JSON.parse(localStorage.getItem('wasteConfig')) || {};
}
setWasteConfig() {
localStorage.setItem('wasteConfig', JSON.stringify(this.wasteConfig));
}
toggleHidePanel(detail) {
if (!this.wasteConfig[detail.buyer]) {
this.wasteConfig[detail.buyer] = {
hidden: true
};
} else
this.wasteConfig[detail.buyer].hidden = !this.wasteConfig[detail.buyer].hidden;
this.setWasteConfig();
}
}
ngModule.vnComponent('vnItemWasteIndex', { ngModule.vnComponent('vnItemWasteIndex', {
template: require('./index.html'), template: require('./index.html'),
controller: Section controller: Controller
}); });

View File

@ -0,0 +1,53 @@
import './index.js';
import crudModel from 'core/mocks/crud-model';
describe('Item', () => {
describe('Component vnItemWasteIndex', () => {
let $scope;
let controller;
beforeEach(ngModule('item'));
beforeEach(inject(($componentController, $rootScope) => {
$scope = $rootScope.$new();
$scope.model = crudModel;
const $element = angular.element('<vn-item-waste-index></vn-item-waste-index>');
controller = $componentController('vnItemWasteIndex', {$element, $scope});
}));
describe('getWasteConfig / setWasteConfig', () => {
it('should return the local storage wasteConfig', () => {
const result = controller.getWasteConfig();
expect(result).toEqual({});
});
it('should set and return the local storage wasteConfig', () => {
controller.wasteConfig = {salesPerson: {hidden: true}};
controller.setWasteConfig();
const result = controller.getWasteConfig();
expect(result).toEqual(controller.wasteConfig);
});
});
describe('toggleHidePanel()', () => {
it('should make details hidden by default', () => {
controller.wasteConfig = {};
controller.toggleHidePanel({buyer: 'salesPerson'});
expect(controller.wasteConfig.salesPerson.hidden).toEqual(true);
});
it('should toggle hidden false', () => {
controller.wasteConfig = {salesPerson: {hidden: true}};
controller.toggleHidePanel({buyer: 'salesPerson'});
expect(controller.wasteConfig.salesPerson.hidden).toEqual(false);
});
});
});
});

View File

@ -1,21 +1,24 @@
@import "variables"; @import "variables";
@import "effects";
vn-item-waste-index, vn-item-waste-index,
vn-item-waste-detail { vn-item-waste-detail {
.header { .header {
margin-bottom: 16px; padding: 12px 0 5px 0;
text-transform: uppercase; color: gray;
font-size: 1.25rem; font-size: 1.2rem;
line-height: 1; border-bottom: $border;
padding: 7px; margin-bottom: 10px;
padding-bottom: 7px;
padding-bottom: 4px; & > vn-none > vn-icon {
font-weight: lighter; @extend %clickable-light;
background-color: $color-bg; color: $color-button;
border-bottom: 1px solid #f7931e; font-size: 1.4rem;
white-space: nowrap; }
overflow: hidden;
text-overflow: ellipsis; vn-none > .arrow {
transition: transform 200ms;
}
} }
vn-table vn-th.waste-family, vn-table vn-th.waste-family,
@ -23,4 +26,12 @@ vn-item-waste-detail {
max-width: 64px; max-width: 64px;
width: 64px width: 64px
} }
.hidden {
display: none;
}
.header > vn-none > .arrow.hidden {
display: block;
transform: rotate(180deg);
}
} }

View File

@ -1,3 +1,4 @@
Family: Familia Family: Familia
Percentage: Porcentaje Percentage: Porcentaje
Dwindle: Mermas Dwindle: Mermas
Minimize/Maximize: Minimizar/Maximizar

View File

@ -86,8 +86,8 @@ describe('sale priceDifference()', () => {
const firstItem = result.items[0]; const firstItem = result.items[0];
const secondtItem = result.items[1]; const secondtItem = result.items[1];
expect(firstItem.movable).toEqual(440); expect(firstItem.movable).toEqual(410);
expect(secondtItem.movable).toEqual(1980); expect(secondtItem.movable).toEqual(1870);
await tx.rollback(); await tx.rollback();
} catch (e) { } catch (e) {

View File

@ -1,7 +1,8 @@
const models = require('vn-loopback/server/server').models; const models = require('vn-loopback/server/server').models;
const soap = require('soap'); const soap = require('soap');
describe('ticket sendSms()', () => { // #3673 sendSms tests excluded
xdescribe('ticket sendSms()', () => {
it('should send a message and log it', async() => { it('should send a message and log it', async() => {
const tx = await models.Ticket.beginTransaction({}); const tx = await models.Ticket.beginTransaction({});

View File

@ -18,7 +18,14 @@
</vn-thead> </vn-thead>
<vn-tbody> <vn-tbody>
<vn-tr ng-repeat="sale in $ctrl.ticket.sale.items track by sale.id"> <vn-tr ng-repeat="sale in $ctrl.ticket.sale.items track by sale.id">
<vn-td number>{{("000000"+sale.itemFk).slice(-6)}}</vn-td> <vn-td number>
<span
title="{{::sale.item.name}}"
vn-click-stop="itemDescriptor.show($event, sale.itemFk, sale.id)"
class="link">
{{::sale.itemFk | zeroFill:6}}
</span>
</vn-td>
<vn-td vn-fetched-tags> <vn-td vn-fetched-tags>
<div> <div>
<vn-one title="{{::sale.item.name}}">{{::sale.item.name}}</vn-one> <vn-one title="{{::sale.item.name}}">{{::sale.item.name}}</vn-one>
@ -83,5 +90,9 @@
</div> </div>
</div> </div>
</vn-side-menu> </vn-side-menu>
<vn-item-descriptor-popover
vn-id="item-descriptor"
warehouse-fk="$ctrl.ticket.warehouseFk"
ticket-fk="$ctrl.ticket.id">
</vn-item-descriptor-popover>