latestsBuys + e2e path #340
|
@ -0,0 +1,2 @@
|
|||
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES ('Buy', '*', '*', 'ALLOW', 'ROLE', 'buyer');
|
|
@ -2,22 +2,26 @@ import ngModule from '../module';
|
|||
import template from './smart-table.html';
|
||||
import './smart-table.scss';
|
||||
|
||||
/**
|
||||
* Directive to hide/show selected columns of a table, don't use with rowspan.
|
||||
*/
|
||||
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]');
|
||||
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,8 +42,8 @@ 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-smart-table=${userConfig.tableCode}] > div`;
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
module.exports = Self => {
|
||||
Self.remoteMethod('editLatestBuys', {
|
||||
description: 'Updates a column for one of more buys',
|
||||
accessType: 'WRITE',
|
||||
accepts: [{
|
||||
arg: 'column',
|
||||
type: 'Object',
|
||||
required: true,
|
||||
description: `the column to edit and it's new value`
|
||||
},
|
||||
{
|
||||
arg: 'buys',
|
||||
type: ['Object'],
|
||||
required: true,
|
||||
description: `the buys which will be modified`
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/editLatestBuys`,
|
||||
verb: 'POST'
|
||||
}
|
||||
});
|
||||
|
||||
Self.editLatestBuys = async(column, buys) => {
|
||||
let modelName;
|
||||
let identifier;
|
||||
switch (column.field) {
|
||||
case 'size':
|
||||
case 'density':
|
||||
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 'minPrice':
|
||||
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 = buys.map(buy => {
|
||||
return buy[identifier];
|
||||
});
|
||||
|
||||
let value = {};
|
||||
value[column.field] = column.newValue;
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
};
|
|
@ -12,43 +12,44 @@ 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: '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: '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',
|
||||
arg: 'active',
|
||||
type: 'Boolean',
|
||||
description: 'Whether the the item is or not active',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'visible',
|
||||
type: 'Boolean',
|
||||
description: 'Whether the the item is or not visible',
|
||||
}, {
|
||||
arg: 'salesPersonFk',
|
||||
type: 'Integer',
|
||||
description: 'The buyer of the item',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'description',
|
||||
type: 'String',
|
||||
description: 'The item description',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
|
@ -64,42 +65,100 @@ module.exports = Self => {
|
|||
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)
|
||||
// ? {or: [{'i.id': value}]}
|
||||
// : {or: [{'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 {'t.workerFk': value};
|
||||
// case 'typeFk':
|
||||
// return {'i.typeFk': value};
|
||||
// case 'isActive':
|
||||
// return {'i.isActive': 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;
|
||||
|
||||
stmt = new ParameterizedSQL('CALL cache.last_buy_refresh(FALSE)');
|
||||
stmts.push(stmt);
|
||||
stmts.push('CALL cache.last_buy_refresh(FALSE)');
|
||||
stmts.push('CALL cache.visible_refresh(@calc_id, FALSE, 1)');
|
||||
|
||||
stmt = new ParameterizedSQL(`
|
||||
SELECT
|
||||
size
|
||||
i.image,
|
||||
i.id AS itemFk,
|
||||
i.size,
|
||||
i.density,
|
||||
i.typeFk,
|
||||
t.name AS type,
|
||||
i.family,
|
||||
intr.description AS intrastat,
|
||||
ori.code AS origin,
|
||||
i.isActive,
|
||||
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.minPrice,
|
||||
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`
|
||||
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;
|
||||
|
||||
|
|
|
@ -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,64 @@
|
|||
{
|
||||
"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"
|
||||
},
|
||||
"minPrice": {
|
||||
"type": "number"
|
||||
},
|
||||
"weight": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
"entry": {
|
||||
"type": "belongsTo",
|
||||
"model": "Entry",
|
||||
"foreignKey": "entryFk",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,4 @@
|
|||
module.exports = Self => {
|
||||
require('../methods/entry/latestBuysFilter')(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
|
||||
|
|
|
@ -6,6 +6,7 @@ import './latest-buys';
|
|||
import './search-panel';
|
||||
import './latest-buys-search-panel';
|
||||
import './descriptor';
|
||||
import './descriptor-popover';
|
||||
import './card';
|
||||
import './summary';
|
||||
import './log';
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
<form ng-submit="$ctrl.onSearch()">
|
||||
<vn-horizontal>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
label="General search"
|
||||
ng-model="filter.search"
|
||||
info="Search items by id, name or barcode"
|
||||
|
@ -12,7 +11,6 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
vn-focus
|
||||
url="ItemCategories"
|
||||
label="Category"
|
||||
|
@ -20,7 +18,7 @@
|
|||
value-field="id"
|
||||
ng-model="filter.categoryFk">
|
||||
</vn-autocomplete>
|
||||
<vn-autocomplete vn-one
|
||||
<vn-autocomplete
|
||||
url="ItemTypes"
|
||||
label="Type"
|
||||
where="{categoryFk: filter.categoryFk}"
|
||||
|
@ -39,7 +37,6 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
disabled="false"
|
||||
ng-model="filter.salesPersonFk"
|
||||
url="Clients/activeWorkersWithRole"
|
||||
|
@ -50,6 +47,18 @@
|
|||
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
|
||||
|
@ -65,7 +74,6 @@
|
|||
<vn-horizontal ng-repeat="itemTag in filter.tags">
|
||||
<vn-autocomplete
|
||||
vn-id="tag"
|
||||
vn-one
|
||||
ng-model="itemTag.tagFk"
|
||||
data="tags.model"
|
||||
show-field="name"
|
||||
|
@ -73,14 +81,12 @@
|
|||
on-change="itemTag.value = null">
|
||||
</vn-autocomplete>
|
||||
<vn-textfield
|
||||
vn-one
|
||||
ng-show="tag.selection.isFree !== false"
|
||||
vn-id="text"
|
||||
label="Value"
|
||||
ng-model="itemTag.value">
|
||||
</vn-textfield>
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
ng-show="tag.selection.isFree === false"
|
||||
url="{{$ctrl.getSourceTable(tag.selection)}}"
|
||||
label="Value"
|
||||
|
@ -110,7 +116,6 @@
|
|||
</vn-horizontal>
|
||||
<vn-horizontal ng-repeat="fieldFilter in $ctrl.fieldFilters">
|
||||
<vn-autocomplete
|
||||
vn-one
|
||||
label="Field"
|
||||
ng-model="fieldFilter.name"
|
||||
data="$ctrl.moreFields"
|
||||
|
|
|
@ -5,7 +5,7 @@ class Controller extends SearchPanel {
|
|||
constructor($element, $) {
|
||||
super($element, $);
|
||||
let model = 'Item';
|
||||
let moreFields = ['id', 'description', 'name', 'isActive'];
|
||||
let moreFields = ['id', 'description', 'name'];
|
||||
|
||||
let properties;
|
||||
let validations = window.validations;
|
||||
|
|
|
@ -1,28 +1,19 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="Entries/latestBuysFilter"
|
||||
url="Buys/latestBuysFilter"
|
||||
limit="20"
|
||||
data="buys"
|
||||
auto-load="true">
|
||||
data="$ctrl.buys">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
panel="vn-latest-buys-search-panel"
|
||||
suggested-filter="$ctrl.filterParams"
|
||||
info="Search buys"
|
||||
filter="$ctrl.filterParams"
|
||||
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-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
panel="vn-latest-buys-search-panel"
|
||||
info="Search buys"
|
||||
model="model"
|
||||
auto-state="false">
|
||||
</vn-searchbar>
|
||||
</vn-portal> -->
|
||||
<vn-data-viewer
|
||||
model="model"
|
||||
class="vn-mb-xl vn-w-xl">
|
||||
|
@ -33,72 +24,98 @@
|
|||
vn-smart-table="latestBuys">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th shrink
|
||||
field='Selection'>
|
||||
<vn-multi-check
|
||||
<vn-th shrink>
|
||||
<vn-multi-check
|
||||
model="model">
|
||||
</vn-multi-check>
|
||||
</vn-th>
|
||||
<vn-th shrink field='status'></vn-th>
|
||||
<vn-th field="id" number>Id</vn-th>
|
||||
<vn-th field="landed" center>Landed</vn-th>
|
||||
<vn-th>Reference</vn-th>
|
||||
<vn-th field="supplierFk">Supplier</vn-th>
|
||||
<vn-th field="currencyFk" center>Currency</vn-th>
|
||||
<vn-th field="companyFk" center>Company</vn-th>
|
||||
<vn-th field="isBooked" center>Booked</vn-th>
|
||||
<vn-th field="isConfirmed" center>Confirmed</vn-th>
|
||||
<vn-th field="isOrdered" center>Ordered</vn-th>
|
||||
<vn-th>Notes</vn-th>
|
||||
<vn-th field="picture">Picture</vn-th>
|
||||
<vn-th field="id">Id</vn-th>
|
||||
<vn-th field="grouping">Grouping</vn-th>
|
||||
<vn-th field="packing">Packing</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>Comission value</vn-th>
|
||||
<vn-th field="packageValue" expand>Package value</vn-th>
|
||||
<vn-th field="isIgnored">Is ignored</vn-th>
|
||||
<vn-th field="groupingMode" expand>Grouping mode</vn-th>
|
||||
<vn-th field="price2">price2</vn-th>
|
||||
<vn-th field="price3">price3</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="buy.card.summary({id: {{::buy.id}}})">
|
||||
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>
|
||||
<vn-icon
|
||||
ng-show="buy.isInventory"
|
||||
class="bright"
|
||||
vn-tooltip="Inventory buy"
|
||||
icon="icon-inventory">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-show="buy.isRaid"
|
||||
class="bright"
|
||||
vn-tooltip="Virtual buy"
|
||||
icon="icon-net">
|
||||
</vn-icon>
|
||||
<vn-td shrink >
|
||||
<img
|
||||
ng-src="{{::$root.imagePath}}/catalog/50x50/{{::buy.image}}"
|
||||
zoom-image="{{::$root.imagePath}}/catalog/1600x900/{{::item.image}}"
|
||||
vn-click-stop
|
||||
on-error-src/>
|
||||
</vn-td>
|
||||
<vn-td number>{{::buy.size}}</vn-td>
|
||||
<vn-td center>
|
||||
<span
|
||||
class="link"
|
||||
vn-click-stop="travelDescriptor.show($event, buy.travelFk)">
|
||||
{{::buy.landed | date:'dd/MM/yyyy'}}
|
||||
<vn-td shrink>
|
||||
<span
|
||||
vn-click-stop="itemDescriptor.show($event, buy.itemFk)"
|
||||
class="link">
|
||||
{{::buy.itemFk | zeroFill:6}}
|
||||
</span>
|
||||
</vn-td>
|
||||
<vn-td expand>{{::buy.ref}}</vn-td>
|
||||
<vn-td expand>{{::buy.supplierName}}</vn-td>
|
||||
<vn-td center expand>{{::buy.currencyCode}}</vn-td>
|
||||
<vn-td center expand>{{::buy.companyCode}}</vn-td>
|
||||
<vn-td center><vn-check ng-model="buy.isBooked" disabled="true"></vn-check></vn-td>
|
||||
<vn-td center><vn-check ng-model="buy.isConfirmed" disabled="true"></vn-check></vn-td>
|
||||
<vn-td center><vn-check ng-model="buy.isOrdered" disabled="true"></vn-check></vn-td>
|
||||
<vn-td shrink>
|
||||
<vn-icon
|
||||
ng-if="buy.notes.length"
|
||||
vn-tooltip="{{::buy.notes}}"
|
||||
icon="insert_drive_file"
|
||||
class="bright">
|
||||
</vn-icon>
|
||||
<vn-td number>{{::buy.grouping}}</vn-td>
|
||||
<vn-td number>{{::buy.packing}}</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 shrink>{{::buy.groupingMode}}</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>
|
||||
|
@ -109,12 +126,41 @@
|
|||
<vn-button class="round sm vn-mb-sm"
|
||||
icon="edit"
|
||||
ng-show="$ctrl.totalChecked > 0"
|
||||
ng-click="$ctrl.edit()"
|
||||
ng-click="edit.show($event)"
|
||||
vn-tooltip="Edit buys"
|
||||
tooltip-position="left">
|
||||
</vn-button>
|
||||
</vn-vertical>
|
||||
</div>
|
||||
<vn-travel-descriptor-popover
|
||||
vn-id="travelDescriptor">
|
||||
</vn-travel-descriptor-popover>
|
||||
<vn-dialog class="edit"
|
||||
vn-id="edit"
|
||||
on-accept="$ctrl.onEditAccept()"
|
||||
message="Edit buy(s)">
|
||||
<tpl-body>
|
||||
<vn-horizontal>
|
||||
<vn-autocomplete
|
||||
vn-two
|
||||
ng-model="$ctrl.editedColumn.field"
|
||||
data="$ctrl.columns"
|
||||
show-field="displayName"
|
||||
value-field="field"
|
||||
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>
|
||||
|
|
|
@ -8,7 +8,33 @@ export default class Controller extends Section {
|
|||
id: false,
|
||||
actions: false
|
||||
};
|
||||
this.editedColumn;
|
||||
}
|
||||
|
||||
get columns() {
|
||||
if (this._columns) return this._columns;
|
||||
|
||||
this._columns = [
|
||||
{field: 'quantity', displayName: 'quantity'},
|
||||
{field: 'buyingValue', displayName: 'buyingValue'},
|
||||
{field: 'freightValue', displayName: 'freightValue'},
|
||||
{field: 'packing', displayName: 'packing'},
|
||||
{field: 'grouping', displayName: 'grouping'},
|
||||
{field: 'groupingMode', displayName: 'groupingMode'},
|
||||
{field: 'comissionValue', displayName: 'comissionValue'},
|
||||
{field: 'packageValue', displayName: 'packageValue'},
|
||||
{field: 'price2', displayName: 'price2'},
|
||||
{field: 'price3', displayName: 'price3'},
|
||||
{field: 'minPrice', displayName: 'minPrice'},
|
||||
{field: 'weight', displayName: 'weight'},
|
||||
{field: 'size', displayName: 'size'},
|
||||
{field: 'density', displayName: 'density'},
|
||||
{field: 'description', displayName: 'description'}
|
||||
];
|
||||
|
||||
return this._columns;
|
||||
}
|
||||
|
||||
get checked() {
|
||||
const buys = this.$.model.data || [];
|
||||
const checkedBuys = [];
|
||||
|
@ -20,9 +46,36 @@ export default class Controller extends Section {
|
|||
return checkedBuys;
|
||||
}
|
||||
|
||||
uncheck() {
|
||||
console.log('clicked!');
|
||||
const lines = this.checked;
|
||||
for (let line of lines) {
|
||||
if (line.checked)
|
||||
line.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
get totalChecked() {
|
||||
return this.checked.length;
|
||||
}
|
||||
|
||||
onEditAccept() {
|
||||
let data = {
|
||||
column: this.editedColumn,
|
||||
buys: this.checked
|
||||
};
|
||||
|
||||
this.$http.post('Buys/editLatestBuys', data)
|
||||
.then(() => {
|
||||
this.$.edit.hide();
|
||||
this.uncheck();
|
||||
this.$.model.refresh();
|
||||
});
|
||||
|
||||
this.editedColumn = null;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.component('vnEntryLatestBuys', {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"module": "entry",
|
||||
"name": "Entries",
|
||||
"icon": "icon-entry",
|
||||
"dependencies": ["travel"],
|
||||
"dependencies": ["travel", "item"],
|
||||
"validations": true,
|
||||
"menus": {
|
||||
"main": [
|
||||
|
@ -25,12 +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"
|
||||
"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 or not active',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'salesPersonFk',
|
||||
type: 'Integer',
|
||||
description: 'The buyer of the item',
|
||||
http: {source: 'query'}
|
||||
}, {
|
||||
arg: 'description',
|
||||
type: 'String',
|
||||
description: 'The item description',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
|
|
|
@ -11,21 +11,21 @@
|
|||
vn-smart-table="itemIndex">
|
||||
<vn-thead>
|
||||
<vn-tr>
|
||||
<vn-th th-id="picture" shrink></vn-th>
|
||||
<vn-th field="picture" 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>
|
||||
|
|
|
@ -14,12 +14,12 @@
|
|||
</vn-multi-check>
|
||||
</vn-th>
|
||||
<vn-th field="id" number>Id</vn-th>
|
||||
<vn-th th-id="worker">Worker</vn-th>
|
||||
<vn-th th-id="agency">Agency</vn-th>
|
||||
<vn-th th-id="vehicle">Vehicle</vn-th>
|
||||
<vn-th th-id="created">Date</vn-th>
|
||||
<vn-th th-id="m3" number>m³</vn-th>
|
||||
<vn-th th-id="description">Description</vn-th>
|
||||
<vn-th field="worker">Worker</vn-th>
|
||||
<vn-th field="agency">Agency</vn-th>
|
||||
<vn-th field="vehicle">Vehicle</vn-th>
|
||||
<vn-th field="created">Date</vn-th>
|
||||
<vn-th field="m3" number>m³</vn-th>
|
||||
<vn-th field="description">Description</vn-th>
|
||||
<vn-th shrink></vn-th>
|
||||
</vn-tr>
|
||||
</vn-thead>
|
||||
|
|
Loading…
Reference in New Issue