Merge pull request 'latestsBuys + e2e path' (#340) from 2341-Entry_lastBuy_section into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #340 Reviewed-by: Javi Gallego <jgallego@verdnatura.es>
This commit is contained in:
commit
1d73bba204
|
@ -0,0 +1,2 @@
|
|||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES ('Buy', '*', '*', 'ALLOW', 'ROLE', 'buyer');
|
|
@ -733,6 +733,39 @@ INSERT INTO `vn`.`intrastat`(`id`, `description`, `taxClassFk`, `taxCodeFk`)
|
|||
(05080000, 'Coral y materiales similares', 2, 2),
|
||||
(06021010, 'Plantas vivas: Esqueje/injerto, Vid', 1, 1);
|
||||
|
||||
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`, `minPrice`)
|
||||
VALUES
|
||||
(1, 2, 70, 'AMA', 1, 1, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 67, 1, NULL, 0),
|
||||
(2, 2, 70, 'AZL', 1, 2, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 66, 1, NULL, 0),
|
||||
(3, 1, 60, 'AMR', 1, 3, NULL, 1, 05080000, 0, 4751000000, 0, NULL, 0, 65, 1, NULL, 0),
|
||||
(4, 1, 60, 'AMR', 1, 1, 'Increases block', 1, 05080000, 1, 4751000000, 0, NULL, 0, 69, 2, NULL, 0),
|
||||
(5, 3, 30, 'GRE', 1, 2, NULL, 2, 06021010, 1, 4751000000, 0, NULL, 0, 74, 2, NULL, 0),
|
||||
(6, 5, 30, 'GRE', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 62, 2, NULL, 0),
|
||||
(7, 5, 90, 'AZL', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 64, 2, NULL, 0),
|
||||
(8, 2, 70, 'AMA', 1, 1, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 75, 1, NULL, 0),
|
||||
(9, 2, 70, 'AZL', 1, 2, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 76, 1, NULL, 0),
|
||||
(10, 1, 60, 'AMR', 1, 3, NULL, 1, 05080000, 0, 4751000000, 0, NULL, 0, 77, 1, NULL, 0),
|
||||
(11, 1, 60, 'AMR', 1, 1, NULL, 1, 05080000, 1, 4751000000, 0, NULL, 0, 78, 2, NULL, 0),
|
||||
(12, 3, 30, 'GRE', 1, 2, NULL, 2, 06021010, 1, 4751000000, 0, NULL, 0, 82, 2, NULL, 0),
|
||||
(13, 5, 30, 'GRE', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 83, 2, NULL, 0),
|
||||
(14, 5, 90, 'AZL', 1, 2, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 84, 2, NULL, 0),
|
||||
(15, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
|
||||
(16, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 0, 4751000000, 0, NULL, 0, 67350, 2, NULL, 0),
|
||||
(71, 4, NULL, NULL, NULL, 1, NULL, NULL, 06021010, 1, 4751000000, 0, NULL, 0, 88, 2, NULL, 0);
|
||||
|
||||
INSERT INTO `vn`.`expedition`(`id`, `agencyModeFk`, `ticketFk`, `isBox`, `created`, `itemFk`, `counter`, `checked`, `workerFk`)
|
||||
VALUES
|
||||
(1, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18),
|
||||
(2, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 2, 1, 18),
|
||||
(3, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 2, 3, 1, 18),
|
||||
(4, 1, 1, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 4, 4, 1, 18),
|
||||
(5, 1, 2, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18),
|
||||
(6, 7, 3, 71, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), 1, 1, 1, 18),
|
||||
(7, 2, 4, 71, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), 1, 1, 1, 18),
|
||||
(8, 3, 5, 71, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), 1, 1, 1, 18),
|
||||
(9, 3, 6, 71, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), 1, 1, 1, 18),
|
||||
(10, 7, 7, 71, CURDATE(), 1, 1, 1, 18);
|
||||
|
||||
INSERT INTO `vn`.`item`(`id`, `typeFk`, `size`, `inkFk`, `stems`, `originFk`, `description`, `producerFk`, `intrastatFk`, `isOnOffer`, `expenceFk`, `isBargain`, `comment`, `relevancy`, `image`, `taxClassFk`, `subName`)
|
||||
VALUES
|
||||
(1, 2, 70, 'AMA', 1, 1, NULL, 1, 06021010, 0, 2000000000, 0, NULL, 0, 67, 1, NULL),
|
||||
|
@ -1233,23 +1266,23 @@ INSERT INTO `bs`.`waste`(`buyer`, `year`, `week`, `family`, `saleTotal`, `saleWa
|
|||
('HankPym', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 1), 'Miscellaneous Accessories', '186', '0', '0.0'),
|
||||
('HankPym', YEAR(DATE_ADD(CURDATE(), INTERVAL -1 WEEK)), WEEK(DATE_ADD(CURDATE(), INTERVAL -1 WEEK), 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`,`weight`, `created`)
|
||||
INSERT INTO `vn`.`buy`(`id`,`entryFk`,`itemFk`,`buyingValue`,`quantity`,`packageFk`,`stickers`,`freightValue`,`packageValue`,`comissionValue`,`packing`,`grouping`,`groupingMode`,`location`,`price1`,`price2`,`price3`,`producer`,`printedStickers`,`isChecked`,`isIgnored`,`weight`, `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, 1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
||||
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(3, 3, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, 1, CURDATE()),
|
||||
(4, 2, 2, 5, 450, 3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, 0.00, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(5, 3, 3, 55, 500, 5, 1, 1.000, 1.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, 0.00, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(6, 4, 8, 50, 1000, 4, 1, 1.000, 1.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(7, 4, 9, 20, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, 0.00, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(8, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(9, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(10, 5, 1, 50, 10, 4, 1, 2.500, 2.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(11, 5, 4, 1.25, 10, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, 0.00, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00, 0.00, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, 0.00, NULL, 0, 1, 0, 4, CURDATE());
|
||||
(1, 1, 1, 50, 5000, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
||||
(2, 2, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(3, 3, 1, 50, 100, 4, 1, 1.500, 1.500, 0.000, 1, 1, 0, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 1, CURDATE()),
|
||||
(4, 2, 2, 5, 450, 3, 1, 1.000, 1.000, 0.000, 10, 10, 0, NULL, 0.00, 7.30, 7.00, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(5, 3, 3, 55, 500, 5, 1, 1.000, 1.000, 0.000, 1, 1, 0, NULL, 0.00, 78.3, 75.6, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(6, 4, 8, 50, 1000, 4, 1, 1.000, 1.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(7, 4, 9, 20, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 30.50, 29.00, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(8, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 2.5, CURDATE()),
|
||||
(9, 4, 4, 1.25, 1000, 3, 1, 0.500, 0.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(10, 5, 1, 50, 10, 4, 1, 2.500, 2.500, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(11, 5, 4, 1.25, 10, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(12, 6, 4, 1.25, 0, 3, 1, 2.500, 2.500, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(13, 7, 1, 50, 0, 3, 1, 2.000, 2.000, 0.000, 1, 1, 1, NULL, 0.00, 99.6, 99.4, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(14, 7, 2, 5, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 7.30, 7.00, NULL, 0, 1, 0, 4, CURDATE()),
|
||||
(15, 7, 4, 1.25, 0, 3, 1, 2.000, 2.000, 0.000, 10, 10, 1, NULL, 0.00, 1.75, 1.67, NULL, 0, 1, 0, 4, CURDATE());
|
||||
|
||||
INSERT INTO `hedera`.`order`(`id`, `date_send`, `customer_id`, `delivery_method_id`, `agency_id`, `address_id`, `company_id`, `note`, `source_app`, `confirmed`,`total`, `date_make`, `first_row_stamp`, `confirm_date`)
|
||||
VALUES
|
||||
|
|
|
@ -220,23 +220,23 @@ export default {
|
|||
topbarSearch: 'vn-topbar',
|
||||
searchButton: 'vn-searchbar vn-icon[icon="search"]',
|
||||
closeItemSummaryPreview: '.vn-popup.shown',
|
||||
fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="menu"]',
|
||||
fieldsToShowForm: '.vn-dialog.shown form',
|
||||
fieldsToShowButton: 'vn-item-index vn-table > div > div > vn-icon-button[icon="more_vert"]',
|
||||
fieldsToShowForm: '.vn-popover.shown .content',
|
||||
firstItemImage: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(1) > img',
|
||||
firstItemImageTd: 'vn-item-index vn-table a:nth-child(1) vn-td:nth-child(1)',
|
||||
firstItemId: 'vn-item-index vn-tbody > a:nth-child(1) > vn-td:nth-child(2)',
|
||||
idCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(2) > vn-check',
|
||||
stemsCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(3) > vn-check',
|
||||
sizeCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(4) > vn-check',
|
||||
nicheCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(5) > vn-check',
|
||||
typeCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(6) > vn-check',
|
||||
categoryCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(7) > vn-check',
|
||||
intrastadCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(8) > vn-check',
|
||||
originCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(9) > vn-check',
|
||||
buyerCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(10) > vn-check',
|
||||
destinyCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(11) > vn-check',
|
||||
taxClassCheckbox: '.vn-dialog.shown form vn-horizontal:nth-child(12) > vn-check',
|
||||
saveFieldsButton: '.vn-dialog.shown vn-horizontal:nth-child(16) > vn-button > button'
|
||||
idCheckbox: '.vn-popover.shown vn-horizontal:nth-child(1) > vn-check',
|
||||
stemsCheckbox: '.vn-popover.shown vn-horizontal:nth-child(2) > vn-check',
|
||||
sizeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(3) > vn-check',
|
||||
nicheCheckbox: '.vn-popover.shown vn-horizontal:nth-child(4) > vn-check',
|
||||
typeCheckbox: '.vn-popover.shown vn-horizontal:nth-child(5) > vn-check',
|
||||
categoryCheckbox: '.vn-popover.shown vn-horizontal:nth-child(6) > vn-check',
|
||||
intrastadCheckbox: '.vn-popover.shown vn-horizontal:nth-child(7) > vn-check',
|
||||
originCheckbox: '.vn-popover.shown vn-horizontal:nth-child(8) > vn-check',
|
||||
buyerCheckbox: '.vn-popover.shown vn-horizontal:nth-child(9) > vn-check',
|
||||
destinyCheckbox: '.vn-popover.shown vn-horizontal:nth-child(10) > vn-check',
|
||||
taxClassCheckbox: '.vn-popover.shown vn-horizontal:nth-child(11) > vn-check',
|
||||
saveFieldsButton: '.vn-popover.shown vn-button[label="Save"] > button'
|
||||
},
|
||||
itemCreateView: {
|
||||
temporalName: 'vn-item-create vn-textfield[ng-model="$ctrl.item.provisionalName"]',
|
||||
|
@ -898,5 +898,15 @@ export default {
|
|||
agency: 'vn-entry-descriptor div.body vn-label-value:nth-child(1) span',
|
||||
travelsQuicklink: 'vn-entry-descriptor vn-quick-link[icon="local_airport"] > a',
|
||||
entriesQuicklink: 'vn-entry-descriptor vn-quick-link[icon="icon-entry"] > a'
|
||||
},
|
||||
entryLatestBuys: {
|
||||
firstBuy: 'vn-entry-latest-buys vn-tbody > a:nth-child(1)',
|
||||
allBuysCheckBox: 'vn-entry-latest-buys vn-thead vn-check',
|
||||
secondBuyCheckBox: 'vn-entry-latest-buys a:nth-child(2) vn-check[ng-model="buy.checked"]',
|
||||
editBuysButton: 'vn-entry-latest-buys vn-button[icon="edit"]',
|
||||
fieldAutocomplete: 'vn-autocomplete[ng-model="$ctrl.editedColumn.field"]',
|
||||
newValueInput: 'vn-textfield[ng-model="$ctrl.editedColumn.newValue"]',
|
||||
latestBuysSectionButton: 'a[ui-sref="entry.latestBuys"]',
|
||||
acceptEditBuysDialog: 'button[response="accept"]'
|
||||
}
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ describe('Client Add address path', () => {
|
|||
});
|
||||
|
||||
it(`should click on the add new address button to access to the new address form`, async() => {
|
||||
await page.waitFor(500);
|
||||
await page.waitToClick(selectors.clientAddresses.createAddress);
|
||||
await page.waitForState('client.card.address.create');
|
||||
});
|
||||
|
|
|
@ -55,7 +55,6 @@ describe('Item index path', () => {
|
|||
});
|
||||
|
||||
it('should mark all unchecked boxes to leave the index as it was', async() => {
|
||||
await page.waitFor(3000); // otherwise the snackbar doesnt appear some times.
|
||||
await page.waitToClick(selectors.itemsIndex.fieldsToShowButton);
|
||||
await page.waitToClick(selectors.itemsIndex.idCheckbox);
|
||||
await page.waitToClick(selectors.itemsIndex.stemsCheckbox);
|
||||
|
|
|
@ -18,7 +18,7 @@ describe('Ticket purchase request path', () => {
|
|||
});
|
||||
|
||||
it('should add a new request', async() => {
|
||||
await page.waitFor('.vn-popup', {hidden: true}),
|
||||
await page.waitFor(500);
|
||||
await page.waitToClick(selectors.ticketRequests.addRequestButton);
|
||||
await page.write(selectors.ticketRequests.descriptionInput, 'New stuff');
|
||||
await page.write(selectors.ticketRequests.quantity, '9');
|
||||
|
|
|
@ -17,6 +17,7 @@ describe('Route create path', () => {
|
|||
|
||||
describe('as employee', () => {
|
||||
it('should click on the add new route button and open the creation form', async() => {
|
||||
await page.waitFor(500);
|
||||
await page.waitToClick(selectors.routeIndex.addNewRouteButton);
|
||||
await page.waitForState('route.create');
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('InvoiceOut descriptor path', () => {
|
||||
// #2415 e2e fix InvoiceOut descriptor path
|
||||
xdescribe('InvoiceOut descriptor path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
|
@ -63,7 +64,7 @@ describe('InvoiceOut descriptor path', () => {
|
|||
await page.waitForState('ticket.index');
|
||||
});
|
||||
|
||||
it('should search for tickets with an specific invoiceOut to find no results', async() => {
|
||||
it('should search now for tickets with an specific invoiceOut to find no results', async() => {
|
||||
await page.doSearch('T2222222');
|
||||
const nResults = await page.countElement(selectors.ticketsIndex.searchResult);
|
||||
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
import selectors from '../../helpers/selectors.js';
|
||||
import getBrowser from '../../helpers/puppeteer';
|
||||
|
||||
describe('Entry lastest buys path', () => {
|
||||
let browser;
|
||||
let page;
|
||||
|
||||
beforeAll(async() => {
|
||||
browser = await getBrowser();
|
||||
page = browser.page;
|
||||
await page.loginAndModule('buyer', 'entry');
|
||||
});
|
||||
|
||||
afterAll(async() => {
|
||||
await browser.close();
|
||||
});
|
||||
|
||||
it('should access the latest buys seccion and search not seeing the edit buys button yet', async() => {
|
||||
await page.waitToClick(selectors.entryLatestBuys.latestBuysSectionButton);
|
||||
await page.waitFor(250);
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: false});
|
||||
});
|
||||
|
||||
it('should select all lines but one and then check the edit buys button appears', async() => {
|
||||
await page.waitToClick(selectors.entryLatestBuys.allBuysCheckBox);
|
||||
await page.waitToClick(selectors.entryLatestBuys.secondBuyCheckBox);
|
||||
await page.waitForSelector(selectors.entryLatestBuys.editBuysButton, {visible: true});
|
||||
});
|
||||
|
||||
it('should open the edit dialog', async() => {
|
||||
await page.waitToClick(selectors.entryLatestBuys.editBuysButton);
|
||||
await page.waitForSelector(selectors.entryLatestBuys.fieldAutocomplete, {visible: true});
|
||||
});
|
||||
|
||||
it('should search for the "Description" field and type a new description for the items in each selected buy', async() => {
|
||||
await page.autocompleteSearch(selectors.entryLatestBuys.fieldAutocomplete, 'Description');
|
||||
await page.write(selectors.entryLatestBuys.newValueInput, 'Crafted item');
|
||||
await page.waitToClick(selectors.entryLatestBuys.acceptEditBuysDialog);
|
||||
});
|
||||
|
||||
it('should navigate to the entry.buy section by clicking one of the buys', async() => {
|
||||
await page.waitToClick(selectors.entryLatestBuys.firstBuy);
|
||||
await page.waitForState('entry.card.buy');
|
||||
});
|
||||
});
|
|
@ -11,7 +11,7 @@ import './visible-by';
|
|||
import './bind';
|
||||
import './repeat-last';
|
||||
import './title';
|
||||
import './uvc';
|
||||
import './smart-table';
|
||||
import './droppable';
|
||||
import './http-click';
|
||||
import './http-submit';
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
<div style="position: relative;">
|
||||
<div style="position: absolute; top: 0; left: 0; padding: .3em; z-index: 1">
|
||||
<div style="position: absolute; top: 0; left: 0; z-index: 1">
|
||||
<vn-icon-button
|
||||
icon="menu"
|
||||
ng-click="$ctrl.showUvc($event)">
|
||||
class="vn-pt-sm"
|
||||
icon="more_vert"
|
||||
ng-click="$ctrl.showSmartTable($event)">
|
||||
</vn-icon-button>
|
||||
<vn-dialog
|
||||
<vn-popover
|
||||
class="modal-form"
|
||||
vn-id="uvc"
|
||||
vn-id="smart-table"
|
||||
message="Fields to show">
|
||||
<tpl-body>
|
||||
<div class="vn-pa-md">
|
||||
|
@ -24,6 +25,6 @@
|
|||
</vn-horizontal>
|
||||
</div>
|
||||
</tpl-body>
|
||||
</vn-dialog>
|
||||
</vn-popover>
|
||||
</div>
|
||||
</div>
|
|
@ -1,23 +1,28 @@
|
|||
import ngModule from '../module';
|
||||
import template from './uvc.html';
|
||||
import './uvc.scss';
|
||||
import template from './smart-table.html';
|
||||
import './smart-table.scss';
|
||||
|
||||
/**
|
||||
* Directive to hide/show selected columns of a table, don't use with rowspan.
|
||||
* Property smart-table-ignore ignores one or more vn-th with prop field.
|
||||
*/
|
||||
directive.$inject = ['$http', '$compile', 'vnApp', '$translate'];
|
||||
export function directive($http, $compile, vnApp, $translate) {
|
||||
function getHeaderList($element, $scope) {
|
||||
let allHeaders = $element[0].querySelectorAll(`vn-th[field], vn-th[th-id]`);
|
||||
let headerList = Array.from(allHeaders);
|
||||
let filtrableHeaders = $element[0].querySelectorAll('vn-th[field]:not([smart-table-ignore])');
|
||||
let headerList = Array.from(filtrableHeaders);
|
||||
let ids = [];
|
||||
let titles = {};
|
||||
|
||||
headerList.forEach(header => {
|
||||
let id = header.getAttribute('th-id') || header.getAttribute('field');
|
||||
let id = header.getAttribute('field');
|
||||
ids.push(id);
|
||||
titles[id] = header.innerText || id.charAt(0).toUpperCase() + id.slice(1);
|
||||
});
|
||||
|
||||
$scope.fields = ids;
|
||||
$scope.titles = titles;
|
||||
$scope.allHeaders = Array.from($element[0].querySelectorAll('vn-th'));
|
||||
|
||||
return headerList;
|
||||
}
|
||||
|
@ -38,34 +43,33 @@ export function directive($http, $compile, vnApp, $translate) {
|
|||
Object.keys(userConfig.configuration).forEach(key => {
|
||||
let index;
|
||||
if (userConfig.configuration[key] === false) {
|
||||
index = headerList.findIndex(el => {
|
||||
return (el.getAttribute('th-id') == key || el.getAttribute('field') == key);
|
||||
index = $scope.allHeaders.findIndex(el => {
|
||||
return el.getAttribute('field') == key;
|
||||
});
|
||||
|
||||
let baseSelector = `vn-table[vn-uvc=${userConfig.tableCode}] > div`;
|
||||
let baseSelector = `vn-table[vn-smart-table=${userConfig.tableCode}] > div`;
|
||||
selectors.push(`${baseSelector} vn-thead > vn-tr > vn-th:nth-child(${index + 1})`);
|
||||
selectors.push(`${baseSelector} vn-tbody > vn-tr > vn-td:nth-child(${index + 1})`);
|
||||
selectors.push(`${baseSelector} vn-tbody > .vn-tr > vn-td:nth-child(${index + 1})`);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
if (document.querySelector('style[id="uvc"]')) {
|
||||
let child = document.querySelector('style[id="uvc"]');
|
||||
if (document.querySelector('style[id="smart-table"]')) {
|
||||
let child = document.querySelector('style[id="smart-table"]');
|
||||
child.parentNode.removeChild(child);
|
||||
}
|
||||
|
||||
if (selectors.length) {
|
||||
let rule = selectors.join(', ') + '{display: none;}';
|
||||
$scope.css = document.createElement('style');
|
||||
$scope.css.setAttribute('id', 'uvc');
|
||||
$scope.css.setAttribute('id', 'smart-table');
|
||||
document.head.appendChild($scope.css);
|
||||
$scope.css.appendChild(document.createTextNode(rule));
|
||||
}
|
||||
|
||||
$scope.$on('$destroy', () => {
|
||||
if ($scope.css && document.querySelector('style[id="uvc"]')) {
|
||||
let child = document.querySelector('style[id="uvc"]');
|
||||
if ($scope.css && document.querySelector('style[id="smart-table"]')) {
|
||||
let child = document.querySelector('style[id="smart-table"]');
|
||||
child.parentNode.removeChild(child);
|
||||
}
|
||||
});
|
||||
|
@ -80,13 +84,13 @@ export function directive($http, $compile, vnApp, $translate) {
|
|||
restrict: 'A',
|
||||
link: async function($scope, $element, $attrs) {
|
||||
let cTemplate = $compile(template)($scope)[0];
|
||||
$scope.$ctrl.showUvc = event => {
|
||||
$scope.$ctrl.showSmartTable = event => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
$scope.uvc.show();
|
||||
$scope.smartTable.show(event.target);
|
||||
};
|
||||
|
||||
let tableCode = $attrs.vnUvc.trim();
|
||||
let tableCode = $attrs.vnSmartTable.trim();
|
||||
let headerList = getHeaderList($element, $scope);
|
||||
|
||||
let defaultConfigView = {tableCode: tableCode, configuration: {}};
|
||||
|
@ -98,16 +102,16 @@ export function directive($http, $compile, vnApp, $translate) {
|
|||
|
||||
addHideClass($scope, headerList, config);
|
||||
|
||||
let table = document.querySelector(`vn-table[vn-uvc=${tableCode}]`);
|
||||
let table = document.querySelector(`vn-table[vn-smart-table=${tableCode}]`);
|
||||
|
||||
table.insertBefore(cTemplate, table.firstChild);
|
||||
$scope.$ctrl.saveConfiguration = async tableConfiguration => {
|
||||
let newConfig = await saveConfiguration(tableConfiguration);
|
||||
vnApp.showSuccess($translate.instant('Data saved!'));
|
||||
addHideClass($scope, headerList, newConfig.data);
|
||||
$scope.uvc.hide();
|
||||
$scope.smartTable.hide();
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
ngModule.directive('vnUvc', directive);
|
||||
ngModule.directive('vnSmartTable', directive);
|
|
@ -1,4 +1,4 @@
|
|||
vn-table vn-dialog[vn-id="uvc"]{
|
||||
vn-table vn-popover[vn-id="smart-table"]{
|
||||
& > div {
|
||||
min-width: 288px;
|
||||
align-items: center;
|
|
@ -22,7 +22,9 @@
|
|||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.icon-latestBuys:before {
|
||||
content: "\e95f";
|
||||
}
|
||||
.icon-zone:before {
|
||||
content: "\e95d";
|
||||
}
|
||||
|
|
|
@ -102,6 +102,7 @@
|
|||
<glyph unicode="" glyph-name="anonymous" d="M230.4 605.867c12.8 46.933 29.867 93.867 46.933 140.8 8.533 34.133 21.333 64 29.867 98.133 4.267 12.8 8.533 12.8 21.333 12.8 38.4-12.8 72.533-21.333 110.933-25.6 12.8-4.267 29.867 0 46.933 0 34.133 4.267 68.267 8.533 102.4 12.8s72.533 12.8 106.667 17.067c4.267 0 8.533 0 12.8 0s8.533 0 12.8-8.533c12.8-46.933 29.867-93.867 42.667-136.533 12.8-38.4 25.6-76.8 34.133-115.2-192 4.267-379.733 4.267-567.467 4.267zM456.533 247.467c34.133 8.533 64 12.8 98.133 4.267 8.533 0 12.8 0 12.8 8.533 17.067 34.133 42.667 59.733 76.8 72.533 38.4 17.067 76.8 21.333 115.2 8.533 34.133-8.533 59.733-29.867 81.067-55.467 25.6-34.133 38.4-72.533 34.133-119.467-8.533-51.2-34.133-89.6-76.8-115.2-51.2-34.133-132.267-29.867-179.2 12.8-42.667 34.133-59.733 76.8-64 128 0 8.533-4.267 12.8-12.8 17.067-21.333 4.267-42.667 4.267-64 0-8.533-4.267-8.533-4.267-8.533-12.8 0-21.333-4.267-46.933-12.8-68.267-12.8-29.867-34.133-55.467-64-72.533-55.467-38.4-136.533-34.133-183.467 8.533-42.667 34.133-64 76.8-59.733 128 0 59.733 29.867 106.667 85.333 136.533s115.2 25.6 170.667-12.8c12.8-8.533 21.333-17.067 34.133-29.867 0-8.533 8.533-21.333 17.067-38.4zM307.2 302.933c-64 0-115.2-51.2-115.2-110.933 0-64 46.933-115.2 110.933-115.2s115.2 46.933 115.2 110.933c4.267 64-46.933 115.2-110.933 115.2zM712.533 302.933c-64 0-115.2-51.2-115.2-110.933 0-64 46.933-115.2 110.933-115.2 59.733 0 115.2 46.933 115.2 110.933 0 59.733-46.933 115.2-110.933 115.2zM1024 409.6c-341.333 0-682.667 0-1024 0 0 0 0 0 0 0 17.067 8.533 29.867 17.067 46.933 21.333 42.667 12.8 85.333 29.867 132.267 42.667 34.133 8.533 68.267 17.067 102.4 21.333 89.6 17.067 183.467 21.333 277.333 17.067 55.467-4.267 110.933-8.533 166.4-17.067 38.4-4.267 72.533-12.8 110.933-21.333s72.533-21.333 110.933-34.133c21.333-4.267 51.2-17.067 76.8-29.867 0 0 0 0 0 0z" />
|
||||
<glyph unicode="" glyph-name="zone" d="M243.2 448c-12.8 17.067-25.6 34.133-38.4 51.2-34.133 46.933-68.267 98.133-89.6 153.6-17.067 34.133-25.6 72.533-17.067 110.933 8.533 51.2 38.4 89.6 85.333 110.933 59.733 25.6 132.267 8.533 174.933-34.133 34.133-38.4 42.667-81.067 34.133-132.267-8.533-46.933-29.867-85.333-51.2-123.733-29.867-46.933-59.733-89.6-89.6-132.267-4.267 0-4.267 0-8.533-4.267zM247.467 823.467c-46.933 0-89.6-38.4-89.6-89.6 0-46.933 38.4-89.6 85.333-89.6s89.6 38.4 89.6 85.333c0 55.467-38.4 93.867-85.333 93.867zM490.667 379.733l-17.067 25.6 12.8 8.533-34.133 183.467c0 0 0 8.533-8.533 8.533l-42.667 4.267c0 0-68.267-110.933-157.867-217.6 4.267 4.267-93.867 110.933-132.267 187.733l-110.933-51.2c0 0-4.267 0-4.267-8.533l25.6-145.067 34.133-21.333-8.533-21.333-17.067 8.533 59.733-332.8 213.333 102.4 238.933-21.333-51.2 290.133zM149.333 285.867c-12.8 4.267-29.867 12.8-42.667 17.067 4.267 8.533 4.267 17.067 8.533 21.333 17.067 0 29.867-4.267 42.667-12.8-4.267-8.533-4.267-17.067-8.533-25.6zM256 268.8c-17.067 0-34.133 4.267-46.933 4.267 0 8.533 4.267 17.067 4.267 25.6 12.8 0 29.867-4.267 42.667-4.267 0-8.533 0-17.067 0-25.6zM315.733 277.333c-4.267 8.533-4.267 12.8-8.533 21.333 17.067 8.533 29.867 17.067 42.667 21.333 4.267-8.533 8.533-12.8 8.533-21.333-12.8-8.533-25.6-12.8-42.667-21.333zM405.333 328.533c-4.267 8.533-8.533 12.8-12.8 21.333 12.8 8.533 25.6 17.067 38.4 25.6 4.267-4.267 8.533-12.8 12.8-21.333-8.533-8.533-21.333-17.067-38.4-25.6zM972.8 460.8l-29.867 25.6 12.8 21.333 12.8-8.533-34.133 187.733c0 0 0 8.533-8.533 8.533l-226.133 17.067-209.067-93.867c0 0-8.533-4.267-4.267-12.8l29.867-170.667 21.333-12.8-17.067-17.067 55.467-307.2 213.333 102.4 234.667-21.333-51.2 281.6zM580.267 465.067c-4.267 4.267-8.533 12.8-12.8 17.067 12.8 12.8 21.333 21.333 29.867 34.133 4.267-4.267 12.8-12.8 17.067-17.067-12.8-8.533-25.6-21.333-34.133-34.133zM657.067 541.867c-4.267 4.267-8.533 12.8-12.8 21.333 12.8 8.533 25.6 17.067 38.4 25.6 8.533-8.533 12.8-17.067 12.8-21.333-12.8-8.533-25.6-17.067-38.4-25.6zM797.867 571.733c-12.8 4.267-25.6 4.267-42.667 4.267 0 8.533 0 17.067 0 25.6 17.067 0 34.133 0 51.2-4.267-4.267-8.533-4.267-17.067-8.533-25.6zM891.733 520.533c-12.8 8.533-25.6 17.067-38.4 25.6 4.267 8.533 8.533 12.8 12.8 21.333 12.8-8.533 25.6-17.067 38.4-25.6-4.267-8.533-8.533-12.8-12.8-21.333z" />
|
||||
<glyph unicode="" glyph-name="inventory" d="M273.067 226.133c4.267 0 8.533 4.267 8.533 8.533v85.333h98.133v-221.867h-217.6v221.867h98.133v-81.067c0-8.533 8.533-12.8 12.8-12.8zM512 226.133c4.267 0 8.533 4.267 8.533 8.533v85.333h98.133v-221.867h-217.6v221.867h98.133v-81.067c0-8.533 8.533-12.8 12.8-12.8zM750.933 226.133c4.267 0 8.533 4.267 8.533 8.533v85.333h98.133v-221.867h-217.6v221.867h98.133v-81.067c4.267-8.533 8.533-12.8 12.8-12.8zM644.267 780.8h98.133v-81.067c0-4.267 4.267-8.533 8.533-8.533s8.533 4.267 8.533 8.533v81.067h98.133v-221.867h-217.6v221.867h4.267zM401.067 780.8h98.133v-81.067c0-4.267 4.267-8.533 8.533-8.533s8.533 4.267 8.533 8.533v81.067h98.133v-221.867h-213.333v221.867zM162.133 780.8h98.133v-81.067c0-4.267 4.267-8.533 8.533-8.533s8.533 4.267 8.533 8.533v81.067h98.133v-221.867h-213.333v221.867zM153.6 537.6h780.8v-38.4h-844.8v38.4zM68.267-42.667h-42.667v981.333h42.667v-908.8zM89.6 38.4v38.4h844.8v-38.4zM998.4-42.667h-42.667v981.333h42.667z" />
|
||||
<glyph unicode="" glyph-name="latestBuys" d="M183.467 750.933h712.533v-38.4h-768v38.4zM89.6 64c8.533 0 12.8 0 21.333-4.267v900.267h-42.667v-900.267c8.533 4.267 12.8 4.267 21.333 4.267zM955.733 512v448h-42.667v-413.867c17.067-12.8 29.867-21.333 42.667-34.133zM145.067-8.533c0-30.633-24.833-55.467-55.467-55.467s-55.467 24.833-55.467 55.467c0 30.633 24.833 55.467 55.467 55.467s55.467-24.833 55.467-55.467zM418.133 426.667h-290.133v-38.4h273.067c4.267 17.067 8.533 29.867 17.067 38.4zM392.533 106.667h-264.533v-38.4h281.6c-8.533 12.8-12.8 25.6-17.067 38.4zM725.333 247.467c-12.8 0-21.333-8.533-21.333-21.333s8.533-21.333 21.333-21.333c12.8 0 21.333 8.533 21.333 21.333 0 8.533-12.8 21.333-21.333 21.333zM721.067 541.867c-166.4 0-298.667-136.533-298.667-302.933s132.267-302.933 298.667-302.933c166.4 0 298.667 136.533 298.667 302.933 0 170.667-132.267 302.933-298.667 302.933zM725.333 34.133c-98.133 0-174.933 72.533-187.733 162.133h-34.133l51.2 64 59.733-64h-38.4c8.533-68.267 72.533-123.733 149.333-123.733 81.067 0 149.333 64 149.333 145.067s-68.267 145.067-149.333 145.067c-68.267 0-128-46.933-145.067-110.933l-21.333 29.867-17.067-12.8c8.533 29.867 25.6 55.467 46.933 76.8l-25.6 21.333c-4.267 4.267-4.267 12.8 0 17.067l12.8 12.8c4.267 4.267 12.8 4.267 17.067 0l25.6-25.6c21.333 12.8 51.2 25.6 76.8 25.6v29.867h-8.533c-8.533 0-12.8 4.267-12.8 12.8v17.067c0 8.533 4.267 12.8 12.8 12.8h59.733c8.533 0 12.8-4.267 12.8-12.8v-17.067c0-8.533-4.267-12.8-12.8-12.8h-8.533v-21.333c29.867-4.267 55.467-12.8 81.067-29.867l34.133 29.867c4.267 4.267 12.8 4.267 17.067 0l12.8-12.8c4.267-4.267 4.267-12.8 0-17.067l-25.6-25.6c29.867-34.133 51.2-76.8 51.2-128 4.267-102.4-81.067-187.733-183.467-187.733zM772.267 226.133c0-25.6-21.333-46.933-46.933-46.933s-46.933 21.333-46.933 46.933c0 25.6 21.333 46.933 46.933 46.933 8.533 0 17.067-4.267 21.333-4.267l46.933 46.933 21.333-21.333-46.933-46.933c4.267-4.267 4.267-12.8 4.267-21.333z" />
|
||||
<glyph unicode="" glyph-name="wiki" d="M793.6 733.867c0 0 4.267 0 4.267 0l76.8 12.8v-42.667c0-34.133-21.333-68.267-46.933-72.533 0 0-4.267 0-4.267 0l-76.8-12.8v42.667c0 34.133 21.333 64 46.933 72.533zM742.4 597.333l38.4 4.267c12.8 0 25.6-12.8 25.6-29.867v-21.333l-38.4-4.267c-12.8 0-25.6 12.8-25.6 29.867v21.333zM618.667 699.733l68.267 8.533c25.6 4.267 42.667-21.333 42.667-55.467v-38.4l-68.267-8.533c-25.6-4.267-42.667 21.333-42.667 55.467v38.4zM665.6 588.8c4.267 0 4.267 0 0 0l59.733 4.267v-29.867c0-25.6-17.067-46.933-34.133-55.467 0 0-4.267 0-4.267 0l-55.467-8.533v29.867c4.267 29.867 17.067 51.2 34.133 59.733zM443.733 648.533c0 0-4.267 0-4.267 0-119.467 85.333-273.067 46.933-277.333 46.933s-8.533 0-12.8 8.533c0 4.267 0 8.533 8.533 12.8 0 0 42.667 12.8 98.133 8.533 51.2 0 128-12.8 196.267-59.733 4.267-4.267 4.267-8.533 4.267-12.8-4.267-4.267-8.533-4.267-12.8-4.267zM443.733 512c0 0-4.267 0-4.267 0-119.467 85.333-273.067 46.933-277.333 46.933s-8.533 0-12.8 8.533c0 4.267 0 8.533 8.533 12.8 0 0 42.667 12.8 98.133 8.533 51.2 0 128-12.8 196.267-59.733 4.267-4.267 4.267-8.533 4.267-12.8-4.267 0-8.533-4.267-12.8-4.267zM443.733 379.733c0 0-4.267 0-4.267 0-119.467 85.333-273.067 46.933-277.333 46.933s-8.533 0-12.8 8.533c0 4.267 0 8.533 8.533 12.8 0 0 42.667 12.8 98.133 8.533 51.2 0 128-12.8 196.267-59.733 4.267-4.267 4.267-8.533 4.267-12.8-4.267 0-8.533-4.267-12.8-4.267zM443.733 247.467c0 0-4.267 0-4.267 0-119.467 85.333-273.067 46.933-277.333 46.933s-8.533 0-12.8 8.533c0 4.267 0 8.533 8.533 12.8 0 0 42.667 12.8 98.133 8.533 51.2 0 128-12.8 196.267-59.733 4.267-4.267 4.267-8.533 4.267-12.8-4.267 0-8.533-4.267-12.8-4.267zM588.8 379.733c-4.267 0-4.267 0-8.533 4.267s0 8.533 4.267 12.8c68.267 46.933 140.8 59.733 196.267 59.733s93.867-8.533 98.133-8.533c4.267 0 8.533-8.533 8.533-12.8s-8.533-8.533-12.8-8.533v0c0 0-153.6 38.4-277.333-46.933-4.267 4.267-4.267 0-8.533 0zM588.8 247.467c-4.267 0-4.267 0-8.533 4.267s0 8.533 4.267 12.8c68.267 46.933 140.8 59.733 196.267 59.733s93.867-8.533 98.133-8.533c4.267 0 8.533-8.533 8.533-12.8s-8.533-8.533-12.8-8.533v0c0 0-153.6 38.4-277.333-46.933-4.267 4.267-4.267 0-8.533 0zM985.6 738.133v64l-8.533 4.267c-4.267 0-81.067 29.867-179.2 29.867-106.667 0-200.533-34.133-277.333-98.133-76.8 64-170.667 98.133-277.333 98.133-102.4 0-174.933-29.867-179.2-29.867l-12.8-4.267v-59.733c-34.133-4.267-51.2-17.067-51.2-34.133v-614.4h452.267c17.067-12.8 38.4-21.333 64-21.333s46.933 8.533 64 21.333h443.733v614.4c0 17.067-17.067 25.6-38.4 29.867v0zM512 145.067c-38.4 17.067-166.4 64-298.667 64-51.2 0-98.133-8.533-136.533-21.333v597.333c21.333 8.533 85.333 25.6 162.133 25.6 98.133 0 183.467-29.867 256-89.6v-358.4l17.067 17.067v-234.667zM955.733 183.467c-42.667 17.067-89.6 25.6-140.8 25.6-128 0-251.733-51.2-290.133-64v238.933l17.067-17.067v349.867c68.267 59.733 153.6 89.6 256 89.6 76.8 0 136.533-17.067 162.133-25.6v-597.333z" />
|
||||
<glyph unicode="" glyph-name="attach" d="M960 866.133c-42.667 42.667-98.133 64-157.867 64s-115.2-21.333-157.867-64l-593.067-593.067c-34.133-34.133-55.467-85.333-51.2-136.533 0-42.667 17.067-81.067 46.933-110.933 34.133-38.4 81.067-59.733 132.267-59.733 46.933 0 93.867 17.067 128 51.2l541.867 546.133c25.6 25.6 42.667 64 42.667 98.133s-12.8 68.267-38.4 93.867c-25.6 25.6-59.733 38.4-98.133 38.4-34.133 0-72.533-17.067-98.133-42.667l-354.133-354.133c-4.267 0-4.267-4.267-4.267-12.8s4.267-12.8 8.533-17.067 25.6-8.533 34.133 0l354.133 354.133c12.8 17.067 38.4 25.6 59.733 25.6 25.6 0 51.2-12.8 68.267-34.133 8.533-12.8 17.067-25.6 17.067-42.667 4.267-25.6-4.267-55.467-25.6-72.533l-541.867-541.867c-25.6-25.6-55.467-38.4-93.867-38.4-34.133 0-68.267 12.8-93.867 38.4s-38.4 59.733-38.4 93.867c0 34.133 12.8 68.267 38.4 93.867l588.8 584.533c34.133 34.133 76.8 51.2 123.733 51.2s89.6-17.067 123.733-51.2c34.133-34.133 51.2-76.8 51.2-123.733s-17.067-89.6-51.2-123.733l-401.067-401.067c-4.267-4.267-8.533-12.8-8.533-17.067 0-8.533 4.267-12.8 8.533-17.067 8.533-8.533 25.6-8.533 34.133 0l401.067 401.067c89.6 89.6 89.6 230.4 4.267 320z" />
|
||||
<glyph unicode="" glyph-name="zone2" d="M98.133 17.067c-4.267 29.867-12.8 64-17.067 93.867-17.067 98.133-34.133 192-51.2 290.133-12.8 46.933-21.333 98.133-29.867 149.333 0 4.267 0 8.533 4.267 8.533 42.667 21.333 85.333 42.667 128 59.733 0 0 0 0 4.267 0 4.267-8.533 8.533-12.8 12.8-21.333-21.333-8.533-42.667-21.333-64-29.867-17.067-8.533-34.133-17.067-51.2-21.333-4.267 0-4.267-4.267-4.267-8.533 8.533-42.667 17.067-85.333 25.6-132.267 0-4.267 4.267-4.267 4.267-8.533 8.533-4.267 17.067-8.533 25.6-17.067 0-4.267-4.267-12.8-8.533-17.067-4.267 4.267-12.8 4.267-17.067 8.533 17.067-102.4 38.4-209.067 55.467-311.467 17.067 8.533 29.867 12.8 42.667 21.333 51.2 25.6 102.4 51.2 153.6 72.533 4.267 0 8.533 0 17.067 0 68.267-4.267 136.533-12.8 204.8-17.067 0 0 4.267 0 8.533 0-4.267 17.067-4.267 34.133-8.533 51.2-12.8 68.267-25.6 136.533-38.4 204.8 0 8.533-4.267 17.067-12.8 25.6-4.267 4.267-4.267 8.533-8.533 12.8 12.8 4.267 8.533 17.067 8.533 25.6-8.533 51.2-17.067 106.667-29.867 157.867 0 4.267 0 4.267-8.533 4.267-17.067 0-38.4 4.267-55.467 4.267 4.267 8.533 8.533 17.067 12.8 21.333 0 0 4.267 4.267 8.533 4.267 17.067 0 34.133-4.267 46.933-4.267 4.267 0 8.533 0 12.8 0 68.267 29.867 132.267 64 200.533 93.867 4.267 4.267 8.533 8.533 12.8 8.533 68.267-4.267 136.533-8.533 204.8-17.067 8.533 0 17.067 0 29.867-4.267 4.267 0 8.533-4.267 8.533-8.533 12.8-64 25.6-132.267 34.133-196.267 17.067-102.4 38.4-204.8 55.467-311.467 0-8.533 4.267-17.067 4.267-25.6-17.067 0-34.133 4.267-51.2 4.267-42.667 4.267-89.6 8.533-132.267 12.8-17.067 0-38.4 4.267-55.467 4.267-4.267 0-12.8 0-17.067-4.267-68.267-29.867-132.267-64-200.533-93.867 0 0-4.267 0-8.533 0-76.8 8.533-149.333 12.8-226.133 21.333-4.267 0-8.533 0-12.8 0-72.533-34.133-140.8-68.267-213.333-102.4 0-4.267 0-8.533-4.267-8.533zM989.867 217.6c0 4.267 0 4.267 0 8.533-8.533 34.133-12.8 72.533-21.333 106.667-8.533 46.933-17.067 89.6-25.6 136.533 0 8.533-4.267 12.8-8.533 17.067-8.533 4.267-12.8 12.8-21.333 17.067 4.267 8.533 8.533 12.8 12.8 17.067 4.267-4.267 8.533-4.267 12.8-8.533-4.267 12.8-4.267 21.333-4.267 34.133-8.533 46.933-17.067 93.867-25.6 145.067 0 4.267-4.267 8.533-8.533 8.533-68.267 4.267-136.533 12.8-209.067 17.067-4.267 0-8.533 0-12.8-4.267-64-29.867-123.733-59.733-187.733-85.333-4.267-4.267-8.533-4.267-4.267-12.8 4.267-29.867 12.8-64 17.067-93.867 4.267-21.333 8.533-42.667 12.8-59.733 12.8-4.267 12.8-12.8 21.333-21.333-12.8-4.267-12.8-12.8-12.8-25.6 12.8-68.267 25.6-132.267 38.4-200.533 4.267-25.6 8.533-51.2 12.8-76.8 4.267 0 4.267 0 8.533 4.267 59.733 29.867 119.467 59.733 183.467 89.6-4.267 4.267 0 4.267 4.267 4.267 51.2-4.267 106.667-8.533 157.867-12.8 21.333 0 38.4-4.267 59.733-4.267zM260.267 469.333c-12.8 17.067-25.6 34.133-38.4 46.933-29.867 46.933-59.733 93.867-85.333 145.067-12.8 29.867-21.333 64-17.067 102.4 8.533 51.2 34.133 85.333 81.067 102.4 55.467 21.333 123.733 8.533 162.133-34.133 34.133-34.133 42.667-76.8 34.133-123.733-8.533-42.667-25.6-76.8-46.933-115.2-25.6-42.667-55.467-81.067-85.333-123.733 0 4.267-4.267 0-4.267 0zM260.267 819.2c-46.933 0-81.067-34.133-81.067-81.067s38.4-81.067 81.067-81.067c46.933 0 81.067 38.4 85.333 81.067 0 42.667-38.4 81.067-85.333 81.067zM358.4 349.867c4.267-8.533 4.267-12.8 8.533-21.333-12.8-4.267-25.6-12.8-38.4-17.067-4.267 8.533-4.267 12.8-8.533 21.333 12.8 4.267 25.6 12.8 38.4 17.067zM226.133 302.933c0 8.533 4.267 17.067 4.267 21.333 12.8 0 25.6-4.267 38.4-4.267 0-8.533 0-12.8 0-25.6-12.8 8.533-29.867 8.533-42.667 8.533zM413.867 354.133c-4.267 8.533-8.533 12.8-12.8 21.333 12.8 8.533 21.333 17.067 34.133 25.6 4.267-4.267 8.533-12.8 12.8-17.067-12.8-12.8-21.333-21.333-34.133-29.867zM179.2 341.333c-4.267-8.533-4.267-12.8-8.533-21.333-12.8 4.267-25.6 8.533-38.4 17.067 4.267 8.533 4.267 12.8 8.533 21.333 12.8-8.533 25.6-12.8 38.4-17.067zM682.667 580.267c-12.8-8.533-21.333-17.067-34.133-21.333-4.267 4.267-8.533 12.8-12.8 17.067 12.8 8.533 25.6 17.067 38.4 25.6 4.267-8.533 4.267-17.067 8.533-21.333zM878.933 558.933c-4.267-8.533-8.533-12.8-12.8-21.333-12.8 8.533-25.6 17.067-34.133 21.333 4.267 8.533 8.533 12.8 8.533 21.333 12.8-8.533 25.6-17.067 38.4-21.333zM571.733 486.4c-4.267 4.267-8.533 12.8-12.8 17.067 8.533 8.533 21.333 21.333 29.867 29.867 4.267-4.267 8.533-12.8 12.8-17.067-8.533-8.533-17.067-21.333-29.867-29.867zM785.067 610.133c-4.267-8.533-4.267-17.067-8.533-21.333-12.8 0-25.6 4.267-38.4 4.267 0 8.533 0 12.8 0 21.333 17.067 0 29.867-4.267 46.933-4.267z" />
|
||||
|
|
Before Width: | Height: | Size: 108 KiB After Width: | Height: | Size: 109 KiB |
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,87 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('editLatestBuys', {
|
||||
description: 'Updates a column for one or more buys',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'field',
|
||||
type: 'String',
|
||||
required: true,
|
||||
description: `the column to edit`
|
||||
},
|
||||
{
|
||||
arg: 'newValue',
|
||||
type: 'Any',
|
||||
required: true,
|
||||
description: `The new value to save`
|
||||
},
|
||||
{
|
||||
arg: 'lines',
|
||||
type: ['Object'],
|
||||
required: true,
|
||||
description: `the buys which will be modified`
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/editLatestBuys`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.editLatestBuys = async(field, newValue, lines) => {
|
||||
let modelName;
|
||||
let identifier;
|
||||
|
||||
switch (field) {
|
||||
case 'size':
|
||||
case 'density':
|
||||
case 'minPrice':
|
||||
case 'description':
|
||||
modelName = 'Item';
|
||||
identifier = 'itemFk';
|
||||
break;
|
||||
case 'quantity':
|
||||
case 'buyingValue':
|
||||
case 'freightValue':
|
||||
case 'packing':
|
||||
case 'grouping':
|
||||
case 'groupingMode':
|
||||
case 'comissionValue':
|
||||
case 'packageValue':
|
||||
case 'price2':
|
||||
case 'price3':
|
||||
case 'weight':
|
||||
modelName = 'Buy';
|
||||
identifier = 'id';
|
||||
}
|
||||
|
||||
const models = Self.app.models;
|
||||
const model = models[modelName];
|
||||
|
||||
let tx = await model.beginTransaction({});
|
||||
|
||||
try {
|
||||
let promises = [];
|
||||
let options = {transaction: tx};
|
||||
|
||||
let targets = lines.map(line => {
|
||||
return line[identifier];
|
||||
});
|
||||
|
||||
let value = {};
|
||||
value[field] = newValue;
|
||||
|
||||
// intentarlo con updateAll
|
||||
for (let target of targets)
|
||||
promises.push(model.upsertWithWhere({id: target}, value, options));
|
||||
|
||||
await Promise.all(promises);
|
||||
await tx.commit();
|
||||
} catch (error) {
|
||||
await tx.rollback();
|
||||
throw error;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -0,0 +1,171 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
const buildFilter = require('vn-loopback/util/filter').buildFilter;
|
||||
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('latestBuysFilter', {
|
||||
description: 'Find all instances of the model matched by filter from the data source.',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'Object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
},
|
||||
{
|
||||
arg: 'search',
|
||||
type: 'String',
|
||||
description: `If it's and integer searchs by id, otherwise it searchs by name`,
|
||||
}, {
|
||||
arg: 'id',
|
||||
type: 'Integer',
|
||||
description: 'Item id',
|
||||
}, {
|
||||
arg: 'tags',
|
||||
type: ['Object'],
|
||||
description: 'List of tags to filter with',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'description',
|
||||
type: 'String',
|
||||
description: 'The item description',
|
||||
}, {
|
||||
arg: 'salesPersonFk',
|
||||
type: 'Integer',
|
||||
description: 'The buyer of the item',
|
||||
}, {
|
||||
arg: 'active',
|
||||
type: 'Boolean',
|
||||
description: 'Whether the the item is or not active',
|
||||
}, {
|
||||
arg: 'visible',
|
||||
type: 'Boolean',
|
||||
description: 'Whether the the item is or not visible',
|
||||
}, {
|
||||
arg: 'typeFk',
|
||||
type: 'Integer',
|
||||
description: 'Type id',
|
||||
}, {
|
||||
arg: 'categoryFk',
|
||||
type: 'Integer',
|
||||
description: 'Category id',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: ['Object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/latestBuysFilter`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.latestBuysFilter = async(ctx, filter) => {
|
||||
let conn = Self.dataSource.connector;
|
||||
let where = buildFilter(ctx.args, (param, value) => {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {'i.id': value}
|
||||
: {'i.name': {like: `%${value}%`}};
|
||||
case 'id':
|
||||
return {'i.id': value};
|
||||
case 'description':
|
||||
return {'i.description': {like: `%${value}%`}};
|
||||
case 'categoryFk':
|
||||
return {'ic.id': value};
|
||||
case 'salesPersonFk':
|
||||
return {'it.workerFk': value};
|
||||
case 'typeFk':
|
||||
return {'i.typeFk': value};
|
||||
case 'active':
|
||||
return {'i.isActive': value};
|
||||
case 'visible':
|
||||
if (value)
|
||||
return {'v.visible': {gt: 0}};
|
||||
else if (!value)
|
||||
return {'v.visible': {lte: 0}};
|
||||
}
|
||||
});
|
||||
filter = mergeFilters(ctx.args.filter, {where});
|
||||
|
||||
let stmts = [];
|
||||
let stmt;
|
||||
|
||||
stmts.push('CALL cache.last_buy_refresh(FALSE)');
|
||||
stmts.push('CALL cache.visible_refresh(@calc_id, FALSE, 1)');
|
||||
|
||||
stmt = new ParameterizedSQL(`
|
||||
SELECT
|
||||
i.image,
|
||||
i.id AS itemFk,
|
||||
i.size,
|
||||
i.density,
|
||||
i.typeFk,
|
||||
i.family,
|
||||
i.isActive,
|
||||
i.minPrice,
|
||||
i.description,
|
||||
t.name AS type,
|
||||
intr.description AS intrastat,
|
||||
ori.code AS origin,
|
||||
b.entryFk,
|
||||
b.id,
|
||||
b.quantity,
|
||||
b.buyingValue,
|
||||
b.freightValue,
|
||||
b.isIgnored,
|
||||
b.packing,
|
||||
b.grouping,
|
||||
b.groupingMode,
|
||||
b.comissionValue,
|
||||
b.packageValue,
|
||||
b.price2,
|
||||
b.price3,
|
||||
b.ektFk,
|
||||
b.weight
|
||||
FROM cache.last_buy lb
|
||||
LEFT JOIN cache.visible v ON v.item_id = lb.item_id
|
||||
AND v.calc_id = @calc_id
|
||||
JOIN item i ON i.id = lb.item_id
|
||||
JOIN itemType it ON it.id = i.typeFk AND lb.warehouse_id = it.warehouseFk
|
||||
JOIN buy b ON b.id = lb.buy_id
|
||||
LEFT JOIN itemCategory ic ON ic.id = it.categoryFk
|
||||
LEFT JOIN itemType t ON t.id = i.typeFk
|
||||
LEFT JOIN intrastat intr ON intr.id = i.intrastatFk
|
||||
LEFT JOIN origin ori ON ori.id = i.originFk`
|
||||
);
|
||||
|
||||
if (ctx.args.tags) {
|
||||
let i = 1;
|
||||
for (const tag of ctx.args.tags) {
|
||||
const tAlias = `it${i++}`;
|
||||
|
||||
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 {
|
||||
stmt.merge({
|
||||
sql: `JOIN vn.itemTag ${tAlias} ON ${tAlias}.itemFk = i.id
|
||||
AND ${tAlias}.value LIKE ?`,
|
||||
params: [`%${tag.value}%`],
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stmt.merge(conn.makeSuffix(filter));
|
||||
let buysIndex = stmts.push(stmt) - 1;
|
||||
|
||||
let sql = ParameterizedSQL.join(stmts, ';');
|
||||
let result = await conn.executeStmt(sql);
|
||||
return buysIndex === 0 ? result : result[buysIndex];
|
||||
};
|
||||
};
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
const model = app.models.Buy;
|
||||
|
||||
describe('Buy editLatestsBuys()', () => {
|
||||
it('should change the value of a given column for the selected buys', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
search: 'Ranged weapon longbow 2m'
|
||||
}
|
||||
};
|
||||
|
||||
let [original] = await model.latestBuysFilter(ctx);
|
||||
|
||||
const field = 'size';
|
||||
let newValue = 99;
|
||||
const lines = [{itemFk: original.itemFk, id: original.id}];
|
||||
|
||||
await model.editLatestBuys(field, newValue, lines);
|
||||
|
||||
let [result] = await model.latestBuysFilter(ctx);
|
||||
|
||||
expect(result.size).toEqual(99);
|
||||
|
||||
newValue = original.size;
|
||||
await model.editLatestBuys(field, newValue, lines);
|
||||
|
||||
let [restoredFixture] = await model.latestBuysFilter(ctx);
|
||||
|
||||
expect(restoredFixture.size).toEqual(original.size);
|
||||
});
|
||||
});
|
|
@ -0,0 +1,139 @@
|
|||
const app = require('vn-loopback/server/server');
|
||||
|
||||
describe('Buy latests buys filter()', () => {
|
||||
it('should return the entry matching "search"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
search: 'Ranged weapon longbow 2m'
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
let firstBuy = results[0];
|
||||
|
||||
expect(results.length).toEqual(1);
|
||||
expect(firstBuy.size).toEqual(70);
|
||||
});
|
||||
|
||||
it('should return the entry matching "id"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
id: 1
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toEqual(1);
|
||||
});
|
||||
|
||||
it('should return results matching "tags"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
tags: [
|
||||
{tagFk: 27, value: '2m'}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(2);
|
||||
});
|
||||
|
||||
it('should return results matching "categoryFk"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
categoryFk: 1
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(4);
|
||||
});
|
||||
|
||||
it('should return results matching "typeFk"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
typeFk: 2
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(4);
|
||||
});
|
||||
|
||||
it('should return results matching "active"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
active: true
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(6);
|
||||
});
|
||||
|
||||
it('should return results matching "not active"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
active: false
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should return results matching "visible"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
visible: true
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(5);
|
||||
});
|
||||
|
||||
it('should return results matching "not visible"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
visible: false
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(0);
|
||||
});
|
||||
|
||||
it('should return results matching "salesPersonFk"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
salesPersonFk: 35
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(6);
|
||||
});
|
||||
|
||||
it('should return results matching "description"', async() => {
|
||||
let ctx = {
|
||||
args: {
|
||||
description: 'Increases block'
|
||||
}
|
||||
};
|
||||
|
||||
let results = await app.models.Buy.latestBuysFilter(ctx);
|
||||
|
||||
expect(results.length).toBe(1);
|
||||
});
|
||||
});
|
|
@ -2,6 +2,9 @@
|
|||
"Entry": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"Buy": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"EntryLog": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/entry/editLatestBuys')(Self);
|
||||
require('../methods/entry/latestBuysFilter')(Self);
|
||||
};
|
|
@ -0,0 +1,61 @@
|
|||
{
|
||||
"name": "Buy",
|
||||
"base": "Loggable",
|
||||
"log": {
|
||||
"model": "EntryLog",
|
||||
"relation": "entry"
|
||||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
"table": "buy"
|
||||
}
|
||||
},
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "number",
|
||||
"id": true,
|
||||
"description": "Identifier"
|
||||
},
|
||||
"quantity": {
|
||||
"type": "number"
|
||||
},
|
||||
"buyingValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"freightValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"packing": {
|
||||
"type": "number"
|
||||
},
|
||||
"grouping": {
|
||||
"type": "number"
|
||||
},
|
||||
"groupingMode": {
|
||||
"type": "number"
|
||||
},
|
||||
"comissionValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"packageValue": {
|
||||
"type": "number"
|
||||
},
|
||||
"price2": {
|
||||
"type": "number"
|
||||
},
|
||||
"price3": {
|
||||
"type": "number"
|
||||
},
|
||||
"weight": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"entry": {
|
||||
"type": "belongsTo",
|
||||
"model": "Entry",
|
||||
"foreignKey": "entryFk",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
module.exports = Self => {
|
||||
require('../methods/entry/filter')(Self);
|
||||
require('../methods/entry/getEntry')(Self);
|
||||
|
|
|
@ -10,7 +10,8 @@ class Controller extends ModuleCard {
|
|||
scope: {
|
||||
fields: ['id', 'code']
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
relation: 'travel',
|
||||
scope: {
|
||||
fields: ['id', 'landed', 'agencyFk', 'warehouseOutFk'],
|
||||
|
@ -35,12 +36,14 @@ class Controller extends ModuleCard {
|
|||
}
|
||||
]
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
relation: 'supplier',
|
||||
scope: {
|
||||
fields: ['id', 'nickname']
|
||||
}
|
||||
}, {
|
||||
},
|
||||
{
|
||||
relation: 'currency'
|
||||
}
|
||||
]
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
<slot-descriptor>
|
||||
<vn-entry-descriptor></vn-entry-descriptor>
|
||||
</slot-descriptor>
|
|
@ -0,0 +1,9 @@
|
|||
import ngModule from '../module';
|
||||
import DescriptorPopover from 'salix/components/descriptor-popover';
|
||||
|
||||
class Controller extends DescriptorPopover {}
|
||||
|
||||
ngModule.vnComponent('vnEntryDescriptorPopover', {
|
||||
slotTemplate: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -11,15 +11,23 @@ class Controller extends Descriptor {
|
|||
}
|
||||
|
||||
get travelFilter() {
|
||||
return this.entry && JSON.stringify({
|
||||
agencyFk: this.entry.travel.agencyFk
|
||||
});
|
||||
let travelFilter;
|
||||
const entryTravel = this.entry && this.entry.travel;
|
||||
|
||||
if (entryTravel && entryTravel.agencyFk) {
|
||||
travelFilter = this.entry && JSON.stringify({
|
||||
agencyFk: entryTravel.agencyFk
|
||||
});
|
||||
}
|
||||
return travelFilter;
|
||||
}
|
||||
|
||||
get entryFilter() {
|
||||
if (!this.entry) return null;
|
||||
let entryTravel = this.entry && this.entry.travel;
|
||||
|
||||
const date = new Date(this.entry.travel.landed);
|
||||
if (!entryTravel || !entryTravel.landed) return null;
|
||||
|
||||
const date = new Date(entryTravel.landed);
|
||||
date.setHours(0, 0, 0, 0);
|
||||
|
||||
const from = new Date(date.getTime());
|
||||
|
@ -35,6 +43,48 @@ class Controller extends Descriptor {
|
|||
});
|
||||
}
|
||||
|
||||
loadData() {
|
||||
const filter = {
|
||||
include: [
|
||||
{
|
||||
relation: 'travel',
|
||||
scope: {
|
||||
fields: ['id', 'landed', 'agencyFk', 'warehouseOutFk'],
|
||||
include: [
|
||||
{
|
||||
relation: 'agency',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'warehouseOut',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'warehouseIn',
|
||||
scope: {
|
||||
fields: ['name']
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
relation: 'supplier',
|
||||
scope: {
|
||||
fields: ['id', 'nickname']
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
return this.getData(`Entries/${this.id}`, {filter})
|
||||
.then(res => this.entity = res.data);
|
||||
}
|
||||
|
||||
showEntryReport() {
|
||||
this.vnReport.show('entry-order', {
|
||||
entryId: this.entry.id
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Entry Component vnEntryDescriptor', () => {
|
||||
let $httpBackend;
|
||||
let controller;
|
||||
const entry = {id: 2};
|
||||
|
||||
beforeEach(ngModule('entry'));
|
||||
|
||||
beforeEach(inject($componentController => {
|
||||
beforeEach(inject(($componentController, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
controller = $componentController('vnEntryDescriptor', {$element: null}, {entry});
|
||||
}));
|
||||
|
||||
|
@ -24,4 +26,18 @@ describe('Entry Component vnEntryDescriptor', () => {
|
|||
expect(controller.vnReport.show).toHaveBeenCalledWith('entry-order', params);
|
||||
});
|
||||
});
|
||||
|
||||
describe('loadData()', () => {
|
||||
it('should perform ask for the entry', () => {
|
||||
let query = `Entries/${entry.id}`;
|
||||
jest.spyOn(controller, 'getData');
|
||||
|
||||
$httpBackend.expectGET(query).respond();
|
||||
controller.loadData();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.getData).toHaveBeenCalledTimes(1);
|
||||
expect(controller.getData).toHaveBeenCalledWith(query, jasmine.any(Object));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -2,8 +2,11 @@ export * from './module';
|
|||
|
||||
import './main';
|
||||
import './index/';
|
||||
import './latest-buys';
|
||||
import './search-panel';
|
||||
import './latest-buys-search-panel';
|
||||
import './descriptor';
|
||||
import './descriptor-popover';
|
||||
import './card';
|
||||
import './summary';
|
||||
import './log';
|
||||
|
|
|
@ -13,3 +13,5 @@ Created: Creado
|
|||
Booked: Facturado
|
||||
Is inventory: Inventario
|
||||
Notes: Notas
|
||||
Status: Estado
|
||||
Selection: Selección
|
|
@ -0,0 +1,167 @@
|
|||
<mg-ajax path="Tags" options="mgIndex as tags"></mg-ajax>
|
||||
<div class="search-panel">
|
||||
<form ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
label="General search"
|
||||
ng-model="filter.search"
|
||||
info="Search items by id, name or barcode"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-focus
|
||||
url="ItemCategories"
|
||||
label="Category"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
ng-model="filter.categoryFk">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete
|
||||
url="ItemTypes"
|
||||
label="Type"
|
||||
where="{categoryFk: filter.categoryFk}"
|
||||
show-field="name"
|
||||
value-field="id"
|
||||
ng-model="filter.typeFk"
|
||||
fields="['categoryFk']"
|
||||
include="'category'">
|
||||
<tpl-item>
|
||||
<div>{{name}}</div>
|
||||
<div class="text-caption text-secondary">
|
||||
{{category.name}}
|
||||
</div>
|
||||
</tpl-item>>
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
disabled="false"
|
||||
ng-model="filter.salesPersonFk"
|
||||
url="Clients/activeWorkersWithRole"
|
||||
show-field="nickname"
|
||||
search-function="{firstName: $search}"
|
||||
value-field="id"
|
||||
where="{role: 'employee'}"
|
||||
label="Buyer">
|
||||
</vn-autocomplete>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-check
|
||||
label="Is active"
|
||||
ng-model="filter.active"
|
||||
triple-state="true">
|
||||
</vn-check>
|
||||
<vn-check
|
||||
label="Is visible"
|
||||
ng-model="filter.visible"
|
||||
triple-state="true">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-pt-sm">
|
||||
<vn-one class="text-subtitle1" translate>
|
||||
Tags
|
||||
</vn-one>
|
||||
<vn-icon-button
|
||||
vn-none
|
||||
vn-bind="+"
|
||||
vn-tooltip="Add tag"
|
||||
icon="add_circle"
|
||||
ng-click="filter.tags.push({})">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal ng-repeat="itemTag in filter.tags">
|
||||
<vn-autocomplete
|
||||
vn-id="tag"
|
||||
ng-model="itemTag.tagFk"
|
||||
data="tags.model"
|
||||
show-field="name"
|
||||
label="Tag"
|
||||
on-change="itemTag.value = null">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield
|
||||
ng-show="tag.selection.isFree !== false"
|
||||
vn-id="text"
|
||||
label="Value"
|
||||
ng-model="itemTag.value">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
ng-show="tag.selection.isFree === false"
|
||||
url="{{$ctrl.getSourceTable(tag.selection)}}"
|
||||
label="Value"
|
||||
ng-model="itemTag.value"
|
||||
show-field="name"
|
||||
value-field="name">
|
||||
</vn-autocomplete>
|
||||
<vn-icon-button
|
||||
vn-none
|
||||
vn-tooltip="Remove tag"
|
||||
icon="delete"
|
||||
ng-click="filter.tags.splice($index, 1)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-pt-sm">
|
||||
<vn-one class="text-subtitle1" translate>
|
||||
More fields
|
||||
</vn-one>
|
||||
<vn-icon-button
|
||||
vn-none
|
||||
vn-bind="+"
|
||||
vn-tooltip="Add field"
|
||||
icon="add_circle"
|
||||
ng-click="$ctrl.fieldFilters.push({})">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal ng-repeat="fieldFilter in $ctrl.fieldFilters">
|
||||
<vn-autocomplete
|
||||
label="Field"
|
||||
ng-model="fieldFilter.name"
|
||||
data="$ctrl.moreFields"
|
||||
value-field="name"
|
||||
show-field="label"
|
||||
show-filter="false"
|
||||
translate-fields="['label']"
|
||||
selection="info"
|
||||
on-change="fieldFilter.value = null">
|
||||
</vn-autocomplete>
|
||||
<vn-one ng-switch="info.type">
|
||||
<div ng-switch-when="Number">
|
||||
<vn-input-number
|
||||
label="Value"
|
||||
ng-model="fieldFilter.value">
|
||||
</vn-input-number>
|
||||
</div>
|
||||
<div ng-switch-when="Boolean">
|
||||
<vn-check
|
||||
label="Value"
|
||||
ng-model="fieldFilter.value">
|
||||
</vn-check>
|
||||
</div>
|
||||
<div ng-switch-when="Date">
|
||||
<vn-date-picker
|
||||
label="Value"
|
||||
ng-model="fieldFilter.value">
|
||||
</vn-date-picker>
|
||||
</div>
|
||||
<div ng-switch-default>
|
||||
<vn-textfield
|
||||
label="Value"
|
||||
ng-model="fieldFilter.value">
|
||||
</vn-textfield>
|
||||
</div>
|
||||
</vn-one>
|
||||
<vn-icon-button
|
||||
vn-none
|
||||
vn-tooltip="Remove field"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.removeField($index, fieldFilter.name)"
|
||||
tabindex="-1">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal class="vn-mt-lg">
|
||||
<vn-submit label="Search"></vn-submit>
|
||||
</vn-horizontal>
|
||||
</form>
|
||||
</div>
|
|
@ -0,0 +1,79 @@
|
|||
import ngModule from '../module';
|
||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||
|
||||
class Controller extends SearchPanel {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
let model = 'Item';
|
||||
let moreFields = ['description', 'name'];
|
||||
|
||||
let properties;
|
||||
let validations = window.validations;
|
||||
|
||||
if (validations && validations[model])
|
||||
properties = validations[model].properties;
|
||||
else
|
||||
properties = {};
|
||||
|
||||
this.moreFields = [];
|
||||
for (let field of moreFields) {
|
||||
let prop = properties[field];
|
||||
this.moreFields.push({
|
||||
name: field,
|
||||
label: prop ? prop.description : field,
|
||||
type: prop ? prop.type : null
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
get filter() {
|
||||
let filter = this.$.filter;
|
||||
|
||||
for (let fieldFilter of this.fieldFilters)
|
||||
filter[fieldFilter.name] = fieldFilter.value;
|
||||
|
||||
return filter;
|
||||
}
|
||||
|
||||
set filter(value) {
|
||||
if (!value)
|
||||
value = {};
|
||||
if (!value.tags)
|
||||
value.tags = [{}];
|
||||
|
||||
this.fieldFilters = [];
|
||||
for (let field of this.moreFields) {
|
||||
if (value[field.name] != undefined) {
|
||||
this.fieldFilters.push({
|
||||
name: field.name,
|
||||
value: value[field.name],
|
||||
info: field
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this.$.filter = value;
|
||||
}
|
||||
|
||||
getSourceTable(selection) {
|
||||
if (!selection || selection.isFree === true)
|
||||
return null;
|
||||
|
||||
if (selection.sourceTable) {
|
||||
return ''
|
||||
+ selection.sourceTable.charAt(0).toUpperCase()
|
||||
+ selection.sourceTable.substring(1) + 's';
|
||||
} else if (selection.sourceTable == null)
|
||||
return `ItemTags/filterItemTags/${selection.id}`;
|
||||
}
|
||||
|
||||
removeField(index, field) {
|
||||
this.fieldFilters.splice(index, 1);
|
||||
this.$.filter[field] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnLatestBuysSearchPanel', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,45 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Entry', () => {
|
||||
describe('Component vnLatestBuysSearchPanel', () => {
|
||||
let $element;
|
||||
let controller;
|
||||
|
||||
beforeEach(ngModule('entry'));
|
||||
|
||||
beforeEach(angular.mock.inject($componentController => {
|
||||
$element = angular.element(`<vn-latest-buys-search-panel></vn-latest-buys-search-panel>`);
|
||||
controller = $componentController('vnLatestBuysSearchPanel', {$element});
|
||||
}));
|
||||
|
||||
describe('getSourceTable()', () => {
|
||||
it(`should return null if there's no selection`, () => {
|
||||
let selection = null;
|
||||
let result = controller.getSourceTable(selection);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it(`should return null if there's a selection but its isFree property is truthy`, () => {
|
||||
let selection = {isFree: true};
|
||||
let result = controller.getSourceTable(selection);
|
||||
|
||||
expect(result).toBeNull();
|
||||
});
|
||||
|
||||
it(`should return the formated sourceTable concatenated to a path`, () => {
|
||||
let selection = {sourceTable: 'hello guy'};
|
||||
let result = controller.getSourceTable(selection);
|
||||
|
||||
expect(result).toEqual('Hello guys');
|
||||
});
|
||||
|
||||
it(`should return a path if there's no sourceTable and the selection has an id`, () => {
|
||||
let selection = {id: 99};
|
||||
let result = controller.getSourceTable(selection);
|
||||
|
||||
expect(result).toEqual(`ItemTags/filterItemTags/${selection.id}`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,177 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="Buys/latestBuysFilter"
|
||||
limit="20"
|
||||
data="$ctrl.buys">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
panel="vn-latest-buys-search-panel"
|
||||
placeholder="Search by item id or name"
|
||||
info="You can search by item id or name"
|
||||
suggested-filter="{isActive: true}"
|
||||
model="model"
|
||||
auto-state="false">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<vn-data-viewer
|
||||
model="model"
|
||||
class="vn-mb-xl vn-w-xl">
|
||||
<vn-card>
|
||||
<vn-table
|
||||
model="model"
|
||||
show-fields="$ctrl.showFields"
|
||||
vn-smart-table="latestBuys">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th shrink>
|
||||
<vn-multi-check
|
||||
model="model">
|
||||
</vn-multi-check>
|
||||
</vn-th>
|
||||
<vn-th field="Image">Picture</vn-th>
|
||||
<vn-th smart-table-ignore field="id">Id</vn-th>
|
||||
<vn-th field="packing">Packing</vn-th>
|
||||
<vn-th field="grouping">Grouping</vn-th>
|
||||
<vn-th field="description" style="text-align: center">Description</vn-th>
|
||||
<vn-th field="size">Size</vn-th>
|
||||
<vn-th field="type">Type</vn-th>
|
||||
<vn-th field="intrastat">Intrastat</vn-th>
|
||||
<vn-th field="origin">Origin</vn-th>
|
||||
<vn-th field="density">Density</vn-th>
|
||||
<vn-th field="isActive">Active</vn-th>
|
||||
<vn-th field="family">Family</vn-th>
|
||||
<vn-th field="entryFk">Entry</vn-th>
|
||||
<vn-th field="quantity">Quantity</vn-th>
|
||||
<vn-th field="buyingValue">Buying value</vn-th>
|
||||
<vn-th field="freightValue">Freight value</vn-th>
|
||||
<vn-th field="comissionValue" expand>Commission value</vn-th>
|
||||
<vn-th field="packageValue" expand>Package value</vn-th>
|
||||
<vn-th field="isIgnored">Is ignored</vn-th>
|
||||
<vn-th expand field="price2">Grouping price</vn-th>
|
||||
<vn-th expand field="price3">Packing price</vn-th>
|
||||
<vn-th field="minPrice">Min price</vn-th>
|
||||
<vn-th field="ektFk">Ekt</vn-th>
|
||||
<vn-th field="weight">Weight</vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
<vn-tbody>
|
||||
<a ng-repeat="buy in $ctrl.buys"
|
||||
class="clickable vn-tr search-result"
|
||||
ui-sref="entry.card.buy({id: {{::buy.entryFk}}})">
|
||||
<vn-td shrink>
|
||||
<vn-check
|
||||
ng-model="buy.checked"
|
||||
vn-click-stop>
|
||||
</vn-check>
|
||||
</vn-td>
|
||||
<vn-td shrink >
|
||||
<img
|
||||
ng-src="{{::$root.imagePath}}/catalog/50x50/{{::buy.image}}"
|
||||
zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{::buy.image}}"
|
||||
vn-click-stop
|
||||
on-error-src/>
|
||||
</vn-td>
|
||||
<vn-td shrink>
|
||||
<span
|
||||
vn-click-stop="itemDescriptor.show($event, buy.itemFk)"
|
||||
class="link">
|
||||
{{::buy.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<vn-chip translate-attr="buy.groupingMode == 2 ? {title: 'Minimun amount'} : {title: 'Packing'}" ng-class="{'message': buy.groupingMode == 2}">
|
||||
<span translate>{{::buy.packing | dashIfEmpty}}</span>
|
||||
</vn-chip>
|
||||
</vn-td>
|
||||
<vn-td number>
|
||||
<vn-chip translate-attr="buy.groupingMode == 1 ? {title: 'Minimun amount'} : {title: 'Grouping'}" ng-class="{'message': buy.groupingMode == 1}">
|
||||
<span translate>{{::buy.grouping | dashIfEmpty}}</span>
|
||||
</vn-chip>
|
||||
</vn-td>
|
||||
<vn-td vn-two title="{{::buy.description}}">
|
||||
{{::buy.description | dashIfEmpty}}
|
||||
</vn-td>
|
||||
<vn-td number>{{::buy.size}}</vn-td>
|
||||
<vn-td shrink title="{{::buy.type}}">
|
||||
{{::buy.type}}
|
||||
</vn-td>
|
||||
<vn-td shrink title="{{::item.intrastat}}">
|
||||
{{::buy.intrastat}}
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::buy.origin}}</vn-td>
|
||||
<vn-td shrink>{{::buy.density}}</vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::buy.isActive">
|
||||
</vn-check>
|
||||
</vn-td>
|
||||
<vn-td shrink>{{::buy.family}}</vn-td>
|
||||
<vn-td shrink>
|
||||
<span
|
||||
vn-click-stop="entryDescriptor.show($event, buy.entryFk)"
|
||||
class="link">
|
||||
{{::buy.entryFk}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td number>{{::buy.quantity}}</vn-td>
|
||||
<vn-td number>{{::buy.buyingValue | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{::buy.freightValue | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{::buy.comissionValue | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{::buy.packageValue | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td shrink>{{::buy.isIgnored}}</vn-td>
|
||||
<vn-td number>{{::buy.price2 | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{::buy.price3 | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{::buy.minPrice | currency: 'EUR':2}}</vn-td>
|
||||
<vn-td number>{{::buy.ektFk | dashIfEmpty}}</vn-td>
|
||||
<vn-td number>{{::buy.weight}}</vn-td>
|
||||
</a>
|
||||
</vn-tbody>
|
||||
</vn-table>
|
||||
</vn-card>
|
||||
</vn-data-viewer>
|
||||
<div fixed-bottom-right>
|
||||
<vn-vertical style="align-items: center;">
|
||||
<vn-button class="round sm vn-mb-sm"
|
||||
icon="edit"
|
||||
ng-show="$ctrl.totalChecked > 0"
|
||||
ng-click="edit.show($event)"
|
||||
vn-tooltip="Edit buy(s)"
|
||||
tooltip-position="left">
|
||||
</vn-button>
|
||||
</vn-vertical>
|
||||
</div>
|
||||
<vn-dialog class="edit"
|
||||
vn-id="edit"
|
||||
on-accept="$ctrl.onEditAccept()"
|
||||
on-close="$ctrl.editedColumn = null"
|
||||
message="Edit buy(s)">
|
||||
<tpl-body>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-two
|
||||
ng-model="$ctrl.editedColumn.field"
|
||||
data="$ctrl.columns"
|
||||
value-field="field"
|
||||
show-field="displayName"
|
||||
label="Field to edit">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="Value"
|
||||
ng-model="$ctrl.editedColumn.newValue">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Create</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
||||
<vn-item-descriptor-popover
|
||||
vn-id="itemDescriptor">
|
||||
</vn-item-descriptor-popover>
|
||||
<vn-entry-descriptor-popover
|
||||
vn-id="entryDescriptor">
|
||||
</vn-entry-descriptor-popover>
|
|
@ -0,0 +1,78 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
|
||||
export default class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
this.showFields = {
|
||||
id: false,
|
||||
actions: false
|
||||
};
|
||||
this.editedColumn;
|
||||
}
|
||||
|
||||
get columns() {
|
||||
if (this._columns) return this._columns;
|
||||
|
||||
this._columns = [
|
||||
{field: 'quantity', displayName: this.$t('Quantity')},
|
||||
{field: 'buyingValue', displayName: this.$t('Buying value')},
|
||||
{field: 'freightValue', displayName: this.$t('Freight value')},
|
||||
{field: 'packing', displayName: this.$t('Packing')},
|
||||
{field: 'grouping', displayName: this.$t('Grouping')},
|
||||
{field: 'comissionValue', displayName: this.$t('Commission value')},
|
||||
{field: 'packageValue', displayName: this.$t('Package value')},
|
||||
{field: 'price2', displayName: this.$t('Grouping price')},
|
||||
{field: 'price3', displayName: this.$t('Packing price')},
|
||||
{field: 'weight', displayName: this.$t('Weight')},
|
||||
{field: 'description', displayName: this.$t('Description')},
|
||||
{field: 'minPrice', displayName: this.$t('Min price')},
|
||||
{field: 'size', displayName: this.$t('Size')},
|
||||
{field: 'density', displayName: this.$t('Density')}
|
||||
];
|
||||
|
||||
return this._columns;
|
||||
}
|
||||
|
||||
get checked() {
|
||||
const buys = this.$.model.data || [];
|
||||
const checkedBuys = [];
|
||||
for (let buy of buys) {
|
||||
if (buy.checked)
|
||||
checkedBuys.push(buy);
|
||||
}
|
||||
|
||||
return checkedBuys;
|
||||
}
|
||||
|
||||
uncheck() {
|
||||
const lines = this.checked;
|
||||
for (let line of lines) {
|
||||
if (line.checked)
|
||||
line.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
get totalChecked() {
|
||||
return this.checked.length;
|
||||
}
|
||||
|
||||
onEditAccept() {
|
||||
let data = {
|
||||
field: this.editedColumn.field,
|
||||
newValue: this.editedColumn.newValue,
|
||||
lines: this.checked
|
||||
};
|
||||
|
||||
return this.$http.post('Buys/editLatestBuys', data)
|
||||
.then(() => {
|
||||
this.uncheck();
|
||||
this.$.model.refresh();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnEntryLatestBuys', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,82 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Entry', () => {
|
||||
describe('Component vnEntryLatestBuys', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('entry'));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, $compile, $rootScope, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
let $element = $compile('<vn-entry-latest-buys></vn-entry-latest-buys')($rootScope);
|
||||
controller = $componentController('vnEntryLatestBuys', {$element});
|
||||
controller.$ = {
|
||||
model: {refresh: () => {}},
|
||||
edit: {hide: () => {}}
|
||||
};
|
||||
}));
|
||||
|
||||
describe('get columns', () => {
|
||||
it(`should return a set of columns`, () => {
|
||||
let result = controller.columns;
|
||||
|
||||
let length = result.length;
|
||||
let anyColumn = Object.keys(result[Math.floor(Math.random() * Math.floor(length))]);
|
||||
|
||||
expect(anyColumn).toContain('field', 'displayName');
|
||||
});
|
||||
});
|
||||
|
||||
describe('get checked', () => {
|
||||
it(`should return a set of checked lines`, () => {
|
||||
controller.$.model.data = [
|
||||
{checked: true, id: 1},
|
||||
{checked: true, id: 2},
|
||||
{checked: true, id: 3},
|
||||
{checked: false, id: 4},
|
||||
];
|
||||
|
||||
let result = controller.checked;
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
});
|
||||
});
|
||||
|
||||
describe('uncheck()', () => {
|
||||
it(`should clear the selection of lines on the controller`, () => {
|
||||
controller.$.model.data = [
|
||||
{checked: true, id: 1},
|
||||
{checked: true, id: 2},
|
||||
{checked: true, id: 3},
|
||||
{checked: false, id: 4},
|
||||
];
|
||||
|
||||
let result = controller.checked;
|
||||
|
||||
expect(result.length).toEqual(3);
|
||||
|
||||
controller.uncheck();
|
||||
|
||||
result = controller.checked;
|
||||
|
||||
expect(result.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('onEditAccept()', () => {
|
||||
it(`should perform a query to update columns`, () => {
|
||||
controller.editedColumn = {field: 'my field', newValue: 'the new value'};
|
||||
let query = 'Buys/editLatestBuys';
|
||||
|
||||
$httpBackend.expectPOST(query).respond();
|
||||
controller.onEditAccept();
|
||||
$httpBackend.flush();
|
||||
|
||||
const result = controller.checked;
|
||||
|
||||
expect(result.length).toEqual(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
Minimun amount: Minimun purchase quantity
|
|
@ -0,0 +1,13 @@
|
|||
Edit buy(s): Editar compra(s)
|
||||
Buying value: Precio
|
||||
Freight value: Porte
|
||||
Commission value: Comisión
|
||||
Package value: Embalaje
|
||||
Is ignored: Ignorado
|
||||
Grouping price: Precio grouping
|
||||
Packing price: Precio packing
|
||||
Min price: Precio min
|
||||
Ekt: Ekt
|
||||
Weight: Peso
|
||||
Minimun amount: Cantidad mínima de compra
|
||||
Field to edit: Campo a editar
|
|
@ -1,5 +1,6 @@
|
|||
#Ordenar alfabeticamente
|
||||
|
||||
entry: entrada
|
||||
Latest buys: Últimas compras
|
||||
|
||||
# Sections
|
||||
|
|
|
@ -2,11 +2,12 @@
|
|||
"module": "entry",
|
||||
"name": "Entries",
|
||||
"icon": "icon-entry",
|
||||
"dependencies": ["travel"],
|
||||
"dependencies": ["travel", "item"],
|
||||
"validations": true,
|
||||
"menus": {
|
||||
"main": [
|
||||
{"state": "entry.index", "icon": "icon-entry"}
|
||||
{"state": "entry.index", "icon": "icon-entry"},
|
||||
{"state": "entry.latestBuys", "icon": "icon-latestBuys"}
|
||||
],
|
||||
"card": [
|
||||
{"state": "entry.card.buy", "icon": "icon-lines"},
|
||||
|
@ -24,7 +25,14 @@
|
|||
"url": "/index?q",
|
||||
"state": "entry.index",
|
||||
"component": "vn-entry-index",
|
||||
"description": "Entries"
|
||||
"description": "Entries",
|
||||
"acl": ["buyer"]
|
||||
}, {
|
||||
"url": "/latest-buys?q",
|
||||
"state": "entry.latestBuys",
|
||||
"component": "vn-entry-latest-buys",
|
||||
"description": "Latest buys",
|
||||
"acl": ["buyer"]
|
||||
}, {
|
||||
"url": "/:id",
|
||||
"state": "entry.card",
|
||||
|
|
|
@ -12,42 +12,38 @@ module.exports = Self => {
|
|||
arg: 'filter',
|
||||
type: 'Object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'tags',
|
||||
type: ['Object'],
|
||||
description: 'List of tags to filter with',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'search',
|
||||
type: 'String',
|
||||
description: `If it's and integer searchs by id, otherwise it searchs by name`,
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'id',
|
||||
type: 'Integer',
|
||||
description: 'Item id',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'categoryFk',
|
||||
type: 'Integer',
|
||||
description: 'Category id',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'typeFk',
|
||||
type: 'Integer',
|
||||
description: 'Type id',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'isActive',
|
||||
type: 'Boolean',
|
||||
description: 'Whether the the item is o not active',
|
||||
http: {source: 'query'}
|
||||
description: 'Whether the the item is or not active',
|
||||
}, {
|
||||
arg: 'salesPersonFk',
|
||||
type: 'Integer',
|
||||
description: 'The buyer of the item',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'description',
|
||||
type: 'String',
|
||||
description: 'The item description',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
|
|
|
@ -122,6 +122,9 @@
|
|||
"mysql": {
|
||||
"columnName": "expenceFk"
|
||||
}
|
||||
},
|
||||
"minPrice": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
|
|
@ -8,24 +8,24 @@
|
|||
<vn-table
|
||||
model="model"
|
||||
show-fields="$ctrl.showFields"
|
||||
vn-uvc="itemIndex">
|
||||
vn-smart-table="itemIndex">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th th-id="picture" shrink></vn-th>
|
||||
<vn-th shrink></vn-th>
|
||||
<vn-th field="id" shrink>Id</vn-th>
|
||||
<vn-th th-id="grouping" shrink>Grouping</vn-th>
|
||||
<vn-th th-id="packing" shrink>Packing</vn-th>
|
||||
<vn-th th-id="description" style="text-align: center">Description</vn-th>
|
||||
<vn-th th-id="stems" shrink>Stems</vn-th>
|
||||
<vn-th th-id="size" shrink>Size</vn-th>
|
||||
<vn-th th-id="niche" shrink>Niche</vn-th>
|
||||
<vn-th th-id="type" shrink>Type</vn-th>
|
||||
<vn-th th-id="category" shrink>Category</vn-th>
|
||||
<vn-th th-id="intrastat" shrink>Intrastat</vn-th>
|
||||
<vn-th th-id="origin" shrink>Origin</vn-th>
|
||||
<vn-th th-id="salesperson" shrink>Buyer</vn-th>
|
||||
<vn-th th-id="density" shrink>Density</vn-th>
|
||||
<vn-th th-id="active" shrink>Active</vn-th>
|
||||
<vn-th field="grouping" shrink>Grouping</vn-th>
|
||||
<vn-th field="packing" shrink>Packing</vn-th>
|
||||
<vn-th field="description" style="text-align: center">Description</vn-th>
|
||||
<vn-th field="stems" shrink>Stems</vn-th>
|
||||
<vn-th field="size" shrink>Size</vn-th>
|
||||
<vn-th field="niche" shrink>Niche</vn-th>
|
||||
<vn-th field="type" shrink>Type</vn-th>
|
||||
<vn-th field="category" shrink>Category</vn-th>
|
||||
<vn-th field="intrastat" shrink>Intrastat</vn-th>
|
||||
<vn-th field="origin" shrink>Origin</vn-th>
|
||||
<vn-th field="salesperson" shrink>Buyer</vn-th>
|
||||
<vn-th field="density" shrink>Density</vn-th>
|
||||
<vn-th field="active" shrink>Active</vn-th>
|
||||
<vn-th></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
|
|
|
@ -70,7 +70,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
|
||||
window.open = jasmine.createSpy('open');
|
||||
const params = {
|
||||
clientId: ticket.client.id,
|
||||
recipientId: ticket.client.id,
|
||||
ticketId: ticket.id
|
||||
};
|
||||
controller.showDeliveryNote();
|
||||
|
@ -85,7 +85,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
|
||||
const params = {
|
||||
recipient: ticket.client.email,
|
||||
clientId: ticket.client.id,
|
||||
recipientId: ticket.client.id,
|
||||
ticketId: ticket.id
|
||||
};
|
||||
controller.sendDeliveryNote();
|
||||
|
@ -135,7 +135,7 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
});
|
||||
|
||||
describe('canStowaway()', () => {
|
||||
fit('should make a query and return if the ticket can be stowawayed', () => {
|
||||
it('should make a query and return if the ticket can be stowawayed', () => {
|
||||
controller.canStowaway();
|
||||
$httpBackend.flush();
|
||||
|
||||
|
@ -179,13 +179,10 @@ describe('Ticket Component vnTicketDescriptor', () => {
|
|||
|
||||
describe('loadData()', () => {
|
||||
it(`should perform a get query to store the ticket data into the controller`, () => {
|
||||
controller.ticket = null;
|
||||
|
||||
$httpBackend.expectRoute('GET', `Tickets/${ticket.id}`).respond(ticket);
|
||||
controller.id = ticket.id;
|
||||
$httpBackend.when('GET', `Tickets/${ticket.id}/isEditable`).respond();
|
||||
$httpBackend.expectRoute('GET', `Tickets/${ticket.id}`).respond();
|
||||
controller.loadData();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.ticket).toEqual(ticket);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue