Merge branch 'dev' into 2409-last_entries_contextmenu
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
This commit is contained in:
commit
5a16a10b8f
|
@ -2,6 +2,9 @@
|
||||||
"Account": {
|
"Account": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
"AccountingType": {
|
||||||
|
"dataSource": "vn"
|
||||||
|
},
|
||||||
"Bank": {
|
"Bank": {
|
||||||
"dataSource": "vn"
|
"dataSource": "vn"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"name": "AccountingType",
|
||||||
|
"base": "VnModel",
|
||||||
|
"options": {
|
||||||
|
"mysql": {
|
||||||
|
"table": "accountingType"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "Number",
|
||||||
|
"id": true,
|
||||||
|
"description": "Identifier"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "String",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
"receiptDescription": {
|
||||||
|
"type": "String",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"acls": [{
|
||||||
|
"accessType": "READ",
|
||||||
|
"principalType": "ROLE",
|
||||||
|
"principalId": "$everyone",
|
||||||
|
"permission": "ALLOW"
|
||||||
|
}]
|
||||||
|
}
|
|
@ -2,39 +2,49 @@
|
||||||
"name": "Bank",
|
"name": "Bank",
|
||||||
"base": "VnModel",
|
"base": "VnModel",
|
||||||
"options": {
|
"options": {
|
||||||
"mysql": {
|
"mysql": {
|
||||||
"table": "bank"
|
"table": "bank"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
"type": "Number",
|
"type": "Number",
|
||||||
"id": true,
|
"id": true,
|
||||||
"description": "Identifier"
|
"description": "Identifier"
|
||||||
},
|
},
|
||||||
"bank": {
|
"bank": {
|
||||||
"type": "string",
|
"type": "String",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"account": {
|
"account": {
|
||||||
"type": "string",
|
"type": "String",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
"cash": {
|
"accountingTypeFk": {
|
||||||
"type": "string",
|
"type": "Number",
|
||||||
"required": true
|
"required": true,
|
||||||
},
|
"mysql": {
|
||||||
"entityFk": {
|
"columnName": "cash"
|
||||||
"type": "string",
|
}
|
||||||
"required": true
|
},
|
||||||
},
|
"entityFk": {
|
||||||
"isActive": {
|
"type": "Number",
|
||||||
"type": "string",
|
"required": true
|
||||||
"required": true
|
},
|
||||||
},
|
"isActive": {
|
||||||
"currencyFk": {
|
"type": "Boolean",
|
||||||
"type": "string",
|
"required": true
|
||||||
"required": true
|
},
|
||||||
}
|
"currencyFk": {
|
||||||
|
"type": "Number",
|
||||||
|
"required": true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"relations": {
|
||||||
|
"accountingType": {
|
||||||
|
"type": "belongsTo",
|
||||||
|
"model": "AccountingType",
|
||||||
|
"foreignKey": "accountingTypeFk"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,2 @@
|
||||||
|
ALTER TABLE `vn`.`accountingType`
|
||||||
|
ADD COLUMN `receiptDescription` VARCHAR(50) NULL AFTER `description`;
|
|
@ -116,13 +116,13 @@ INSERT INTO `vn`.`shelving` (`code`, `parkingFk`, `isPrinted`, `priority`, `park
|
||||||
('GVC', '1', '0', '1', '0', '106'),
|
('GVC', '1', '0', '1', '0', '106'),
|
||||||
('HEJ', '2', '0', '1', '0', '106');
|
('HEJ', '2', '0', '1', '0', '106');
|
||||||
|
|
||||||
INSERT INTO `vn`.`accountingType`(`id`, `description`)
|
INSERT INTO `vn`.`accountingType`(`id`, `description`, `receiptDescription`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Digital money'),
|
(1, 'Digital money', ''),
|
||||||
(2, 'Cash'),
|
(2, 'Cash', 'Cash'),
|
||||||
(3, 'Card'),
|
(3, 'Card', 'Pay on receipt'),
|
||||||
(4, 'Stolen Money'),
|
(4, 'Stolen Money', ''),
|
||||||
(5, 'Miscellaneous');
|
(5, 'Miscellaneous', '');
|
||||||
|
|
||||||
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
|
INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
|
||||||
VALUES
|
VALUES
|
||||||
|
@ -133,8 +133,8 @@ INSERT INTO `vn`.`currency`(`id`, `code`, `name`, `ratio`)
|
||||||
|
|
||||||
INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`)
|
INSERT INTO `vn`.`bank`(`id`, `bank`, `account`, `cash`, `entityFk`, `isActive`, `currencyFk`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, 'Pay on receipt', '0000000000', 4, 0, 1, 1),
|
(1, 'Pay on receipt', '0000000000', 3, 0, 1, 1),
|
||||||
(2, 'Cash', '1111111111', 1, 0, 1, 1);
|
(2, 'Cash', '1111111111', 2, 0, 1, 1);
|
||||||
|
|
||||||
INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
|
INSERT INTO `vn`.`deliveryMethod`(`id`, `code`, `description`)
|
||||||
VALUES
|
VALUES
|
||||||
|
|
|
@ -189,8 +189,9 @@ export default {
|
||||||
newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
|
newPaymentBank: '.vn-dialog.shown vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
|
||||||
newPaymentAmount: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.receipt.amountPaid"]',
|
newPaymentAmount: '.vn-dialog.shown vn-input-number[ng-model="$ctrl.receipt.amountPaid"]',
|
||||||
saveButton: '.vn-dialog.shown [response="accept"]',
|
saveButton: '.vn-dialog.shown [response="accept"]',
|
||||||
firstBalanceLine: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)'
|
firstLineBalance: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(8)',
|
||||||
|
firstLineReference: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable',
|
||||||
|
firstLineReferenceInput: 'vn-client-balance-index vn-tbody > vn-tr:nth-child(1) > vn-td-editable > div > field > vn-textfield'
|
||||||
},
|
},
|
||||||
webPayment: {
|
webPayment: {
|
||||||
confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]',
|
confirmFirstPaymentButton: 'vn-client-web-payment vn-tr:nth-child(1) vn-icon-button[icon="done_all"]',
|
||||||
|
|
|
@ -53,15 +53,28 @@ describe('Client balance path', () => {
|
||||||
expect(message.type).toBe('success');
|
expect(message.type).toBe('success');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should check balance is now 0 and the company is now VNL becouse the user local settings were removed', async() => {
|
it('should edit the 1st line reference', async() => {
|
||||||
|
await page.waitToClick(selectors.clientBalance.firstLineReference);
|
||||||
|
await page.write(selectors.clientBalance.firstLineReferenceInput, 'Miscellaneous payment');
|
||||||
|
await page.keyboard.press('Enter');
|
||||||
|
const message = await page.waitForSnackbar();
|
||||||
|
|
||||||
|
expect(message.type).toBe('success');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should check balance is now 0, the reference was saved and the company is now VNL becouse the user local settings were removed', async() => {
|
||||||
await page.waitForSpinnerLoad();
|
await page.waitForSpinnerLoad();
|
||||||
let company = await page
|
let company = await page
|
||||||
.waitToGetProperty(selectors.clientBalance.company, 'value');
|
.waitToGetProperty(selectors.clientBalance.company, 'value');
|
||||||
|
|
||||||
|
let reference = await page
|
||||||
|
.waitToGetProperty(selectors.clientBalance.firstLineReference, 'innerText');
|
||||||
|
|
||||||
let firstBalanceLine = await page
|
let firstBalanceLine = await page
|
||||||
.waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
|
.waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText');
|
||||||
|
|
||||||
expect(company).toEqual('VNL');
|
expect(company).toEqual('VNL');
|
||||||
|
expect(reference).toEqual('Miscellaneous payment');
|
||||||
expect(firstBalanceLine).toContain('0.00');
|
expect(firstBalanceLine).toContain('0.00');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -76,7 +89,7 @@ describe('Client balance path', () => {
|
||||||
|
|
||||||
it('should check balance is now -100', async() => {
|
it('should check balance is now -100', async() => {
|
||||||
let result = await page
|
let result = await page
|
||||||
.waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
|
.waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText');
|
||||||
|
|
||||||
expect(result).toContain('-€100.00');
|
expect(result).toContain('-€100.00');
|
||||||
});
|
});
|
||||||
|
@ -92,7 +105,7 @@ describe('Client balance path', () => {
|
||||||
|
|
||||||
it('should check balance is now 50', async() => {
|
it('should check balance is now 50', async() => {
|
||||||
let result = await page
|
let result = await page
|
||||||
.waitToGetProperty(selectors.clientBalance.firstBalanceLine, 'innerText');
|
.waitToGetProperty(selectors.clientBalance.firstLineBalance, 'innerText');
|
||||||
|
|
||||||
expect(result).toEqual('€50.00');
|
expect(result).toEqual('€50.00');
|
||||||
});
|
});
|
||||||
|
|
|
@ -31,7 +31,7 @@ describe('Item request path', () => {
|
||||||
it('should the status of the request should now be accepted', async() => {
|
it('should the status of the request should now be accepted', async() => {
|
||||||
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
|
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
|
||||||
|
|
||||||
expect(status).toContain('Aceptada');
|
expect(status).toContain('Accepted');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should now click on the second declain request icon then type the reason', async() => {
|
it('should now click on the second declain request icon then type the reason', async() => {
|
||||||
|
@ -40,6 +40,6 @@ describe('Item request path', () => {
|
||||||
await page.respondToDialog('accept');
|
await page.respondToDialog('accept');
|
||||||
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
|
let status = await page.waitToGetProperty(selectors.itemRequest.firstRequestStatus, 'innerText');
|
||||||
|
|
||||||
expect(status).toContain('Denegada');
|
expect(status).toContain('Denied');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -67,13 +67,13 @@ export default class Contextmenu {
|
||||||
get cell() {
|
get cell() {
|
||||||
if (!this.target) return null;
|
if (!this.target) return null;
|
||||||
|
|
||||||
return this.target.closest('vn-td, .vn-td');
|
return this.target.closest('vn-td, .vn-td, vn-td-editable');
|
||||||
}
|
}
|
||||||
|
|
||||||
get cellIndex() {
|
get cellIndex() {
|
||||||
if (!this.row) return null;
|
if (!this.row) return null;
|
||||||
|
|
||||||
const cells = this.row.querySelectorAll('vn-td, .vn-td');
|
const cells = this.row.querySelectorAll('vn-td, .vn-td, vn-td-editable');
|
||||||
return Array.from(cells).findIndex(
|
return Array.from(cells).findIndex(
|
||||||
cellItem => cellItem == this.cell
|
cellItem => cellItem == this.cell
|
||||||
);
|
);
|
||||||
|
|
|
@ -42,11 +42,11 @@ module.exports = Self => {
|
||||||
r.workerFk,
|
r.workerFk,
|
||||||
c.code company,
|
c.code company,
|
||||||
r.created,
|
r.created,
|
||||||
r.invoiceFk ref,
|
r.invoiceFk description,
|
||||||
NULL debit,
|
NULL debit,
|
||||||
r.amountPaid credit,
|
r.amountPaid credit,
|
||||||
r.bankFk,
|
r.bankFk,
|
||||||
u.nickname userNickname,
|
u.name userName,
|
||||||
r.clientFk,
|
r.clientFk,
|
||||||
FALSE hasPdf,
|
FALSE hasPdf,
|
||||||
FALSE isInvoice
|
FALSE isInvoice
|
||||||
|
|
|
@ -17,11 +17,17 @@
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
url="Banks"
|
|
||||||
label="Bank"
|
label="Bank"
|
||||||
|
url="Banks"
|
||||||
show-field="bank"
|
show-field="bank"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
ng-model="$ctrl.receipt.bankFk">
|
fields="['accountingTypeFk']"
|
||||||
|
include="{relation: 'accountingType'}"
|
||||||
|
order="id"
|
||||||
|
ng-model="$ctrl.receipt.bankFk"
|
||||||
|
search-function="{or: [{id: $search}, {bank: {like: '%'+ $search +'%'}}]}"
|
||||||
|
selection="$ctrl.bankSelection">
|
||||||
|
<tpl-item>{{id}}: {{bank}}</tpl-item>
|
||||||
</vn-autocomplete>
|
</vn-autocomplete>
|
||||||
<vn-input-number
|
<vn-input-number
|
||||||
vn-focus
|
vn-focus
|
||||||
|
@ -31,6 +37,13 @@
|
||||||
rule>
|
rule>
|
||||||
</vn-input-number>
|
</vn-input-number>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield
|
||||||
|
label="Reference"
|
||||||
|
ng-model="$ctrl.receipt.description"
|
||||||
|
rule>
|
||||||
|
</vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
</tpl-body>
|
</tpl-body>
|
||||||
<tpl-buttons>
|
<tpl-buttons>
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||||
|
|
|
@ -50,6 +50,19 @@ class Controller extends Dialog {
|
||||||
return this.receipt.description;
|
return this.receipt.description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get bankSelection() {
|
||||||
|
return this._bankSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
set bankSelection(value) {
|
||||||
|
this._bankSelection = value;
|
||||||
|
|
||||||
|
if (value) {
|
||||||
|
const accountingType = value.accountingType;
|
||||||
|
this.receipt.description = accountingType && accountingType.receiptDescription;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getAmountPaid() {
|
getAmountPaid() {
|
||||||
const filter = {
|
const filter = {
|
||||||
where: {
|
where: {
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
import './index';
|
||||||
|
|
||||||
|
describe('Client', () => {
|
||||||
|
describe('Component vnClientBalancCreate', () => {
|
||||||
|
let controller;
|
||||||
|
let $httpBackend;
|
||||||
|
let $httpParamSerializer;
|
||||||
|
|
||||||
|
beforeEach(ngModule('client'));
|
||||||
|
|
||||||
|
beforeEach(inject(($componentController, $rootScope, _$httpBackend_, _$httpParamSerializer_) => {
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
|
$httpParamSerializer = _$httpParamSerializer_;
|
||||||
|
let $scope = $rootScope.$new();
|
||||||
|
const $element = angular.element('<vn-client-balance-create></vn-client-balance-create>');
|
||||||
|
const $transclude = {
|
||||||
|
$$boundTransclude: {
|
||||||
|
$$slots: []
|
||||||
|
}
|
||||||
|
};
|
||||||
|
controller = $componentController('vnClientBalanceCreate', {$element, $scope, $transclude});
|
||||||
|
controller.receipt = {
|
||||||
|
clientFk: 101,
|
||||||
|
companyFk: 442
|
||||||
|
};
|
||||||
|
}));
|
||||||
|
|
||||||
|
describe('bankSelection() setter', () => {
|
||||||
|
it('should set the receipt description property', () => {
|
||||||
|
controller.bankSelection = {
|
||||||
|
id: 1,
|
||||||
|
bank: 'Cash',
|
||||||
|
accountingType: {
|
||||||
|
id: 2,
|
||||||
|
receiptDescription: 'Cash'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(controller.receipt.description).toEqual('Cash');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getAmountPaid()', () => {
|
||||||
|
it('should make an http GET query and then set the receipt amountPaid property', () => {
|
||||||
|
controller.$params = {id: 101};
|
||||||
|
const receipt = controller.receipt;
|
||||||
|
const filter = {
|
||||||
|
where: {
|
||||||
|
clientFk: 101,
|
||||||
|
companyFk: 442
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const serializedParams = $httpParamSerializer({filter});
|
||||||
|
$httpBackend.expect('GET', `ClientRisks?${serializedParams}`,).respond([{amount: 20}]);
|
||||||
|
controller.getAmountPaid();
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(receipt.amountPaid).toEqual(20);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('responseHandler()', () => {
|
||||||
|
it('should make an http POST query and then call to the parent responseHandler() method', () => {
|
||||||
|
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||||
|
|
||||||
|
controller.$params = {id: 101};
|
||||||
|
|
||||||
|
$httpBackend.expect('POST', `Receipts`,).respond({id: 1});
|
||||||
|
controller.responseHandler('accept');
|
||||||
|
$httpBackend.flush();
|
||||||
|
|
||||||
|
expect(controller.vnApp.showSuccess).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -68,25 +68,33 @@
|
||||||
<span
|
<span
|
||||||
vn-click-stop="workerDescriptor.show($event, balance.workerFk)"
|
vn-click-stop="workerDescriptor.show($event, balance.workerFk)"
|
||||||
class="link">
|
class="link">
|
||||||
{{::balance.userNickname}}
|
{{::balance.userName}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td expand>
|
<vn-td-editable disabled="balance.isInvoice || !$ctrl.isAdministrative" expand>
|
||||||
<div ng-show="::balance.ref">
|
<text>
|
||||||
<span
|
<div ng-show="::balance.description">
|
||||||
ng-if="balance.isInvoice"
|
<span
|
||||||
title="{{'BILL' | translate: {ref: balance.ref} }}"
|
ng-if="balance.isInvoice"
|
||||||
vn-click-stop="$ctrl.showInvoiceOutDescriptor($event, balance)"
|
title="{{'BILL' | translate: {ref: balance.description} }}"
|
||||||
class="link">
|
vn-click-stop="$ctrl.showInvoiceOutDescriptor($event, balance)"
|
||||||
{{'BILL' | translate: {ref: balance.ref} }}
|
class="link">
|
||||||
</span>
|
{{'BILL' | translate: {ref: balance.description} }}
|
||||||
<span
|
</span>
|
||||||
ng-if="!balance.isInvoice"
|
<span
|
||||||
title="{{::balance.ref}}">
|
ng-if="!balance.isInvoice"
|
||||||
{{::balance.ref}}
|
title="{{::balance.description}}">
|
||||||
</span>
|
{{balance.description}}
|
||||||
</div>
|
</span>
|
||||||
</vn-td>
|
</div>
|
||||||
|
</text>
|
||||||
|
<field>
|
||||||
|
<vn-textfield vn-acl="administrative" class="dense" vn-focus
|
||||||
|
ng-model="balance.description"
|
||||||
|
on-change="$ctrl.changeDescription(balance)">
|
||||||
|
</vn-textfield>
|
||||||
|
</field>
|
||||||
|
</vn-td-editable>
|
||||||
<vn-td number>{{::balance.bankFk}}</vn-td>
|
<vn-td number>{{::balance.bankFk}}</vn-td>
|
||||||
<vn-td number expand>{{::balance.debit | currency: 'EUR':2}}</vn-td>
|
<vn-td number expand>{{::balance.debit | currency: 'EUR':2}}</vn-td>
|
||||||
<vn-td number expand>{{::balance.credit | currency: 'EUR':2}}</vn-td>
|
<vn-td number expand>{{::balance.credit | currency: 'EUR':2}}</vn-td>
|
||||||
|
|
|
@ -39,6 +39,10 @@ class Controller extends Section {
|
||||||
this.getBalances();
|
this.getBalances();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get isAdministrative() {
|
||||||
|
return this.aclService.hasAny(['administrative']);
|
||||||
|
}
|
||||||
|
|
||||||
getData() {
|
getData() {
|
||||||
return this.$.model.applyFilter(null, {
|
return this.$.model.applyFilter(null, {
|
||||||
clientId: this.$params.id,
|
clientId: this.$params.id,
|
||||||
|
@ -58,7 +62,7 @@ class Controller extends Section {
|
||||||
return balance.companyFk === selectedCompany;
|
return balance.companyFk === selectedCompany;
|
||||||
});
|
});
|
||||||
|
|
||||||
return currentBalance.amount;
|
return currentBalance && currentBalance.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
getBalances() {
|
getBalances() {
|
||||||
|
@ -79,6 +83,13 @@ class Controller extends Section {
|
||||||
|
|
||||||
this.$.invoiceOutDescriptor.show(event.target, balance.id);
|
this.$.invoiceOutDescriptor.show(event.target, balance.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
changeDescription(balance) {
|
||||||
|
const params = {description: balance.description};
|
||||||
|
const endpoint = `Receipts/${balance.id}`;
|
||||||
|
this.$http.patch(endpoint, params)
|
||||||
|
.then(() => this.vnApp.showSuccess(this.$t('Data saved!')));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Controller.$inject = ['$element', '$scope'];
|
Controller.$inject = ['$element', '$scope'];
|
||||||
|
|
|
@ -3,10 +3,12 @@ import './index';
|
||||||
describe('Client', () => {
|
describe('Client', () => {
|
||||||
describe('Component vnClientBalanceIndex', () => {
|
describe('Component vnClientBalanceIndex', () => {
|
||||||
let controller;
|
let controller;
|
||||||
|
let $httpBackend;
|
||||||
|
|
||||||
beforeEach(ngModule('client'));
|
beforeEach(ngModule('client'));
|
||||||
|
|
||||||
beforeEach(inject(($componentController, $rootScope) => {
|
beforeEach(inject(($componentController, $rootScope, _$httpBackend_) => {
|
||||||
|
$httpBackend = _$httpBackend_;
|
||||||
let $scope = $rootScope.$new();
|
let $scope = $rootScope.$new();
|
||||||
const $element = angular.element('<vn-client-balance-index></vn-client-balance-index>');
|
const $element = angular.element('<vn-client-balance-index></vn-client-balance-index>');
|
||||||
controller = $componentController('vnClientBalanceIndex', {$element, $scope});
|
controller = $componentController('vnClientBalanceIndex', {$element, $scope});
|
||||||
|
@ -133,5 +135,21 @@ describe('Client', () => {
|
||||||
expect(controller.getBalances).toHaveBeenCalledWith();
|
expect(controller.getBalances).toHaveBeenCalledWith();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('changeDescription()', () => {
|
||||||
|
it('should make an http PATCH query', () => {
|
||||||
|
const expectedParams = {description: 'Web'};
|
||||||
|
|
||||||
|
$httpBackend.expect('PATCH', `Receipts/1`, expectedParams).respond(200);
|
||||||
|
controller.changeDescription({
|
||||||
|
id: 1,
|
||||||
|
description: 'Web',
|
||||||
|
accountingType: {
|
||||||
|
description: 'Cash'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$httpBackend.flush();
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -56,12 +56,14 @@
|
||||||
label="For me"
|
label="For me"
|
||||||
ng-model="filter.mine">
|
ng-model="filter.mine">
|
||||||
</vn-check>
|
</vn-check>
|
||||||
<vn-check
|
<vn-autocomplete
|
||||||
vn-one
|
vn-one
|
||||||
triple-state="true"
|
ng-model="filter.state"
|
||||||
label="Confirmed"
|
data="$ctrl.states"
|
||||||
ng-model="filter.isOk">
|
value-field="code"
|
||||||
</vn-check>
|
label="State">
|
||||||
|
<tpl-item>{{name}}</tpl-item>
|
||||||
|
</vn-autocomplete>
|
||||||
</vn-horizontal>
|
</vn-horizontal>
|
||||||
<vn-horizontal class="vn-mt-lg">
|
<vn-horizontal class="vn-mt-lg">
|
||||||
<vn-submit label="Search"></vn-submit>
|
<vn-submit label="Search"></vn-submit>
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
import ngModule from '../module';
|
import ngModule from '../module';
|
||||||
import SearchPanel from 'core/components/searchbar/search-panel';
|
import SearchPanel from 'core/components/searchbar/search-panel';
|
||||||
|
|
||||||
|
class Controller extends SearchPanel {
|
||||||
|
constructor($element, $) {
|
||||||
|
super($element, $);
|
||||||
|
|
||||||
|
this.states = [
|
||||||
|
{code: 'pending', name: this.$t('Pending')},
|
||||||
|
{code: 'accepted', name: this.$t('Accepted')},
|
||||||
|
{code: 'denied', name: this.$t('Denied')}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnRequestSearchPanel', {
|
ngModule.vnComponent('vnRequestSearchPanel', {
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: SearchPanel
|
controller: Controller
|
||||||
});
|
});
|
||||||
|
|
|
@ -24,14 +24,15 @@
|
||||||
<vn-tr>
|
<vn-tr>
|
||||||
<vn-th field="ticketFk" number>Ticket ID</vn-th>
|
<vn-th field="ticketFk" number>Ticket ID</vn-th>
|
||||||
<vn-th field="shipped" expand>Shipped</vn-th>
|
<vn-th field="shipped" expand>Shipped</vn-th>
|
||||||
<vn-th field="description" expand>Description</vn-th>
|
<vn-th field="description" filter-enabled="false" expand>Description</vn-th>
|
||||||
<vn-th field="quantity" number editable>Requested</vn-th>
|
<vn-th field="quantity" number editable>Requested</vn-th>
|
||||||
<vn-th field="price" number>Price</vn-th>
|
<vn-th field="price" number>Price</vn-th>
|
||||||
<vn-th field="atenderNickname">Atender</vn-th>
|
<vn-th field="attenderName">Atender</vn-th>
|
||||||
<vn-th field="itemFk">Item</vn-th>
|
<vn-th>Item</vn-th>
|
||||||
<vn-th field="saleQuantity">Achieved</vn-th>
|
<vn-th field="saleQuantity">Achieved</vn-th>
|
||||||
<vn-th field="description">Concept</vn-th>
|
<vn-th field="description" filter-enabled="false">Concept</vn-th>
|
||||||
<vn-th field="isOk">State</vn-th>
|
<vn-th field="isOk">State</vn-th>
|
||||||
|
<vn-th></vn-th>
|
||||||
</vn-tr>
|
</vn-tr>
|
||||||
</vn-thead>
|
</vn-thead>
|
||||||
<vn-tbody>
|
<vn-tbody>
|
||||||
|
@ -83,7 +84,7 @@
|
||||||
{{request.itemDescription}}
|
{{request.itemDescription}}
|
||||||
</span>
|
</span>
|
||||||
</vn-td>
|
</vn-td>
|
||||||
<vn-td>{{$ctrl.getState(request.isOk)}}</vn-td>
|
<vn-td translate>{{$ctrl.getState(request.isOk)}}</vn-td>
|
||||||
<vn-td>
|
<vn-td>
|
||||||
<vn-icon
|
<vn-icon
|
||||||
ng-if="request.response.length"
|
ng-if="request.response.length"
|
||||||
|
@ -128,4 +129,29 @@
|
||||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||||
<button response="accept" translate>Save</button>
|
<button response="accept" translate>Save</button>
|
||||||
</tpl-buttons>
|
</tpl-buttons>
|
||||||
</vn-dialog>
|
</vn-dialog>
|
||||||
|
|
||||||
|
<vn-contextmenu vn-id="contextmenu" targets="['vn-data-viewer']" model="model"
|
||||||
|
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||||
|
<slot-menu>
|
||||||
|
<vn-item translate
|
||||||
|
ng-if="contextmenu.isFilterAllowed()"
|
||||||
|
ng-click="contextmenu.filterBySelection()">
|
||||||
|
Filter by selection
|
||||||
|
</vn-item>
|
||||||
|
<vn-item translate
|
||||||
|
ng-if="contextmenu.isFilterAllowed()"
|
||||||
|
ng-click="contextmenu.excludeSelection()">
|
||||||
|
Exclude selection
|
||||||
|
</vn-item>
|
||||||
|
<vn-item translate
|
||||||
|
ng-if="contextmenu.isFilterAllowed()"
|
||||||
|
ng-click="contextmenu.removeFilter()" >
|
||||||
|
Remove filter
|
||||||
|
</vn-item>
|
||||||
|
<vn-item translate
|
||||||
|
ng-click="contextmenu.removeAllFilters()" >
|
||||||
|
Remove all filters
|
||||||
|
</vn-item>
|
||||||
|
</slot-menu>
|
||||||
|
</vn-contextmenu>
|
|
@ -17,18 +17,19 @@ export default class Controller extends Section {
|
||||||
this.filterParams = {
|
this.filterParams = {
|
||||||
mine: true,
|
mine: true,
|
||||||
from: today,
|
from: today,
|
||||||
to: nextWeek
|
to: nextWeek,
|
||||||
|
state: 'pending'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getState(isOk) {
|
getState(isOk) {
|
||||||
if (isOk === null)
|
if (isOk === null)
|
||||||
return 'Nueva';
|
return 'Pending';
|
||||||
else if (isOk)
|
else if (isOk)
|
||||||
return 'Aceptada';
|
return 'Accepted';
|
||||||
else
|
else
|
||||||
return 'Denegada';
|
return 'Denied';
|
||||||
}
|
}
|
||||||
|
|
||||||
confirmRequest(request) {
|
confirmRequest(request) {
|
||||||
|
@ -92,6 +93,31 @@ export default class Controller extends Section {
|
||||||
this.vnApp.showSuccess(this.$t('Data saved!'));
|
this.vnApp.showSuccess(this.$t('Data saved!'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exprBuilder(param, value) {
|
||||||
|
switch (param) {
|
||||||
|
case 'ticketFk':
|
||||||
|
case 'quantity':
|
||||||
|
case 'price':
|
||||||
|
case 'isOk':
|
||||||
|
return {[`tr.${param}`]: value};
|
||||||
|
case 'attenderName':
|
||||||
|
return {[`ua.name`]: value};
|
||||||
|
case 'shipped':
|
||||||
|
return {'t.shipped': {
|
||||||
|
between: this.dateRange(value)}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dateRange(value) {
|
||||||
|
const minHour = new Date(value);
|
||||||
|
minHour.setHours(0, 0, 0, 0);
|
||||||
|
const maxHour = new Date(value);
|
||||||
|
maxHour.setHours(23, 59, 59, 59);
|
||||||
|
|
||||||
|
return [minHour, maxHour];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngModule.vnComponent('vnItemRequest', {
|
ngModule.vnComponent('vnItemRequest', {
|
||||||
|
|
|
@ -24,17 +24,17 @@ describe('Item', () => {
|
||||||
let isOk = null;
|
let isOk = null;
|
||||||
let result = controller.getState(isOk);
|
let result = controller.getState(isOk);
|
||||||
|
|
||||||
expect(result).toEqual('Nueva');
|
expect(result).toEqual('Pending');
|
||||||
|
|
||||||
isOk = 1;
|
isOk = 1;
|
||||||
result = controller.getState(isOk);
|
result = controller.getState(isOk);
|
||||||
|
|
||||||
expect(result).toEqual('Aceptada');
|
expect(result).toEqual('Accepted');
|
||||||
|
|
||||||
isOk = 0;
|
isOk = 0;
|
||||||
result = controller.getState(isOk);
|
result = controller.getState(isOk);
|
||||||
|
|
||||||
expect(result).toEqual('Denegada');
|
expect(result).toEqual('Denied');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -3,4 +3,7 @@ Specify the reasons to deny this request: Especifica las razones para descartar
|
||||||
Buy requests: Peticiones de compra
|
Buy requests: Peticiones de compra
|
||||||
Search request by id or alias: Buscar peticiones por identificador o alias
|
Search request by id or alias: Buscar peticiones por identificador o alias
|
||||||
Requested: Solicitado
|
Requested: Solicitado
|
||||||
Achieved: Conseguido
|
Achieved: Conseguido
|
||||||
|
Pending: Pendiente
|
||||||
|
Accepted: Aceptada
|
||||||
|
Denied: Rechazada
|
|
@ -44,8 +44,8 @@ module.exports = Self => {
|
||||||
type: 'Date',
|
type: 'Date',
|
||||||
description: `Date to`
|
description: `Date to`
|
||||||
}, {
|
}, {
|
||||||
arg: 'isOk',
|
arg: 'state',
|
||||||
type: 'Boolean',
|
type: 'String',
|
||||||
description: `Search request by request state`
|
description: `Search request by request state`
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
@ -77,8 +77,13 @@ module.exports = Self => {
|
||||||
return {'t.id': value};
|
return {'t.id': value};
|
||||||
case 'attenderFk':
|
case 'attenderFk':
|
||||||
return {'tr.attenderFk': value};
|
return {'tr.attenderFk': value};
|
||||||
case 'isOk':
|
case 'state':
|
||||||
return {'tr.isOk': value};
|
switch (value) {
|
||||||
|
case 'pending':
|
||||||
|
return {'tr.isOk': null};
|
||||||
|
default:
|
||||||
|
return {'tr.isOk': value};
|
||||||
|
}
|
||||||
case 'clientFk':
|
case 'clientFk':
|
||||||
return {'t.clientFk': value};
|
return {'t.clientFk': value};
|
||||||
case 'from':
|
case 'from':
|
||||||
|
|
|
@ -12,4 +12,4 @@ Order id: Id cesta
|
||||||
Grouped States: Estado agrupado
|
Grouped States: Estado agrupado
|
||||||
Days onward: Días adelante
|
Days onward: Días adelante
|
||||||
With problems: Con problemas
|
With problems: Con problemas
|
||||||
Pending: Pendientes
|
Pending: Pendiente
|
Loading…
Reference in New Issue