#847 ticket.index new

This commit is contained in:
Gerard 2018-11-27 13:28:15 +01:00
parent 7976ca130e
commit 97ba5ae190
12 changed files with 249 additions and 34 deletions

View File

@ -211,13 +211,13 @@
"component": "vn-ticket-request-create", "component": "vn-ticket-request-create",
"description": "Purchase request", "description": "Purchase request",
"acl": ["salesPerson"] "acl": ["salesPerson"]
}/* , },
{ {
"url": "/create?clientFk", "url": "/create?clientFk",
"state": "ticket.create", "state": "ticket.create",
"component": "vn-ticket-create", "component": "vn-ticket-create",
"description": "New ticket" "description": "New ticket"
} */ }
], ],
"menu": [ "menu": [
{"state": "ticket.card.data.stepOne", "icon": "settings"}, {"state": "ticket.card.data.stepOne", "icon": "settings"},

View File

@ -0,0 +1,44 @@
<vn-title>New ticket</vn-title>
<vn-autocomplete
vn-focus
vn-id="client"
url="/api/Clients"
label="Client"
search-function="{or: [{id: {regexp: $search}}, {name: {regexp: $search}}]}"
show-field="name"
value-field="id"
field="$ctrl.clientFk">
<tpl-item>{{id}}: {{name}}</tpl-item>
</vn-autocomplete>
<vn-autocomplete
disabled="!$ctrl.clientFk"
url="{{ $ctrl.clientFk ? '/api/Clients/'+ $ctrl.clientFk +'/addresses' : null }}"
fields="['nickname', 'street', 'city']"
field="$ctrl.addressFk"
show-field="nickname"
value-field="id"
label="Address">
<tpl-item>{{nickname}}: {{street}}, {{city}}</tpl-item>
</vn-autocomplete>
<vn-date-picker
label="Landed"
model="$ctrl.landed"
ini-options="{enableTime: false}">
</vn-date-picker>
<vn-autocomplete
vn-one
disabled="!$ctrl.clientFk || !$ctrl.landed"
field="$ctrl.warehouseFk"
url="/agency/api/Warehouses"
show-field="name"
value-field="id"
label="Warehouse">
</vn-autocomplete>
<vn-autocomplete
disabled="!$ctrl.clientFk || !$ctrl.landed || !$ctrl.warehouseFk"
data="$ctrl._availableAgencies"
label="Agency"
show-field="agency"
value-field="id"
field="$ctrl.ticket.agencyModeFk">
</vn-autocomplete>

View File

@ -0,0 +1,110 @@
import ngModule from '../module';
class Controller {
constructor($http, vnApp, $translate, $state, $stateParams) {
this.$stateParams = $stateParams;
this.$http = $http;
this.translate = $translate;
this.vnApp = vnApp;
this.ticket = {};
this.$state = $state;
this.clientFk = $stateParams.clientFk;
}
$onInit() {
if (this.$stateParams && this.$stateParams.clientFk)
this.clientFk = this.$stateParams.clientFk;
}
set ticket(value) {
if (value)
this._ticket = value;
}
get ticket() {
return this._ticket;
}
set clientFk(value) {
this.ticket.clientFk = value;
if (value) {
let filter = {where: {clientFk: value, isDefaultAddress: true}};
filter = encodeURIComponent(JSON.stringify(filter));
let query = `/api/Addresses?filter=${filter}`;
this.$http.get(query).then(res => {
this.addressFk = res.data[0].id;
});
} else
this.addressFk = null;
}
get clientFk() {
return this.ticket.clientFk;
}
set addressFk(value) {
this.ticket.addressFk = value;
}
get addressFk() {
return this.ticket.addressFk;
}
set landed(value) {
this.ticket.landed = value;
}
get landed() {
return this.ticket.landed;
}
set warehouseFk(value) {
this.ticket.warehouseFk = value;
this.getAvailableAgencies();
}
get warehouseFk() {
return this.ticket.warehouseFk;
}
getAvailableAgencies() {
this.ticket.agencyModeFk = null;
if (this.ticket.landed && this.ticket.addressFk) {
let filter = {warehouseFk: this.ticket.warehouseFk, addressFk: this.ticket.addressFk, landed: this.ticket.landed};
filter = encodeURIComponent(JSON.stringify(filter));
let query = `/api/Agencies/getAgenciesWithWarehouse?filter=${filter}`;
this.$http.get(query).then(res => {
this._availableAgencies = res.data[0];
});
}
}
onSubmit() {
this.createTicket();
}
createTicket() {
let params = {
clientFk: this.ticket.clientFk,
landed: this.ticket.landed,
addressFk: this.ticket.addressFk,
agencyModeFk: this.ticket.agencyModeFk,
warehouseFk: this.ticket.warehouseFk,
};
this.$http.post(`ticket/api/Tickets/new`, params).then(res => {
this.vnApp.showSuccess(this.translate.instant('Data saved!'));
this.$state.go('ticket.card.summary', {id: res.data.id});
});
}
}
Controller.$inject = ['$http', 'vnApp', '$translate', '$state', '$stateParams'];
ngModule.component('vnTicketCreateCard', {
template: require('./card.html'),
controller: Controller,
bindings: {
ticket: '<?'
}
});

View File

@ -0,0 +1,11 @@
<div margin-medium>
<div style="max-width: 70em; margin: 0 auto;" >
<vn-card pad-large>
<vn-ticket-create-card vn-id="card" on-save=""></vn-ticket-create-card>
</vn-card>
<vn-button-bar>
<vn-submit ng-click="$ctrl.onSubmit()" label="Create">
</vn-submit>
</vn-button-bar>
</div>
</div>

View File

@ -0,0 +1,20 @@
import ngModule from '../module';
class Controller {
constructor($scope, $http, $state) {
this.$ = $scope;
this.$http = $http;
this.$state = $state;
}
async onSubmit() {
let newTicketID = await this.$.card.createTicket();
this.$state.go('ticket.card.summary', {id: newTicketID});
}
}
Controller.$inject = ['$scope', '$http', '$state'];
ngModule.component('vnTicketCreate', {
template: require('./index.html'),
controller: Controller
});

View File

@ -0,0 +1 @@
New ticket: Nueva ticket

View File

@ -97,6 +97,9 @@
scroll-selector="ui-view"> scroll-selector="ui-view">
</vn-pagination> </vn-pagination>
</div> </div>
<a ui-sref="ticket.create" vn-tooltip="New ticket" vn-bind="+" fixed-bottom-right>
<vn-float-button icon="add"></vn-float-button>
</a>
<vn-dialog <vn-dialog
vn-id="summary" vn-id="summary"
class="dialog-summary"> class="dialog-summary">

View File

@ -3,8 +3,8 @@ export * from './module';
import './search-panel'; import './search-panel';
import './index'; import './index';
import './card'; import './card';
/* import './create/card'; import './create/card';
import './create/index'; */ import './create/index';
import './summary'; import './summary';
import './data'; import './data';
import './data/step-one'; import './data/step-one';

View File

@ -16,7 +16,7 @@ module.exports = Self => {
arg: 'warehouseFk', arg: 'warehouseFk',
type: 'number', type: 'number',
required: true, required: true,
description: 'The id of the wharehouse where the inventory happened', description: 'The id of the warehouse where the inventory happened',
}], }],
returns: { returns: {
type: 'boolean', type: 'boolean',
@ -86,15 +86,17 @@ module.exports = Self => {
} }
async function createTicket(params, transaction) { async function createTicket(params, transaction) {
let ticket = await Self.app.models.Ticket.new({ let ticket = await Self.app.models.Ticket.new(
shipped: new Date(), ctx,
landed: new Date(), {
clientFk: params.clientFk, shipped: new Date(),
warehouseFk: params.warehouseFk, landed: new Date(),
companyFk: params.companyFk, clientFk: params.clientFk,
addressFk: params.addressFk, warehouseFk: params.warehouseFk,
userId: params.userId companyFk: params.companyFk,
}, {transaction: transaction}); addressFk: params.addressFk,
userId: params.userId
}, {transaction: transaction});
return ticket.id; return ticket.id;
} }

View File

@ -27,7 +27,7 @@ module.exports = Self => {
} }
}); });
Self.moveToNewTicket = async(ctx, params) => { Self.moveToNewTicket = async (ctx, params) => {
let userId = ctx.req.accessToken.userId; let userId = ctx.req.accessToken.userId;
let model = Self.app.models; let model = Self.app.models;
let thisTicketIsEditable = await model.Ticket.isEditable(params.ticket.oldTicketFk); let thisTicketIsEditable = await model.Ticket.isEditable(params.ticket.oldTicketFk);
@ -53,7 +53,7 @@ module.exports = Self => {
let transaction = await Self.beginTransaction({}); let transaction = await Self.beginTransaction({});
try { try {
let newTicket = await model.Ticket.new(newTicketParams, {transaction: transaction}); let newTicket = await model.Ticket.new(ctx, newTicketParams, {transaction: transaction});
let selectedSalesId = []; let selectedSalesId = [];
params.sales.forEach(sale => { params.sales.forEach(sale => {

View File

@ -1,7 +1,7 @@
let UserError = require('../../helpers').UserError; let UserError = require('../../helpers').UserError;
module.exports = Self => { module.exports = Self => {
Self.remoteMethod('new', { Self.remoteMethodCtx('new', {
description: 'Create a newticket and returns the new ID', description: 'Create a newticket and returns the new ID',
accessType: 'WRITE', accessType: 'WRITE',
accepts: [{ accepts: [{
@ -21,17 +21,40 @@ module.exports = Self => {
} }
}); });
Self.new = async(params, transaction) => { Self.new = async (ctx, params, transaction) => {
let existsAddress = await Self.app.models.Address.findOne({ let address = await Self.app.models.Address.findOne({
where: { where: {id: params.addressFk},
id: params.addressFk, fields: ['clientFk'],
clientFk: params.clientFk} include: [
{relation: 'client'}
]
}); });
if (!existsAddress) if (!address)
throw new UserError(`This address doesn't exist`); throw new UserError(`This address doesn't exist`);
let query = `CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @result); if (address.client().isFreezed)
throw new UserError(`You can't create an order for a frozen client`);
if (!address.client().isActive)
throw new UserError(`You can't create an order for a inactive client`);
if (!address.client().isTaxDataChecked)
throw new UserError(`You can't create an order for a client that doesn't has tax data verified`);
let clientFk = address.clientFk;
let query = `SELECT vn.clientGetDebt(?, CURDATE()) AS debt`;
let clientDebt = await Self.rawSql(query, [clientFk]);
if (clientDebt[0].debt > 0)
throw new UserError(`You can't create an order for a client that has a debt`);
if (!params.userId && ctx.req && ctx.req.accessToken.userId)
params.userId = ctx.req.accessToken.userId;
query = `CALL vn.ticketCreateWithUser(?, ?, ?, ?, ?, ?, ?, ?, ?, @result);
SELECT @result newTicketId;`; SELECT @result newTicketId;`;
let result = await Self.rawSql(query, [ let result = await Self.rawSql(query, [
params.clientFk, params.clientFk,
@ -43,10 +66,10 @@ module.exports = Self => {
params.routeFk | null, params.routeFk | null,
params.landed, params.landed,
params.userId params.userId
], transaction); ], {options: transaction});
return await Self.findOne({ return await Self.findOne({
where: {id: result[1][0].newTicketId} where: {id: result[1][0].newTicketId}
}, transaction); }, {options: transaction});
}; };
}; };

View File

@ -3,16 +3,17 @@ const app = require(`${servicesDir}/ticket/server/server`);
describe('ticket new()', () => { describe('ticket new()', () => {
let ticket; let ticket;
let today = new Date(); let today = new Date();
let ctx = {req: {accessToken: {userId: 1}}};
afterAll(async() => { afterAll(async () => {
await app.models.Ticket.destroyById(ticket.id); await app.models.Ticket.destroyById(ticket.id);
}); });
it('should throw an error if the address doesnt exist', async() => { it('should throw an error if the address doesnt exist', async () => {
let error; let error;
let params = {addressFk: 'invalid address', clientFk: 101}; let params = {addressFk: 'invalid address', clientFk: 104};
await app.models.Ticket.new(params) await app.models.Ticket.new(ctx, params)
.catch(response => { .catch(response => {
expect(response.message).toEqual(`This address doesn't exist`); expect(response.message).toEqual(`This address doesn't exist`);
error = response; error = response;
@ -21,19 +22,19 @@ describe('ticket new()', () => {
expect(error).toBeDefined(); expect(error).toBeDefined();
}); });
it('should return the id of the created ticket', async() => { it('should return the id of the created ticket', async () => {
let params = { let params = {
warehouseFk: 1, warehouseFk: 1,
clientFk: 101, clientFk: 104,
companyFk: 442, companyFk: 442,
addressFk: 1, addressFk: 4,
agencyModeFk: 1, agencyModeFk: 1,
userId: 9, userId: 9,
shipped: today, shipped: today,
landed: today landed: today
}; };
ticket = await app.models.Ticket.new(params); ticket = await app.models.Ticket.new(ctx, params);
let newestTicketIdInFixtures = 21; let newestTicketIdInFixtures = 21;