changes to percentage filter
gitea/salix/2008-item_buyer_waste_detail This commit looks good
Details
gitea/salix/2008-item_buyer_waste_detail This commit looks good
Details
This commit is contained in:
parent
1307f6c5fb
commit
2b2e6532f6
|
@ -1,30 +0,0 @@
|
||||||
USE `bs`;
|
|
||||||
DROP procedure IF EXISTS `waste_getDetail`;
|
|
||||||
|
|
||||||
DELIMITER $$
|
|
||||||
USE `bs`$$
|
|
||||||
CREATE DEFINER=`root`@`%`PROCEDURE `waste_getDetail` ()
|
|
||||||
BEGIN
|
|
||||||
DECLARE vWeek INT;
|
|
||||||
DECLARE vYear INT;
|
|
||||||
|
|
||||||
SELECT week, year
|
|
||||||
INTO vWeek, vYear
|
|
||||||
FROM vn.time
|
|
||||||
WHERE dated = CURDATE();
|
|
||||||
|
|
||||||
SELECT *, 100 * dwindle / total AS percentage
|
|
||||||
FROM (
|
|
||||||
SELECT buyer,
|
|
||||||
ws.family,
|
|
||||||
sum(ws.saleTotal) AS total,
|
|
||||||
sum(ws.saleWaste) AS dwindle
|
|
||||||
FROM bs.waste ws
|
|
||||||
WHERE `year` = vYear AND `week` = vWeek
|
|
||||||
GROUP BY buyer, family
|
|
||||||
) sub
|
|
||||||
ORDER BY percentage DESC;
|
|
||||||
END$$
|
|
||||||
|
|
||||||
DELIMITER ;
|
|
||||||
|
|
|
@ -1135,6 +1135,19 @@ INSERT INTO `bi`.`claims_ratio`(`id_Cliente`, `Consumo`, `Reclamaciones`, `Ratio
|
||||||
(103, 2000, 0.00, 0.00, 0.02, 1.00),
|
(103, 2000, 0.00, 0.00, 0.02, 1.00),
|
||||||
(104, 2500, 150.00, 0.02, 0.10, 1.00);
|
(104, 2500, 150.00, 0.02, 0.10, 1.00);
|
||||||
|
|
||||||
|
INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `saleTotal`, `saleWaste`, `rate`)
|
||||||
|
VALUES
|
||||||
|
('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Clavel', '1062', '51', '4.8'),
|
||||||
|
('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Clavel Colombia', '35074', '687', '2.0'),
|
||||||
|
('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Clavel Mini', '1777', '13', '0.7'),
|
||||||
|
('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Clavel Short', '9182', '59', '0.6'),
|
||||||
|
('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Contenedores', '-74', '0', '0.0'),
|
||||||
|
('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Embalajes', '-7', '0', '0.0'),
|
||||||
|
('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Portes', '1100', '0', '0.0'),
|
||||||
|
('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Accesorios Funerarios', '848', '-187', '-22.1'),
|
||||||
|
('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Accesorios Varios', '186', '0', '0.0'),
|
||||||
|
('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Adhesivos', '277', '0', '0.0');
|
||||||
|
|
||||||
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`minPrice`,`producer`,`printedStickers`,`isChecked`,`isIgnored`, `created`)
|
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`minPrice`,`producer`,`printedStickers`,`isChecked`,`isIgnored`, `created`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
||||||
|
|
|
@ -29,7 +29,7 @@ describe('Ticket List sale path', () => {
|
||||||
const value = await nightmare
|
const value = await nightmare
|
||||||
.waitToGetProperty(selectors.ticketSales.firstSaleDiscount, 'innerText');
|
.waitToGetProperty(selectors.ticketSales.firstSaleDiscount, 'innerText');
|
||||||
|
|
||||||
expect(value).toContain('0 %');
|
expect(value).toContain('0.00%');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the first sale contains the total import', async() => {
|
it('should confirm the first sale contains the total import', async() => {
|
||||||
|
|
|
@ -173,10 +173,10 @@ xdescribe('Ticket Edit sale path', () => {
|
||||||
|
|
||||||
it('should confirm the discount have been updated', async() => {
|
it('should confirm the discount have been updated', async() => {
|
||||||
const result = await nightmare
|
const result = await nightmare
|
||||||
.waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50 %')
|
.waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50.00%')
|
||||||
.waitToGetProperty(`${selectors.ticketSales.firstSaleDiscount} > span`, 'innerText');
|
.waitToGetProperty(`${selectors.ticketSales.firstSaleDiscount} > span`, 'innerText');
|
||||||
|
|
||||||
expect(result).toContain('50 %');
|
expect(result).toContain('50.00%');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should confirm the total import for that item have been updated', async() => {
|
it('should confirm the total import for that item have been updated', async() => {
|
||||||
|
|
|
@ -1,15 +1,22 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
|
|
||||||
/**
|
export default function percentage($translate) {
|
||||||
* Formats a number multiplying by 100 and adding character %.
|
function percentage(input, fractionSize = 2) {
|
||||||
*
|
|
||||||
* @return {String} The formated number
|
|
||||||
*/
|
|
||||||
export default function percentage() {
|
|
||||||
return function(input) {
|
|
||||||
if (input == null || input === '')
|
if (input == null || input === '')
|
||||||
return null;
|
return null;
|
||||||
return `${input} %`;
|
|
||||||
};
|
return new Intl.NumberFormat($translate.use(), {
|
||||||
|
style: 'percent',
|
||||||
|
minimumFractionDigits: fractionSize,
|
||||||
|
maximumFractionDigits: fractionSize
|
||||||
|
}).format(parseFloat(input));
|
||||||
|
}
|
||||||
|
|
||||||
|
percentage.$stateful = true;
|
||||||
|
|
||||||
|
return percentage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
percentage.$inject = ['$translate'];
|
||||||
|
|
||||||
ngModule.filter('percentage', percentage);
|
ngModule.filter('percentage', percentage);
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('getWasteDetail', {
|
||||||
|
description: 'Returns the ',
|
||||||
|
accessType: 'READ',
|
||||||
|
accepts: [],
|
||||||
|
returns: {
|
||||||
|
type: ['Object'],
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/getWasteDetail`,
|
||||||
|
verb: 'GET'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.getWasteDetail = async() => {
|
||||||
|
const wastes = await Self.rawSql(`
|
||||||
|
SELECT *, 100 * dwindle / total AS percentage
|
||||||
|
FROM (
|
||||||
|
SELECT buyer,
|
||||||
|
ws.family,
|
||||||
|
sum(ws.saleTotal) AS total,
|
||||||
|
sum(ws.saleWaste) AS dwindle
|
||||||
|
FROM bs.waste ws
|
||||||
|
WHERE year = YEAR(CURDATE()) AND week = WEEK(CURDATE(), 1)
|
||||||
|
GROUP BY buyer, family
|
||||||
|
) sub
|
||||||
|
ORDER BY percentage DESC;`);
|
||||||
|
|
||||||
|
const details = [];
|
||||||
|
|
||||||
|
for (let waste of wastes) {
|
||||||
|
const buyerName = waste.buyer;
|
||||||
|
|
||||||
|
let buyerDetail = details.find(waste => {
|
||||||
|
return waste.buyer == buyerName;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!buyerDetail) {
|
||||||
|
buyerDetail = {
|
||||||
|
buyer: buyerName,
|
||||||
|
lines: []
|
||||||
|
};
|
||||||
|
details.push(buyerDetail);
|
||||||
|
}
|
||||||
|
|
||||||
|
buyerDetail.lines.push(waste);
|
||||||
|
}
|
||||||
|
|
||||||
|
return details;
|
||||||
|
};
|
||||||
|
};
|
|
@ -0,0 +1,23 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
|
||||||
|
describe('item getWasteDetail()', () => {
|
||||||
|
it('should check for the waste breakdown for every worker', async() => {
|
||||||
|
let result = await app.models.Item.getWasteDetail();
|
||||||
|
|
||||||
|
const firstBuyer = result[0].buyer;
|
||||||
|
const firstBuyerLines = result[0].lines;
|
||||||
|
const secondBuyer = result[1].buyer;
|
||||||
|
const secondBuyerLines = result[1].lines;
|
||||||
|
const thirdBuyer = result[2].buyer;
|
||||||
|
const thirdBuyerLines = result[2].lines;
|
||||||
|
|
||||||
|
expect(result.length).toEqual(3);
|
||||||
|
expect(firstBuyer).toEqual('CharlesXavier');
|
||||||
|
expect(firstBuyerLines.length).toEqual(4);
|
||||||
|
expect(secondBuyer).toEqual('DavidCharlesHaller');
|
||||||
|
expect(secondBuyerLines.length).toEqual(3);
|
||||||
|
|
||||||
|
expect(thirdBuyer).toEqual('HankPym');
|
||||||
|
expect(thirdBuyerLines.length).toEqual(3);
|
||||||
|
});
|
||||||
|
});
|
|
@ -11,6 +11,7 @@ module.exports = Self => {
|
||||||
require('../methods/item/regularize')(Self);
|
require('../methods/item/regularize')(Self);
|
||||||
require('../methods/item/getVisibleAvailable')(Self);
|
require('../methods/item/getVisibleAvailable')(Self);
|
||||||
require('../methods/item/new')(Self);
|
require('../methods/item/new')(Self);
|
||||||
|
require('../methods/item/getWasteDetail')(Self);
|
||||||
|
|
||||||
Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'});
|
Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'});
|
||||||
|
|
||||||
|
|
|
@ -61,3 +61,4 @@ Diary: Histórico
|
||||||
Item diary: Registro de compra-venta
|
Item diary: Registro de compra-venta
|
||||||
Last entries: Últimas entradas
|
Last entries: Últimas entradas
|
||||||
Tags: Etiquetas
|
Tags: Etiquetas
|
||||||
|
Waste breakdown: Desglose de mermas
|
|
@ -7,7 +7,8 @@
|
||||||
"menus": {
|
"menus": {
|
||||||
"main": [
|
"main": [
|
||||||
{"state": "item.index", "icon": "icon-item"},
|
{"state": "item.index", "icon": "icon-item"},
|
||||||
{"state": "item.request", "icon": "pan_tool"}
|
{"state": "item.request", "icon": "pan_tool"},
|
||||||
|
{"state": "item.waste", "icon": "icon-claims"}
|
||||||
],
|
],
|
||||||
"card": [
|
"card": [
|
||||||
{"state": "item.card.basicData", "icon": "settings"},
|
{"state": "item.card.basicData", "icon": "settings"},
|
||||||
|
@ -141,11 +142,8 @@
|
||||||
"url" : "/waste",
|
"url" : "/waste",
|
||||||
"state": "item.waste",
|
"state": "item.waste",
|
||||||
"component": "vn-item-waste",
|
"component": "vn-item-waste",
|
||||||
"description": "Waste",
|
"description": "Waste breakdown",
|
||||||
"params": {
|
"acl": ["buyer"]
|
||||||
"item": "$ctrl.item"
|
|
||||||
},
|
|
||||||
"acl": ["employee"]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
|
@ -1,120 +1,32 @@
|
||||||
<vn-crud-model auto-load="true"
|
<vn-crud-model auto-load="true"
|
||||||
vn-id="model"
|
vn-id="model"
|
||||||
url="Items/filter"
|
url="Items/getWasteDetail"
|
||||||
limit="20"
|
data="details">
|
||||||
data="requests"
|
|
||||||
order="shipped DESC, isOk ASC">
|
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-data-viewer model="model">
|
<vn-data-viewer model="model">
|
||||||
<vn-card>
|
<vn-card>
|
||||||
<vn-table model="model">
|
<section ng-repeat="detail in details" class="vn-pa-md">
|
||||||
<vn-thead>
|
<vn-horizontal class="header">
|
||||||
<vn-tr>
|
<h5><span translate>{{detail.buyer}}</span></h5>
|
||||||
<vn-th field="buer" number>Buyer</vn-th>
|
</vn-horizontal>
|
||||||
<vn-th field="family">Family</vn-th>
|
<vn-table>
|
||||||
<vn-th field="percentage">Percentage</vn-th>
|
<vn-thead>
|
||||||
<vn-th field="salesPersonNickname">Mermas</vn-th>
|
<vn-tr>
|
||||||
<vn-th field="total">Total</vn-th>
|
<vn-th>Family</vn-th>
|
||||||
</vn-tr>
|
<vn-th shrink>Percentage</vn-th>
|
||||||
</vn-thead>
|
<vn-th number>Dwindle</vn-th>
|
||||||
<vn-tbody>
|
<vn-th number>Total</vn-th>
|
||||||
<vn-tr ng-repeat="request in requests">
|
</vn-tr>
|
||||||
<vn-td number>
|
</vn-thead>
|
||||||
<span class="link"
|
<vn-tbody>
|
||||||
ng-click="$ctrl.showTicketDescriptor($event, request.ticketFk)">
|
<vn-tr ng-repeat="waste in detail.lines">
|
||||||
{{request.ticketFk}}
|
<vn-td>{{::waste.family}}</vn-td>
|
||||||
</span>
|
<vn-td shrink>{{::(waste.percentage / 100) | percentage: 2}}</vn-td>
|
||||||
</vn-td>
|
<vn-td number>{{::waste.dwindle | currency: 'EUR'}}</vn-td>
|
||||||
<vn-td>
|
<vn-td number>{{::waste.total | currency: 'EUR'}}</vn-td>
|
||||||
<span title="{{::request.shipped | date: 'dd/MM/yyyy'}}"
|
</vn-tr>
|
||||||
class="chip {{$ctrl.compareDate(request.shipped)}}">
|
</vn-tbody>
|
||||||
{{::request.shipped | date: 'dd/MM/yyyy'}}
|
</vn-table>
|
||||||
</span>
|
</section>
|
||||||
</vn-td>
|
|
||||||
<vn-td>{{::request.warehouse}}</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<span
|
|
||||||
class="link"
|
|
||||||
ng-click="$ctrl.showWorkerDescriptor($event, request.salesPersonFk)">
|
|
||||||
{{::request.salesPersonNickname}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td title="{{::request.description}}">{{::request.description}}</vn-td>
|
|
||||||
<vn-td number>{{::request.quantity}}</vn-td>
|
|
||||||
<vn-td number>{{::request.price | currency: 'EUR':2}}</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<span
|
|
||||||
class="link"
|
|
||||||
ng-click="$ctrl.showWorkerDescriptor($event, request.attenderFk)">
|
|
||||||
{{::request.atenderNickname}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td-editable disabled="request.isOk != null" number>
|
|
||||||
<text>{{request.itemFk}}</text>
|
|
||||||
<field>
|
|
||||||
<vn-input-number class="dense" vn-focus
|
|
||||||
ng-model="request.itemFk">
|
|
||||||
</vn-input-number>
|
|
||||||
</field>
|
|
||||||
</vn-td-editable>
|
|
||||||
<vn-td-editable disabled="!request.itemFk || request.isOk != null" number>
|
|
||||||
<text number>{{request.saleQuantity}}</text>
|
|
||||||
<field>
|
|
||||||
<vn-input-number class="dense" vn-focus
|
|
||||||
ng-model="request.saleQuantity"
|
|
||||||
on-change="$ctrl.changeQuantity(request)">
|
|
||||||
</vn-input-number>
|
|
||||||
</field>
|
|
||||||
</vn-td-editable>
|
|
||||||
<vn-td>
|
|
||||||
<span
|
|
||||||
class="link"
|
|
||||||
ng-click="$ctrl.showItemDescriptor($event, request.itemFk)"
|
|
||||||
title="{{request.itemDescription}}">
|
|
||||||
{{request.itemDescription}}
|
|
||||||
</span>
|
|
||||||
</vn-td>
|
|
||||||
<vn-td>{{$ctrl.getState(request.isOk)}}</vn-td>
|
|
||||||
<vn-td>
|
|
||||||
<vn-icon
|
|
||||||
ng-if="request.response.length"
|
|
||||||
ranslate-attr="{title: request.response}"
|
|
||||||
icon="insert_drive_file">
|
|
||||||
</vn-icon>
|
|
||||||
<vn-icon-button
|
|
||||||
ng-if="request.isOk != 0"
|
|
||||||
icon="thumb_down"
|
|
||||||
ng-click="$ctrl.showDenyReason($event, request)"
|
|
||||||
translate-attr="{title: 'Discard'}">
|
|
||||||
</vn-icon-button>
|
|
||||||
</vn-td>
|
|
||||||
</vn-tr>
|
|
||||||
</vn-tbody>
|
|
||||||
</vn-table>
|
|
||||||
</vn-card>
|
</vn-card>
|
||||||
</vn-data-viewer>
|
</vn-data-viewer>
|
||||||
<vn-worker-descriptor-popover
|
|
||||||
vn-id="workerDescriptor">
|
|
||||||
</vn-worker-descriptor-popover>
|
|
||||||
<vn-ticket-descriptor-popover
|
|
||||||
vn-id="ticketDescriptor">
|
|
||||||
</vn-ticket-descriptor-popover>
|
|
||||||
<vn-item-descriptor-popover
|
|
||||||
vn-id="itemDescriptor">
|
|
||||||
</vn-item-descriptor-popover>
|
|
||||||
<vn-dialog
|
|
||||||
vn-id="denyReason"
|
|
||||||
on-response="$ctrl.denyRequest($response)">
|
|
||||||
<tpl-body>
|
|
||||||
<h5 class="vn-pa-md" translate>Specify the reasons to deny this request</h5>
|
|
||||||
<vn-horizontal class="vn-pa-md">
|
|
||||||
<vn-textarea
|
|
||||||
ng-model="$ctrl.denyObservation">
|
|
||||||
</vn-textarea>
|
|
||||||
</vn-horizontal>
|
|
||||||
</tpl-body>
|
|
||||||
<tpl-buttons>
|
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
|
||||||
<button response="accept" translate>Save</button>
|
|
||||||
</tpl-buttons>
|
|
||||||
</vn-dialog>
|
|
|
@ -2,11 +2,7 @@ import ngModule from '../module';
|
||||||
import Component from 'core/lib/component';
|
import Component from 'core/lib/component';
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
export default class Controller extends Component {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
ngModule.component('vnItemWaste', {
|
ngModule.component('vnItemWaste', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller
|
controller: Component
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,133 +0,0 @@
|
||||||
import './index.js';
|
|
||||||
import crudModel from 'core/mocks/crud-model';
|
|
||||||
|
|
||||||
describe('Item', () => {
|
|
||||||
describe('Component vnItemRequest', () => {
|
|
||||||
let $scope;
|
|
||||||
let $element;
|
|
||||||
let controller;
|
|
||||||
let $httpBackend;
|
|
||||||
|
|
||||||
beforeEach(ngModule('item'));
|
|
||||||
|
|
||||||
beforeEach(angular.mock.inject(($componentController, $rootScope, _$httpBackend_) => {
|
|
||||||
$httpBackend = _$httpBackend_;
|
|
||||||
$scope = $rootScope.$new();
|
|
||||||
$scope.model = crudModel;
|
|
||||||
$scope.denyReason = {hide: () => {}};
|
|
||||||
$element = angular.element('<vn-item-request></vn-item-request>');
|
|
||||||
controller = $componentController('vnItemRequest', {$element, $scope});
|
|
||||||
}));
|
|
||||||
|
|
||||||
afterAll(() => {
|
|
||||||
$scope.$destroy();
|
|
||||||
$element.remove();
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('getState()', () => {
|
|
||||||
it(`should return an string depending to the isOK value`, () => {
|
|
||||||
let isOk = null;
|
|
||||||
let result = controller.getState(isOk);
|
|
||||||
|
|
||||||
expect(result).toEqual('Nueva');
|
|
||||||
|
|
||||||
isOk = 1;
|
|
||||||
result = controller.getState(isOk);
|
|
||||||
|
|
||||||
expect(result).toEqual('Aceptada');
|
|
||||||
|
|
||||||
isOk = 0;
|
|
||||||
result = controller.getState(isOk);
|
|
||||||
|
|
||||||
expect(result).toEqual('Denegada');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('confirmRequest()', () => {
|
|
||||||
it(`should do nothing if the request does't have itemFk or saleQuantity`, () => {
|
|
||||||
let request = {};
|
|
||||||
spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
|
|
||||||
controller.confirmRequest(request);
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).not.toHaveBeenCalledWith();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should perform a query and call vnApp.showSuccess() and refresh if the conditions are met', () => {
|
|
||||||
spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
let model = controller.$.model;
|
|
||||||
spyOn(model, 'refresh');
|
|
||||||
|
|
||||||
const expectedResult = {concept: 'Melee Weapon'};
|
|
||||||
let request = {itemFk: 1, saleQuantity: 1, id: 1};
|
|
||||||
|
|
||||||
$httpBackend.when('POST', `TicketRequests/${request.id}/confirm`).respond(expectedResult);
|
|
||||||
$httpBackend.expect('POST', `TicketRequests/${request.id}/confirm`).respond(expectedResult);
|
|
||||||
controller.confirmRequest(request);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('changeQuantity()', () => {
|
|
||||||
it(`should call confirmRequest() if there's no sale id in the request`, () => {
|
|
||||||
let request = {};
|
|
||||||
spyOn(controller, 'confirmRequest');
|
|
||||||
|
|
||||||
controller.changeQuantity(request);
|
|
||||||
|
|
||||||
expect(controller.confirmRequest).toHaveBeenCalledWith(jasmine.any(Object));
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should perform a query and call vnApp.showSuccess() if the conditions are met`, () => {
|
|
||||||
let request = {saleFk: 1, saleQuantity: 1};
|
|
||||||
spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
|
|
||||||
|
|
||||||
$httpBackend.when('PATCH', `Sales/${request.saleFk}/`).respond();
|
|
||||||
$httpBackend.expect('PATCH', `Sales/${request.saleFk}/`).respond();
|
|
||||||
controller.changeQuantity(request);
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('compareDate()', () => {
|
|
||||||
it(`should return "success" if receives a future date`, () => {
|
|
||||||
let date = '3019-02-18T11:00:00.000Z';
|
|
||||||
|
|
||||||
let result = controller.compareDate(date);
|
|
||||||
|
|
||||||
expect(result).toEqual('success');
|
|
||||||
});
|
|
||||||
|
|
||||||
it(`should return "warning" if date is today`, () => {
|
|
||||||
let date = new Date();
|
|
||||||
|
|
||||||
let result = controller.compareDate(date);
|
|
||||||
|
|
||||||
expect(result).toEqual('warning');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('denyRequest()', () => {
|
|
||||||
it(`should perform a query and call vnApp.showSuccess(), refresh(), hide() and set denyObservation to null in the controller`, () => {
|
|
||||||
spyOn(controller.vnApp, 'showSuccess');
|
|
||||||
|
|
||||||
const request = {id: 1};
|
|
||||||
const expectedResult = {isOk: false, attenderFk: 106, response: 'Denied!'};
|
|
||||||
controller.selectedRequest = request;
|
|
||||||
|
|
||||||
$httpBackend.when('POST', `TicketRequests/${request.id}/deny`).respond(expectedResult);
|
|
||||||
$httpBackend.expect('POST', `TicketRequests/${request.id}/deny`).respond(expectedResult);
|
|
||||||
controller.denyRequest('accept');
|
|
||||||
$httpBackend.flush();
|
|
||||||
|
|
||||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Data saved!');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
Discard: Descartar
|
Family: Familia
|
||||||
Specify the reasons to deny this request: Especifica las razones para descartar la petición
|
Percentage: Porcentaje
|
||||||
Buy requests: Peticiones de compra
|
Dwindle: Mermas
|
||||||
Search request by id or alias: Buscar peticiones por identificador o alias
|
|
||||||
Requested: Solicitado
|
|
||||||
Achieved: Conseguido
|
|
|
@ -1,18 +1,19 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
vn-item-request {
|
vn-item-waste {
|
||||||
vn-dialog[vn-id="denyReason"] {
|
.header {
|
||||||
button.close {
|
margin-bottom: 16px;
|
||||||
display: none
|
text-transform: uppercase;
|
||||||
}
|
font-size: 15pt;
|
||||||
vn-button {
|
line-height: 1;
|
||||||
margin: 0 auto
|
padding: 7px;
|
||||||
}
|
padding-bottom: 7px;
|
||||||
vn-textarea {
|
padding-bottom: 4px;
|
||||||
width: 100%
|
font-weight: lighter;
|
||||||
}
|
background-color: #fde6ca;
|
||||||
}
|
border-bottom: 0.1em solid #f7931e;
|
||||||
vn-icon[icon=insert_drive_file]{
|
white-space: nowrap;
|
||||||
color: $color-font-secondary;
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,5 +4,6 @@ module.exports = new Stylesheet([
|
||||||
`${appPath}/common/css/spacing.css`,
|
`${appPath}/common/css/spacing.css`,
|
||||||
`${appPath}/common/css/misc.css`,
|
`${appPath}/common/css/misc.css`,
|
||||||
`${appPath}/common/css/layout.css`,
|
`${appPath}/common/css/layout.css`,
|
||||||
`${appPath}/common/css/email.css`])
|
`${appPath}/common/css/email.css`,
|
||||||
|
`${__dirname}/style.css`])
|
||||||
.mergeStyles();
|
.mergeStyles();
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
.external-link {
|
||||||
|
border: 2px dashed #8dba25;
|
||||||
|
border-radius: 3px;
|
||||||
|
text-align: center
|
||||||
|
}
|
|
@ -49,8 +49,15 @@
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
<p v-html="$t('wasteDetailLink')"></p>
|
||||||
|
<div class="external-link vn-pa-sm vn-m-md">
|
||||||
|
<a href="https://salix.verdnatura.es/#!/item/waste" target="_blank">
|
||||||
|
https://salix.verdnatura.es/#!/item/waste
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Footer block -->
|
<!-- Footer block -->
|
||||||
<div class="grid-row">
|
<div class="grid-row">
|
||||||
<div class="grid-block">
|
<div class="grid-block">
|
||||||
|
|
|
@ -6,3 +6,4 @@ buyer: Comprador
|
||||||
percentage: Porcentaje
|
percentage: Porcentaje
|
||||||
weakening: Mermas
|
weakening: Mermas
|
||||||
total: Total
|
total: Total
|
||||||
|
wasteDetailLink: 'Para ver el desglose de mermas haz clic en el siguiente enlace:'
|
Loading…
Reference in New Issue