latestsBuys + e2e path #340

Merged
carlosjr merged 18 commits from 2341-Entry_lastBuy_section into dev 2020-09-02 13:36:04 +00:00
21 changed files with 539 additions and 158 deletions
Showing only changes of commit 3a82ef0e06 - Show all commits

View File

@ -0,0 +1,2 @@
INSERT INTO `salix`.`ACL` (`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
VALUES ('Buy', '*', '*', 'ALLOW', 'ROLE', 'buyer');

View File

@ -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`;

View File

@ -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;
}
};
};

View File

@ -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;

View File

@ -2,6 +2,9 @@
"Entry": {
"dataSource": "vn"
},
"Buy": {
"dataSource": "vn"
},
"EntryLog": {
"dataSource": "vn"
}

View File

@ -0,0 +1,4 @@
module.exports = Self => {
require('../methods/entry/editLatestBuys')(Self);
require('../methods/entry/latestBuysFilter')(Self);
};

View File

@ -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
}
}
}

View File

@ -1,5 +1,4 @@
module.exports = Self => {
require('../methods/entry/latestBuysFilter')(Self);
require('../methods/entry/filter')(Self);
require('../methods/entry/getEntry')(Self);
};

View File

@ -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'
}
]

View File

@ -0,0 +1,3 @@
<slot-descriptor>
<vn-entry-descriptor></vn-entry-descriptor>
</slot-descriptor>

View File

@ -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
});

View File

@ -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

View File

@ -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';

View File

@ -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"

View File

@ -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;

View File

@ -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>

View File

@ -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', {

View File

@ -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",

View File

@ -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: {

View File

@ -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>

View File

@ -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></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></vn-th>
<vn-th field="description">Description</vn-th>
<vn-th shrink></vn-th>
</vn-tr>
</vn-thead>