diff --git a/client/core/src/components/grid/style.scss b/client/core/src/components/grid/style.scss index ce292e522..62365a593 100644 --- a/client/core/src/components/grid/style.scss +++ b/client/core/src/components/grid/style.scss @@ -1,17 +1,25 @@ .vn-grid { border-collapse: collapse; width: 100%; - td, th{ - text-align: left; - padding: 10px; + + & > thead, + & > tbody, + & > tfoot { + tr { + td, th { + text-align: left; + padding: 10px; + + &[number]{ + text-align: right; + } + } + } } & > thead, & > tbody { border-bottom: 3px solid #9D9D9D; } - & > tbody > tr{ + & > tbody > tr { border-bottom: 1px solid #9D9D9D; } - td[number], th[number]{ - text-align: right; - } } \ No newline at end of file diff --git a/client/ticket/routes.json b/client/ticket/routes.json index 322f026e6..577654d62 100644 --- a/client/ticket/routes.json +++ b/client/ticket/routes.json @@ -182,6 +182,18 @@ "description": "Sale checked", "icon": "assignment" } + }, + { + "url" : "/components", + "state": "ticket.card.components", + "component": "vn-ticket-components", + "params": { + "ticket": "$ctrl.ticket" + }, + "menu": { + "description": "Components", + "icon": "icon-components" + } } ] } \ No newline at end of file diff --git a/client/ticket/src/card/ticket-card.html b/client/ticket/src/card/ticket-card.html index 5c4db119f..b2a43a6e4 100644 --- a/client/ticket/src/card/ticket-card.html +++ b/client/ticket/src/card/ticket-card.html @@ -1,6 +1,6 @@ - + diff --git a/client/ticket/src/component/component.html b/client/ticket/src/component/component.html new file mode 100644 index 000000000..3180843e5 --- /dev/null +++ b/client/ticket/src/component/component.html @@ -0,0 +1,67 @@ + + + + + Components + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ItemDescriptionQuantitySerieComponentsImportTotal import
+ Base {{::$ctrl.base() | currency:'€':3}} +
+ Margin {{::$ctrl.profitMargin() | currency:'€':3}} +
+ Total {{::$ctrl.total() | currency:'€':3}} +
{{::sale.itemFk}}{{::sale.item.name}}{{::sale.quantity}}
{{::component.componentRate.componentType.type}}{{::component.componentRate.name}}{{::component.value | currency:'€':3}}{{::sale.quantity * component.value | currency:'€':3}}
+
+ +
+
diff --git a/client/ticket/src/component/component.js b/client/ticket/src/component/component.js new file mode 100644 index 000000000..7772ac694 --- /dev/null +++ b/client/ticket/src/component/component.js @@ -0,0 +1,45 @@ +import ngModule from '../module'; +import './style.scss'; + +class Controller { + total() { + let sum; + if (this.sales) { + sum = 0; + for (let sale of this.sales) + for (let component of sale.components) + sum += sale.quantity * component.value; + } + return sum; + } + base() { + let sum; + if (this.sales) { + sum = 0; + for (let sale of this.sales) + for (let component of sale.components) + if (component.componentRate.name == 'valor de compra') + sum += sale.quantity * component.value; + } + return sum; + } + profitMargin() { + let sum; + if (this.sales) { + sum = 0; + for (let sale of this.sales) + for (let component of sale.components) + if (component.componentRate.name != 'valor de compra') + sum += sale.quantity * component.value; + } + return sum; + } +} + +ngModule.component('vnTicketComponents', { + template: require('./component.html'), + controller: Controller, + bindings: { + ticket: '<' + } +}); diff --git a/client/ticket/src/component/component.spec.js b/client/ticket/src/component/component.spec.js new file mode 100644 index 000000000..eb7268402 --- /dev/null +++ b/client/ticket/src/component/component.spec.js @@ -0,0 +1,92 @@ +import './component.js'; + +describe('ticket', () => { + describe('Component vnTicketComponents', () => { + let $componentController; + let controller; + + beforeEach(() => { + angular.mock.module('ticket'); + }); + + beforeEach(angular.mock.inject(_$componentController_ => { + $componentController = _$componentController_; + controller = $componentController('vnTicketComponents'); + })); + + describe('total()', () => { + it('should return the sum from all componenets in each sale', () => { + controller.sales = [{ + components: [ + {componentRate: {name: 'valor de compra'}, value: 5}, + {componentRate: {name: 'reparto'}, value: 5}, + {componentRate: {name: 'recobro'}, value: 5} + ], + quantity: 1 + }, + { + components: [ + {componentRate: {name: 'valor de compra'}, value: 1}, + {componentRate: {name: 'reparto'}, value: 1}, + {componentRate: {name: 'recobro'}, value: 1} + ], + quantity: 5 + } + ]; + let result = controller.total(); + + expect(result).toEqual(30); + }); + }); + + describe('base()', () => { + it(`should return the sum from all 'valor de compra' componenets in each sale`, () => { + controller.sales = [{ + components: [ + {componentRate: {name: 'valor de compra'}, value: 5}, + {componentRate: {name: 'reparto'}, value: 5}, + {componentRate: {name: 'recobro'}, value: 5} + ], + quantity: 1 + }, + { + components: [ + {componentRate: {name: 'valor de compra'}, value: 1}, + {componentRate: {name: 'reparto'}, value: 1}, + {componentRate: {name: 'recobro'}, value: 1} + ], + quantity: 5 + } + ]; + let result = controller.base(); + + expect(result).toEqual(10); + }); + }); + + describe('profitMargin()', () => { + it(`should return the sum from all componenets but 'valor de compra' in each sale`, () => { + controller.sales = [{ + components: [ + {componentRate: {name: 'valor de compra'}, value: 5}, + {componentRate: {name: 'reparto'}, value: 5}, + {componentRate: {name: 'recobro'}, value: 5} + ], + quantity: 1 + }, + { + components: [ + {componentRate: {name: 'valor de compra'}, value: 1}, + {componentRate: {name: 'reparto'}, value: 1}, + {componentRate: {name: 'recobro'}, value: 1} + ], + quantity: 5 + } + ]; + let result = controller.profitMargin(); + + expect(result).toEqual(20); + }); + }); + }); +}); diff --git a/client/ticket/src/component/style.scss b/client/ticket/src/component/style.scss new file mode 100644 index 000000000..a08ba23a5 --- /dev/null +++ b/client/ticket/src/component/style.scss @@ -0,0 +1,27 @@ +vn-ticket-components .vn-grid { + tbody:not(:last-child) { + border-bottom: none; + } + + tfoot tr:first-child td { + padding-top: 10px !important; + } + + tr { + td { + padding-top: .1em !important; + padding-bottom: .1em !important; + } + + td.first { + padding-top: 10px !important; + } + + td.last { + padding-bottom: 10px !important; + } + } + tr:not(:first-child):not(:last-child), { + border-bottom: none; + } +} \ No newline at end of file diff --git a/client/ticket/src/locale/es.yml b/client/ticket/src/locale/es.yml index 07b1bb8c3..4710e2647 100644 --- a/client/ticket/src/locale/es.yml +++ b/client/ticket/src/locale/es.yml @@ -6,6 +6,7 @@ Basic data: Datos básicos Checked: Comprobado Client: Cliente Company: Empresa +Components: Componentes Counter: Contador Created : Añadido Date : Fecha @@ -15,13 +16,15 @@ Description: Descripción Discount: Descuento Employee : Empleado Expedition: Expedición +Import: Importe Is checked: Comprobado Item: Articulo Landing: Llegada Landed: F. entrega -Name: Nombre +Margin: Margen m³ per unit: m³ por unidad m³ per quantity: m³ por cantidad +Name: Nombre Notes: Notas New price: Nuevo precio New : Nuevo @@ -40,7 +43,8 @@ Some fields are invalid: Algunos campos no son válidos State: Estado The observation type must be unique: El tipo de observación debe ser único Tickets: Tickets +Total import: Importe total Tracking: Revisión Volume: Volumen Warehouse: Almacén -Worker: Trabajador \ No newline at end of file +Worker: Trabajador diff --git a/client/ticket/src/ticket.js b/client/ticket/src/ticket.js index 765a92490..1ec452142 100644 --- a/client/ticket/src/ticket.js +++ b/client/ticket/src/ticket.js @@ -18,3 +18,4 @@ import './tracking/index'; import './tracking/edit/edit'; import './fetched-tags/fetched-tags'; import './sale-checked/sale-checked'; +import './component/component'; diff --git a/client/ticket/src/volume/ticket-volume.html b/client/ticket/src/volume/ticket-volume.html index 3e9ff00bf..53e6ba87c 100644 --- a/client/ticket/src/volume/ticket-volume.html +++ b/client/ticket/src/volume/ticket-volume.html @@ -19,9 +19,9 @@ {{::sale.itemFk}} {{::sale.quantity}} - {{::sale.volume.m3_uni}} - {{::sale.volume.volumeTimesQuantity}} - {{::sale.volume.m3_total}} + {{::sale.volume.m3_uni | number:3}} + {{::sale.volume.volumeTimesQuantity | number:3}} + {{::sale.volume.m3_total | number:3}} diff --git a/services/loopback/common/methods/sale/filter.js b/services/loopback/common/methods/sale/filter.js index f9b6304f6..23688b341 100644 --- a/services/loopback/common/methods/sale/filter.js +++ b/services/loopback/common/methods/sale/filter.js @@ -10,28 +10,28 @@ module.exports = Self => { limit: params.size, order: params.order || 'concept ASC', include: [{ - relation: "item", + relation: 'item', scope: { include: { - relation: "itemTag", + relation: 'itemTag', scope: { - fields: ["tagFk", "value"], + fields: ['tagFk', 'value'], include: { - relation: "tag", + relation: 'tag', scope: { - fields: ["name"] + fields: ['name'] } }, limit: 6 } }, - fields: ["itemFk", "name"] + fields: ['itemFk', 'name'] } }, { - relation: "isChecked", + relation: 'isChecked', scope: { - fields: ["isChecked"] + fields: ['isChecked'] } }] }; diff --git a/services/ticket/common/methods/sale/saleComponentFilter.js b/services/ticket/common/methods/sale/saleComponentFilter.js new file mode 100644 index 000000000..f949709cd --- /dev/null +++ b/services/ticket/common/methods/sale/saleComponentFilter.js @@ -0,0 +1,52 @@ +module.exports = Self => { + Self.installMethod('saleComponentFilter', filterParams); + + function filterParams(params) { + return { + where: { + ticketFk: params.ticketFk + }, + skip: (params.page - 1) * params.size, + limit: params.size, + order: params.order || 'concept ASC', + include: [{ + relation: "item", + scope: { + include: { + relation: "itemTag", + scope: { + fields: ["tagFk", "value"], + include: { + relation: "tag", + scope: { + fields: ["name"] + } + }, + limit: 6 + } + }, + fields: ["itemFk", "name"] + } + }, + { + relation: "components", + scope: { + fields: ["componentFk", "value"], + include: { + relation: "componentRate", + scope: { + fields: ["componentTypeRate", "name"], + include: { + relation: "componentType", + scope: { + fields: ["type"] + } + } + } + } + } + } + ] + }; + } +}; diff --git a/services/ticket/common/models/componentRate.json b/services/ticket/common/models/componentRate.json index 41e987880..6e796cbb2 100644 --- a/services/ticket/common/models/componentRate.json +++ b/services/ticket/common/models/componentRate.json @@ -2,38 +2,45 @@ "name": "ComponentRate", "base": "VnModel", "options": { - "mysql": { + "mysql": { "table": "componentRate" - } + } }, "properties": { - "id": { - "id": true, - "type": "Number", - "description": "Identifier" - }, - "name": { - "type": "String" - }, - "classRate": { - "type": "Number" - }, - "tax": { - "type": "Number" - }, - "isRenewable": { - "type": "Number" - }, - "componentTypeRate": { - "type": "Number" - } + "id": { + "id": true, + "type": "Number", + "description": "Identifier" + }, + "name": { + "type": "String" + }, + "classRate": { + "type": "Number" + }, + "tax": { + "type": "Number" + }, + "isRenewable": { + "type": "Number" + }, + "componentTypeRate": { + "type": "Number" + } + }, + "relations": { + "componentType": { + "type": "belongsTo", + "model": "ComponentTypeRate", + "foreignKey": "componentTypeRate" + } }, "acls": [ - { - "accessType": "READ", - "principalType": "ROLE", - "principalId": "$everyone", - "permission": "ALLOW" - } + { + "accessType": "READ", + "principalType": "ROLE", + "principalId": "$everyone", + "permission": "ALLOW" + } ] -} \ No newline at end of file +} diff --git a/services/ticket/common/models/componentTypeRate.json b/services/ticket/common/models/componentTypeRate.json new file mode 100644 index 000000000..ce2fd2abc --- /dev/null +++ b/services/ticket/common/models/componentTypeRate.json @@ -0,0 +1,19 @@ +{ + "name": "ComponentTypeRate", + "base": "VnModel", + "options": { + "mysql": { + "table": "componentTypeRate" + } + }, + "properties": { + "id": { + "id": true, + "type": "Number", + "description": "Identifier" + }, + "type": { + "type": "String" + } + } +} diff --git a/services/ticket/common/models/sale.js b/services/ticket/common/models/sale.js index 0769447ad..c8afd2123 100644 --- a/services/ticket/common/models/sale.js +++ b/services/ticket/common/models/sale.js @@ -1,3 +1,4 @@ module.exports = function(Self) { require('../methods/sale/filter.js')(Self); + require('../methods/sale/saleComponentFilter.js')(Self); }; diff --git a/services/ticket/common/models/sale.json b/services/ticket/common/models/sale.json index fec1f2dd9..529329613 100644 --- a/services/ticket/common/models/sale.json +++ b/services/ticket/common/models/sale.json @@ -51,6 +51,11 @@ "type": "hasOne", "model": "SaleChecked", "foreignKey": "saleFk" - } + }, + "components": { + "type": "hasMany", + "model": "SaleComponent", + "foreignKey": "saleFk" + } } } diff --git a/services/ticket/common/models/saleComponent.json b/services/ticket/common/models/saleComponent.json index b990b1ed8..d10564ea8 100644 --- a/services/ticket/common/models/saleComponent.json +++ b/services/ticket/common/models/saleComponent.json @@ -22,7 +22,7 @@ }, "componentRate": { "type": "belongsTo", - "model": "componentRate", + "model": "ComponentRate", "foreignKey": "componentFk" } } diff --git a/services/ticket/server/model-config.json b/services/ticket/server/model-config.json index 7d2bf6776..bb5715e73 100644 --- a/services/ticket/server/model-config.json +++ b/services/ticket/server/model-config.json @@ -23,6 +23,9 @@ "ComponentRate": { "dataSource": "vn" }, + "ComponentTypeRate": { + "dataSource": "vn" + }, "SaleComponent": { "dataSource": "vn" },