Merge pull request '3977-invoiceIn.tax' (#969) from 3977-invoiceIn.tax into dev
gitea/salix/pipeline/head This commit looks good
Details
gitea/salix/pipeline/head This commit looks good
Details
Reviewed-on: #969 Reviewed-by: Joan Sanchez <joan@verdnatura.es>
This commit is contained in:
commit
fdd780a470
|
@ -0,0 +1,5 @@
|
|||
INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES('Expense', '*', 'READ', 'ALLOW', 'ROLE', 'employee');
|
||||
|
||||
INSERT INTO `salix`.`ACL`(`model`, `property`, `accessType`, `permission`, `principalType`, `principalId`)
|
||||
VALUES('Expense', '*', 'WRITE', 'ALLOW', 'ROLE', 'administrative');
|
|
@ -982,7 +982,7 @@ export default {
|
|||
save: 'vn-invoice-in-basic-data button[type=submit]'
|
||||
},
|
||||
invoiceInTax: {
|
||||
addTaxButton: 'vn-invoice-in-tax vn-icon-button[icon="add_circle"]',
|
||||
addTaxButton: 'vn-invoice-in-tax vn-icon-button[vn-tooltip="Add tax"]',
|
||||
thirdExpence: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.expenseFk"]',
|
||||
thirdTaxableBase: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-input-number[ng-model="invoiceInTax.taxableBase"]',
|
||||
thirdTaxType: 'vn-invoice-in-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="invoiceInTax.taxTypeSageFk"]',
|
||||
|
|
|
@ -33,6 +33,13 @@
|
|||
show-field="id"
|
||||
rule>
|
||||
<tpl-item>{{id}}: {{name}}</tpl-item>
|
||||
<append>
|
||||
<vn-icon-button
|
||||
vn-tooltip="Create expense"
|
||||
icon="add_circle"
|
||||
vn-click-stop="createExpense.show()">
|
||||
</vn-icon-button>
|
||||
</append>
|
||||
</vn-autocomplete>
|
||||
<vn-input-number vn-one
|
||||
disabled="$ctrl.invoiceIn.currency.code != 'EUR'"
|
||||
|
@ -97,3 +104,40 @@
|
|||
</vn-submit>
|
||||
</vn-button-bar>
|
||||
</form>
|
||||
|
||||
<!-- Dialog of create expense-->
|
||||
<vn-dialog
|
||||
vn-id="createExpense"
|
||||
on-accept="$ctrl.onResponse()">
|
||||
<tpl-body>
|
||||
<section>
|
||||
<h5 class="vn-py-sm">{{$ctrl.$t('New expense')}}</h5>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one
|
||||
vn-id="code"
|
||||
label="Code"
|
||||
ng-model="$ctrl.expense.code"
|
||||
required="true"
|
||||
vn-focus>
|
||||
</vn-textfield>
|
||||
<vn-check
|
||||
vn-one
|
||||
label="It's a withholding"
|
||||
ng-model="$ctrl.expense.isWithheld">
|
||||
</vn-check>
|
||||
</vn-horizontal>
|
||||
<vn-horizontal>
|
||||
<vn-textfield vn-one
|
||||
vn-id="description"
|
||||
label="Description"
|
||||
ng-model="$ctrl.expense.description"
|
||||
required="true">
|
||||
</vn-textfield>
|
||||
</vn-horizontal>
|
||||
</section>
|
||||
</tpl-body>
|
||||
<tpl-buttons>
|
||||
<input type="button" response="cancel" translate-attr="{value: 'Cancel'}"/>
|
||||
<button response="accept" translate>Save</button>
|
||||
</tpl-buttons>
|
||||
</vn-dialog>
|
|
@ -1,7 +1,12 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import UserError from 'core/lib/user-error';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $, vnWeekDays) {
|
||||
super($element, $);
|
||||
this.expense = {};
|
||||
}
|
||||
taxRate(invoiceInTax, taxRateSelection) {
|
||||
const taxTypeSage = taxRateSelection && taxRateSelection.rate;
|
||||
const taxableBase = invoiceInTax && invoiceInTax.taxableBase;
|
||||
|
@ -26,6 +31,27 @@ class Controller extends Section {
|
|||
this.card.reload();
|
||||
});
|
||||
}
|
||||
|
||||
onResponse() {
|
||||
try {
|
||||
if (!this.expense.code)
|
||||
throw new Error(`The code can't be empty`);
|
||||
if (!this.expense.description)
|
||||
throw new UserError(`The description can't be empty`);
|
||||
|
||||
const data = [{
|
||||
id: this.expense.code,
|
||||
isWithheld: this.expense.isWithheld,
|
||||
name: this.expense.description
|
||||
}];
|
||||
|
||||
this.$http.post(`Expenses`, data) .then(() => {
|
||||
this.vnApp.showSuccess(this.$t('Expense saved!'));
|
||||
});
|
||||
} catch (e) {
|
||||
this.vnApp.showError(this.$t(e.message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnInvoiceInTax', {
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
import './index.js';
|
||||
import watcher from 'core/mocks/watcher';
|
||||
import crudModel from 'core/mocks/crud-model';
|
||||
const UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
describe('InvoiceIn', () => {
|
||||
describe('Component tax', () => {
|
||||
let controller;
|
||||
let $scope;
|
||||
let vnApp;
|
||||
let $httpBackend;
|
||||
|
||||
beforeEach(ngModule('invoiceIn'));
|
||||
|
||||
beforeEach(inject(($componentController, $rootScope, _vnApp_) => {
|
||||
beforeEach(inject(($componentController, $rootScope, _vnApp_, _$httpBackend_) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
vnApp = _vnApp_;
|
||||
jest.spyOn(vnApp, 'showError');
|
||||
$scope = $rootScope.$new();
|
||||
|
@ -19,6 +22,7 @@ describe('InvoiceIn', () => {
|
|||
|
||||
const $element = angular.element('<vn-invoice-in-tax></vn-invoice-in-tax>');
|
||||
controller = $componentController('vnInvoiceInTax', {$element, $scope});
|
||||
controller.$.model = crudModel;
|
||||
controller.invoiceIn = {id: 1};
|
||||
}));
|
||||
|
||||
|
@ -55,5 +59,56 @@ describe('InvoiceIn', () => {
|
|||
expect(controller.card.reload).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('onResponse()', () => {
|
||||
it('should return success message', () => {
|
||||
controller.expense = {
|
||||
code: 7050000005,
|
||||
isWithheld: 0,
|
||||
description: 'Test'
|
||||
};
|
||||
|
||||
const data = [{
|
||||
id: controller.expense.code,
|
||||
isWithheld: controller.expense.isWithheld,
|
||||
name: controller.expense.description
|
||||
}];
|
||||
|
||||
jest.spyOn(controller.vnApp, 'showSuccess');
|
||||
$httpBackend.expect('POST', `Expenses`, data).respond();
|
||||
|
||||
controller.onResponse();
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.vnApp.showSuccess).toHaveBeenCalledWith('Expense saved!');
|
||||
});
|
||||
|
||||
it('should return an error if code is empty', () => {
|
||||
controller.expense = {
|
||||
code: null,
|
||||
isWithheld: 0,
|
||||
description: 'Test'
|
||||
};
|
||||
|
||||
jest.spyOn(controller.vnApp, 'showError');
|
||||
controller.onResponse();
|
||||
|
||||
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The code can't be empty`);
|
||||
});
|
||||
|
||||
it('should return an error if description is empty', () => {
|
||||
controller.expense = {
|
||||
code: 7050000005,
|
||||
isWithheld: 0,
|
||||
description: null
|
||||
};
|
||||
|
||||
jest.spyOn(controller.vnApp, 'showError');
|
||||
controller.onResponse();
|
||||
|
||||
expect(controller.vnApp.showError).toHaveBeenCalledWith(`The description can't be empty`);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
Create expense: Crear gasto
|
||||
New expense: Nuevo gasto
|
||||
It's a withholding: Es una retención
|
||||
The fields can't be empty: Los campos no pueden estar vacíos
|
||||
The code can't be empty: El código no puede estar vacío
|
||||
The description can't be empty: La descripción no puede estar vacía
|
||||
Expense saved!: Gasto guardado!
|
|
@ -17,9 +17,6 @@
|
|||
},
|
||||
"isWithheld": {
|
||||
"type": "number"
|
||||
},
|
||||
"taxTypeFk": {
|
||||
"type": "number"
|
||||
}
|
||||
},
|
||||
"relations": {
|
||||
|
@ -28,13 +25,5 @@
|
|||
"model": "TaxType",
|
||||
"foreignKey": "taxTypeFk"
|
||||
}
|
||||
},
|
||||
"acls": [
|
||||
{
|
||||
"accessType": "READ",
|
||||
"principalType": "ROLE",
|
||||
"principalId": "$everyone",
|
||||
"permission": "ALLOW"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue