Merge pull request '2245-ticket_component' (#369) from 2245-ticket_component into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #369 Reviewed-by: Carlos Jimenez <carlosjr@verdnatura.es>
This commit is contained in:
commit
a9c1f97b72
|
@ -540,6 +540,32 @@ INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agen
|
||||||
(6, NULL, 57, CURDATE(), 5, 7, 'sixth route', 1.7, 60, CURDATE(), CURDATE(), 3),
|
(6, NULL, 57, CURDATE(), 5, 7, 'sixth route', 1.7, 60, CURDATE(), CURDATE(), 3),
|
||||||
(7, NULL, 57, CURDATE(), 6, 8, 'seventh route', 0, 70, CURDATE(), CURDATE(), 5);
|
(7, NULL, 57, CURDATE(), 6, 8, 'seventh route', 0, 70, CURDATE(), CURDATE(), 5);
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`,`zonePrice`, `zoneBonus`, `created`)
|
||||||
|
VALUES
|
||||||
|
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, 5, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||||
|
(2 , 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T1111111', 0, 1, 5, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||||
|
(3 , 1, 7, 1, 6, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T2222222', 0, 3, 5, 1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
||||||
|
(4 , 3, 2, 1, 2, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T3333333', 0, 9, 5, 1, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
|
||||||
|
(5 , 3, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T4444444', 0, 10, 5, 1, DATE_ADD(CURDATE(), INTERVAL -4 MONTH)),
|
||||||
|
(6 , 1, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Mountain Drive Gotham', 1, 'A1111111', 0, 10, 5, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||||
|
(7 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Mountain Drive Gotham', 1, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
(8 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Bat cave', 121, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
(9 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Stark tower', 124, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
(10, 1, 1, 5, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'Ingram Street', 2, NULL, 0, 1, 5, 1, CURDATE()),
|
||||||
|
(11, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'NY roofs', 122, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
(12, 1, 1, 1, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, 5, 1, CURDATE()),
|
||||||
|
(13, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
(14, 1, 2, 1, NULL, CURDATE(), CURDATE(), 104, 'Malibu Point', 4, NULL, 0, 9, 5, 1, CURDATE()),
|
||||||
|
(15, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 105, 'Plastic Cell', 125, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
(16, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
(17, 1, 7, 2, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, 5, 1, CURDATE()),
|
||||||
|
(18, 1, 4, 4, 4, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 108, 'Cerebro', 128, NULL, 0, 12, 5, 1, CURDATE()),
|
||||||
|
(19, 1, 5, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 1, NULL, 5, 1, CURDATE()),
|
||||||
|
(20, 1, 5, 5, 3, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||||
|
(21, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland', 102, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||||
|
(22, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan', 103, NULL, 0, 13, 5, 1, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||||
|
(23, NULL, 8, 1, 7, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'address 21', 121, NULL, 0, 5, 5, 1, CURDATE()),
|
||||||
|
(24 ,NULL, 8, 1, 7, CURDATE(), CURDATE(), 101, 'Bruce Wayne', 1, NULL, 0, 5, 5, 1, CURDATE());
|
||||||
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `created`)
|
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `created`)
|
||||||
VALUES
|
VALUES
|
||||||
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||||
|
@ -786,6 +812,10 @@ INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `d
|
||||||
(16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
|
(16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL),
|
||||||
(71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 88, 2, NULL);
|
(71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 88, 2, NULL);
|
||||||
|
|
||||||
|
INSERT INTO `vn`.`expeditionBoxVol`(`boxFk`, `m3`, `ratio`)
|
||||||
|
VALUES
|
||||||
|
(71,0.141,1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`)
|
INSERT INTO `vn`.`packaging`(`id`, `volume`, `width`, `height`, `depth`, `isPackageReturnable`, `created`, `itemFk`, `price`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 0.00, 10, 10, 0, 1, CURDATE(), 6, 1.50),
|
(1, 0.00, 10, 10, 0, 1, CURDATE(), 6, 1.50),
|
||||||
|
|
|
@ -521,11 +521,11 @@ export default {
|
||||||
zone: 'vn-autocomplete[ng-model="$ctrl.zoneId"]',
|
zone: 'vn-autocomplete[ng-model="$ctrl.zoneId"]',
|
||||||
nextStepButton: 'vn-step-control .buttons > section:last-child vn-button',
|
nextStepButton: 'vn-step-control .buttons > section:last-child vn-button',
|
||||||
finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]',
|
finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]',
|
||||||
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two vn-tfoot > vn-tr > :nth-child(6)',
|
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > vn-side-menu div:nth-child(4)',
|
||||||
chargesReason: 'vn-ticket-basic-data-step-two div:nth-child(3) > vn-radio',
|
chargesReason: 'vn-ticket-basic-data-step-two div:nth-child(3) > vn-radio',
|
||||||
},
|
},
|
||||||
ticketComponents: {
|
ticketComponents: {
|
||||||
base: 'vn-ticket-components [name="base-sum"]'
|
base: 'vn-ticket-components > vn-side-menu div:nth-child(1) > div:nth-child(2)'
|
||||||
},
|
},
|
||||||
ticketRequests: {
|
ticketRequests: {
|
||||||
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
|
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
|
||||||
|
|
|
@ -24,7 +24,6 @@ describe('Ticket List components path', () => {
|
||||||
await page.waitPropertyLength(selectors.ticketComponents.base, 'innerText', minLength);
|
await page.waitPropertyLength(selectors.ticketComponents.base, 'innerText', minLength);
|
||||||
const base = await page.waitToGetProperty(selectors.ticketComponents.base, 'innerText');
|
const base = await page.waitToGetProperty(selectors.ticketComponents.base, 'innerText');
|
||||||
|
|
||||||
|
|
||||||
expect(base).toContain('Base');
|
expect(base).toContain('Base');
|
||||||
expect(base.length).toBeGreaterThan(minLength);
|
expect(base.length).toBeGreaterThan(minLength);
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
.vn-radio {
|
.vn-radio {
|
||||||
|
|
||||||
& > .btn {
|
& > .btn {
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
|
|
||||||
|
@ -25,4 +26,8 @@
|
||||||
&.disabled.checked > .btn > .mark {
|
&.disabled.checked > .btn > .mark {
|
||||||
background-color: $color-font-secondary;
|
background-color: $color-font-secondary;
|
||||||
}
|
}
|
||||||
|
> div {
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,6 @@
|
||||||
<div class="focus-mark"></div>
|
<div class="focus-mark"></div>
|
||||||
<div class="mark"></div>
|
<div class="mark"></div>
|
||||||
</div>
|
</div>
|
||||||
<span translate>
|
<div translate>
|
||||||
{{::$ctrl.label}}
|
{{::$ctrl.label}}
|
||||||
</span>
|
</div>
|
|
@ -0,0 +1,26 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('freightCost', {
|
||||||
|
description: 'Returns the freight cost of a ticket',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: {
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'ticket id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
type: 'Number',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/freightCost`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.freightCost = async ticketFk => {
|
||||||
|
const [freightCost] = await Self.rawSql(`SELECT vn.ticket_getFreightCost(?) total`, [ticketFk]);
|
||||||
|
return freightCost.total;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,53 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getComponentsSum', {
|
||||||
|
description: 'Returns a list of component and their sum from a ticket',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: {
|
||||||
|
arg: 'id',
|
||||||
|
type: 'number',
|
||||||
|
required: true,
|
||||||
|
description: 'ticket id',
|
||||||
|
http: {source: 'path'}
|
||||||
|
},
|
||||||
|
returns: {
|
||||||
|
type: 'Number',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/:id/getComponentsSum`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Self.getComponentsSum = async id => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
let salesComponents = [];
|
||||||
|
let componentsSum = [];
|
||||||
|
let sales = await models.Sale.find({where: {ticketFk: id}});
|
||||||
|
let components = await models.Component.find();
|
||||||
|
if (sales.length > 0) {
|
||||||
|
for (let sale of sales) {
|
||||||
|
let myComponents = await models.SaleComponent.find({where: {saleFk: sale.id}});
|
||||||
|
salesComponents = salesComponents.concat(myComponents);
|
||||||
|
}
|
||||||
|
|
||||||
|
salesComponents.reduce((acumulator, currentValue) => {
|
||||||
|
if (!acumulator[currentValue.componentFk]) {
|
||||||
|
let defaultValue = 0;
|
||||||
|
let tarjetComponent = components.find(component => component.id === currentValue.componentFk);
|
||||||
|
|
||||||
|
acumulator[currentValue.componentFk] = {
|
||||||
|
componentFk: currentValue.componentFk,
|
||||||
|
value: defaultValue,
|
||||||
|
name: tarjetComponent.name
|
||||||
|
};
|
||||||
|
componentsSum.push(acumulator[currentValue.componentFk]);
|
||||||
|
}
|
||||||
|
|
||||||
|
acumulator[currentValue.componentFk].value += currentValue.value;
|
||||||
|
|
||||||
|
return acumulator;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return componentsSum;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,17 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('ticket freightCost()', () => {
|
||||||
|
it('should return the freight cost of a given ticket', async() => {
|
||||||
|
let ticketId = 7;
|
||||||
|
let freightCost = await app.models.Ticket.freightCost(ticketId);
|
||||||
|
|
||||||
|
expect(freightCost).toBe(4);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null if the ticket does not exist', async() => {
|
||||||
|
let ticketId = 99;
|
||||||
|
let freightCost = await app.models.Ticket.freightCost(ticketId);
|
||||||
|
|
||||||
|
expect(freightCost).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
|
@ -0,0 +1,20 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('ticket getComponentsSum()', () => {
|
||||||
|
it('should get the list of component for the ticket sales', async() => {
|
||||||
|
const ticketId = 7;
|
||||||
|
const components = await app.models.Ticket.getComponentsSum(ticketId);
|
||||||
|
const length = components.length;
|
||||||
|
const anyComponent = components[Math.floor(Math.random() * Math.floor(length))];
|
||||||
|
|
||||||
|
expect(components.length).toBeGreaterThan(0);
|
||||||
|
expect(anyComponent.componentFk).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return 0 if the given ticket does not have sales', async() => {
|
||||||
|
const ticketWithoutSales = 21;
|
||||||
|
const components = await app.models.Ticket.getComponentsSum(ticketWithoutSales);
|
||||||
|
|
||||||
|
expect(components.length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
|
@ -30,6 +30,8 @@ module.exports = Self => {
|
||||||
require('../methods/ticket/deleteStowaway')(Self);
|
require('../methods/ticket/deleteStowaway')(Self);
|
||||||
require('../methods/ticket/sendSms')(Self);
|
require('../methods/ticket/sendSms')(Self);
|
||||||
require('../methods/ticket/isLocked')(Self);
|
require('../methods/ticket/isLocked')(Self);
|
||||||
|
require('../methods/ticket/freightCost')(Self);
|
||||||
|
require('../methods/ticket/getComponentsSum')(Self);
|
||||||
|
|
||||||
Self.observe('before save', async function(ctx) {
|
Self.observe('before save', async function(ctx) {
|
||||||
if (ctx.isNewInstance) return;
|
if (ctx.isNewInstance) return;
|
||||||
|
|
|
@ -3,27 +3,12 @@
|
||||||
data="ticketUpdateActions"
|
data="ticketUpdateActions"
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-card ng-show="::$ctrl.totalPriceDifference" class="vn-w-lg vn-pa-md vn-mb-md">
|
|
||||||
<h6
|
|
||||||
class="text-secondary"
|
|
||||||
style="font-weight: normal;"
|
|
||||||
translate>
|
|
||||||
Charge difference to
|
|
||||||
</h6>
|
|
||||||
<div ng-repeat="action in ticketUpdateActions">
|
|
||||||
<vn-radio
|
|
||||||
ng-model="$ctrl.ticket.option"
|
|
||||||
label="{{::action.description}}"
|
|
||||||
val={{::action.id}}>
|
|
||||||
</vn-radio>
|
|
||||||
</div>
|
|
||||||
</vn-card>
|
|
||||||
<vn-card class="vn-w-lg">
|
<vn-card class="vn-w-lg">
|
||||||
<vn-table>
|
<vn-table>
|
||||||
<vn-thead>
|
<vn-thead>
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th number>Item</vn-th>
|
<vn-th number>Item</vn-th>
|
||||||
<vn-th style="text-align:center">Description</vn-th>
|
<vn-th class="align-center">Description</vn-th>
|
||||||
<vn-th number>Quantity</vn-th>
|
<vn-th number>Quantity</vn-th>
|
||||||
<vn-th number>Price (PPU)</vn-th>
|
<vn-th number>Price (PPU)</vn-th>
|
||||||
<vn-th number>New (PPU)</vn-th>
|
<vn-th number>New (PPU)</vn-th>
|
||||||
|
@ -51,10 +36,31 @@
|
||||||
<vn-td></vn-td>
|
<vn-td></vn-td>
|
||||||
<vn-td></vn-td>
|
<vn-td></vn-td>
|
||||||
<vn-td></vn-td>
|
<vn-td></vn-td>
|
||||||
<vn-td number><strong>{{$ctrl.totalPrice | currency: 'EUR': 2}}</strong></vn-td>
|
|
||||||
<vn-td number><strong>{{$ctrl.totalNewPrice | currency: 'EUR': 2}}</strong></vn-td>
|
|
||||||
<vn-td number><strong>{{$ctrl.totalPriceDifference | currency: 'EUR': 2}}</strong></vn-td>
|
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-tfoot>
|
</vn-tfoot>
|
||||||
</vn-table>
|
</vn-table>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
|
<vn-side-menu side="right">
|
||||||
|
<div class="vn-pa-md">
|
||||||
|
<div class="totalBox align-left">
|
||||||
|
<h6 class="align-center" translate>Total</h6>
|
||||||
|
<div> <vn-label translate>Price</vn-label> {{$ctrl.totalPrice | currency: 'EUR': 2}} </div>
|
||||||
|
<div> <vn-label translate>New price</vn-label> {{$ctrl.totalNewPrice | currency: 'EUR': 2}} </div>
|
||||||
|
<div> <vn-label translate>Difference</vn-label> {{$ctrl.totalPriceDifference | currency: 'EUR': 2}} </div>
|
||||||
|
</div>
|
||||||
|
<vn-card ng-show="::$ctrl.totalPriceDifference">
|
||||||
|
<div class="totalBox align-left" >
|
||||||
|
<h6 class="align-center" translate>Charge difference to</h6>
|
||||||
|
<div ng-repeat="action in ticketUpdateActions">
|
||||||
|
<vn-radio
|
||||||
|
ng-model="$ctrl.ticket.option"
|
||||||
|
label="{{::action.description}}"
|
||||||
|
val={{::action.id}}>
|
||||||
|
</vn-radio>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</vn-card>
|
||||||
|
</div>
|
||||||
|
</vn-side-menu>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import ngModule from '../../module';
|
import ngModule from '../../module';
|
||||||
import Component from 'core/lib/component';
|
import Component from 'core/lib/component';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
class Controller extends Component {
|
class Controller extends Component {
|
||||||
$onInit() {
|
$onInit() {
|
||||||
|
|
|
@ -3,3 +3,6 @@ New (PPU): Nuevo (Ud.)
|
||||||
Difference: Diferencia
|
Difference: Diferencia
|
||||||
Charge difference to: Cargar diferencia a
|
Charge difference to: Cargar diferencia a
|
||||||
The ticket has been unrouted: El ticket ha sido desenrutado
|
The ticket has been unrouted: El ticket ha sido desenrutado
|
||||||
|
Price: Precio
|
||||||
|
New price: Nuevo precio
|
||||||
|
Price difference: Diferencia de precio
|
|
@ -0,0 +1,9 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center
|
||||||
|
}
|
|
@ -7,9 +7,6 @@
|
||||||
auto-load="true">
|
auto-load="true">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-data-viewer model="model" class="vn-w-xl">
|
<vn-data-viewer model="model" class="vn-w-xl">
|
||||||
<vn-card class="vn-pa-lg text-right" name="base-sum">
|
|
||||||
<span translate>Base to commission</span> {{$ctrl.base() | currency: 'EUR':3}}
|
|
||||||
</vn-card>
|
|
||||||
<vn-card class="vn-mt-md">
|
<vn-card class="vn-mt-md">
|
||||||
<table class="vn-table">
|
<table class="vn-table">
|
||||||
<thead>
|
<thead>
|
||||||
|
@ -24,7 +21,7 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody ng-repeat="sale in components track by sale.id">
|
<tbody ng-repeat="sale in components track by sale.id">
|
||||||
<tr style="height: initial;">
|
<tr class="initial">
|
||||||
<td rowspan="{{::sale.components.length + 1}}" number>
|
<td rowspan="{{::sale.components.length + 1}}" number>
|
||||||
<span
|
<span
|
||||||
ng-click="descriptor.show($event, sale.itemFk, sale.id)"
|
ng-click="descriptor.show($event, sale.itemFk, sale.id)"
|
||||||
|
@ -64,6 +61,25 @@
|
||||||
</table>
|
</table>
|
||||||
</vn-card>
|
</vn-card>
|
||||||
</vn-data-viewer>
|
</vn-data-viewer>
|
||||||
|
<vn-side-menu side="right">
|
||||||
|
<div class="totalBox align-left">
|
||||||
|
<h6 class="align-center" translate>Total</h6>
|
||||||
|
<div> <vn-label translate>Base to commission</vn-label> {{$ctrl.base() | currency: 'EUR':2}} </div>
|
||||||
|
<div> <vn-label translate>Total without VAT</vn-label> {{$ctrl.getTotal() | currency: 'EUR': 3}} </div>
|
||||||
|
</div>
|
||||||
|
<div class="totalBox align-left">
|
||||||
|
<h6 class="align-center" translate>Components</h6>
|
||||||
|
<section ng-repeat="component in $ctrl.componentsList">
|
||||||
|
<div>
|
||||||
|
<vn-label>{{component.name}}</vn-label> {{component.value | currency: 'EUR': 3}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<div class="totalBox align-left">
|
||||||
|
<h6 class="align-center" translate>Theorical cost</h6>
|
||||||
|
<div> <vn-label translate>Price</vn-label> {{$ctrl.theoricalCost | currency: 'EUR': 2}} </div>
|
||||||
|
</div>
|
||||||
|
</vn-side-menu>
|
||||||
<vn-item-descriptor-popover
|
<vn-item-descriptor-popover
|
||||||
vn-id="descriptor"
|
vn-id="descriptor"
|
||||||
warehouse-fk="$ctrl.ticket.warehouseFk">
|
warehouse-fk="$ctrl.ticket.warehouseFk">
|
||||||
|
|
|
@ -29,11 +29,22 @@ class Controller extends Section {
|
||||||
}]
|
}]
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
get ticket() {
|
||||||
|
return this._ticket;
|
||||||
|
}
|
||||||
|
|
||||||
|
set ticket(value) {
|
||||||
|
this._ticket = value;
|
||||||
|
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
|
this.getTheoricalCost();
|
||||||
|
this.getComponentsSum();
|
||||||
|
}
|
||||||
|
|
||||||
base() {
|
base() {
|
||||||
let sales = this.$.model.data;
|
let sales = this.$.model.data;
|
||||||
let sum = 0;
|
let sum = 0;
|
||||||
|
|
||||||
if (!sales) return;
|
if (!sales) return;
|
||||||
|
|
||||||
for (let sale of sales) {
|
for (let sale of sales) {
|
||||||
|
@ -42,9 +53,29 @@ class Controller extends Section {
|
||||||
sum += sale.quantity * saleComponent.value;
|
sum += sale.quantity * saleComponent.value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getTotal() {
|
||||||
|
const sales = this.$.model.data;
|
||||||
|
let total = 0;
|
||||||
|
if (!sales) return;
|
||||||
|
for (let sale of sales) {
|
||||||
|
for (let saleComponent of sale.components)
|
||||||
|
total += sale.quantity * saleComponent.value;
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
getTheoricalCost() {
|
||||||
|
this.$http.get(`Tickets/${this.ticket.id}/freightCost`)
|
||||||
|
.then(res => this.theoricalCost = res.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
getComponentsSum() {
|
||||||
|
this.$http.get(`Tickets/${this.ticket.id}/getComponentsSum`)
|
||||||
|
.then(res => this.componentsList = res.data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnTicketComponents', {
|
ngModule.vnComponent('vnTicketComponents', {
|
||||||
|
|
|
@ -4,76 +4,72 @@ import crudModel from 'core/mocks/crud-model';
|
||||||
describe('ticket', () => {
|
describe('ticket', () => {
|
||||||
describe('Component vnTicketComponents', () => {
|
describe('Component vnTicketComponents', () => {
|
||||||
let controller;
|
let controller;
|
||||||
|
let $httpBackend;
|
||||||
|
|
||||||
beforeEach(ngModule('ticket'));
|
beforeEach(ngModule('ticket'));
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope, $state) => {
|
beforeEach(inject(($componentController, $rootScope, $state, _$httpBackend_) => {
|
||||||
$state.params.id = '1';
|
$state.params.id = '1';
|
||||||
let $scope = $rootScope.$new();
|
let $scope = $rootScope.$new();
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
$scope.model = crudModel;
|
$scope.model = crudModel;
|
||||||
$scope.model.data = [{
|
$scope.model.data = [{
|
||||||
|
quantity: 1,
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
|
value: 5,
|
||||||
component: {
|
component: {
|
||||||
name: 'valor de compra',
|
|
||||||
componentType: {
|
componentType: {
|
||||||
isBase: 1
|
isBase: 1
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
value: 5
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
value: 5,
|
||||||
component: {
|
component: {
|
||||||
name: 'reparto',
|
|
||||||
componentType: {
|
componentType: {
|
||||||
isBase: 0
|
isBase: 0
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
value: 5
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
value: 5,
|
||||||
component: {
|
component: {
|
||||||
name: 'recobro',
|
|
||||||
componentType: {
|
componentType: {
|
||||||
isBase: 0
|
isBase: 0
|
||||||
}
|
}
|
||||||
},
|
|
||||||
value: 5
|
|
||||||
}
|
}
|
||||||
],
|
}
|
||||||
quantity: 1
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
quantity: 5,
|
||||||
components: [
|
components: [
|
||||||
{
|
{
|
||||||
|
value: 1,
|
||||||
component: {
|
component: {
|
||||||
name: 'valor de compra',
|
|
||||||
componentType: {
|
componentType: {
|
||||||
isBase: 1
|
isBase: 1
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
value: 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
value: 1,
|
||||||
component: {
|
component: {
|
||||||
name: 'reparto',
|
|
||||||
componentType: {
|
componentType: {
|
||||||
isBase: 0
|
isBase: 0
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
value: 1
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
value: 1,
|
||||||
component: {
|
component: {
|
||||||
name: 'recobro',
|
|
||||||
componentType: {
|
componentType: {
|
||||||
isBase: 0
|
isBase: 0
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
value: 1
|
]
|
||||||
},
|
|
||||||
],
|
|
||||||
quantity: 5
|
|
||||||
}];
|
}];
|
||||||
const $element = angular.element('<vn-ticket-components></vn-ticket-components>');
|
const $element = angular.element('<vn-ticket-components></vn-ticket-components>');
|
||||||
controller = $componentController('vnTicketComponents', {$element, $scope});
|
controller = $componentController('vnTicketComponents', {$element, $scope});
|
||||||
|
@ -86,5 +82,55 @@ describe('ticket', () => {
|
||||||
expect(result).toEqual(10);
|
expect(result).toEqual(10);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('ticket setter', () => {
|
||||||
|
it('should set the ticket data and then call getTheoricalCost() and getComponentsSum()', () => {
|
||||||
|
jest.spyOn(controller, 'getTheoricalCost');
|
||||||
|
jest.spyOn(controller, 'getComponentsSum');
|
||||||
|
controller._ticket = undefined;
|
||||||
|
controller.ticket = {
|
||||||
|
id: 7
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(controller.ticket).toBeDefined();
|
||||||
|
expect(controller.getTheoricalCost).toHaveBeenCalledWith();
|
||||||
|
expect(controller.getComponentsSum).toHaveBeenCalledWith();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTotal()', () => {
|
||||||
|
it('should return the total sum of a ticket', () => {
|
||||||
|
let result = controller.getTotal();
|
||||||
|
|
||||||
|
expect(result).toEqual(30);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getTheoricalCost()', () => {
|
||||||
|
it('should make a request to get the theorical cost of a ticket', () => {
|
||||||
|
controller._ticket = {
|
||||||
|
id: 7
|
||||||
|
};
|
||||||
|
$httpBackend.expect('GET', `Tickets/${controller._ticket.id}/freightCost`).respond('My freight cost');
|
||||||
|
controller.getTheoricalCost();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.theoricalCost).toBe('My freight cost');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getComponentsSum()', () => {
|
||||||
|
it('should make a request to get the component list', () => {
|
||||||
|
controller._ticket = {
|
||||||
|
id: 7
|
||||||
|
};
|
||||||
|
|
||||||
|
$httpBackend.expect('GET', `Tickets/${controller._ticket.id}/getComponentsSum`).respond('My component list');
|
||||||
|
controller.getComponentsSum();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.componentsList).toBe('My component list');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Theorical cost: Porte teorico
|
||||||
|
Total without VAT: Total sin IVA
|
|
@ -24,4 +24,19 @@ vn-ticket-components {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.totalBox {
|
||||||
|
max-width: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-left {
|
||||||
|
text-align: left
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
text-align: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.initial {
|
||||||
|
height: initial
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue