Merge branch 'dev' into 6159-businessAfterInsert
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
This commit is contained in:
commit
0d05aa521b
|
@ -6,6 +6,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
|
||||
## [2338.01] - 2023-09-21
|
||||
|
||||
### Added
|
||||
|
||||
### Changed
|
||||
|
||||
### Fixed
|
||||
|
||||
## [2336.01] - 2023-09-07
|
||||
|
||||
### Added
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
ALTER TABLE `vn`.`deviceLog` ADD serialNumber varchar(45) DEFAULT NULL NULL;
|
||||
|
||||
INSERT INTO `salix`.`ACL` ( model, property, accessType, permission, principalType, principalId)
|
||||
VALUES( 'DeviceLog', 'create', 'WRITE', 'ALLOW', 'ROLE', 'employee');
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
INSERT INTO `salix`.`ACL` (model, property, accessType, permission, principalType, principalId)
|
||||
VALUES
|
||||
('Worker', 'search', 'READ', 'ALLOW', 'ROLE', 'employee');
|
|
@ -0,0 +1,2 @@
|
|||
INSERT INTO `salix`.`ACL` (`model`,`property`,`accessType`,`permission`,`principalType`,`principalId`)
|
||||
VALUES ('ExpeditionState','addExpeditionState','WRITE','ALLOW','ROLE','delivery');
|
|
@ -0,0 +1,3 @@
|
|||
UPDATE `vn`.`department`
|
||||
SET code='VN'
|
||||
WHERE name='VERDNATURA';
|
|
@ -97,13 +97,6 @@ TABLES=(
|
|||
)
|
||||
dump_tables ${TABLES[@]}
|
||||
|
||||
TABLES=(
|
||||
postgresql
|
||||
labour_agreement
|
||||
media_type
|
||||
)
|
||||
dump_tables ${TABLES[@]}
|
||||
|
||||
TABLES=(
|
||||
sage
|
||||
TiposIva
|
||||
|
|
|
@ -7,7 +7,6 @@ SCHEMAS=(
|
|||
edi
|
||||
hedera
|
||||
pbx
|
||||
postgresql
|
||||
sage
|
||||
salix
|
||||
stock
|
||||
|
@ -23,7 +22,6 @@ IGNORETABLES=(
|
|||
--ignore-table=bs.productionIndicators
|
||||
--ignore-table=bs.VentasPorCliente
|
||||
--ignore-table=bs.v_ventas
|
||||
--ignore-table=postgresql.currentWorkersStats
|
||||
--ignore-table=vn.accounting__
|
||||
--ignore-table=vn.agencyModeZone
|
||||
--ignore-table=vn.agencyProvince
|
||||
|
|
|
@ -54,7 +54,6 @@ xdescribe('worker workerTimeControl_check()', () => {
|
|||
});
|
||||
|
||||
it('should throw an error if the worker with a special category has not finished the 9h break', async() => {
|
||||
// dayBreak to 9h in postgresql.professional_category
|
||||
const workerId = 1110;
|
||||
const tabletId = 1;
|
||||
let stmts = [];
|
||||
|
@ -91,7 +90,6 @@ xdescribe('worker workerTimeControl_check()', () => {
|
|||
});
|
||||
|
||||
it('should check f the worker with a special category has finished the 9h break', async() => {
|
||||
// dayBreak to 9h in postgresql.professional_category
|
||||
const workerId = 1110;
|
||||
const tabletId = 1;
|
||||
let stmts = [];
|
||||
|
@ -239,12 +237,6 @@ xdescribe('worker workerTimeControl_check()', () => {
|
|||
|
||||
stmts.push('START TRANSACTION');
|
||||
|
||||
stmt = new ParameterizedSQL(`INSERT INTO postgresql.calendar_employee(businessFk,calendar_state_id,date)
|
||||
VALUES
|
||||
(?,1,CURDATE())`, [
|
||||
workerId
|
||||
]);
|
||||
stmts.push(stmt);
|
||||
stmt = new ParameterizedSQL(`INSERT INTO vn.workerTimeControl(userFk,timed,manual,direction)
|
||||
VALUES
|
||||
(?,TIMESTAMPADD(HOUR,-24,NOW()),0,"in"),
|
||||
|
|
|
@ -632,6 +632,7 @@ let actions = {
|
|||
await this.write(selector, value.toString());
|
||||
break;
|
||||
case 'vn-autocomplete':
|
||||
case 'vn-worker-autocomplete':
|
||||
if (value)
|
||||
await this.autocompleteSearch(selector, value.toString());
|
||||
else
|
||||
|
@ -667,6 +668,7 @@ let actions = {
|
|||
switch (tagName) {
|
||||
case 'vn-textfield':
|
||||
case 'vn-autocomplete':
|
||||
case 'vn-worker-autocomplete':
|
||||
case 'vn-input-time':
|
||||
case 'vn-datalist':
|
||||
el = await input.$('input');
|
||||
|
|
|
@ -187,7 +187,7 @@ export default {
|
|||
country: 'vn-client-create vn-autocomplete[ng-model="$ctrl.client.countryFk"]',
|
||||
userName: 'vn-client-create vn-textfield[ng-model="$ctrl.client.userName"]',
|
||||
email: 'vn-client-create vn-textfield[ng-model="$ctrl.client.email"]',
|
||||
salesPerson: 'vn-client-create vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
|
||||
salesPerson: 'vn-client-create vn-worker-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
|
||||
saveNewProvicenButton: '#saveProvince',
|
||||
saveNewCityButton: '#saveCity',
|
||||
saveNewPoscode: '#savePostcode',
|
||||
|
@ -199,7 +199,7 @@ export default {
|
|||
email: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.email"]',
|
||||
phone: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.phone"]',
|
||||
mobile: 'vn-client-basic-data vn-textfield[ng-model="$ctrl.client.mobile"]',
|
||||
salesPerson: 'vn-client-basic-data vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
|
||||
salesPerson: 'vn-client-basic-data vn-worker-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
|
||||
channel: 'vn-client-basic-data vn-autocomplete[ng-model="$ctrl.client.contactChannelFk"]',
|
||||
transferor: 'vn-client-basic-data vn-autocomplete[ng-model="$ctrl.client.transferorFk"]',
|
||||
businessType: 'vn-client-basic-data vn-autocomplete[ng-model="$ctrl.client.businessTypeFk"]',
|
||||
|
@ -735,7 +735,7 @@ export default {
|
|||
},
|
||||
createStateView: {
|
||||
state: 'vn-autocomplete[ng-model="$ctrl.stateFk"]',
|
||||
worker: 'vn-autocomplete[ng-model="$ctrl.workerFk"]',
|
||||
worker: 'vn-worker-autocomplete[ng-model="$ctrl.workerFk"]',
|
||||
saveStateButton: `button[type=submit]`
|
||||
},
|
||||
claimsIndex: {
|
||||
|
@ -781,12 +781,12 @@ export default {
|
|||
firstClaimReason: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimReasonFk"]',
|
||||
firstClaimResult: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimResultFk"]',
|
||||
firstClaimResponsible: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
|
||||
firstClaimWorker: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.workerFk"]',
|
||||
firstClaimWorker: 'vn-claim-development vn-horizontal:nth-child(1) vn-worker-autocomplete[ng-model="claimDevelopment.workerFk"]',
|
||||
firstClaimRedelivery: 'vn-claim-development vn-horizontal:nth-child(1) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]',
|
||||
secondClaimReason: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimReasonFk"]',
|
||||
secondClaimResult: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResultFk"]',
|
||||
secondClaimResponsible: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
|
||||
secondClaimWorker: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.workerFk"]',
|
||||
secondClaimWorker: 'vn-claim-development vn-horizontal:nth-child(2) vn-worker-autocomplete[ng-model="claimDevelopment.workerFk"]',
|
||||
secondClaimRedelivery: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]',
|
||||
saveDevelopmentButton: 'button[type=submit]'
|
||||
},
|
||||
|
@ -854,7 +854,7 @@ export default {
|
|||
|
||||
},
|
||||
createRouteView: {
|
||||
worker: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.workerFk"]',
|
||||
worker: 'vn-route-create vn-worker-autocomplete[ng-model="$ctrl.route.workerFk"]',
|
||||
createdDatePicker: 'vn-route-create vn-date-picker[ng-model="$ctrl.route.created"]',
|
||||
vehicleAuto: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.vehicleFk"]',
|
||||
agency: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.agencyModeFk"]',
|
||||
|
@ -976,7 +976,7 @@ export default {
|
|||
street: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.street"]',
|
||||
user: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.name"]',
|
||||
email: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.email"]',
|
||||
boss: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.bossFk"]',
|
||||
boss: 'vn-worker-create vn-worker-autocomplete[ng-model="$ctrl.worker.bossFk"]',
|
||||
role: 'vn-worker-create vn-autocomplete[ng-model="$ctrl.worker.roleFk"]',
|
||||
iban: 'vn-worker-create vn-textfield[ng-model="$ctrl.worker.iban"]',
|
||||
createButton: 'vn-worker-create vn-submit[label="Create"]',
|
||||
|
|
|
@ -59,7 +59,7 @@ describe('Ticket Create new tracking state path', () => {
|
|||
const result = await page
|
||||
.waitToGetProperty(selectors.createStateView.worker, 'value');
|
||||
|
||||
expect(result).toEqual('salesPersonNick');
|
||||
expect(result).toEqual('salesPerson');
|
||||
});
|
||||
|
||||
it(`should succesfully create a valid state`, async() => {
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
<label>
|
||||
<span translate>{{$ctrl.label}}</span>
|
||||
<span class="required">*</span>
|
||||
</label>
|
||||
</label>
|
||||
</div>
|
||||
<div class="icons pre">
|
||||
<vn-icon
|
||||
|
@ -50,4 +50,4 @@
|
|||
on-select="$ctrl.onDropDownSelect(item)"
|
||||
on-data-ready="$ctrl.onDataReady()"
|
||||
on-close-start="$ctrl.onDropDownClose()">
|
||||
</vn-drop-down>
|
||||
</vn-drop-down>
|
||||
|
|
|
@ -17,10 +17,9 @@ import './style.scss';
|
|||
* @event change Thrown when value is changed
|
||||
*/
|
||||
export default class Autocomplete extends Field {
|
||||
constructor($element, $, $compile, $transclude) {
|
||||
super($element, $, $compile);
|
||||
constructor($element, $, $transclude) {
|
||||
super($element, $, $transclude);
|
||||
this.$transclude = $transclude;
|
||||
this.$compile = $compile;
|
||||
this._selection = null;
|
||||
this.input = this.element.querySelector('input');
|
||||
}
|
||||
|
@ -153,7 +152,14 @@ export default class Autocomplete extends Field {
|
|||
filter.include = this.include;
|
||||
|
||||
let json = encodeURIComponent(JSON.stringify(filter));
|
||||
this.$http.get(`${this.url}?filter=${json}`).then(
|
||||
|
||||
let url;
|
||||
if (this.url.includes('?'))
|
||||
url = `${this.url}&filter=${json}`;
|
||||
else
|
||||
url = `${this.url}?filter=${json}`;
|
||||
|
||||
this.$http.get(url).then(
|
||||
json => this.onSelectionRequest(json.data),
|
||||
() => this.onSelectionRequest()
|
||||
);
|
||||
|
@ -282,7 +288,7 @@ export default class Autocomplete extends Field {
|
|||
this.refreshSelection();
|
||||
}
|
||||
}
|
||||
Autocomplete.$inject = ['$element', '$scope', '$compile', '$transclude'];
|
||||
Autocomplete.$inject = ['$element', '$scope', '$transclude'];
|
||||
|
||||
ngModule.vnComponent('vnAutocomplete', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -13,12 +13,12 @@
|
|||
class="dropdown"
|
||||
ng-click="$ctrl.onContainerClick($event)">
|
||||
</ul>
|
||||
<div
|
||||
ng-if="$ctrl.statusText"
|
||||
<div
|
||||
ng-if="$ctrl.statusText"
|
||||
ng-click="$ctrl.onLoadMoreClick($event)"
|
||||
class="status"
|
||||
translate>
|
||||
{{$ctrl.statusText}}
|
||||
</div>
|
||||
</div>
|
||||
</default>
|
||||
</default>
|
||||
|
|
|
@ -3,8 +3,8 @@ import FormInput from '../form-input';
|
|||
import './style.scss';
|
||||
|
||||
export default class Field extends FormInput {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
constructor($element, $scope, $transclude) {
|
||||
super($element, $scope, $transclude);
|
||||
|
||||
this.prefix = null;
|
||||
this.suffix = null;
|
||||
|
@ -197,7 +197,7 @@ export default class Field extends FormInput {
|
|||
});
|
||||
}
|
||||
}
|
||||
Field.$inject = ['$element', '$scope'];
|
||||
Field.$inject = ['$element', '$scope', '$transclude'];
|
||||
|
||||
ngModule.vnComponent('vnField', {
|
||||
template: require('./index.html'),
|
||||
|
|
|
@ -51,6 +51,7 @@ import './textarea';
|
|||
import './th';
|
||||
import './treeview';
|
||||
import './wday-picker';
|
||||
import './worker-autocomplete';
|
||||
import './datalist';
|
||||
import './contextmenu';
|
||||
import './rating';
|
||||
|
|
|
@ -27,7 +27,7 @@ export default class Controller extends Component {
|
|||
setTimeout(() => element.classList.add('shown'), 30);
|
||||
shape.element = element;
|
||||
|
||||
if (data.additionalData) {
|
||||
if (data.additionalData && this.vnToken.token) {
|
||||
this.additionalData = data.additionalData;
|
||||
let supportButton = document.createElement('i');
|
||||
supportButton.setAttribute('class', 'material-icons clickable');
|
||||
|
|
|
@ -7,12 +7,15 @@ export default class Controller extends Dialog {
|
|||
}
|
||||
|
||||
responseHandler(response) {
|
||||
if (response !== 'accept')
|
||||
return super.responseHandler(response);
|
||||
|
||||
this.$http.post('Ostickets/send-to-support', {
|
||||
reason: this.reason,
|
||||
additionalData: this.additionalData
|
||||
})
|
||||
.then(() => super.responseHandler(response))
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Email sended!')));
|
||||
.then(() => super.responseHandler(response))
|
||||
.then(() => this.vnApp.showSuccess(this.$t('Email sended!')));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<tpl-item>
|
||||
<div>
|
||||
{{name}}
|
||||
</div>
|
||||
<div class="text-caption text-secondary">
|
||||
{{nickname}}, {{code}}
|
||||
</div>
|
||||
</tpl-item>
|
|
@ -0,0 +1,40 @@
|
|||
import ngModule from '../../module';
|
||||
import Autocomplete from '../autocomplete';
|
||||
|
||||
export default class WorkerAutocomplete extends Autocomplete {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
super.$onInit();
|
||||
|
||||
let url = 'Workers/search';
|
||||
if (this.departments) {
|
||||
const parameter = encodeURIComponent(JSON.stringify(this.departments));
|
||||
url = `Workers/search?departmentCodes=${parameter}`;
|
||||
}
|
||||
Object.assign(this, {
|
||||
label: 'Worker',
|
||||
url,
|
||||
searchFunction: function({$search}) {
|
||||
return {and: [
|
||||
{'active': {neq: false}},
|
||||
{or: [
|
||||
{'name': $search},
|
||||
{'nickname': {like: '%' + $search + '%'}},
|
||||
{'code': {like: $search + '%'}}
|
||||
]}
|
||||
]};
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnWorkerAutocomplete', {
|
||||
slotTemplate: require('./index.html'),
|
||||
controller: WorkerAutocomplete,
|
||||
bindings: {
|
||||
departments: '<?'
|
||||
},
|
||||
});
|
|
@ -185,5 +185,6 @@
|
|||
"You don't have enough privileges.": "You don't have enough privileges.",
|
||||
"This ticket is locked.": "This ticket is locked.",
|
||||
"This ticket is not editable.": "This ticket is not editable.",
|
||||
"The ticket doesn't exist.": "The ticket doesn't exist."
|
||||
"The ticket doesn't exist.": "The ticket doesn't exist.",
|
||||
"Ticket without Route": "Ticket without route"
|
||||
}
|
||||
|
|
|
@ -315,5 +315,6 @@
|
|||
"This ticket is not editable.": "Este ticket no es editable.",
|
||||
"The ticket doesn't exist.": "No existe el ticket.",
|
||||
"Social name should be uppercase": "La razón social debe ir en mayúscula",
|
||||
"Street should be uppercase": "La dirección fiscal debe ir en mayúscula"
|
||||
"Street should be uppercase": "La dirección fiscal debe ir en mayúscula",
|
||||
"Ticket without Route": "Ticket sin ruta"
|
||||
}
|
||||
|
|
|
@ -25,15 +25,13 @@
|
|||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
disabled="false"
|
||||
ng-model="$ctrl.claim.workerFk"
|
||||
url="Workers/activeWithRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
where="{role: 'salesPerson'}"
|
||||
ng-model="$ctrl.claim.workerFk"
|
||||
departments="['VT']"
|
||||
label="Attended by">
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
<vn-autocomplete
|
||||
ng-model="$ctrl.claim.claimStateFk"
|
||||
data="claimStates"
|
||||
|
|
|
@ -36,7 +36,7 @@
|
|||
data="claimDevelopments"
|
||||
form="form">
|
||||
</vn-watcher>
|
||||
<vn-vertical class="vn-w-md">
|
||||
<vn-vertical class="vn-w-lg">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-vertical>
|
||||
<form name="form">
|
||||
|
@ -66,16 +66,11 @@
|
|||
show-field="description"
|
||||
rule>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
ng-model="claimDevelopment.workerFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'employee'}"
|
||||
label="Worker"
|
||||
rule>
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
<vn-autocomplete
|
||||
label="Redelivery"
|
||||
ng-model="claimDevelopment.claimRedeliveryFk"
|
||||
|
@ -118,4 +113,4 @@
|
|||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button> -->
|
||||
</vn-button-bar>
|
||||
</vn-vertical>
|
||||
</vn-vertical>
|
||||
|
|
|
@ -22,26 +22,18 @@
|
|||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.salesPersonFk"
|
||||
url="Workers/activeWithRole"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: {inq: ['salesTeamBoss', 'salesPerson', 'officeBoss']}}"
|
||||
departments="['VT']"
|
||||
label="Salesperson">
|
||||
<tpl-item>{{firstName}} {{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
</vn-worker-autocomplete>
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.attenderFk"
|
||||
url="Workers/activeWithRole"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: {inq: ['salesTeamBoss', 'salesPerson']}}"
|
||||
departments="['VT']"
|
||||
label="Attended by">
|
||||
<tpl-item>{{firstName}} {{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete vn-one
|
||||
|
|
|
@ -14,13 +14,13 @@
|
|||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Comercial Name"
|
||||
vn-one
|
||||
label="Comercial Name"
|
||||
ng-model="$ctrl.client.name"
|
||||
rule
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.client.businessTypeFk"
|
||||
url="BusinessTypes"
|
||||
|
@ -37,8 +37,8 @@
|
|||
rule>
|
||||
</vn-textfield>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Email"
|
||||
vn-one
|
||||
label="Email"
|
||||
ng-model="$ctrl.client.email"
|
||||
rule
|
||||
info="You can save multiple emails">
|
||||
|
@ -59,18 +59,15 @@
|
|||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.client.salesPersonFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
departments="['VT']"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'salesPerson'}"
|
||||
label="Salesperson"
|
||||
vn-acl="salesAssistant">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
</vn-worker-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.client.contactChannelFk"
|
||||
data="contactChannels"
|
||||
|
|
|
@ -17,12 +17,11 @@
|
|||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.buyerId"
|
||||
url="Workers/activeWithRole"
|
||||
url="TicketRequests/getItemTypeWorker"
|
||||
search-function="{firstName: $search}"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
where="{role: {inq: ['logistic', 'buyer']}}"
|
||||
label="Buyer">
|
||||
<tpl-item>{{nickname}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
|
|
@ -15,18 +15,15 @@
|
|||
rule
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
label="Salesperson"
|
||||
ng-model="$ctrl.client.salesPersonFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
search-function="{firstName: $search}"
|
||||
show-field="firstName"
|
||||
where="{role: 'salesPerson'}">
|
||||
<tpl-item>{{firstName}} {{lastName}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
departments="['VT']"
|
||||
show-field="nickname">
|
||||
</vn-worker-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
<vn-autocomplete
|
||||
vn-id="businessTypeFk"
|
||||
ng-model="$ctrl.client.businessTypeFk"
|
||||
url="BusinessTypes"
|
||||
|
@ -68,7 +65,7 @@
|
|||
show-field="code"
|
||||
rule>
|
||||
<tpl-item>
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{code}} - {{town.name}} ({{town.province.name}},
|
||||
{{town.province.country.country}})
|
||||
</tpl-item>
|
||||
<append>
|
||||
|
@ -82,7 +79,7 @@
|
|||
</append>
|
||||
</vn-datalist>
|
||||
<vn-datalist
|
||||
vn-id="town"
|
||||
vn-id="town"
|
||||
label="City"
|
||||
ng-model="$ctrl.client.city"
|
||||
selection="$ctrl.town"
|
||||
|
@ -90,7 +87,7 @@
|
|||
fields="['id', 'name', 'provinceFk']"
|
||||
value-field="name">
|
||||
<tpl-item>
|
||||
{{name}}, {{province.name}}
|
||||
{{name}}, {{province.name}}
|
||||
({{province.country.country}})
|
||||
</tpl-item>
|
||||
</vn-datalist>
|
||||
|
@ -150,4 +147,4 @@
|
|||
<vn-geo-postcode
|
||||
vn-id="postcode"
|
||||
on-response="$ctrl.onResponse($response)">
|
||||
</vn-geo-postcode>
|
||||
</vn-geo-postcode>
|
||||
|
|
|
@ -14,17 +14,12 @@
|
|||
vn-one label="Name"
|
||||
ng-model="filter.name">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.salesPersonFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
search-function="{firstName: $search}"
|
||||
show-field="firstName"
|
||||
value-field="id"
|
||||
where="{role: 'salesPerson'}"
|
||||
departments="['VT']"
|
||||
label="Salesperson">
|
||||
<tpl-item>{{firstName}} {{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
|
|
|
@ -54,11 +54,10 @@
|
|||
vn-id="salesPerson"
|
||||
disabled="false"
|
||||
ng-model="$ctrl.filter.salesPersonFk"
|
||||
url="Workers/activeWithRole"
|
||||
url="TicketRequests/getItemTypeWorker"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: {inq: ['logistic', 'buyer']}}"
|
||||
label="Buyer"
|
||||
on-change="$ctrl.addFilters()">
|
||||
</vn-autocomplete>
|
||||
|
|
|
@ -54,11 +54,10 @@
|
|||
vn-id="buyer"
|
||||
disabled="false"
|
||||
ng-model="$ctrl.filter.buyerFk"
|
||||
url="Workers/activeWithRole"
|
||||
url="TicketRequests/getItemTypeWorker"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: {inq: ['logistic', 'buyer']}}"
|
||||
label="Buyer"
|
||||
on-change="$ctrl.addFilters()">
|
||||
</vn-autocomplete>
|
||||
|
|
|
@ -44,8 +44,7 @@ class Controller extends Section {
|
|||
{
|
||||
field: 'buyerFk',
|
||||
autocomplete: {
|
||||
url: 'Workers/activeWithRole',
|
||||
where: `{role: {inq: ['logistic', 'buyer']}}`,
|
||||
url: 'TicketRequests/getItemTypeWorker',
|
||||
searchFunction: '{firstName: $search}',
|
||||
showField: 'nickname',
|
||||
valueField: 'id',
|
||||
|
|
|
@ -22,12 +22,11 @@
|
|||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.attenderFk"
|
||||
url="Workers/activeWithRole"
|
||||
url="TicketRequests/getItemTypeWorker"
|
||||
search-function="{firstName: $search}"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
where="{role: {inq: ['logistic', 'buyer']}}"
|
||||
label="Buyer">
|
||||
<tpl-item>{{nickname}}</tpl-item>
|
||||
label="Atender">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
|
@ -46,18 +45,13 @@
|
|||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.requesterFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'salesPerson'}"
|
||||
label="Comercial">
|
||||
<tpl-item>{{firstName}} {{lastName}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
departments="['VT']"
|
||||
label="Salesperson">
|
||||
</vn-worker-autocomplete>
|
||||
</vn-horizontal>
|
||||
|
||||
<section class="vn-px-md">
|
||||
<vn-horizontal class="manifold-panel vn-pa-md">
|
||||
<vn-date-picker
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
|
@ -43,16 +43,12 @@
|
|||
label="Nickname"
|
||||
ng-model="filter.nickname">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.salesPersonFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'employee'}"
|
||||
departments="['VT']"
|
||||
label="Sales person">
|
||||
<tpl-item>{{firstName}} {{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Invoice"
|
||||
|
|
|
@ -25,16 +25,13 @@
|
|||
show-field="name"
|
||||
value-field="id">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.workerFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
search-function="{firstName: $search}"
|
||||
departments="['VT']"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
where="{role: 'salesPerson'}"
|
||||
label="Sales person">
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-date-picker
|
||||
|
@ -86,4 +83,4 @@
|
|||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -24,7 +24,14 @@ module.exports = Self => {
|
|||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const route = await Self.app.models.Route.findById(id, null, myOptions);
|
||||
const route = await Self.app.models.Route.findById(id, {
|
||||
include: {
|
||||
relation: 'agencyMode',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
}, myOptions);
|
||||
|
||||
const zoneAgencyModes = await Self.app.models.ZoneAgencyMode.find({
|
||||
where: {
|
||||
|
@ -35,11 +42,13 @@ module.exports = Self => {
|
|||
const zoneIds = [];
|
||||
for (let zoneAgencyMode of zoneAgencyModes)
|
||||
zoneIds.push(zoneAgencyMode.zoneFk);
|
||||
|
||||
const minDate = new Date(route.created);
|
||||
minDate.setHours(0, 0, 0, 0);
|
||||
|
||||
const maxDate = new Date(route.created);
|
||||
maxDate.setHours(23, 59, 59, 59);
|
||||
|
||||
let tickets = await Self.app.models.Ticket.find({
|
||||
where: {
|
||||
zoneFk: {inq: zoneIds},
|
||||
|
@ -80,6 +89,12 @@ module.exports = Self => {
|
|||
]
|
||||
}, myOptions);
|
||||
|
||||
return tickets;
|
||||
return tickets.map(ticket => {
|
||||
const simpleTicket = ticket.toJSON();
|
||||
return {
|
||||
...simpleTicket,
|
||||
agencyName: route.agencyMode().name
|
||||
};
|
||||
});
|
||||
};
|
||||
};
|
||||
|
|
|
@ -8,20 +8,11 @@
|
|||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
ng-model="$ctrl.route.workerFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'employee'}"
|
||||
label="Worker"
|
||||
vn-name="worker">
|
||||
<tpl-item>
|
||||
<div>{{::nickname}}</div>
|
||||
<div class="text-secondary text-caption">{{::name}}</div>
|
||||
</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
<vn-autocomplete
|
||||
label="Vehicle"
|
||||
ng-model="$ctrl.route.vehicleFk"
|
||||
|
|
|
@ -8,16 +8,12 @@
|
|||
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||
<vn-card class="vn-pa-lg">
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
label="Worker"
|
||||
<vn-worker-autocomplete
|
||||
ng-model="$ctrl.route.workerFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
where="{role: 'employee'}">
|
||||
</vn-autocomplete>
|
||||
show-field="nickname">
|
||||
</vn-worker-autocomplete>
|
||||
<vn-date-picker
|
||||
label="Created"
|
||||
label="Created"
|
||||
ng-model="$ctrl.route.created">
|
||||
</vn-date-picker>
|
||||
</vn-horizontal>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
|
@ -15,16 +15,11 @@
|
|||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-px-lg">
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.workerFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'employee'}"
|
||||
label="Worker">
|
||||
</vn-autocomplete>
|
||||
show-field="nickname">
|
||||
</vn-worker-autocomplete>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Agency"
|
||||
|
|
|
@ -19,17 +19,17 @@
|
|||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th shrink>
|
||||
<vn-multi-check
|
||||
<vn-multi-check
|
||||
model="model">
|
||||
</vn-multi-check>
|
||||
</vn-th>
|
||||
<vn-th number>Ticket</vn-th>
|
||||
<vn-th>Client</vn-th>
|
||||
<vn-th shrink>Province</vn-th>
|
||||
<vn-th shrink>
|
||||
<vn-th shrink>
|
||||
<span translate>
|
||||
Population
|
||||
</span>
|
||||
Population
|
||||
</span>
|
||||
</vn-th>
|
||||
<vn-th expand>PC</vn-th>
|
||||
<vn-th>Address</vn-th>
|
||||
|
@ -39,7 +39,7 @@
|
|||
<vn-tbody>
|
||||
<vn-tr ng-repeat="ticket in $ctrl.possibleTickets">
|
||||
<vn-td shrink>
|
||||
<vn-check
|
||||
<vn-check
|
||||
ng-model="ticket.checked">
|
||||
</vn-check>
|
||||
</vn-td>
|
||||
|
@ -62,7 +62,7 @@
|
|||
<vn-icon-button
|
||||
icon="link_off"
|
||||
class="pointer"
|
||||
title="{{'Unlink zone' | translate: {zoneName: ticket.zone.name, agencyName: ticket.agencyMode.name} }}"
|
||||
title="{{'Unlink zone' | translate: {zoneName: ticket.zone.name, agencyName: ticket.agencyName} }}"
|
||||
ng-click="unlinkZoneConfirmation.show(ticket)">
|
||||
</vn-icon-button>
|
||||
</vn-td>
|
||||
|
|
|
@ -15,29 +15,25 @@
|
|||
rule
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.supplier.workerFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
search-function="{firstName: $search}"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
where="{role: 'employee'}"
|
||||
label="Responsible"
|
||||
info="Responsible for approving invoices">
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check
|
||||
label="Verified"
|
||||
label="Verified"
|
||||
ng-model="$ctrl.supplier.isSerious">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
label="Active"
|
||||
label="Active"
|
||||
ng-model="$ctrl.supplier.isActive">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
label="PayMethodChecked"
|
||||
label="PayMethodChecked"
|
||||
ng-model="$ctrl.supplier.isPayMethodChecked"
|
||||
vn-acl="financial">
|
||||
</vn-check>
|
||||
|
@ -45,7 +41,7 @@
|
|||
<vn-horizontal>
|
||||
<vn-textarea
|
||||
vn-one
|
||||
label="Notes"
|
||||
label="Notes"
|
||||
ng-model="$ctrl.supplier.note"
|
||||
rule>
|
||||
</vn-textarea>
|
||||
|
@ -63,4 +59,4 @@
|
|||
ng-click="watcher.loadOriginalData()">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
@ -17,12 +17,11 @@
|
|||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.buyerId"
|
||||
url="Workers/activeWithRole"
|
||||
url="TicketRequests/getItemTypeWorker"
|
||||
search-function="{firstName: $search}"
|
||||
show-field="nickname"
|
||||
value-field="id"
|
||||
where="{role: {inq: ['logistic', 'buyer']}}"
|
||||
label="Buyer">
|
||||
<tpl-item>{{nickname}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('addExpeditionState', {
|
||||
description: 'Update an expedition state',
|
||||
accessType: 'WRITE',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'expeditions',
|
||||
type: ['object'],
|
||||
required: true,
|
||||
description: 'Array of objects containing expeditionFk and stateCode'
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: 'boolean',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/addExpeditionState`,
|
||||
verb: 'post'
|
||||
}
|
||||
});
|
||||
|
||||
Self.addExpeditionState = async(expeditions, options) => {
|
||||
const models = Self.app.models;
|
||||
let tx;
|
||||
const myOptions = {};
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
if (!myOptions.transaction) {
|
||||
tx = await Self.beginTransaction({});
|
||||
myOptions.transaction = tx;
|
||||
}
|
||||
let expeditionId;
|
||||
try {
|
||||
for (const expedition of expeditions) {
|
||||
const expeditionStateType = await models.ExpeditionStateType.findOne(
|
||||
{
|
||||
fields: ['id'],
|
||||
where: {code: expedition.stateCode}
|
||||
}, myOptions
|
||||
);
|
||||
if (!expeditionStateType)
|
||||
throw new UserError(`Invalid state code: ${expedition.stateCode}.`);
|
||||
|
||||
const typeFk = expeditionStateType.id;
|
||||
expeditionId = expedition.expeditionFk;
|
||||
|
||||
await models.ExpeditionState.create({
|
||||
expeditionFk: expedition.expeditionFk,
|
||||
typeFk,
|
||||
}, myOptions);
|
||||
}
|
||||
|
||||
if (tx) await tx.commit();
|
||||
} catch (e) {
|
||||
if (tx) await tx.rollback();
|
||||
if (e instanceof UserError)
|
||||
throw e;
|
||||
|
||||
throw new UserError(`Invalid expedition id: ${expeditionId}.`);
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,75 @@
|
|||
const models = require('vn-loopback/server/server').models;
|
||||
|
||||
describe('expeditionState addExpeditionState()', () => {
|
||||
it('should update the expedition states', async() => {
|
||||
const tx = await models.ExpeditionState.beginTransaction({});
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const payload = [
|
||||
{
|
||||
expeditionFk: 8,
|
||||
stateCode: 'ON DELIVERY'
|
||||
},
|
||||
];
|
||||
|
||||
await models.ExpeditionState.addExpeditionState(payload, options);
|
||||
|
||||
const expeditionState = await models.ExpeditionState.findOne({
|
||||
where: {id: 5}
|
||||
});
|
||||
|
||||
expect(expeditionState.typeFk).toEqual(1);
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
await tx.rollback();
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
|
||||
it('should throw an error an error when an stateCode does not exist', async() => {
|
||||
const tx = await models.ExpeditionState.beginTransaction({});
|
||||
let error;
|
||||
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const payload = [
|
||||
{
|
||||
expeditionFk: 2,
|
||||
stateCode: 'DUMMY'
|
||||
}
|
||||
];
|
||||
await models.ExpeditionState.addExpeditionState(payload, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
await tx.rollback();
|
||||
}
|
||||
|
||||
expect(error.message).toContain('Invalid state code: DUMMY.');
|
||||
});
|
||||
|
||||
it('should throw an error when expeditionFk does not exist', async() => {
|
||||
const tx = await models.ExpeditionState.beginTransaction({});
|
||||
let error;
|
||||
try {
|
||||
const options = {transaction: tx};
|
||||
const payload = [
|
||||
{
|
||||
expeditionFk: 50,
|
||||
stateCode: 'LOST'
|
||||
}
|
||||
];
|
||||
|
||||
await models.ExpeditionState.addExpeditionState(payload, options);
|
||||
|
||||
await tx.rollback();
|
||||
} catch (e) {
|
||||
error = e;
|
||||
await tx.rollback();
|
||||
}
|
||||
|
||||
expect(error.message).toContain('Invalid expedition id: 50.');
|
||||
});
|
||||
});
|
|
@ -22,9 +22,13 @@ module.exports = Self => {
|
|||
}
|
||||
});
|
||||
|
||||
Self.getItemTypeWorker = async filter => {
|
||||
Self.getItemTypeWorker = async(filter, options) => {
|
||||
const myOptions = {};
|
||||
const conn = Self.dataSource.connector;
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
const query =
|
||||
`SELECT DISTINCT u.id, u.nickname
|
||||
FROM itemType it
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('priceDifference', {
|
||||
description: 'Returns sales with price difference if the ticket is editable',
|
||||
|
|
|
@ -93,6 +93,8 @@ module.exports = Self => {
|
|||
}, myOptions);
|
||||
const dmsType = await models.DmsType.findOne({where: {code: 'Ticket'}, fields: ['id']}, myOptions);
|
||||
const ctxUploadFile = Object.assign({}, ctx);
|
||||
if (ticket.route() === null)
|
||||
throw new UserError('Ticket without route');
|
||||
ctxUploadFile.args = {
|
||||
warehouseId: ticket.warehouseFk,
|
||||
companyId: ticket.companyFk,
|
||||
|
|
|
@ -20,6 +20,9 @@
|
|||
"ExpeditionState": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"ExpeditionStateType": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Packaging": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "ExpeditionStateType",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "expeditionStateType"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "number",
|
||||
"description": "Identifier"
|
||||
},
|
||||
"description": {
|
||||
"type": "string"
|
||||
},
|
||||
"code": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
module.exports = function(Self) {
|
||||
require('../methods/expedition-state/filter')(Self);
|
||||
require('../methods/expedition-state/addExpeditionState')(Self);
|
||||
};
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="search-panel">
|
||||
<vn-crud-model
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
auto-load="true"
|
||||
url="Warehouses"
|
||||
data="warehouses">
|
||||
</vn-crud-model>
|
||||
<form id="manifold-form" ng-submit="$ctrl.onSearch()">
|
||||
|
@ -62,16 +62,12 @@
|
|||
label="Nickname"
|
||||
ng-model="filter.nickname">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="filter.salesPersonFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'employee'}"
|
||||
departments="['VT']"
|
||||
label="Sales person">
|
||||
<tpl-item>{{firstName}} {{name}}</tpl-item>
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Invoice"
|
||||
|
|
|
@ -14,22 +14,15 @@
|
|||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.stateFk"
|
||||
ng-model="$ctrl.stateFk"
|
||||
data="states"
|
||||
label="State"
|
||||
vn-focus>
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
url="Workers/activeWithInheritedRole"
|
||||
ng-if="$ctrl.isPickerDesignedState"
|
||||
ng-model="$ctrl.workerFk"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'employee'}"
|
||||
label="Worker">
|
||||
</vn-autocomplete>
|
||||
ng-model="$ctrl.workerFk">
|
||||
</vn-worker-autocomplete>
|
||||
</vn-horizontal>
|
||||
</vn-card>
|
||||
<vn-button-bar>
|
||||
|
@ -43,4 +36,4 @@
|
|||
ui-sref="ticket.card.tracking.index">
|
||||
</vn-button>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
</form>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('activeWithInheritedRole', {
|
||||
description: 'Returns active workers with a role',
|
||||
description: 'Returns active workers with an inherited role',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'filter',
|
||||
|
@ -24,7 +24,7 @@ module.exports = Self => {
|
|||
`SELECT DISTINCT w.id, w.firstName, w.lastName, u.name, u.nickname
|
||||
FROM worker w
|
||||
JOIN account.user u ON u.id = w.userFk
|
||||
JOIN account.roleRole i ON i.role = u.role
|
||||
JOIN account.roleRole i ON i.role = u.role
|
||||
JOIN account.role r ON r.id = i.inheritsFrom`;
|
||||
|
||||
return Self.activeWorkers(query, filter);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethod('activeWithRole', {
|
||||
description: 'Returns active workers with an inherited role',
|
||||
description: 'Returns active workers with a role',
|
||||
accessType: 'READ',
|
||||
accepts: [{
|
||||
arg: 'filter',
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('search', {
|
||||
description: 'Returns an array of search results for a specified worker',
|
||||
accepts: [{
|
||||
arg: 'filter',
|
||||
type: 'object',
|
||||
description: 'Filter to define conditions and paginate the data.',
|
||||
required: true
|
||||
},
|
||||
{
|
||||
arg: 'departmentCodes',
|
||||
type: ['string'],
|
||||
description: 'Department codes to search workers',
|
||||
}],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/search`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.search = async(ctx, filter, departmentCodes) => {
|
||||
const models = Self.app.models;
|
||||
const conn = Self.dataSource.connector;
|
||||
|
||||
if (departmentCodes) {
|
||||
const departments = await models.Department.find({
|
||||
fields: ['id', 'sons'],
|
||||
where: {code: {inq: departmentCodes}}
|
||||
});
|
||||
|
||||
const allLeaves = await getAllLeaves(ctx, departments);
|
||||
const where = {'departmentFk': {inq: allLeaves}};
|
||||
filter = mergeFilters(filter, {where});
|
||||
}
|
||||
|
||||
const stmt = new ParameterizedSQL(`
|
||||
SELECT *
|
||||
FROM(
|
||||
SELECT DISTINCT w.id, w.code, u.name, u.nickname, u.active, b.departmentFk
|
||||
FROM worker w
|
||||
JOIN account.user u ON u.id = w.id
|
||||
JOIN business b ON b.workerFk = w.id
|
||||
) w`);
|
||||
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
return conn.executeStmt(stmt);
|
||||
};
|
||||
|
||||
async function getAllLeaves(ctx, departments) {
|
||||
const models = Self.app.models;
|
||||
const leaves = [];
|
||||
for (const department of departments) {
|
||||
if (department.sons > 0) {
|
||||
const subLeaves = await models.Department.getLeaves(ctx, department.id, null);
|
||||
const grandLeaves = await getAllLeaves(ctx, subLeaves);
|
||||
leaves.push(...grandLeaves);
|
||||
}
|
||||
leaves.push(department.id);
|
||||
}
|
||||
return leaves;
|
||||
}
|
||||
};
|
|
@ -23,6 +23,9 @@
|
|||
"Device": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"DeviceLog": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"DeviceProduction": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
{
|
||||
"name": "DeviceLog",
|
||||
"base": "VnModel",
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "deviceLog"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "number"
|
||||
},
|
||||
"android_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"userFk": {
|
||||
"type": "number"
|
||||
},
|
||||
"created": {
|
||||
"type": "date"
|
||||
},
|
||||
"nameApp": {
|
||||
"type": "string"
|
||||
},
|
||||
"versionApp": {
|
||||
"type": "string"
|
||||
},
|
||||
"deviceProductionFk": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"user": {
|
||||
"type": "belongsTo",
|
||||
"model": "VnUser",
|
||||
"foreignKey": "userFk"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ module.exports = Self => {
|
|||
require('../methods/worker/new')(Self);
|
||||
require('../methods/worker/deallocatePDA')(Self);
|
||||
require('../methods/worker/allocatePDA')(Self);
|
||||
require('../methods/worker/search')(Self);
|
||||
require('../methods/worker/isAuthorized')(Self);
|
||||
|
||||
Self.validatesUniquenessOf('locker', {
|
||||
|
|
|
@ -37,14 +37,11 @@
|
|||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
ng-model="$ctrl.worker.bossFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
where="{role: 'employee'}"
|
||||
label="Boss">
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
<vn-autocomplete
|
||||
label="Marital status"
|
||||
data="$ctrl.maritalStatus"
|
||||
|
|
|
@ -131,15 +131,12 @@
|
|||
value-field="id"
|
||||
label="Company">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
vn-one
|
||||
ng-model="$ctrl.worker.bossFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
where="{role: 'employee'}"
|
||||
label="Boss">
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
|
|
|
@ -44,13 +44,11 @@
|
|||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
<vn-worker-autocomplete
|
||||
ng-model="$ctrl.department.workerFk"
|
||||
url="Workers/activeWithInheritedRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
label="Boss department">
|
||||
</vn-autocomplete>
|
||||
</vn-worker-autocomplete>
|
||||
<vn-autocomplete
|
||||
ng-model="$ctrl.department.clientFk"
|
||||
url="Clients/"
|
||||
|
@ -69,7 +67,7 @@
|
|||
ng-model="$ctrl.department.hasToMistake">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check
|
||||
label="worksInProduction"
|
||||
ng-model="$ctrl.department.isProduction">
|
||||
|
@ -78,12 +76,12 @@
|
|||
label="Fill in days without physical check-ins"
|
||||
ng-model="$ctrl.department.hasToRefill">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check
|
||||
label="Send check-ins by email"
|
||||
ng-model="$ctrl.department.hasToSendMail">
|
||||
</vn-check>
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
</vn-vertical>
|
||||
</vn-card>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "salix-back",
|
||||
"version": "23.36.01",
|
||||
"version": "23.38.01",
|
||||
"author": "Verdnatura Levante SL",
|
||||
"description": "Salix backend",
|
||||
"license": "GPL-3.0",
|
||||
|
|
Loading…
Reference in New Issue