2708 - Extra community changes #503
|
@ -25,9 +25,11 @@ pipeline {
|
|||
switch (env.BRANCH_NAME) {
|
||||
case 'master':
|
||||
env.NODE_ENV = 'production'
|
||||
env.BACK_REPLICAS = 4
|
||||
break
|
||||
case 'test':
|
||||
env.NODE_ENV = 'test'
|
||||
env.BACK_REPLICAS = 2
|
||||
break
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,7 @@ module.exports = Self => {
|
|||
throw new UserError(`You don't have enough privileges`);
|
||||
|
||||
if (process.env.NODE_ENV == 'test')
|
||||
throw new UserError(`You can't upload images on the test instance`);
|
||||
throw new UserError(`You can't upload images on the test environment`);
|
||||
|
||||
// Upload file to temporary path
|
||||
const tempContainer = await TempContainer.container(args.collection);
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
DROP TRIGGER IF EXISTS `vn`.`itemTag_afterUpdate`;
|
||||
|
||||
DELIMITER $$
|
||||
USE `vn`$$
|
||||
CREATE DEFINER=`root`@`%` TRIGGER `vn`.`itemTag_afterUpdate`
|
||||
AFTER UPDATE ON `itemTag` FOR EACH ROW
|
||||
trig: BEGIN
|
||||
IF @isTriggerDisabled THEN
|
||||
LEAVE trig;
|
||||
END IF;
|
||||
|
||||
DROP TEMPORARY TABLE IF EXISTS tmp.item;
|
||||
CREATE TEMPORARY TABLE tmp.item
|
||||
SELECT NEW.itemFk id;
|
||||
|
||||
CALL item_refreshTags();
|
||||
DROP TEMPORARY TABLE tmp.item;
|
||||
END$$
|
||||
DELIMITER ;
|
File diff suppressed because it is too large
Load Diff
|
@ -59,7 +59,6 @@ IGNORETABLES=(
|
|||
--ignore-table=vn.mail__
|
||||
--ignore-table=vn.manaSpellers
|
||||
--ignore-table=vn.outgoingInvoiceKk
|
||||
--ignore-table=vn.payment
|
||||
--ignore-table=vn.paymentExchangeInsurance
|
||||
--ignore-table=vn.payrollCenter
|
||||
--ignore-table=vn.plantpassport__
|
||||
|
|
|
@ -8,7 +8,7 @@ services:
|
|||
ports:
|
||||
- 80
|
||||
deploy:
|
||||
replicas: 3
|
||||
replicas: 2
|
||||
back:
|
||||
image: registry.verdnatura.es/salix-back:${BRANCH_NAME:?}
|
||||
build: .
|
||||
|
@ -30,7 +30,7 @@ services:
|
|||
- /mnt/storage/dms:/var/lib/salix/dms
|
||||
- /mnt/storage/image:/var/lib/salix/image
|
||||
deploy:
|
||||
replicas: 6
|
||||
replicas: ${BACK_REPLICAS:?}
|
||||
configs:
|
||||
datasources:
|
||||
external: true
|
||||
|
|
|
@ -721,9 +721,9 @@ export default {
|
|||
},
|
||||
workerSummary: {
|
||||
header: 'vn-worker-summary h5',
|
||||
id: 'vn-worker-summary vn-one:nth-child(1) > vn-label-value:nth-child(2) > section > span',
|
||||
email: 'vn-worker-summary vn-one:nth-child(1) > vn-label-value:nth-child(3) > section > span',
|
||||
department: 'vn-worker-summary vn-one:nth-child(1) > vn-label-value:nth-child(4) > section > span',
|
||||
id: 'vn-worker-summary vn-one:nth-child(1) > vn-label-value:nth-child(3) > section > span',
|
||||
email: 'vn-worker-summary vn-one:nth-child(1) > vn-label-value:nth-child(4) > section > span',
|
||||
department: 'vn-worker-summary vn-one:nth-child(1) > vn-label-value:nth-child(5) > section > span',
|
||||
userId: 'vn-worker-summary vn-one:nth-child(2) > vn-label-value:nth-child(2) > section > span',
|
||||
userName: 'vn-worker-summary vn-one:nth-child(2) > vn-label-value:nth-child(3) > section > span',
|
||||
role: 'vn-worker-summary vn-one:nth-child(2) > vn-label-value:nth-child(4) > section > span',
|
||||
|
|
|
@ -187,7 +187,10 @@ export default class Field extends FormInput {
|
|||
}
|
||||
|
||||
onChange() {
|
||||
this.emit('change', {value: this.field});
|
||||
// Changes doesn't reflect until appling async
|
||||
this.$.$applyAsync(() => {
|
||||
this.emit('change', {value: this.field});
|
||||
});
|
||||
}
|
||||
}
|
||||
Field.$inject = ['$element', '$scope'];
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import Component from '../../lib/component';
|
||||
import './style.scss';
|
||||
|
||||
export default class SearchPanel extends Component {
|
||||
set filter(value) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
@import "variables";
|
||||
@import "./variables";
|
||||
|
||||
vn-searchbar {
|
||||
display: block;
|
||||
|
@ -44,4 +44,27 @@ vn-searchbar {
|
|||
& > form {
|
||||
padding: $spacing-lg;
|
||||
}
|
||||
|
||||
& > form#manifold-form {
|
||||
padding: 0;
|
||||
|
||||
.manifold-panel {
|
||||
border: $border-thin-light;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
text-align: right;
|
||||
|
||||
.or {
|
||||
font-weight: bold;
|
||||
font-size: 26px;
|
||||
color: $color-font-secondary
|
||||
}
|
||||
|
||||
vn-icon[icon="info"] {
|
||||
position: absolute;
|
||||
top: 2px;
|
||||
right: 2px
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import ngModule from '../../module';
|
||||
import './style.scss';
|
||||
|
||||
export default class Th {
|
||||
constructor($element) {
|
||||
|
|
|
@ -73,6 +73,21 @@ ui-view > .vn-summary {
|
|||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
position: relative;
|
||||
span {
|
||||
display: block;
|
||||
}
|
||||
a {
|
||||
color: $color-font;
|
||||
}
|
||||
}
|
||||
h4 span:after {
|
||||
font-family: 'Material Icons';
|
||||
content: 'open_in_new';
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
text-transform: none;
|
||||
color: $color-spacer
|
||||
}
|
||||
& > * {
|
||||
margin: $spacing-sm;
|
||||
|
|
|
@ -52,6 +52,7 @@ Suppliers: Proveedores
|
|||
Summary: Vista previa
|
||||
Basic data: Datos básicos
|
||||
List: Listado
|
||||
Go to: Ir a
|
||||
|
||||
# Misc
|
||||
|
||||
|
|
|
@ -86,5 +86,7 @@
|
|||
"The social name cannot be empty": "The social name cannot be empty",
|
||||
"The nif cannot be empty": "The nif cannot be empty",
|
||||
"A travel with this data already exists": "A travel with this data already exists",
|
||||
"The observation type can't be repeated": "The observation type can't be repeated"
|
||||
"The observation type can't be repeated": "The observation type can't be repeated",
|
||||
"New ticket request has been created with price": "New ticket request has been created '{{description}}' for day <strong>{{shipped}}</strong>, with a quantity of <strong>{{quantity}}</strong> and a price of <strong>{{price}} €</strong>",
|
||||
"New ticket request has been created": "New ticket request has been created '{{description}}' for day <strong>{{shipped}}</strong>, with a quantity of <strong>{{quantity}}</strong>"
|
||||
}
|
|
@ -164,5 +164,7 @@
|
|||
"You can not select this payment method without a registered bankery account": "No se puede utilizar este método de pago si no has registrado una cuenta bancaria",
|
||||
"You can't upload images on the test environment": "No puedes subir imágenes en el entorno de pruebas",
|
||||
"The selected ticket is not suitable for this route": "El ticket seleccionado no es apto para esta ruta",
|
||||
"Sorts whole route": "Reordena ruta entera"
|
||||
"Sorts whole route": "Reordena ruta entera",
|
||||
"New ticket request has been created with price": "Se ha creado una nueva petición de compra '{{description}}' para el día <strong>{{shipped}}</strong>, con una cantidad de <strong>{{quantity}}</strong> y un precio de <strong>{{price}} €</strong>",
|
||||
"New ticket request has been created": "Se ha creado una nueva petición de compra '{{description}}' para el día <strong>{{shipped}}</strong>, con una cantidad de <strong>{{quantity}}</strong>"
|
||||
}
|
|
@ -24,9 +24,9 @@ exports.translateValues = async(instance, changes) => {
|
|||
|
||||
function formatDate(date) {
|
||||
return new Intl.DateTimeFormat('es', {
|
||||
year: '2-digit',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit'
|
||||
|
|
|
@ -35,14 +35,13 @@ module.exports = Self => {
|
|||
accountConfig
|
||||
} = this;
|
||||
|
||||
let newEntry;
|
||||
let dn = `uid=${userName},${this.userDn}`;
|
||||
|
||||
if (info.hasAccount) {
|
||||
let {user} = info;
|
||||
|
||||
let oldUser = await client.searchOne(this.userDn, {
|
||||
scope: 'sub',
|
||||
attributes: ['userPassword', 'sambaNTPassword'],
|
||||
filter: `&(uid=${userName})`
|
||||
});
|
||||
|
||||
|
@ -52,7 +51,7 @@ module.exports = Self => {
|
|||
? nameArgs.splice(1).join(' ')
|
||||
: '-';
|
||||
|
||||
newEntry = {
|
||||
let newEntry = {
|
||||
uid: userName,
|
||||
objectClass: [
|
||||
'inetOrgPerson',
|
||||
|
@ -101,62 +100,115 @@ module.exports = Self => {
|
|||
if (newEntry[prop] == null)
|
||||
delete newEntry[prop];
|
||||
}
|
||||
|
||||
if (oldUser) {
|
||||
let changes = [];
|
||||
let skipProps = new Set([
|
||||
'dn',
|
||||
'controls'
|
||||
]);
|
||||
|
||||
for (let prop in oldUser) {
|
||||
let deleteProp = !skipProps.has(prop)
|
||||
&& !newEntry.hasOwnProperty(prop);
|
||||
if (!deleteProp) continue;
|
||||
changes.push(new ldap.Change({
|
||||
operation: 'delete',
|
||||
modification: {
|
||||
[prop]: oldUser[prop]
|
||||
}
|
||||
}));
|
||||
}
|
||||
for (let prop in newEntry) {
|
||||
if (this.isEqual(oldUser[prop], newEntry[prop]))
|
||||
continue;
|
||||
changes.push(new ldap.Change({
|
||||
operation: 'replace',
|
||||
modification: {
|
||||
[prop]: newEntry[prop]
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
if (changes.length)
|
||||
await client.modify(dn, changes);
|
||||
} else
|
||||
await client.add(dn, newEntry);
|
||||
} else {
|
||||
try {
|
||||
await client.del(dn);
|
||||
console.log(` -> User '${userName}' removed from LDAP`);
|
||||
} catch (e) {
|
||||
if (e.name !== 'NoSuchObjectError') throw e;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Remove and recreate (if applicable) user
|
||||
|
||||
let dn = `uid=${userName},${this.userDn}`;
|
||||
let operation;
|
||||
|
||||
try {
|
||||
await client.del(dn);
|
||||
operation = 'delete';
|
||||
} catch (e) {
|
||||
if (e.name !== 'NoSuchObjectError') throw e;
|
||||
}
|
||||
|
||||
if (info.hasAccount) {
|
||||
await client.add(dn, newEntry);
|
||||
operation = 'add';
|
||||
}
|
||||
|
||||
if (operation === 'delete')
|
||||
console.log(` -> User '${userName}' removed from LDAP`);
|
||||
isEqual(a, b) {
|
||||
if (Array.isArray(a) && Array.isArray(b)) {
|
||||
if (a.length !== b.length)
|
||||
return false;
|
||||
for (let element of a) {
|
||||
if (b.indexOf(element) === -1)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
} else
|
||||
return a == b;
|
||||
},
|
||||
|
||||
async syncUserGroups(userName, info) {
|
||||
let {client} = this;
|
||||
let {user} = info;
|
||||
let groupDn = this.groupDn;
|
||||
|
||||
let opts = {
|
||||
scope: 'sub',
|
||||
attributes: ['dn'],
|
||||
attributes: ['dn', 'cn'],
|
||||
filter: `&(memberUid=${userName})(objectClass=posixGroup)`
|
||||
};
|
||||
let oldGroups = await client.searchAll(this.groupDn, opts);
|
||||
let oldGroups = await client.searchAll(groupDn, opts);
|
||||
|
||||
let reqs = [];
|
||||
for (let oldGroup of oldGroups) {
|
||||
let change = new ldap.Change({
|
||||
operation: 'delete',
|
||||
modification: {memberUid: userName}
|
||||
});
|
||||
reqs.push(client.modify(oldGroup.dn, change));
|
||||
let deleteGroups = [];
|
||||
let addGroups = [];
|
||||
|
||||
if (info.hasAccount) {
|
||||
let oldSet = new Set();
|
||||
oldGroups.forEach(e => oldSet.add(e.cn));
|
||||
|
||||
let newSet = new Set();
|
||||
user.roles().forEach(e => newSet.add(e.inherits().name));
|
||||
|
||||
for (let group of oldGroups) {
|
||||
if (!newSet.has(group.cn))
|
||||
deleteGroups.push(group.cn);
|
||||
}
|
||||
for (let role of user.roles()) {
|
||||
if (!oldSet.has(role.inherits().name))
|
||||
addGroups.push(role.inherits().name);
|
||||
}
|
||||
} else {
|
||||
for (let group of oldGroups)
|
||||
deleteGroups.push(group.cn);
|
||||
}
|
||||
await Promise.all(reqs);
|
||||
|
||||
if (!info.hasAccount) return;
|
||||
|
||||
reqs = [];
|
||||
for (let role of info.user.roles()) {
|
||||
let change = new ldap.Change({
|
||||
operation: 'add',
|
||||
modification: {memberUid: userName}
|
||||
});
|
||||
let roleName = role.inherits().name;
|
||||
let dn = `cn=${roleName},${this.groupDn}`;
|
||||
reqs.push(client.modify(dn, change));
|
||||
async function applyOperations(groups, operation) {
|
||||
for (let group of groups) {
|
||||
try {
|
||||
let dn = `cn=${group},${groupDn}`;
|
||||
await client.modify(dn, new ldap.Change({
|
||||
operation,
|
||||
modification: {memberUid: userName}
|
||||
}));
|
||||
} catch (err) {
|
||||
if (err.name !== 'NoSuchObjectError')
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
}
|
||||
await Promise.all(reqs);
|
||||
|
||||
await applyOperations(deleteGroups, 'delete');
|
||||
await applyOperations(addGroups, 'add');
|
||||
},
|
||||
|
||||
async getUsers(usersToSync) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<vn-card class="summary">
|
||||
<h5>
|
||||
<a ng-if="::summary.id"
|
||||
<a
|
||||
ng-if="::summary.id"
|
||||
vn-tooltip="Go to the user"
|
||||
ui-sref="account.card.summary({id: {{::summary.id}}})"
|
||||
name="goToSummary">
|
||||
|
@ -10,7 +11,18 @@
|
|||
</h5>
|
||||
<vn-horizontal class="vn-pa-md">
|
||||
<vn-one>
|
||||
<h4 translate>Basic data</h4>
|
||||
<h4 ng-show="$ctrl.isHr">
|
||||
<a
|
||||
ui-sref="account.card.basicData({id:summary.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Basic Data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isHr">
|
||||
Basic Data
|
||||
</h4>
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
value="{{summary.id}}">
|
||||
|
|
|
@ -18,6 +18,9 @@ class Controller extends Summary {
|
|||
this.$http.get(`Accounts/${value.id}`, {filter})
|
||||
.then(res => this.$.summary = res.data);
|
||||
}
|
||||
get isHr() {
|
||||
return this.aclService.hasAny(['hr']);
|
||||
}
|
||||
|
||||
get user() {
|
||||
return this._user;
|
||||
|
|
|
@ -4,7 +4,8 @@
|
|||
</vn-crud-model>
|
||||
<vn-card class="summary">
|
||||
<h5>
|
||||
<a ng-if="::$ctrl.summary.claim.id"
|
||||
<a
|
||||
ng-if="::$ctrl.summary.claim.id"
|
||||
vn-tooltip="Go to the claim"
|
||||
ui-sref="claim.card.summary({id: {{::$ctrl.summary.claim.id}}})"
|
||||
name="goToSummary">
|
||||
|
@ -54,7 +55,18 @@
|
|||
</vn-range>
|
||||
</vn-one>
|
||||
<vn-auto>
|
||||
<h4 translate>Detail</h4>
|
||||
<h4 ng-show="$ctrl.isSalesPerson">
|
||||
<a
|
||||
ui-sref="claim.card.detail({id:$ctrl.claim.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Detail</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
ng-show="!$ctrl.isSalesPerson"
|
||||
translate>
|
||||
Detail
|
||||
</h4>
|
||||
<vn-data-viewer data="::$ctrl.summary.salesClaimed">
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
|
@ -105,7 +117,18 @@
|
|||
</vn-horizontal>
|
||||
</vn-auto>
|
||||
<vn-auto>
|
||||
<h4 translate>Development</h4>
|
||||
<h4 ng-show="$ctrl.isClaimManager">
|
||||
<a
|
||||
ui-sref="claim.card.development({id:$ctrl.claim.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Development</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isClaimManager">
|
||||
Development
|
||||
</h4>
|
||||
<vn-data-viewer data="::$ctrl.summary.developments">
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
|
@ -136,7 +159,18 @@
|
|||
</vn-data-viewer>
|
||||
</vn-auto>
|
||||
<vn-auto>
|
||||
<h4 translate>Action</h4>
|
||||
<h4 ng-show="$ctrl.isClaimManager">
|
||||
<a
|
||||
ui-sref="claim.card.action({id:$ctrl.claim.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Action</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isClaimManager">
|
||||
Action
|
||||
</h4>
|
||||
<vn-data-viewer data="::$ctrl.summary.actions">
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
|
|
|
@ -13,6 +13,14 @@ class Controller extends Summary {
|
|||
this.getSummary();
|
||||
}
|
||||
|
||||
get isSalesPerson() {
|
||||
return this.aclService.hasAny(['salesPerson']);
|
||||
}
|
||||
|
||||
get isClaimManager() {
|
||||
return this.aclService.hasAny(['claimManager']);
|
||||
}
|
||||
|
||||
get claim() {
|
||||
return this._claim;
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ class Controller extends Section {
|
|||
get reportParams() {
|
||||
const userParams = this.$.model.userParams;
|
||||
return Object.assign({
|
||||
authorization: this.vnToken.token,
|
||||
recipient: this.client.email,
|
||||
recipientId: this.client.id
|
||||
}, userParams);
|
||||
}
|
||||
|
|
|
@ -12,7 +12,18 @@
|
|||
</h5>
|
||||
<vn-horizontal>
|
||||
<vn-one>
|
||||
<h4 translate>Basic data</h4>
|
||||
<h4 ng-show="$ctrl.isEmployee">
|
||||
<a
|
||||
ui-sref="client.card.basicData({id:$ctrl.client.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Basic data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isEmployee">
|
||||
Basic data
|
||||
</h4>
|
||||
<vn-label-value label="Id"
|
||||
value="{{$ctrl.summary.id}}">
|
||||
</vn-label-value>
|
||||
|
@ -43,7 +54,18 @@
|
|||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<h4 translate>Fiscal address</h4>
|
||||
<h4 ng-show="$ctrl.isEmployee">
|
||||
<a
|
||||
ui-sref="client.card.fiscalData({id:$ctrl.client.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Fiscal address</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isEmployee">
|
||||
Fiscal address
|
||||
</h4>
|
||||
<vn-label-value label="Social name"
|
||||
value="{{$ctrl.summary.socialName}}">
|
||||
</vn-label-value>
|
||||
|
@ -67,7 +89,18 @@
|
|||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<h4 translate>Fiscal data</h4>
|
||||
<h4 ng-show="$ctrl.isEmployee">
|
||||
<a
|
||||
ui-sref="client.card.fiscalData({id:$ctrl.client.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Fiscal data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isEmployee">
|
||||
Fiscal data
|
||||
</h4>
|
||||
<vn-vertical>
|
||||
<vn-check
|
||||
label="Is equalizated"
|
||||
|
@ -107,7 +140,18 @@
|
|||
</vn-vertical>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<h4 translate>Billing data</h4>
|
||||
<h4 ng-show="$ctrl.isEmployee">
|
||||
<a
|
||||
ui-sref="client.card.billingData({id:$ctrl.client.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Billing data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isEmployee">
|
||||
Billing data
|
||||
</h4>
|
||||
<vn-label-value label="Pay method"
|
||||
value="{{$ctrl.summary.payMethod.name}}">
|
||||
</vn-label-value>
|
||||
|
@ -136,7 +180,18 @@
|
|||
</vn-vertical>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<h4 translate>Default address</h4>
|
||||
<h4 ng-show="$ctrl.isEmployee">
|
||||
<a
|
||||
ui-sref="client.card.address.index({id:$ctrl.client.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Address</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isEmployee">
|
||||
Address
|
||||
</h4>
|
||||
<vn-label-value label="Name"
|
||||
value="{{$ctrl.summary.defaultAddress.nickname}}">
|
||||
</vn-label-value>
|
||||
|
@ -148,7 +203,17 @@
|
|||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<h4 translate>Web access</h4>
|
||||
<h4 ng-show="$ctrl.isEmployee">
|
||||
<a
|
||||
ui-sref="client.card.webAccess({id:$ctrl.client.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Web access</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isEmployee">Web access
|
||||
</h4>
|
||||
<vn-label-value label="User"
|
||||
value="{{$ctrl.summary.account.name}}">
|
||||
</vn-label-value>
|
||||
|
|
|
@ -18,6 +18,9 @@ class Controller extends Summary {
|
|||
}
|
||||
});
|
||||
}
|
||||
get isEmployee() {
|
||||
return this.aclService.hasAny(['employee']);
|
||||
}
|
||||
|
||||
sumRisk() {
|
||||
let total = 0;
|
||||
|
|
|
@ -7,6 +7,7 @@ Secured credit: Crédito asegurado
|
|||
Average invoiced: Consumo medio
|
||||
Sales person: Comercial
|
||||
Recovery: Recobro
|
||||
Basic data: Datos básicos
|
||||
Balance due: Saldo vencido
|
||||
Rate: Tarifa
|
||||
Business data: Datos comerciales
|
||||
|
|
|
@ -93,7 +93,12 @@ module.exports = Self => {
|
|||
let where = buildFilter(ctx.args, (param, value) => {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return {'e.id': value};
|
||||
return /^\d+$/.test(value)
|
||||
? {'e.id': value}
|
||||
: {or: [
|
||||
{'s.name': {like: `%${value}%`}},
|
||||
{'s.nickname': {like: `%${value}%`}}
|
||||
]};
|
||||
case 'ref':
|
||||
param = `e.${param}`;
|
||||
return {[param]: {like: `%${value}%`}};
|
||||
|
@ -141,6 +146,7 @@ module.exports = Self => {
|
|||
e.invoiceInFk,
|
||||
t.landed,
|
||||
s.name AS supplierName,
|
||||
s.nickname AS supplierAlias,
|
||||
co.code AS companyCode,
|
||||
cu.code AS currencyCode
|
||||
FROM vn.entry e
|
||||
|
|
|
@ -8,11 +8,14 @@
|
|||
<vn-searchbar
|
||||
vn-focus
|
||||
panel="vn-entry-search-panel"
|
||||
info="Search entrys by id"
|
||||
info="Search entry by id or a suppliers by name or alias"
|
||||
model="model">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<vn-portal slot="menu">
|
||||
<vn-left-menu></vn-left-menu>
|
||||
</vn-portal>
|
||||
<ui-view></ui-view>
|
||||
<ui-view></ui-view>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
vn-one
|
||||
label="General search"
|
||||
ng-model="filter.search"
|
||||
info="Search entries by id"
|
||||
info="Search entry by id or a suppliers by name or alias"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
|
@ -45,8 +45,11 @@
|
|||
label="Supplier"
|
||||
ng-model="filter.supplierFk"
|
||||
url="Suppliers"
|
||||
fields="['name','nickname']"
|
||||
search-function="{or: [{nickname: {like: '%'+ $search +'%'}}, {name: {like: '%'+ $search +'%'}}]}"
|
||||
show-field="name"
|
||||
value-field="id">
|
||||
<tpl-item>{{name}}: {{nickname}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
|
|
|
@ -4,4 +4,5 @@ Nickname: Alias
|
|||
From: Desde
|
||||
To: Hasta
|
||||
Agency: Agencia
|
||||
Warehouse: Almacén
|
||||
Warehouse: Almacén
|
||||
Search entry by id or a suppliers by name or alias: Buscar entrada por id o proveedores por nombre y alias
|
|
@ -119,6 +119,7 @@ module.exports = Self => {
|
|||
ori.code AS origin,
|
||||
ic.name AS category,
|
||||
i.density,
|
||||
i.stemMultiplier,
|
||||
b.grouping,
|
||||
b.packing,
|
||||
itn.code AS niche, @visibleCalc
|
||||
|
|
|
@ -65,7 +65,10 @@
|
|||
"type": "Number",
|
||||
"description": "Density"
|
||||
},
|
||||
"image": {
|
||||
"stemMultiplier": {
|
||||
"type": "Number",
|
||||
"description": "Multiplier"
|
||||
},"image": {
|
||||
"type": "String",
|
||||
"description": "Image"
|
||||
},
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
<vn-th field="origin" shrink>Origin</vn-th>
|
||||
<vn-th field="salesperson" shrink>Buyer</vn-th>
|
||||
<vn-th field="density" shrink>Density</vn-th>
|
||||
<vn-th field="stemMultiplier" shrink>Multiplier</vn-th>
|
||||
<vn-th field="active" shrink>Active</vn-th>
|
||||
<vn-th></vn-th>
|
||||
</vn-tr>
|
||||
|
@ -78,6 +79,7 @@
|
|||
</span>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::item.density}}</vn-td>
|
||||
<vn-td shrink >{{::item.stemMultiplier}}</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
|
|
|
@ -25,7 +25,18 @@
|
|||
</vn-horizontal>
|
||||
</vn-one>
|
||||
<vn-one name="basicData">
|
||||
<h4 translate>Basic data</h4>
|
||||
<h4 ng-show="$ctrl.isBuyer">
|
||||
<a
|
||||
ui-sref="item.card.basicData({id:$ctrl.item.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Basic data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isBuyer">
|
||||
Basic data
|
||||
</h4>
|
||||
<vn-label-value label="Name"
|
||||
value="{{$ctrl.summary.item.name}}">
|
||||
</vn-label-value>
|
||||
|
@ -53,7 +64,18 @@
|
|||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one name="otherData">
|
||||
<h4 translate>Other data</h4>
|
||||
<h4 ng-show="$ctrl.isBuyer">
|
||||
<a
|
||||
ui-sref="item.card.basicData({id:$ctrl.item.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Other data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isBuyer">
|
||||
Other data
|
||||
</h4>
|
||||
<vn-label-value label="Intrastat code"
|
||||
value="{{$ctrl.summary.item.intrastat.id}}">
|
||||
</vn-label-value>
|
||||
|
@ -77,7 +99,18 @@
|
|||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one name="tags">
|
||||
<h4 translate>Tags</h4>
|
||||
<h4 ng-show="$ctrl.isBuyer || $ctrl.isReplenisher">
|
||||
<a
|
||||
ui-sref="item.card.tags({id:$ctrl.item.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Tags</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isBuyer || !$ctrl.isReplenisher">
|
||||
Tags
|
||||
</h4>
|
||||
<vn-label-value
|
||||
label="{{tag.priority}} {{tag.tag.name}}"
|
||||
ng-repeat="tag in $ctrl.summary.tags track by tag.id"
|
||||
|
@ -85,21 +118,54 @@
|
|||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one name="tax">
|
||||
<h4 translate>Tax</h4>
|
||||
<h4 ng-show="$ctrl.isBuyer || $ctrl.isAdministrative">
|
||||
<a
|
||||
ui-sref="item.card.tax({id:$ctrl.item.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Tax</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isBuyer || !$ctrl.isAdministrative">
|
||||
Tax
|
||||
</h4>
|
||||
<vn-label-value label="{{tax.country.country}}"
|
||||
ng-repeat="tax in $ctrl.summary.item.taxes"
|
||||
value="{{tax.taxClass.description}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one name="niche">
|
||||
<h4 translate>Niche</h4>
|
||||
<h4 ng-show="$ctrl.isBuyer || $ctrl.isReplenisher">
|
||||
<a
|
||||
ui-sref="item.card.niche({id:$ctrl.item.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Niche</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isBuyer || !$ctrl.isReplenisher">
|
||||
Niche
|
||||
</h4>
|
||||
<vn-label-value label="{{niche.warehouse.name}}"
|
||||
ng-repeat="niche in $ctrl.summary.niches"
|
||||
value="{{niche.code}}">
|
||||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one name="botanical">
|
||||
<h4 translate>Botanical</h4>
|
||||
<h4 ng-show="$ctrl.isBuyer">
|
||||
<a
|
||||
ui-sref="item.card.botanical({id:$ctrl.item.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Botanical</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isBuyer">
|
||||
Botanical
|
||||
</h4>
|
||||
<vn-label-value label="Botanical"
|
||||
value="{{$ctrl.summary.botanical.botanical}}">
|
||||
</vn-label-value>
|
||||
|
@ -111,7 +177,18 @@
|
|||
</vn-label-value>
|
||||
</vn-one>
|
||||
<vn-one name="barcode">
|
||||
<h4 translate>Barcode</h4>
|
||||
<h4 ng-show="$ctrl.isBuyer || $ctrl.isReplenisher">
|
||||
<a
|
||||
ui-sref="item.card.itemBarcode({id:$ctrl.item.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Barcode</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isBuyer || !$ctrl.isReplenisher">
|
||||
Barcode
|
||||
</h4>
|
||||
<p ng-repeat="barcode in $ctrl.summary.item.itemBarcode track by $index">
|
||||
<b>{{barcode.code}}</b>
|
||||
</p>
|
||||
|
|
|
@ -13,6 +13,22 @@ class Controller extends Summary {
|
|||
if (this.item && this.item.id)
|
||||
this.getSummary();
|
||||
}
|
||||
|
||||
get isBuyer() {
|
||||
return this.aclService.hasAny(['buyer']);
|
||||
}
|
||||
|
||||
get isReplenisher() {
|
||||
return this.aclService.hasAny(['replenisher']);
|
||||
}
|
||||
|
||||
get isAdministrative() {
|
||||
return this.aclService.hasAny(['administrative']);
|
||||
}
|
||||
|
||||
get isEmployee() {
|
||||
return this.aclService.hasAny(['employee']);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnItemSummary', {
|
||||
|
|
|
@ -61,7 +61,18 @@
|
|||
</vn-textarea>
|
||||
</vn-one>
|
||||
<vn-auto>
|
||||
<h4 translate>Ticket</h4>
|
||||
<h4 ng-show="$ctrl.isDelivery">
|
||||
<a
|
||||
ui-sref="route.card.tickets({id:$ctrl.route.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Ticket</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isDelivery">
|
||||
Ticket
|
||||
</h4>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
|
|
|
@ -16,6 +16,10 @@ class Controller extends Summary {
|
|||
});
|
||||
}
|
||||
|
||||
get isDelivery() {
|
||||
return this.aclService.hasAny(['delivery']);
|
||||
}
|
||||
|
||||
get route() {
|
||||
return this._route;
|
||||
}
|
||||
|
|
|
@ -10,7 +10,18 @@
|
|||
</h5>
|
||||
<vn-horizontal>
|
||||
<vn-one>
|
||||
<h4 translate>Basic data</h4>
|
||||
<h4 ng-show="$ctrl.isAdministrative">
|
||||
<a
|
||||
ui-sref="supplier.card.basicData({id:$ctrl.supplier.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Basic data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isAdministrative">
|
||||
Basic data
|
||||
</h4>
|
||||
<vn-vertical>
|
||||
<vn-label-value
|
||||
label="Id"
|
||||
|
@ -37,7 +48,18 @@
|
|||
</vn-vertical>
|
||||
</vn-one>
|
||||
<vn-one>
|
||||
<h4 translate>Billing data</h4>
|
||||
<h4 ng-show="$ctrl.isAdministrative">
|
||||
<a
|
||||
ui-sref="supplier.card.billingData({id:$ctrl.supplier.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Billing data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isAdministrative">
|
||||
Billing data
|
||||
</h4>
|
||||
<vn-label-value
|
||||
label="Pay method"
|
||||
value="{{::$ctrl.summary.payMethod.name}}">
|
||||
|
@ -63,7 +85,18 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-one>
|
||||
<h4 translate>Fiscal data</h4>
|
||||
<h4 ng-show="$ctrl.isAdministrative">
|
||||
<a
|
||||
ui-sref="supplier.card.fiscalData({id:$ctrl.supplier.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Fiscal data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isAdministrative">
|
||||
Fiscal data
|
||||
</h4>
|
||||
<vn-label-value
|
||||
label="Sage tax type"
|
||||
value="{{::$ctrl.summary.sageTaxType.vat}}">
|
||||
|
@ -82,7 +115,18 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-one>
|
||||
<h4 translate>Fiscal address</h4>
|
||||
<h4 ng-show="$ctrl.isAdministrative">
|
||||
<a
|
||||
ui-sref="supplier.card.fiscalData({id:$ctrl.supplier.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Fiscal address</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isAdministrative">
|
||||
Fiscal address
|
||||
</h4>
|
||||
<vn-label-value
|
||||
label="Social name"
|
||||
value="{{::$ctrl.summary.name}}">
|
||||
|
|
|
@ -10,6 +10,10 @@ class Controller extends Summary {
|
|||
this.getSummary();
|
||||
}
|
||||
|
||||
get isAdministrative() {
|
||||
return this.aclService.hasAny(['administrative']);
|
||||
}
|
||||
|
||||
getSummary() {
|
||||
return this.$http.get(`Suppliers/${this.supplier.id}/getSummary`).then(response => {
|
||||
this.summary = response.data;
|
||||
|
|
|
@ -8,10 +8,38 @@ module.exports = function(Self) {
|
|||
Self.observe('before save', async function(ctx) {
|
||||
if (ctx.isNewInstance) {
|
||||
const loopBackContext = LoopBackContext.getCurrentContext();
|
||||
let filter = {where: {userFk: loopBackContext.active.accessToken.userId}};
|
||||
let worker = await Self.app.models.Worker.findOne(filter);
|
||||
const filter = {where: {userFk: loopBackContext.active.accessToken.userId}};
|
||||
const models = Self.app.models;
|
||||
const worker = await models.Worker.findOne(filter);
|
||||
|
||||
ctx.instance.requesterFk = worker.id;
|
||||
const instance = ctx.instance;
|
||||
instance.requesterFk = worker.id;
|
||||
|
||||
const httpCtx = {req: loopBackContext.active};
|
||||
const httpRequest = httpCtx.req.http .req;
|
||||
const $t = httpRequest.__;
|
||||
|
||||
const attenderId = instance.attenderFk;
|
||||
if (attenderId) {
|
||||
const ticket = await models.Ticket.findById(instance.ticketFk);
|
||||
let messageText = 'New ticket request has been created';
|
||||
if (instance.price)
|
||||
messageText = 'New ticket request has been created with price';
|
||||
|
||||
const shipped = new Intl.DateTimeFormat('es', {
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric'
|
||||
}).format(ticket.shipped);
|
||||
|
||||
const message = $t(messageText, {
|
||||
description: instance.description,
|
||||
shipped: shipped,
|
||||
quantity: instance.quantity,
|
||||
price: instance.price
|
||||
});
|
||||
await models.Chat.sendCheckingPresence(httpCtx, attenderId, message);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div class="search-panel">
|
||||
<form ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal class="vn-px-lg vn-pt-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="General search"
|
||||
|
@ -9,7 +9,7 @@
|
|||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Client id"
|
||||
|
@ -21,27 +21,37 @@
|
|||
ng-model="filter.orderFk">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="From"
|
||||
ng-model="filter.from">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="To"
|
||||
ng-model="filter.to">
|
||||
</vn-date-picker>
|
||||
<vn-input-number
|
||||
vn-one
|
||||
min="0"
|
||||
step="1"
|
||||
label="Days onward"
|
||||
ng-model="filter.scopeDays"
|
||||
display-controls="true">
|
||||
</vn-input-number>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<section class="vn-px-md">
|
||||
<vn-horizontal class="manifold-panel vn-pa-md">
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="From"
|
||||
ng-model="filter.from"
|
||||
on-change="$ctrl.from = value">
|
||||
</vn-date-picker>
|
||||
<vn-date-picker
|
||||
vn-one
|
||||
label="To"
|
||||
ng-model="filter.to"
|
||||
on-change="$ctrl.to = value">
|
||||
</vn-date-picker>
|
||||
<vn-none class="or vn-px-md">O</vn-none>
|
||||
<vn-input-number
|
||||
vn-one
|
||||
min="0"
|
||||
step="1"
|
||||
label="Days onward"
|
||||
ng-model="filter.scopeDays"
|
||||
on-change="$ctrl.scopeDays = value"
|
||||
display-controls="true">
|
||||
</vn-input-number>
|
||||
<vn-icon color-marginal
|
||||
icon="info"
|
||||
vn-tooltip="Cannot choose a range of dates and days onward at the same time">
|
||||
</vn-icon>
|
||||
</vn-horizontal>
|
||||
</section>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Nickname"
|
||||
|
@ -63,7 +73,7 @@
|
|||
ng-model="filter.refFk">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Agency"
|
||||
|
@ -87,7 +97,7 @@
|
|||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Warehouse"
|
||||
|
@ -101,7 +111,7 @@
|
|||
url="Provinces">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-check
|
||||
vn-one
|
||||
label="My team"
|
||||
|
@ -121,7 +131,7 @@
|
|||
triple-state="true">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-mt-lg">
|
||||
<vn-horizontal class="vn-px-lg vn-pb-lg vn-mt-lg">
|
||||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
</form>
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import ngModule from '../module';
|
||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||
|
||||
class Controller extends SearchPanel {
|
||||
constructor($, $element) {
|
||||
super($, $element);
|
||||
this.filter = this.$.filter;
|
||||
|
||||
this.getGroupedStates();
|
||||
}
|
||||
|
||||
|
@ -19,6 +22,35 @@ class Controller extends SearchPanel {
|
|||
this.groupedStates = groupedStates;
|
||||
});
|
||||
}
|
||||
|
||||
get from() {
|
||||
return this._from;
|
||||
}
|
||||
|
||||
set from(value) {
|
||||
this._from = value;
|
||||
this.filter.scopeDays = null;
|
||||
}
|
||||
|
||||
get to() {
|
||||
return this._to;
|
||||
}
|
||||
|
||||
set to(value) {
|
||||
this._to = value;
|
||||
this.filter.scopeDays = null;
|
||||
}
|
||||
|
||||
get scopeDays() {
|
||||
return this._scopeDays;
|
||||
}
|
||||
|
||||
set scopeDays(value) {
|
||||
this._scopeDays = value;
|
||||
|
||||
this.filter.from = null;
|
||||
this.filter.to = null;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnTicketSearchPanel', {
|
||||
|
|
|
@ -10,10 +10,11 @@ describe('Ticket Component vnTicketSearchPanel', () => {
|
|||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnTicketSearchPanel', {$element: null});
|
||||
controller.$t = () => {};
|
||||
controller.filter = {};
|
||||
}));
|
||||
|
||||
describe('getGroupedStates()', () => {
|
||||
it('should set an array of groupedStates with the aditionof a name translation', () => {
|
||||
it('should set an array of groupedStates with the adition of a name translation', () => {
|
||||
jest.spyOn(controller, '$t').mockReturnValue('miCodigo');
|
||||
const data = [
|
||||
{
|
||||
|
@ -32,4 +33,39 @@ describe('Ticket Component vnTicketSearchPanel', () => {
|
|||
}]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('from() setter', () => {
|
||||
it('should clear the scope days when setting the from property', () => {
|
||||
controller.filter.scopeDays = 1;
|
||||
|
||||
controller.from = new Date();
|
||||
|
||||
expect(controller.filter.scopeDays).toBeNull();
|
||||
expect(controller.from).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('to() setter', () => {
|
||||
it('should clear the scope days when setting the to property', () => {
|
||||
controller.filter.scopeDays = 1;
|
||||
|
||||
controller.to = new Date();
|
||||
|
||||
expect(controller.filter.scopeDays).toBeNull();
|
||||
expect(controller.to).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('scopeDays() setter', () => {
|
||||
it('should clear the date range when setting the scopeDays property', () => {
|
||||
controller.filter.from = new Date();
|
||||
controller.filter.to = new Date();
|
||||
|
||||
controller.scopeDays = 1;
|
||||
|
||||
expect(controller.filter.from).toBeNull();
|
||||
expect(controller.filter.to).toBeNull();
|
||||
expect(controller.scopeDays).toBeDefined();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -16,4 +16,5 @@ Pending: Pendiente
|
|||
FREE: Libre
|
||||
DELIVERED: Servido
|
||||
ON_PREPARATION: En preparacion
|
||||
PACKED: Encajado
|
||||
PACKED: Encajado
|
||||
Cannot choose a range of dates and days onward at the same time: No se puede selecionar un rango de fechas y días en adelante a la vez
|
|
@ -6,6 +6,7 @@
|
|||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-crud-model
|
||||
vn-id="typesModel"
|
||||
auto-load="true"
|
||||
url="TicketServiceTypes"
|
||||
data="ticketServiceTypes"
|
||||
|
|
|
@ -35,6 +35,10 @@ class Controller extends Section {
|
|||
throw new UserError(`Name can't be empty`);
|
||||
|
||||
return this.$http.post(`TicketServiceTypes`, this.$.newServiceType)
|
||||
.then(res => {
|
||||
this.$.typesModel.refresh();
|
||||
return res;
|
||||
})
|
||||
.then(res => service.ticketServiceTypeFk = res.data.id);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import './index.js';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
|
||||
describe('Ticket component vnTicketService', () => {
|
||||
let controller;
|
||||
|
@ -11,7 +12,7 @@ describe('Ticket component vnTicketService', () => {
|
|||
beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
|
||||
$scope.typesModel = crudModel;
|
||||
$element = angular.element(`<div></div>`);
|
||||
controller = $componentController('vnTicketService', {$scope, $element});
|
||||
}));
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<vn-card class="summary">
|
||||
<h5>
|
||||
<a ng-if="::$ctrl.summary.id"
|
||||
<a
|
||||
ng-if="::$ctrl.summary.id"
|
||||
vn-tooltip="Go to the ticket"
|
||||
ui-sref="ticket.card.summary({id: {{::$ctrl.summary.id}}})"
|
||||
name="goToSummary">
|
||||
|
@ -103,7 +104,13 @@
|
|||
<p><vn-label><strong>Total</strong></vn-label> <strong>{{$ctrl.summary.total | currency: 'EUR':2}}</strong></p>
|
||||
</vn-one>
|
||||
<vn-auto name="sales">
|
||||
<h4 translate>Sale</h4>
|
||||
<h4>
|
||||
<a
|
||||
ui-sref="ticket.card.sale({id:$ctrl.ticket.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Sale</span>
|
||||
</a>
|
||||
</h4>
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
|
@ -158,7 +165,13 @@
|
|||
</vn-table>
|
||||
</vn-auto>
|
||||
<vn-one ng-if="$ctrl.summary.packagings.length != 0">
|
||||
<h4 translate>Packages</h4>
|
||||
<h4>
|
||||
<a
|
||||
ui-sref="ticket.card.package({id:$ctrl.ticket.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Packages</span>
|
||||
</a>
|
||||
</h4>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
|
@ -177,7 +190,13 @@
|
|||
</vn-table>
|
||||
</vn-one>
|
||||
<vn-one class="services" ng-if="$ctrl.summary.services.length != 0">
|
||||
<h4 translate>Service</h4>
|
||||
<h4>
|
||||
<a
|
||||
ui-sref="ticket.card.service({id:$ctrl.ticket.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Service</span>
|
||||
</a>
|
||||
</h4>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
|
@ -202,7 +221,13 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-auto ng-if="$ctrl.summary.requests.length != 0">
|
||||
<h4 translate>Purchase request</h4>
|
||||
<h4>
|
||||
<a
|
||||
ui-sref="ticket.card.request.index({id:$ctrl.ticket.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Purchase request</span>
|
||||
</a>
|
||||
</h4>
|
||||
<vn-table model="model">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
|
|
|
@ -4,4 +4,4 @@ You are going to delete this weekly ticket: Vas a eliminar este ticket programad
|
|||
This ticket will be removed from weekly tickets! Continue anyway?: Este ticket se eliminará de tickets programados! ¿Continuar de todas formas?
|
||||
Search weekly ticket by id or client id: Busca tickets programados por el identificador o el identificador del cliente
|
||||
Search by weekly ticket: Buscar por tickets programados
|
||||
weekDay: Dia
|
||||
Weekday: Llegada
|
|
@ -1,6 +1,7 @@
|
|||
<vn-card class="summary">
|
||||
<h5>
|
||||
<a ng-if="::$ctrl.travelData.id"
|
||||
<a
|
||||
ng-if="::$ctrl.travelData.id"
|
||||
vn-tooltip="Go to the travel"
|
||||
ui-sref="travel.card.summary({id: {{::$ctrl.travelData.id}}})"
|
||||
name="goToSummary">
|
||||
|
@ -132,7 +133,18 @@
|
|||
</vn-table>
|
||||
</vn-auto>
|
||||
<vn-auto ng-if="$ctrl.travelThermographs.length != 0">
|
||||
<h4 translate>Thermographs</h4>
|
||||
<h4 ng-show="$ctrl.isBuyer">
|
||||
<a
|
||||
ui-sref="travel.card.thermograph.index({id:$ctrl.travelData.id})"
|
||||
target="_self">
|
||||
<span translate vn-tooltip="Go to">Thermograph</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translate
|
||||
ng-show="!$ctrl.isBuyer">
|
||||
Thermograph
|
||||
</h4>
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
|
|
|
@ -56,6 +56,10 @@ class Controller extends Summary {
|
|||
|
||||
return total;
|
||||
}
|
||||
|
||||
get isBuyer() {
|
||||
return this.aclService.hasAny(['buyer']);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnTravelSummary', {
|
||||
|
|
|
@ -84,13 +84,6 @@
|
|||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textarea vn-one vn-focus
|
||||
label="Description"
|
||||
ng-model="$ctrl.dms.description"
|
||||
rule>
|
||||
</vn-textarea>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-input-file
|
||||
vn-one
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "Calendar",
|
||||
"base": "Loggable",
|
||||
"base": "VnModel",
|
||||
"log": {
|
||||
"model": "WorkerLog",
|
||||
"relation": "labour"
|
||||
|
|
|
@ -10,7 +10,17 @@
|
|||
</h5>
|
||||
<vn-horizontal class="vn-pa-md">
|
||||
<vn-one>
|
||||
<h4 translate>Basic data</h4>
|
||||
<h4 ng-show="$ctrl.isHr">
|
||||
<a
|
||||
ui-sref="worker.card.basicData({id:$ctrl.worker.id})">
|
||||
<span translate vn-tooltip="Go to">Basic data</span>
|
||||
</a>
|
||||
</h4>
|
||||
<h4
|
||||
translates
|
||||
ng-show="!$ctrl.isHr">
|
||||
Basic data
|
||||
</h4>
|
||||
<vn-label-value label="Id"
|
||||
value="{{worker.id}}">
|
||||
</vn-label-value>
|
||||
|
|
|
@ -52,6 +52,10 @@ class Controller extends Summary {
|
|||
this.$.worker = res.data;
|
||||
});
|
||||
}
|
||||
|
||||
get isHr() {
|
||||
return this.aclService.hasAny(['hr']);
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnWorkerSummary', {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<vn-card class="summary">
|
||||
<h5>
|
||||
<a ng-if="::$ctrl.summary.id"
|
||||
<a
|
||||
ng-if="::$ctrl.summary.id"
|
||||
vn-tooltip="Go to the zone"
|
||||
ui-sref="zone.card.summary({id: {{::$ctrl.summary.id}}})"
|
||||
name="goToSummary">
|
||||
|
@ -36,7 +37,11 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-pa-md">
|
||||
<vn-auto>
|
||||
<h4 translate>Warehouses</h4>
|
||||
<h4>
|
||||
<a ui-sref="zone.card.warehouses({id:$ctrl.zone.id})">
|
||||
<span translate vn-tooltip="Go to">Warehouse</span>
|
||||
</a>
|
||||
</h4>
|
||||
<vn-table model="model" auto-load="false">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
|
|
|
@ -7,4 +7,4 @@ FROM client c
|
|||
JOIN company AS cny
|
||||
JOIN supplierAccount AS sa ON sa.id = cny.supplierAccountFk
|
||||
JOIN bankEntity be ON be.id = sa.bankEntityFk
|
||||
WHERE c.id = ? AND cny.id = ?`
|
||||
WHERE c.id = ? AND cny.id = ?
|
Loading…
Reference in New Issue