Merge branch 'dev' into 2883-invoiceIn-Booking
gitea/salix/pipeline/head This commit looks good Details

This commit is contained in:
Javi Gallego 2021-11-19 07:33:54 +01:00
commit c8e9416448
94 changed files with 358 additions and 199 deletions

View File

@ -27,7 +27,7 @@ module.exports = Self => {
Self.sendCheckingPresence = async(ctx, recipientId, message, options) => {
if (!recipientId) return false;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -60,7 +60,7 @@ module.exports = Self => {
const args = ctx.args;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -54,7 +54,7 @@ module.exports = Self => {
const args = ctx.args;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -16,7 +16,7 @@ module.exports = function(Self) {
const models = Self.app.models;
const userId = ctx.req.accessToken.userId;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -31,7 +31,7 @@ module.exports = function(Self) {
const userId = ctx.req.accessToken.userId;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -23,7 +23,7 @@ module.exports = function(Self) {
const userId = ctx.req.accessToken.userId;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -1,9 +1,9 @@
DROP PROCEDURE IF EXISTS vn.item_getBalance;
DROP PROCEDURE IF EXISTS `vn`.`item_getBalance`;
DELIMITER $$
$$
CREATE
definer = root@`%` procedure vn.item_getBalance(IN vItemId int, IN vWarehouse int)
definer = root@`%` procedure `vn`.`item_getBalance`(IN vItemId int, IN vWarehouse int)
BEGIN
DECLARE vDateInventory DATETIME;
DECLARE vCurdate DATE DEFAULT CURDATE();

View File

@ -739,7 +739,7 @@ INSERT INTO `vn`.`itemType`(`id`, `code`, `name`, `categoryFk`, `warehouseFk`, `
(3, 'WPN', 'Paniculata', 2, 1, 31, 35, 0),
(4, 'PRT', 'Delivery ports', 3, 1, NULL, 35, 1),
(5, 'CON', 'Container', 3, 1, NULL, 35, 1),
(6, 'ALS', 'Alstroemeria', 1, 1, 31, 35, 0);
(6, 'ALS', 'Alstroemeria', 1, 1, 31, 16, 0);
INSERT INTO `vn`.`ink`(`id`, `name`, `picture`, `showOrder`, `hex`)
VALUES
@ -796,25 +796,25 @@ INSERT INTO `vn`.`itemFamily`(`code`, `description`)
('SER', 'Services'),
('VT', 'Sales');
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`, `comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`)
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `expenceFk`, `comment`, `relevancy`, `image`, `subName`, `minPrice`, `stars`, `family`, `isFloramondo`)
VALUES
(1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT'),
(2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT'),
(3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT'),
(4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT'),
(5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT'),
(6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT'),
(7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT'),
(8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT'),
(9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT'),
(10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT'),
(11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT'),
(12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT'),
(13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT'),
(14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT'),
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'),
(16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB'),
(71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT');
(1, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '1', NULL, 0, 1, 'VT', 0),
(2, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '2', NULL, 0, 2, 'VT', 0),
(3, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '3', NULL, 0, 5, 'VT', 0),
(4, 1, 60, 'YEL', 1, 1, 'Increases block', 1, 05080000, 4751000000, NULL, 0, '4', NULL, 0, 3, 'VT', 0),
(5, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '5', NULL, 0, 3, 'VT', 0),
(6, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '6', NULL, 0, 4, 'VT', 0),
(7, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '7', NULL, 0, 4, 'VT', 0),
(8, 2, 70, 'YEL', 1, 1, NULL, 1, 06021010, 2000000000, NULL, 0, '8', NULL, 0, 5, 'VT', 0),
(9, 2, 70, 'BLU', 1, 2, NULL, 1, 06021010, 2000000000, NULL, 0, '9', NULL, 0, 4, 'VT', 0),
(10, 1, 60, 'YEL', 1, 3, NULL, 1, 05080000, 4751000000, NULL, 0, '10', NULL, 0, 4, 'VT', 0),
(11, 1, 60, 'YEL', 1, 1, NULL, 1, 05080000, 4751000000, NULL, 0, '11', NULL, 0, 4, 'VT', 0),
(12, 3, 30, 'RED', 1, 2, NULL, 2, 06021010, 4751000000, NULL, 0, '12', NULL, 0, 3, 'VT', 0),
(13, 5, 30, 'RED', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '13', NULL, 0, 2, 'VT', 1),
(14, 5, 90, 'BLU', 1, 2, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 4, 'VT', 1),
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0),
(16, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'EMB', 0),
(71, 6, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 4751000000, NULL, 0, '', NULL, 0, 0, 'VT', 0);
-- Update the taxClass after insert of the items
UPDATE `vn`.`itemTaxCountry` SET `taxClassFk` = 2

View File

@ -29,11 +29,11 @@ describe('Client create path', () => {
it('should receive an error when clicking the create button having name and Business name fields empty',
async() => {
await page.autocompleteSearch(selectors.createClientView.salesPerson, 'salesPerson');
await page.autocompleteSearch(selectors.createClientView.businessType, 'florist');
await page.write(selectors.createClientView.taxNumber, '74451390E');
await page.write(selectors.createClientView.userName, 'CaptainMarvel');
await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es');
await page.autocompleteSearch(selectors.createClientView.salesPerson, 'salesPerson');
await page.autocompleteSearch(selectors.createClientView.businessType, 'florist');
await page.waitToClick(selectors.createClientView.createButton);
const message = await page.waitForSnackbar();
@ -83,7 +83,6 @@ describe('Client create path', () => {
expect(message.text).toContain('Some fields are invalid');
});
/* Tarea #3370
it(`should attempt to create a new user with all it's data but wrong business type`, async() => {
await page.clearInput(selectors.createClientView.email);
await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es');
@ -91,13 +90,10 @@ describe('Client create path', () => {
await page.waitToClick(selectors.createClientView.createButton);
const message = await page.waitForSnackbar();
expect(message.text).toContain('Some fields are invalid');
});*/
expect(message.text).toContain('The type of business must be filled in basic data');
});
it(`should attempt to create a new user with all it's data but wrong postal code`, async() => {
await page.clearInput(selectors.createClientView.email);
await page.write(selectors.createClientView.email, 'CarolDanvers@verdnatura.es');
await page.autocompleteSearch(selectors.createClientView.businessType, 'florist');
await page.clearInput(selectors.createClientView.postcode);
await page.write(selectors.createClientView.postcode, '479999');

View File

@ -86,12 +86,12 @@
align-items: center;
&.today {
color: $color-font-bg;
color: $color-font;
& > .day-number {
border: 2px solid $color-font-link;
&:hover {
background-color: lighten($color-font-link, 20%);
background-color: $color-marginal;
opacity: .8
}
}

View File

@ -50,7 +50,7 @@ vn-chip {
&.alert,
&.alert.clickable:hover,
&.alert.clickable:focus {
background-color: $color-alert-medium;
background-color: lighten($color-alert, 5%);
}
&.message,
&.message.clickable:hover,

View File

@ -222,11 +222,11 @@
}
}
&.focused {
background-color: $color-bg-panel;
background-color: $color-font-dark;
& > .container {
& > .infix > .control > * {
color: $color-font;
color: $color-marginal;
&::placeholder {
color: $color-font-bg;
@ -235,7 +235,7 @@
& > .prepend,
& > .append,
& > .icons {
color: $color-font-bg-marginal;
color: $color-marginal;
}
}
}

View File

@ -6,14 +6,14 @@ smart-table table {
border-collapse: collapse;
& > thead {
border-bottom: 2px solid $color-spacer;
border-bottom: $border;
& > * > th {
font-weight: normal;
}
}
& > tfoot {
border-top: 2px solid $color-spacer;
border-top: $border;
}
thead, tbody, tfoot {
& > * {
@ -27,7 +27,7 @@ smart-table table {
& > th,
& > td {
text-align: left;
padding: 9px 5px;
padding: 5px;
white-space: nowrap;
text-overflow: ellipsis;
@ -67,7 +67,7 @@ smart-table table {
}
}
tbody > * {
border-bottom: 1px solid $color-spacer-light;
border-bottom: $border-thin;
&:last-child {
border-bottom: none;
@ -76,23 +76,26 @@ smart-table table {
.chip {
padding: 4px;
border-radius: 4px;
color: $color-font-bg;
&.notice {
background-color: $color-notice-medium
background-color: $color-notice-medium;
color: $color-font-bg;
}
&.success {
background-color: $color-success-medium;
color: $color-font-bg;
}
&.warning {
background-color: $color-main-medium;
color: $color-font-bg;
}
&.alert {
background-color: $color-alert-medium;
background-color: lighten($color-alert, 5%);
color: $color-font-bg;
}
&.message {
background-color: $color-bg-dark;
color: $color-font-dark;
background-color: $color-bg-dark
}
}
}

View File

@ -14,7 +14,7 @@ vn-table {
& > vn-thead,
& > thead {
display: table-header-group;
border-bottom: 2px solid $color-spacer;
border-bottom: $border;
& > * > th {
font-weight: normal;
@ -32,7 +32,7 @@ vn-table {
& > vn-tfoot,
& > .vn-tfoot,
& > tfoot {
border-top: 2px solid $color-spacer;
border-top: $border;
display: table-footer-group
}
& > * > vn-tr,
@ -119,7 +119,7 @@ vn-table {
vn-tbody > *,
.vn-tbody > *,
tbody > * {
border-bottom: 1px solid $color-spacer-light;
border-bottom: $border-thin;
&:last-child {
border-bottom: none;
@ -132,23 +132,26 @@ vn-table {
.chip {
padding: 4px;
border-radius: 4px;
color: $color-font-bg;
&.notice {
background-color: $color-notice-medium
background-color: $color-notice-medium;
color: $color-font-bg;
}
&.success {
background-color: $color-success-medium;
color: $color-font-bg;
}
&.warning {
background-color: $color-main-medium;
color: $color-font-bg;
}
&.alert {
background-color: $color-alert-medium;
background-color: lighten($color-alert, 5%);
color: $color-font-bg;
}
&.message {
background-color: $color-bg-dark;
color: $color-font-dark;
background-color: $color-bg-dark
}
}
vn-icon-menu {
@ -194,8 +197,8 @@ vn-table.scrollable > .vn-table,
vn-thead vn-th,
thead vn-th,
thead th {
border-bottom: 2px solid $color-spacer;
background-color: #FFF;
border-bottom: $border;
background-color: $color-bg-panel;
position: sticky;
z-index: 9;
top: 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

View File

@ -1,5 +1,5 @@
import ngModule from '../module';
import noImage from './no-image.png';
import noImage from './no-image-dark.png';
/**
* Sets a default image when there is an error loading

View File

@ -23,30 +23,30 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-basketadd:before {
content: "\e901";
.icon-preserved:before {
content: "\e963";
}
.icon-addperson:before {
content: "\e955";
.icon-treatments:before {
content: "\e964";
}
.icon-supplierfalse:before {
.icon-funeral:before {
content: "\e965";
}
.icon-handmadeArtificial:before {
content: "\e966";
}
.icon-fixedPrice:before {
content: "\e962";
}
.icon-invoice-in-create:before {
content: "\e948";
.icon-accounts:before {
content: "\e95f";
}
.icon-invoiceOut:before {
.icon-clientConsumption:before {
content: "\e960";
}
.icon-invoiceIn:before {
.icon-lastBuy:before {
content: "\e961";
}
.icon-supplier:before {
content: "\e936";
}
.icon-latestBuy:before {
content: "\e95f";
}
.icon-zone:before {
content: "\e95d";
}
@ -86,6 +86,9 @@
.icon-deliveryprices:before {
content: "\e956";
}
.icon-basketadd:before {
content: "\e955";
}
.icon-catalog:before {
content: "\e952";
}
@ -128,9 +131,15 @@
.icon-actions:before {
content: "\e900";
}
.icon-addperson:before {
content: "\e901";
}
.icon-albaran:before {
content: "\e902";
}
.icon-apps:before {
content: "\e948";
}
.icon-artificial:before {
content: "\e903";
}
@ -239,6 +248,9 @@
.icon-mandatory:before {
content: "\e921";
}
.icon-niche:before {
content: "\e922";
}
.icon-no036:before {
content: "\e923";
}
@ -302,6 +314,9 @@
.icon-stowaway:before {
content: "\e92c";
}
.icon-supplier:before {
content: "\e936";
}
.icon-tags:before {
content: "\e937";
}

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 136 KiB

View File

@ -1,6 +1,6 @@
@import "./util";
$font-size: 12pt;
$font-size: 11pt;
$menu-width: 256px;
$topbar-height: 56px;
$mobile-width: 800px;
@ -24,7 +24,7 @@ $spacing-xl: 70px;
// Light theme
$color-primary: #f7931e;
/* $color-primary: #f7931e;
$color-secondary: $color-primary;
$color-font: #222;
@ -72,52 +72,65 @@ $color-success-light: lighten($color-success, 35%);
$color-notice-medium: lighten($color-notice, 20%);
$color-notice-light: lighten($color-notice, 35%);
$color-alert-medium: lighten($color-alert, 20%);
$color-alert-light: lighten($color-alert, 35%);
$color-alert-light: lighten($color-alert, 35%); */
/**/
// Dark theme
/*
$color-header: #3d3d3d;
$color-bg: #222;
$color-bg-dark: #222;
$color-primary: #ec8916;
$color-secondary: $color-primary;
$color-font: #eee;
$color-font-light: #aaa;
$color-font-secondary: #777;
$color-font-dark: white;
$color-font-link: #66bfff;
$color-font-bg: rgba(0, 0, 0, .8);
$color-font-link: #005a9a;
$color-font-bg-marginal: rgba(255, 255, 255, .4);
$color-font-bg-dark: rgba(255, 255, 255, .7);
$color-font-bg-dark-marginal: rgba(255, 255, 255, .4);
$color-header: #3d3d3d;
$color-menu-header: #3d3d3d;
$color-bg: #222;
$color-bg-dark: #222;
$color-active: #666;
$color-active-font: white;
$color-bg-panel: #3c3b3b;
$color-main: #f7931e;
$color-marginal: #ccc;
$color-main: $color-primary;
$color-marginal: #222;
$color-success: #a3d131;
$color-notice: #32b1ce;
$color-alert: #f42121;
$color-alert: #fa3939;
$color-button: $color-secondary;
$color-spacer: rgba(255, 255, 255, .3);
$color-spacer-light: rgba(255, 255, 255, .12);
$color-input-underline: rgba(255, 255, 255, .12);
$color-input-underline-hover: rgba(255, 255, 255, .6);
$color-shadow: rgba(0, 0, 0, .2);
$color-border: rgba(0, 0, 0, .3);
$color-hightlight: rgba(255, 255, 255, .15);
$color-hover-cd: rgba(255, 255, 255, .1);
$color-hover-dc: .7;
$color-disabled: .6;
$color-font-link: lighten($color-main, 10%);
$color-main-medium: darken($color-main, 20%);
$color-main-light: darken($color-main, 35%);
$color-success-medium: darken($color-success, 20%);
$color-success-light: darken($color-success, 35%);
$color-notice-medium: darken($color-notice, 20%);
$color-notice-light: darken($color-notice, 35%);
$color-alert-medium: darken($color-alert, 20%);
$color-alert-light: darken($color-alert, 35%);
$color-primary-medium: lighten($color-primary, 20%);
$color-primary-light: lighten($color-primary, 35%);
$color-font-link-medium: lighten($color-font-link, 20%);
$color-font-link-light: lighten($color-font-link, 35%);
$color-main-medium: lighten($color-main, 20%);
$color-main-light: lighten($color-main, 35%);
$color-success-medium: lighten($color-success, 20%);
$color-success-light: lighten($color-success, 35%);
$color-notice-medium: lighten($color-notice, 20%);
$color-notice-light: lighten($color-notice, 35%);
$color-alert-medium: lighten($color-alert, 20%);
$color-alert-light: lighten($color-alert, 35%);
/**/
// Border
$border-thin: 1px solid $color-spacer;
$border-thin: 1px solid $color-border;
$border-thin-light: 1px solid $color-spacer-light;
$border: 2px solid $color-border;
$shadow: 0 2px 2px 0 rgba(0, 0, 0, .3);

View File

@ -65,11 +65,10 @@ ui-view > .vn-summary {
text-transform: uppercase;
font-size: 1.25rem;
line-height: 1;
padding: 7px;
padding-bottom: 4px; /* Bottom line-height fix */
padding: 7px 0;
padding-bottom: 5px; /* Bottom line-height fix */
font-weight: lighter;
background-color: $color-main-light;
border-bottom: 1px solid $color-main;
border-bottom: 2px solid $color-main;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
@ -78,7 +77,7 @@ ui-view > .vn-summary {
display: block;
}
a {
color: $color-font;
color: $color-font-link;
}
}
h4 span:after {
@ -87,7 +86,7 @@ ui-view > .vn-summary {
position: absolute;
right: 5px;
text-transform: none;
color: $color-spacer
color: $color-font-link;
}
& > * {
margin: $spacing-sm;

View File

@ -60,7 +60,7 @@ vn-bg-title {
font-size: 1.25rem;
}
.totalBox {
border: 1px solid #CCC;
border: $border-thin;
text-align: right;
justify-content: center;
align-items: center;

View File

@ -118,5 +118,6 @@
"reference duplicated": "reference duplicated",
"The PDF document does not exists": "The PDF document does not exists. Try regenerating it from 'Regenerate invoice PDF' option",
"This item is not available": "This item is not available",
"Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}"
"Deny buy request": "Purchase request for ticket id [{{ticketId}}]({{{url}}}) has been rejected. Reason: {{observation}}",
"The type of business must be filled in basic data": "The type of business must be filled in basic data"
}

View File

@ -133,7 +133,7 @@
"reserved": "reservado",
"Changed sale reserved state": "He cambiado el estado reservado de las siguientes lineas al ticket [{{ticketId}}]({{{ticketUrl}}}): {{{changes}}}",
"Bought units from buy request": "Se ha comprado {{quantity}} unidades de [{{itemId}} {{concept}}]({{{urlItem}}}) para el ticket id [{{ticketId}}]({{{url}}})",
"Deny buy request":"Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}",
"Deny buy request": "Se ha rechazado la petición de compra para el ticket id [{{ticketId}}]({{{url}}}). Motivo: {{observation}}",
"MESSAGE_INSURANCE_CHANGE": "He cambiado el crédito asegurado del cliente [{{clientName}} ({{clientId}})]({{{url}}}) a *{{credit}} €*",
"Changed client paymethod": "He cambiado la forma de pago del cliente [{{clientName}} ({{clientId}})]({{{url}}})",
"Sent units from ticket": "Envio *{{quantity}}* unidades de [{{concept}} ({{itemId}})]({{{itemUrl}}}) a *\"{{nickname}}\"* provenientes del ticket id [{{ticketId}}]({{{ticketUrl}}})",
@ -211,6 +211,7 @@
"Can't verify data unless the client has a business type": "No se puede verificar datos de un cliente que no tiene tipo de negocio",
"You don't have enough privileges to set this credit amount": "No tienes suficientes privilegios para establecer esta cantidad de crédito",
"You can't change the credit set to zero from a manager": "No puedes cambiar el cŕedito establecido a cero por un gerente",
"Amounts do not match": "Amounts do not match",
"The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'"
"Amounts do not match": "Las cantidades no coinciden",
"The PDF document does not exists": "El documento PDF no existe. Prueba a regenerarlo desde la opción 'Regenerar PDF factura'",
"The type of business must be filled in basic data": "El tipo de negocio debe estar rellenado en datos básicos"
}

View File

@ -63,7 +63,7 @@ module.exports = Self => {
};
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -20,7 +20,7 @@ module.exports = Self => {
Self.removeFile = async(ctx, id, options) => {
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -22,7 +22,7 @@ module.exports = Self => {
let userId = ctx.req.accessToken.userId;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -24,7 +24,7 @@ module.exports = Self => {
const resolvedState = 3;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -44,7 +44,7 @@ module.exports = Self => {
const userId = ctx.req.accessToken.userId;
const args = ctx.args;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -30,7 +30,7 @@ module.exports = Self => {
Self.updateClaimAction = async(ctx, id, options) => {
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -54,7 +54,7 @@ module.exports = Self => {
Self.uploadFile = async(ctx, id, options) => {
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -25,7 +25,7 @@ module.exports = function(Self) {
Self.canBeInvoiced = async(id, options) => {
const models = Self.app.models;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -55,6 +55,15 @@ module.exports = Self => {
with: /^[\w|.|-]+@[\w|-]+(\.[\w|-]+)*(,[\w|.|-]+@[\w|-]+(\.[\w|-]+)*)*$/
});
Self.validate('businessTypeFk', hasBusinessType, {
message: `The type of business must be filled in basic data`
});
function hasBusinessType(err) {
if (!this.businessTypeFk)
err();
}
Self.validatesLengthOf('postcode', {
allowNull: true,
allowBlank: true,

View File

@ -7,4 +7,5 @@ Create and edit: Crear y editar
You can save multiple emails: >-
Puede guardar varios correos electrónicos encadenándolos mediante comas
sin espacios, ejemplo: user@dominio.com, user2@dominio.com siendo el primer
correo electrónico el principal
correo electrónico el principal
The type of business must be filled in basic data: El tipo de negocio debe estar rellenado en datos básicos

View File

@ -68,7 +68,7 @@ module.exports = Self => {
Self.addBuy = async(ctx, options) => {
const conn = Self.dataSource.connector;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -21,7 +21,7 @@ module.exports = Self => {
Self.deleteBuys = async(ctx, options) => {
const models = Self.app.models;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -32,7 +32,7 @@ module.exports = Self => {
Self.editLatestBuys = async(field, newValue, lines, options) => {
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -108,7 +108,7 @@ module.exports = Self => {
});
Self.filter = async(ctx, filter, options) => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -29,7 +29,7 @@ module.exports = Self => {
Self.getBuys = async(id, filter, options) => {
const models = Self.app.models;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -21,7 +21,7 @@ module.exports = Self => {
Self.getEntry = async(id, options) => {
const models = Self.app.models;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -26,7 +26,7 @@ module.exports = Self => {
Self.importBuysPreview = async(id, buys, options) => {
const models = Self.app.models;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -76,7 +76,7 @@ module.exports = Self => {
});
Self.latestBuysFilter = async(ctx, filter, options) => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -15,16 +15,16 @@ vn-entry-buy-index vn-card {
tbody tr:nth-child(1),
tbody tr:nth-child(2) {
border-left: 1px solid $color-marginal;
border-right: 1px solid $color-marginal;
border-left: 1px solid $color-spacer;
border-right: 1px solid $color-spacer;
}
tbody tr:nth-child(2) {
border-bottom: 1px solid $color-marginal;
border-bottom: 1px solid $color-spacer;
}
tbody{
border-bottom: 1px solid $color-marginal;
border-bottom: 1px solid $color-spacer;
}
tbody:last-child {

View File

@ -2,7 +2,8 @@
vn-id="model"
url="Entries/filter"
limit="20"
auto-load="true">
auto-load="true"
order="landed DESC, id DESC">
</vn-crud-model>
<vn-portal slot="topbar">
<vn-searchbar

View File

@ -7,7 +7,7 @@
"menus": {
"main": [
{"state": "entry.index", "icon": "icon-entry"},
{"state": "entry.latestBuys", "icon": "contact_support"}
{"state": "entry.latestBuys", "icon": "icon-lastBuy"}
],
"card": [
{"state": "entry.card.basicData", "icon": "settings"},

View File

@ -9,13 +9,13 @@ vn-entry-summary .summary {
}
tbody tr:nth-child(1) {
border-top: 1px solid $color-marginal;
border-top: $border-thin;
}
tbody tr:nth-child(1),
tbody tr:nth-child(2) {
border-left: 1px solid $color-marginal;
border-right: 1px solid $color-marginal
border-left: $border-thin;
border-right: $border-thin
}
tbody tr:nth-child(3) {

View File

@ -78,7 +78,7 @@ module.exports = Self => {
{
arg: 'isBooked',
type: 'boolean',
description: 'Whether the the invoice is booked or not',
description: 'Whether the invoice is booked or not',
},
],
returns: {
@ -95,7 +95,7 @@ module.exports = Self => {
const conn = Self.dataSource.connector;
const args = ctx.args;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -21,7 +21,7 @@ module.exports = Self => {
Self.summary = async(id, options) => {
const models = Self.app.models;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -23,7 +23,7 @@ module.exports = Self => {
Self.book = async(ref, options) => {
const models = Self.app.models;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -35,7 +35,7 @@ module.exports = Self => {
throw new UserError(`Action not allowed on the test environment`);
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -35,7 +35,7 @@ module.exports = Self => {
{
arg: 'hasPdf',
type: 'boolean',
description: 'Whether the the invoiceOut has PDF or not',
description: 'Whether the invoiceOut has PDF or not',
http: {source: 'query'}
},
{
@ -87,7 +87,7 @@ module.exports = Self => {
Self.filter = async(ctx, filter, options) => {
const conn = Self.dataSource.connector;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -29,7 +29,7 @@ module.exports = Self => {
Self.getTickets = async(id, filter, options) => {
const models = Self.app.models;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -21,7 +21,7 @@ module.exports = Self => {
Self.summary = async(id, options) => {
let summary = {};
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -0,0 +1,44 @@
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
module.exports = Self => {
Self.remoteMethod('activeBuyers', {
description: 'Returns a list of buyers for the given item type',
accepts: [{
arg: 'filter',
type: 'object',
description: `Filter defining where, order, offset, and limit - must be a JSON-encoded string`
}],
returns: {
type: ['object'],
root: true
},
http: {
path: `/activeBuyers`,
verb: 'GET'
}
});
Self.activeBuyers = async(filter, options) => {
const conn = Self.dataSource.connector;
const where = {isActive: true};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);
filter = mergeFilters(filter, {where});
let stmt = new ParameterizedSQL(
`SELECT DISTINCT w.id workerFk, w.firstName, w.lastName, u.name, u.nickname
FROM worker w
JOIN itemType it ON it.workerFk = w.id
JOIN account.user u ON u.id = w.id
JOIN item i ON i.typeFk = it.id`,
null, myOptions);
stmt.merge(conn.makeSuffix(filter));
return conn.executeStmt(stmt);
};
};

View File

@ -41,10 +41,10 @@ module.exports = Self => {
{
arg: 'isActive',
type: 'boolean',
description: 'Whether the the item is or not active',
description: 'Whether the item is or not active',
},
{
arg: 'salesPersonFk',
arg: 'buyerFk',
type: 'integer',
description: 'The buyer of the item',
},
@ -62,6 +62,11 @@ module.exports = Self => {
arg: 'landed',
type: 'date',
description: 'The item last buy landed date',
},
{
arg: 'isFloramondo',
type: 'boolean',
description: 'Whether the the item is or not floramondo',
}
],
returns: {
@ -104,13 +109,13 @@ module.exports = Self => {
? {or: [{'i.id': value}, codeWhere]}
: {or: [{'i.name': {like: `%${value}%`}}, codeWhere]};
case 'id':
return {'i.id': value};
case 'isActive':
return {'i.isActive': value};
case 'typeFk':
case 'isFloramondo':
param = `i.${param}`;
return {[param]: value};
case 'multiplier':
return {'i.stemMultiplier': value};
case 'typeFk':
return {'i.typeFk': value};
case 'categoryFk':
return {'ic.id': value};
case 'buyerFk':
@ -146,6 +151,7 @@ module.exports = Self => {
i.density,
i.stemMultiplier,
i.typeFk,
i.isFloramondo,
it.name AS typeName,
it.workerFk AS buyerFk,
u.name AS userName,

View File

@ -0,0 +1,24 @@
const models = require('vn-loopback/server/server').models;
describe('Worker activeBuyers', () => {
it('should return the buyers in itemType as result', async() => {
const tx = await models.Item.beginTransaction({});
try {
const options = {transaction: tx};
const filter = {};
const result = await models.Item.activeBuyers(filter, options);
const firstWorker = result[0];
const secondWorker = result[1];
expect(result.length).toEqual(2);
expect(firstWorker.nickname).toEqual('logisticBossNick');
expect(secondWorker.nickname).toEqual('buyerNick');
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -60,4 +60,23 @@ describe('item filter()', () => {
throw e;
}
});
it('should return 2 result filtering by isFloramondo checkbox', async() => {
const tx = await models.Item.beginTransaction({});
const options = {transaction: tx};
try {
const filter = {};
const ctx = {args: {filter: filter, isFloramondo: true}};
const result = await models.Item.filter(ctx, filter, options);
expect(result.length).toEqual(2);
expect(result[0].id).toEqual(13);
await tx.rollback();
} catch (e) {
await tx.rollback();
throw e;
}
});
});

View File

@ -14,6 +14,7 @@ module.exports = Self => {
require('../methods/item/getWasteByWorker')(Self);
require('../methods/item/getWasteByItem')(Self);
require('../methods/item/createIntrastat')(Self);
require('../methods/item/activeBuyers')(Self);
Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'});

View File

@ -140,6 +140,9 @@
},
"isFragile": {
"type": "boolean"
},
"isFloramondo": {
"type": "boolean"
}
},
"relations": {

View File

@ -1,16 +1,19 @@
<vn-crud-model
vn-id="model"
url="Items/filter"
user-params="::$ctrl.filterParams"
limit="12"
order="isActive DESC, name, id"
data="items">
data="items"
auto-load="true">
</vn-crud-model>
<vn-portal slot="topbar">
<vn-searchbar
vn-focus
panel="vn-item-search-panel"
info="Search items by id, name or barcode"
suggested-filter="{isActive: true}"
suggested-filter="$ctrl.filterParams"
filter="$ctrl.filterParams"
model="model">
</vn-searchbar>
</vn-portal>

View File

@ -1,7 +1,15 @@
import ngModule from '../module';
import ModuleMain from 'salix/components/module-main';
export default class Items extends ModuleMain {
constructor($element, $) {
super($element, $);
export default class Items extends ModuleMain {}
this.filterParams = {
isActive: true,
isFloramondo: false
};
}
}
ngModule.vnComponent('vnItems', {
controller: Items,

View File

@ -9,7 +9,7 @@
{"state": "item.index", "icon": "icon-item"},
{"state": "item.request", "icon": "pan_tool"},
{"state": "item.waste.index", "icon": "icon-claims"},
{"state": "item.fixedPrice", "icon": "contact_support"}
{"state": "item.fixedPrice", "icon": "icon-fixedPrice"}
],
"card": [
{"state": "item.card.basicData", "icon": "settings"},

View File

@ -40,13 +40,11 @@
<vn-horizontal>
<vn-autocomplete
vn-one
disabled="false"
ng-model="filter.buyerFk"
url="Workers/activeWithRole"
url="Items/activeBuyers"
show-field="nickname"
search-function="{firstName: $search}"
value-field="id"
where="{role: {inq: ['logistic', 'buyer']}}"
value-field="workerFk"
label="Buyer">
</vn-autocomplete>
</vn-horizontal>
@ -155,6 +153,14 @@
tabindex="-1">
</vn-icon-button>
</vn-horizontal>
<vn-horizontal>
<vn-check
vn-one
label="Floramondo"
ng-model="filter.isFloramondo"
triple-state="true">
</vn-check>
</vn-horizontal>
<vn-horizontal class="vn-mt-lg">
<vn-submit label="Search"></vn-submit>
</vn-horizontal>

View File

@ -11,7 +11,7 @@ vn-monitor-sales-orders {
color: gray;
& > vn-td {
border-bottom: 2px solid $color-marginal;
border-bottom: $border;
font-size: 13px;
}
}

View File

@ -6,7 +6,7 @@ vn-monitor-index {
padding: 12px 0 5px 0;
color: gray;
font-size: 1.2rem;
border-bottom: 2px solid $color-font-secondary;
border-bottom: $border;
margin-bottom: 10px;
& > vn-none > vn-icon {

View File

@ -20,7 +20,7 @@ module.exports = Self => {
});
Self.getSuggestedTickets = async(id, options) => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -26,7 +26,8 @@ module.exports = Self => {
Self.getTickets = async(filter, options) => {
const conn = Self.dataSource.connector;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -30,7 +30,7 @@ module.exports = Self => {
const models = Self.app.models;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -24,7 +24,7 @@ module.exports = Self => {
const models = Self.app.models;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -6,5 +6,5 @@
margin-bottom: 10px;
padding-right: 10px;
padding-left: 10px;
border: 1px solid $color-marginal;
border: 1px solid $color-spacer;
}

View File

@ -28,11 +28,6 @@
icon="icon-disabled"
ng-if="$ctrl.supplier.isActive == false">
</vn-icon>
<vn-icon
vn-tooltip="Verified supplier"
icon="verified_user"
ng-if="$ctrl.supplier.isSerious == true">
</vn-icon>
<vn-icon
vn-tooltip="Unverified supplier"
icon="icon-supplierfalse"

View File

@ -13,7 +13,7 @@
{"state": "supplier.card.fiscalData", "icon": "account_balance"},
{"state": "supplier.card.billingData", "icon": "icon-payment"},
{"state": "supplier.card.address.index", "icon": "icon-delivery"},
{"state": "supplier.card.account", "icon": "contact_support"},
{"state": "supplier.card.account", "icon": "icon-accounts"},
{"state": "supplier.card.contact", "icon": "contact_phone"},
{"state": "supplier.card.log", "icon": "history"},
{"state": "supplier.card.consumption", "icon": "show_chart"}

View File

@ -23,7 +23,9 @@ class Controller extends Component {
}
loadDefaultTicketAction() {
let filter = {where: {code: 'changePrice'}};
const isSalesAssistant = this.aclService.hasAny(['salesAssistant']);
const defaultOption = isSalesAssistant ? 'turnInMana' : 'changePrice';
const filter = {where: {code: defaultOption}};
this.$http.get(`TicketUpdateActions`, {filter}).then(response => {
return this.ticket.option = response.data[0].id;

View File

@ -40,7 +40,7 @@ module.exports = Self => {
ended.setMonth(12);
ended.setDate(0);
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -34,8 +34,8 @@ module.exports = Self => {
const models = Self.app.models;
const args = ctx.args;
const currentUserId = ctx.req.accessToken.userId;
const myOptions = {};
let myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -25,7 +25,7 @@ module.exports = Self => {
const currentUserId = ctx.req.accessToken.userId;
const models = Self.app.models;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -31,7 +31,7 @@ module.exports = Self => {
const models = Self.app.models;
const args = ctx.args;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -41,7 +41,7 @@ module.exports = Self => {
const userId = ctx.req.accessToken.userId;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -28,7 +28,7 @@ module.exports = Self => {
const userId = ctx.req.accessToken.userId;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -34,7 +34,7 @@ module.exports = Self => {
const models = Self.app.models;
const args = ctx.args;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -27,7 +27,7 @@ module.exports = Self => {
const models = Self.app.models;
const myUserId = ctx.req.accessToken.userId;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -25,7 +25,7 @@ module.exports = Self => {
const userId = ctx.req.accessToken.userId;
const stmts = [];
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -11,7 +11,7 @@ vn-worker-calendar {
padding: $spacing-md;
& > vn-calendar {
border: 1px solid #ddd;
border: $border-thin;
margin: $spacing-md;
padding: $spacing-xs;
max-width: 288px;
@ -38,13 +38,12 @@ vn-worker-calendar {
}
vn-side-menu div > .input {
border-color: rgba(0, 0, 0, 0.3);
border-bottom: 1px solid rgba(0, 0, 0, 0.3);
border-bottom: $border-thin;
}
.festive,
vn-avatar.today {
background-color: $color-font-dark;
color: $color-font;
width: 24px;
min-width: 24px;
height: 24px

View File

@ -22,7 +22,7 @@ module.exports = Self => {
Self.byWarehouse = async(filter, options) => {
const conn = Self.dataSource.connector;
const where = {isActive: true};
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -29,7 +29,7 @@ module.exports = Self => {
});
Self.getAgenciesWithWarehouse = async(addressFk, landed, warehouseFk, options) => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -23,7 +23,7 @@ module.exports = Self => {
});
Self.landsThatDay = async(addressFk, landed, options) => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -22,7 +22,7 @@ module.exports = Self => {
Self.clone = async(id, options) => {
const models = Self.app.models;
let tx;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -26,7 +26,7 @@ module.exports = Self => {
});
Self.getEvents = async(geoFk, agencyModeFk, options) => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -32,7 +32,7 @@ module.exports = Self => {
});
Self.getLeaves = async(id, parentId = null, search, options) => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -14,7 +14,7 @@ module.exports = Self => {
});
Self.getUpcomingDeliveries = async options => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -2,7 +2,7 @@ const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
module.exports = Self => {
Self.remoteMethodCtx('includingExpired', {
description: 'Returns a list of agencies from a warehouse',
description: 'Returns a list of zones for the given warehouse and user',
accepts: [{
arg: 'filter',
type: 'Object',
@ -19,7 +19,7 @@ module.exports = Self => {
});
Self.includingExpired = async(ctx, filter, options) => {
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -29,7 +29,7 @@ module.exports = Self => {
Self.toggleIsIncluded = async(id, geoId, isIncluded, options) => {
const models = Self.app.models;
let myOptions = {};
const myOptions = {};
if (typeof options == 'object')
Object.assign(myOptions, options);

View File

@ -28,7 +28,7 @@ module.exports = {
for (let attachment of options.attachments) {
const fileName = attachment.filename;
const filePath = attachment.path;
// if (fileName.includes('.png')) return;
if (fileName.includes('.png')) return;
if (fileName || filePath)
attachments.push(filePath ? filePath : fileName);