diff --git a/client/item/src/descriptor/index.html b/client/item/src/descriptor/index.html index 0a6550efd..f44f13f37 100644 --- a/client/item/src/descriptor/index.html +++ b/client/item/src/descriptor/index.html @@ -3,10 +3,19 @@ - + + @@ -75,3 +84,37 @@ + + + +
+
+ Regularize +
+ + + + +
+
+ + + + +
\ No newline at end of file diff --git a/client/item/src/descriptor/index.js b/client/item/src/descriptor/index.js index e9ab1bf40..6f5f56ae5 100644 --- a/client/item/src/descriptor/index.js +++ b/client/item/src/descriptor/index.js @@ -2,8 +2,42 @@ import ngModule from '../module'; import './style.scss'; class Controller { - constructor($state) { + constructor($state, $scope, $http, vnApp, $translate) { this.$state = $state; + this.$scope = $scope; + this.$http = $http; + this.vnApp = vnApp; + this.$translate = $translate; + this.moreOptions = [ + {callback: this.showRegularizeDialog, name: 'Regularize'} + ]; + } + + set quantity(value) { + this._quantity = parseInt(value); + } + + get quantity() { + return this._quantity; + } + + set warehouseFk(value) { + this._warehouseFk = value; + } + + get warehouseFk() { + if (!this._warehouseFk) + this._warehouseFk = parseInt(window.localStorage.localWarehouseFk); + + return this._warehouseFk; + } + + onMoreChange(callback) { + callback.call(this); + } + + showRegularizeDialog() { + this.$scope.regularize.show(); } set quicklinks(value = {}) { @@ -13,9 +47,26 @@ class Controller { get quicklinks() { return this._quicklinks; } + + saveRegularize(response) { + if (response == 'ACCEPT') { + this.$http.post(`/item/api/Items/regularize`, { + itemFk: this.item.id, + quantity: this.quantity, + warehouseFk: this.warehouseFk + }).then(res => { + this.vnApp.showSuccess(this.$translate.instant('Data saved!')); + }); + } + } + + clearRegularizeDialog() { + this.warehouseFk = null; + this.quantity = null; + } } -Controller.$inject = ['$state']; +Controller.$inject = ['$state', '$scope', '$http', 'vnApp', '$translate']; ngModule.component('vnItemDescriptor', { template: require('./index.html'), diff --git a/client/item/src/descriptor/locale/es.yml b/client/item/src/descriptor/locale/es.yml new file mode 100644 index 000000000..fca4375f4 --- /dev/null +++ b/client/item/src/descriptor/locale/es.yml @@ -0,0 +1 @@ +Regularize: Regularizar \ No newline at end of file diff --git a/client/item/src/descriptor/style.scss b/client/item/src/descriptor/style.scss index 28a1d4203..8b08071e1 100644 --- a/client/item/src/descriptor/style.scss +++ b/client/item/src/descriptor/style.scss @@ -6,4 +6,9 @@ vn-item-descriptor { height: 100%; width: 100%; } + vn-dialog[vn-id=regularize]{ + vn-textfield{ + width: 100% + } + } } diff --git a/services/claim/server/model-config.json b/services/claim/server/model-config.json index b27b60483..434ed525e 100644 --- a/services/claim/server/model-config.json +++ b/services/claim/server/model-config.json @@ -11,9 +11,6 @@ "ClaimRedelivery": { "dataSource": "vn" }, - "ClaimDestination": { - "dataSource": "vn" - }, "ClaimResponsible": { "dataSource": "vn" }, diff --git a/services/loopback/common/methods/item/regularize.js b/services/loopback/common/methods/item/regularize.js new file mode 100644 index 000000000..4bac1d6bf --- /dev/null +++ b/services/loopback/common/methods/item/regularize.js @@ -0,0 +1,119 @@ +module.exports = Self => { + Self.remoteMethodCtx('regularize', { + description: 'Sends items to the trash', + accessType: 'WRITE', + accepts: [{ + arg: 'itemFk', + type: 'number', + required: true, + description: 'The item id', + }, { + arg: 'quantity', + type: 'number', + required: true, + description: 'The visible quantity', + }, { + arg: 'warehouseFk', + type: 'number', + required: true, + description: 'The id of the wharehouse where the inventory happened', + }], + returns: { + type: 'boolean', + root: true + }, + http: { + path: `/regularize`, + verb: 'post' + } + }); + + Self.regularize = async (ctx, itemFk, quantity, warehouseFk) => { + const userId = ctx.req.accessToken.userId; + const models = Self.app.models; + + const itemDestination = await models.ClaimDestination.findOne({ + include: { + relation: 'address', + scope: { + fields: ['clientFk'] + } + }, + where: {description: 'Corregido'} + }); + + let transaction = await Self.beginTransaction({}); + try { + let item = await models.Item.findById(itemFk); + + let ticketFk = await getTicketId({ + clientFk: itemDestination.address.clientFk, + addressFk: itemDestination.addressFk, + warehouseFk: warehouseFk + }, transaction); + + if (!ticketFk) { + ticketFk = await createTicket({ + clientFk: itemDestination.address().clientFk, + addressFk: itemDestination.addressFk, + warehouseFk: warehouseFk, + userId: userId + }, transaction); + } + + + let query = ` + CALL vn.getItemVisibleAvailable(?,curdate(),?,?)`; + + let options = [itemFk, warehouseFk, true]; + let [res] = await Self.rawSql(query, options, {transaction: transaction}); + + let newQuantity = res[0].visible - quantity; + + await models.Sale.create({ + ticketFk: ticketFk, + itemFk: itemFk, + concept: item.name, + quantity: newQuantity, + discount: 100 + }, {transaction: transaction}); + + await transaction.commit(); + return ticketFk; + } catch (e) { + await transaction.rollback(); + throw e; + } + + async function createTicket(params, transaction) { + let ticket = await Self.app.models.Ticket.new({ + shipped: new Date(), + landed: new Date(), + clientFk: params.clientFk, + warehouseFk: params.warehouseFk, + companyFk: params.companyFk, + addressFk: params.addressFk, + userId: params.userId + }, {transaction: transaction}); + + return ticket.id; + } + + + async function getTicketId(params, transaction) { + const currentDate = new Date(); + currentDate.setHours(null, null, null); + + let ticket = await Self.app.models.Ticket.findOne({ + where: { + addressFk: params.addressFk, + warehouseFk: params.warehouseFk, + shipped: currentDate, + landed: currentDate + } + }, {transaction: transaction}); + + return ticket && ticket.id; + } + }; +}; diff --git a/services/loopback/common/methods/item/specs/regularize.spec.js b/services/loopback/common/methods/item/specs/regularize.spec.js new file mode 100644 index 000000000..6e9045d14 --- /dev/null +++ b/services/loopback/common/methods/item/specs/regularize.spec.js @@ -0,0 +1,33 @@ +const app = require(`${servicesDir}/item/server/server`); + +describe('regularize()', () => { + const itemFk = 1; + const warehouseFk = 1; + const trashAddress = 11; + let trashTicket; + + afterAll(async () => { + await app.models.Ticket.destroyById(trashTicket.id); + }); + + it('should create a new ticket and add a line', async () => { + let ctx = {req: {accessToken: {userId: 18}}}; + + + let query = `CALL vn.getItemVisibleAvailable(?,curdate(),?,?)`; + + let options = [itemFk, warehouseFk, true]; + + let [res] = await app.models.Item.rawSql(query, options); + let visible = res[0].visible; + let saleQuantity = visible - 11; + + let ticketFk = await app.models.Item.regularize(ctx, itemFk, 11, warehouseFk); + let sale = await app.models.Sale.findOne({where: {ticketFk: ticketFk}}); + trashTicket = await app.models.Ticket.findById(ticketFk); + + expect(sale.quantity).toEqual(saleQuantity); + expect(sale.discount).toEqual(100); + expect(trashTicket.addressFk).toEqual(trashAddress); + }); +}); diff --git a/services/order/common/methods/order/catalogFilter.js b/services/loopback/common/methods/order/catalogFilter.js similarity index 97% rename from services/order/common/methods/order/catalogFilter.js rename to services/loopback/common/methods/order/catalogFilter.js index 80a74b78f..519c96267 100644 --- a/services/order/common/methods/order/catalogFilter.js +++ b/services/loopback/common/methods/order/catalogFilter.js @@ -1,4 +1,4 @@ -const ParameterizedSQL = require('vn-loopback/node_modules/loopback-connector').ParameterizedSQL; +const ParameterizedSQL = require('loopback-connector').ParameterizedSQL; module.exports = Self => { Self.remoteMethod('catalogFilter', { @@ -61,19 +61,20 @@ module.exports = Self => { for (const tag of tags) { const tAlias = `it${i++}`; - if (tag.tagFk) + if (tag.tagFk) { stmt.merge({ sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id AND ${tAlias}.tagFk = ? AND ${tAlias}.value LIKE ?`, params: [tag.tagFk, `%${tag.value}%`], }); - else + } else { stmt.merge({ sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id AND ${tAlias}.value LIKE ?`, params: [`%${tag.value}%`], }); + } } } diff --git a/services/order/common/methods/order/getSourceValues.js b/services/loopback/common/methods/order/getSourceValues.js similarity index 100% rename from services/order/common/methods/order/getSourceValues.js rename to services/loopback/common/methods/order/getSourceValues.js diff --git a/services/order/common/methods/order/getTaxes.js b/services/loopback/common/methods/order/getTaxes.js similarity index 100% rename from services/order/common/methods/order/getTaxes.js rename to services/loopback/common/methods/order/getTaxes.js diff --git a/services/order/common/methods/order/getTotal.js b/services/loopback/common/methods/order/getTotal.js similarity index 100% rename from services/order/common/methods/order/getTotal.js rename to services/loopback/common/methods/order/getTotal.js diff --git a/services/order/common/methods/order/getTotalVolume.js b/services/loopback/common/methods/order/getTotalVolume.js similarity index 100% rename from services/order/common/methods/order/getTotalVolume.js rename to services/loopback/common/methods/order/getTotalVolume.js diff --git a/services/order/common/methods/order/getVAT.js b/services/loopback/common/methods/order/getVAT.js similarity index 100% rename from services/order/common/methods/order/getVAT.js rename to services/loopback/common/methods/order/getVAT.js diff --git a/services/order/common/methods/order/getVolumes.js b/services/loopback/common/methods/order/getVolumes.js similarity index 100% rename from services/order/common/methods/order/getVolumes.js rename to services/loopback/common/methods/order/getVolumes.js diff --git a/services/order/common/methods/order/isEditable.js b/services/loopback/common/methods/order/isEditable.js similarity index 100% rename from services/order/common/methods/order/isEditable.js rename to services/loopback/common/methods/order/isEditable.js diff --git a/services/order/common/methods/order/new.js b/services/loopback/common/methods/order/new.js similarity index 93% rename from services/order/common/methods/order/new.js rename to services/loopback/common/methods/order/new.js index f2caf2347..5dd537fe8 100644 --- a/services/order/common/methods/order/new.js +++ b/services/loopback/common/methods/order/new.js @@ -1,4 +1,4 @@ -const UserError = require('vn-loopback/common/helpers').UserError; +let UserError = require('../../helpers').UserError; module.exports = Self => { Self.remoteMethod('new', { @@ -22,7 +22,7 @@ module.exports = Self => { Self.new = async params => { let address = await Self.app.models.Address.findOne({ where: {id: params.addressFk}, - fields: 'clientFk' + fields: ['clientFk'] }); let clientFk = address.clientFk; @@ -51,7 +51,7 @@ module.exports = Self => { params.landed, params.agencyModeFk, params.addressFk, - "SALIX" + 'SALIX' ]); return result[0].vOrderId; diff --git a/services/loopback/common/methods/order/newFromTicket.js b/services/loopback/common/methods/order/newFromTicket.js new file mode 100644 index 000000000..533ec6ff9 --- /dev/null +++ b/services/loopback/common/methods/order/newFromTicket.js @@ -0,0 +1,34 @@ +module.exports = Self => { + Self.remoteMethod('newFromTicket', { + description: 'Create a new order and returns the new ID', + accessType: 'WRITE', + accepts: [{ + arg: 'ticketFk', + type: 'number', + description: 'The ticket id', + required: true + }], + returns: { + type: 'number', + root: true + }, + http: { + path: `/newFromTicket`, + verb: 'post' + } + }); + + Self.newFromTicket = async ticketFk => { + let ticket = await Self.app.models.Ticket.findOne({ + where: {id: ticketFk} + }); + + let orderID = await Self.app.models.Order.new({ + addressFk: ticket.addressFk, + landed: ticket.landed, + agencyModeFk: ticket.agencyModeFk + }); + + return orderID; + }; +}; diff --git a/services/order/common/methods/order/specs/catalogFilter.spec.js b/services/loopback/common/methods/order/specs/catalogFilter.spec.js similarity index 100% rename from services/order/common/methods/order/specs/catalogFilter.spec.js rename to services/loopback/common/methods/order/specs/catalogFilter.spec.js diff --git a/services/order/common/methods/order/specs/getTaxes.spec.js b/services/loopback/common/methods/order/specs/getTaxes.spec.js similarity index 100% rename from services/order/common/methods/order/specs/getTaxes.spec.js rename to services/loopback/common/methods/order/specs/getTaxes.spec.js diff --git a/services/order/common/methods/order/specs/getTotal.spec.js b/services/loopback/common/methods/order/specs/getTotal.spec.js similarity index 100% rename from services/order/common/methods/order/specs/getTotal.spec.js rename to services/loopback/common/methods/order/specs/getTotal.spec.js diff --git a/services/order/common/methods/order/specs/getTotalVolume.spec.js b/services/loopback/common/methods/order/specs/getTotalVolume.spec.js similarity index 100% rename from services/order/common/methods/order/specs/getTotalVolume.spec.js rename to services/loopback/common/methods/order/specs/getTotalVolume.spec.js diff --git a/services/order/common/methods/order/specs/getVAT.spec.js b/services/loopback/common/methods/order/specs/getVAT.spec.js similarity index 100% rename from services/order/common/methods/order/specs/getVAT.spec.js rename to services/loopback/common/methods/order/specs/getVAT.spec.js diff --git a/services/order/common/methods/order/specs/getVolumes.spec.js b/services/loopback/common/methods/order/specs/getVolumes.spec.js similarity index 100% rename from services/order/common/methods/order/specs/getVolumes.spec.js rename to services/loopback/common/methods/order/specs/getVolumes.spec.js diff --git a/services/order/common/methods/order/specs/isEditable.spec.js b/services/loopback/common/methods/order/specs/isEditable.spec.js similarity index 100% rename from services/order/common/methods/order/specs/isEditable.spec.js rename to services/loopback/common/methods/order/specs/isEditable.spec.js diff --git a/services/order/common/methods/order/specs/new.spec.js b/services/loopback/common/methods/order/specs/new.spec.js similarity index 72% rename from services/order/common/methods/order/specs/new.spec.js rename to services/loopback/common/methods/order/specs/new.spec.js index d0fdf71a6..8aa9a85d0 100644 --- a/services/order/common/methods/order/specs/new.spec.js +++ b/services/loopback/common/methods/order/specs/new.spec.js @@ -1,62 +1,62 @@ const app = require(`${servicesDir}/order/server/server`); -const UserError = require('vn-loopback/common/helpers').UserError; +let UserError = require('../../../helpers').UserError; describe('order new()', () => { let orderId; - afterAll(async() => { + afterAll(async () => { await app.models.Order.destroyById(orderId); }); - it('should throw an error if the client is frozen', async() => { + it('should throw an error if the client is frozen', async () => { let error; let params = {addressFk: 121}; await app.models.Order.new(params) - .catch(e => { - error = e; - }); + .catch(e => { + error = e; + }); expect(error).toEqual(new UserError(`You can't create an order for a frozen client`)); }); - it('should throw an error if the client isnt frozen and isnt active', async() => { + it('should throw an error if the client isnt frozen and isnt active', async () => { let error; let params = {addressFk: 6}; await app.models.Order.new(params) - .catch(e => { - error = e; - }); + .catch(e => { + error = e; + }); expect(error).toEqual(new UserError(`You can't create an order for a inactive client`)); }); - it('should throw an error if the client isnt frozen and is active but doesnt have data checked', async() => { + it('should throw an error if the client isnt frozen and is active but doesnt have data checked', async () => { let error; let params = {addressFk: 7}; await app.models.Order.new(params) - .catch(e => { - error = e; - }); + .catch(e => { + error = e; + }); expect(error).toEqual(new UserError(`You can't create an order for a client that doesn't has tax data verified`)); }); - it('should throw an error if the client isnt frozen and is active, has data checked but has a debt', async() => { + it('should throw an error if the client isnt frozen and is active, has data checked but has a debt', async () => { let error; let params = {addressFk: 123}; await app.models.Order.new(params) - .catch(e => { - error = e; - }); + .catch(e => { + error = e; + }); expect(error).toEqual(new UserError(`You can't create an order for a client that has a debt`)); }); - it('should create a new order for the user with id 105 when all conditions are met', async() => { + it('should create a new order for the user with id 105 when all conditions are met', async () => { let params = { landed: new Date(), agencyModeFk: 1, diff --git a/services/order/common/methods/order/specs/summary.spec.js b/services/loopback/common/methods/order/specs/summary.spec.js similarity index 100% rename from services/order/common/methods/order/specs/summary.spec.js rename to services/loopback/common/methods/order/specs/summary.spec.js diff --git a/services/order/common/methods/order/summary.js b/services/loopback/common/methods/order/summary.js similarity index 100% rename from services/order/common/methods/order/summary.js rename to services/loopback/common/methods/order/summary.js diff --git a/services/claim/common/models/claim-destination.json b/services/loopback/common/models/claim-destination.json similarity index 100% rename from services/claim/common/models/claim-destination.json rename to services/loopback/common/models/claim-destination.json diff --git a/services/loopback/common/models/item.js b/services/loopback/common/models/item.js index d98867759..a5aa9d779 100644 --- a/services/loopback/common/models/item.js +++ b/services/loopback/common/models/item.js @@ -8,6 +8,7 @@ module.exports = Self => { require('../methods/item/getLastEntries')(Self); require('../methods/item/getSummary')(Self); require('../methods/item/getCard')(Self); + require('../methods/item/regularize')(Self); Self.validatesPresenceOf('name', {message: 'Cannot be blank'}); Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'}); diff --git a/services/order/common/models/order.js b/services/loopback/common/models/order.js similarity index 90% rename from services/order/common/models/order.js rename to services/loopback/common/models/order.js index 0e7ec2400..09d04a010 100644 --- a/services/order/common/models/order.js +++ b/services/loopback/common/models/order.js @@ -9,4 +9,5 @@ module.exports = Self => { require('../methods/order/summary')(Self); require('../methods/order/getVAT')(Self); require('../methods/order/getSourceValues')(Self); + require('../methods/order/newFromTicket')(Self); }; diff --git a/services/order/common/models/order.json b/services/loopback/common/models/order.json similarity index 100% rename from services/order/common/models/order.json rename to services/loopback/common/models/order.json diff --git a/services/loopback/server/model-config.json b/services/loopback/server/model-config.json index 898e5f12a..fa4508883 100644 --- a/services/loopback/server/model-config.json +++ b/services/loopback/server/model-config.json @@ -152,5 +152,14 @@ }, "TicketRequest": { "dataSource": "vn" + }, + "TicketLog": { + "dataSource": "vn" + }, + "ClaimDestination": { + "dataSource": "vn" + }, + "Order": { + "dataSource": "hedera" } } \ No newline at end of file