Merge branch '2008-item_buyer_waste_detail' of verdnatura/salix into dev
gitea/salix/dev This commit looks good
Details
gitea/salix/dev This commit looks good
Details
This commit is contained in:
commit
e1aefc795b
|
@ -1135,6 +1135,19 @@ INSERT INTO `bi`.`claims_ratio`(`id_Cliente`, `Consumo`, `Reclamaciones`, `Ratio
|
|||
(103, 2000, 0.00, 0.00, 0.02, 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), 'Carnation', '1062', '51', '4.8'),
|
||||
('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Carnation Colombia', '35074', '687', '2.0'),
|
||||
('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Carnation Mini', '1777', '13', '0.7'),
|
||||
('CharlesXavier', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Carnation Short', '9182', '59', '0.6'),
|
||||
('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Containers', '-74', '0', '0.0'),
|
||||
('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Packagings', '-7', '0', '0.0'),
|
||||
('DavidCharlesHaller', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Freight', '1100', '0', '0.0'),
|
||||
('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Funeral Accessories', '848', '-187', '-22.1'),
|
||||
('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Miscellaneous Accessories', '186', '0', '0.0'),
|
||||
('HankPym', YEAR(CURDATE()), WEEK(CURDATE(), 1), 'Adhesives', '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`)
|
||||
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)),
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -3,6 +3,7 @@
|
|||
SCHEMAS=(
|
||||
account
|
||||
bi
|
||||
bs
|
||||
cache
|
||||
edi
|
||||
hedera
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('Ticket List sale path', () => {
|
|||
const value = await nightmare
|
||||
.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() => {
|
||||
|
|
|
@ -173,10 +173,10 @@ xdescribe('Ticket Edit sale path', () => {
|
|||
|
||||
it('should confirm the discount have been updated', async() => {
|
||||
const result = await nightmare
|
||||
.waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50 %')
|
||||
.waitForTextInElement(`${selectors.ticketSales.firstSaleDiscount} > span`, '50.00%')
|
||||
.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() => {
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
import ngModule from '../module';
|
||||
|
||||
/**
|
||||
* Formats a number multiplying by 100 and adding character %.
|
||||
*
|
||||
* @return {String} The formated number
|
||||
*/
|
||||
export default function percentage() {
|
||||
return function(input) {
|
||||
export default function percentage($translate) {
|
||||
function percentage(input, fractionSize = 2) {
|
||||
if (input == null || input === '')
|
||||
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);
|
||||
|
|
|
@ -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/getVisibleAvailable')(Self);
|
||||
require('../methods/item/new')(Self);
|
||||
require('../methods/item/getWasteDetail')(Self);
|
||||
|
||||
Self.validatesPresenceOf('originFk', {message: 'Cannot be blank'});
|
||||
|
||||
|
|
|
@ -20,4 +20,5 @@ import './niche';
|
|||
import './botanical';
|
||||
import './barcode';
|
||||
import './summary';
|
||||
import './waste';
|
||||
|
||||
|
|
|
@ -60,4 +60,5 @@ Barcodes: Códigos de barras
|
|||
Diary: Histórico
|
||||
Item diary: Registro de compra-venta
|
||||
Last entries: Últimas entradas
|
||||
Tags: Etiquetas
|
||||
Tags: Etiquetas
|
||||
Waste breakdown: Desglose de mermas
|
|
@ -7,7 +7,8 @@
|
|||
"menus": {
|
||||
"main": [
|
||||
{"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": [
|
||||
{"state": "item.card.basicData", "icon": "settings"},
|
||||
|
@ -137,6 +138,12 @@
|
|||
"item": "$ctrl.item"
|
||||
},
|
||||
"acl": ["employee"]
|
||||
}, {
|
||||
"url" : "/waste",
|
||||
"state": "item.waste",
|
||||
"component": "vn-item-waste",
|
||||
"description": "Waste breakdown",
|
||||
"acl": ["buyer"]
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
<vn-crud-model auto-load="true"
|
||||
vn-id="model"
|
||||
url="Items/getWasteDetail"
|
||||
data="details">
|
||||
</vn-crud-model>
|
||||
<vn-data-viewer model="model">
|
||||
<vn-card>
|
||||
<section ng-repeat="detail in details" class="vn-pa-md">
|
||||
<vn-horizontal class="header">
|
||||
<h5><span translate>{{detail.buyer}}</span></h5>
|
||||
</vn-horizontal>
|
||||
<vn-table>
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th>Family</vn-th>
|
||||
<vn-th shrink>Percentage</vn-th>
|
||||
<vn-th number>Dwindle</vn-th>
|
||||
<vn-th number>Total</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<vn-tr ng-repeat="waste in detail.lines">
|
||||
<vn-td>{{::waste.family}}</vn-td>
|
||||
<vn-td shrink>{{::(waste.percentage / 100) | percentage: 2}}</vn-td>
|
||||
<vn-td number>{{::waste.dwindle | currency: 'EUR'}}</vn-td>
|
||||
<vn-td number>{{::waste.total | currency: 'EUR'}}</vn-td>
|
||||
</vn-tr>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</section>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
|
@ -0,0 +1,8 @@
|
|||
import ngModule from '../module';
|
||||
import Component from 'core/lib/component';
|
||||
import './style.scss';
|
||||
|
||||
ngModule.component('vnItemWaste', {
|
||||
template: require('./index.html'),
|
||||
controller: Component
|
||||
});
|
|
@ -0,0 +1,3 @@
|
|||
Family: Familia
|
||||
Percentage: Porcentaje
|
||||
Dwindle: Mermas
|
|
@ -0,0 +1,19 @@
|
|||
@import "variables";
|
||||
|
||||
vn-item-waste {
|
||||
.header {
|
||||
margin-bottom: 16px;
|
||||
text-transform: uppercase;
|
||||
font-size: 15pt;
|
||||
line-height: 1;
|
||||
padding: 7px;
|
||||
padding-bottom: 7px;
|
||||
padding-bottom: 4px;
|
||||
font-weight: lighter;
|
||||
background-color: #fde6ca;
|
||||
border-bottom: 0.1em solid #f7931e;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
}
|
|
@ -29,6 +29,6 @@ module.exports = Self => {
|
|||
if (!isEditable)
|
||||
throw new UserError(`The sales of this ticket can't be modified`);
|
||||
|
||||
return Self.rawSql('CALL vn.ticketCalculateSale(?)', [id]);
|
||||
return Self.rawSql('CALL vn.sale_calculateComponent(?, null)', [id]);
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,5 +4,6 @@ module.exports = new Stylesheet([
|
|||
`${appPath}/common/css/spacing.css`,
|
||||
`${appPath}/common/css/misc.css`,
|
||||
`${appPath}/common/css/layout.css`,
|
||||
`${appPath}/common/css/email.css`])
|
||||
`${appPath}/common/css/email.css`,
|
||||
`${__dirname}/style.css`])
|
||||
.mergeStyles();
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
.external-link {
|
||||
border: 2px dashed #8dba25;
|
||||
border-radius: 3px;
|
||||
text-align: center
|
||||
}
|
|
@ -49,8 +49,15 @@
|
|||
</tr>
|
||||
</tbody>
|
||||
</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>
|
||||
|
||||
<!-- Footer block -->
|
||||
<div class="grid-row">
|
||||
<div class="grid-block">
|
||||
|
|
|
@ -5,4 +5,5 @@ description: A continuación se muestra la merma semanal a fecha de <strong>{0}<
|
|||
buyer: Comprador
|
||||
percentage: Porcentaje
|
||||
weakening: Mermas
|
||||
total: Total
|
||||
total: Total
|
||||
wasteDetailLink: 'Para ver el desglose de mermas haz clic en el siguiente enlace:'
|
Loading…
Reference in New Issue