3977-invoiceIn.tax #969

Merged
joan merged 6 commits from 3977-invoiceIn.tax into dev 2022-05-13 13:04:44 +00:00
7 changed files with 141 additions and 15 deletions

View File

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

View File

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

View File

@ -33,6 +33,13 @@
show-field="id"
rule>
<tpl-item>{{id}}: {{name}}</tpl-item>
<append>
<vn-icon-button
vn-tooltip="Create expense"
vicent marked this conversation as resolved Outdated

you have a typo in expence, it is expense

you have a typo in expence, it is 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>
vicent marked this conversation as resolved Outdated

SMSdialog?

SMSdialog?
<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"
vicent marked this conversation as resolved Outdated

shouldn't this one be the focused input?

shouldn't this one be the focused input?
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>

View File

@ -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();
});
vicent marked this conversation as resolved Outdated

expense

expense
}
vicent marked this conversation as resolved
Review

if the code inside the conditional throws, there's no point using "else if"

if the code inside the conditional throws, there's no point using "else if"
onResponse() {
try {
if (!this.expense.code)
throw new Error(`The code can't be empty`);
if (!this.expense.description)
vicent marked this conversation as resolved Outdated

if you are creating a data entity to send on a query, why would you call it params and why woulnd't you defined it as follows:

const data = [{
id: this.expence.code,
isWithheld: this.expence.isWithheld,
name: this.expence.description
}]

if you are creating a data entity to send on a query, why would you call it params and why woulnd't you defined it as follows: const data = [{ id: this.expence.code, isWithheld: this.expence.isWithheld, name: this.expence.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', {

View File

@ -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();
});
});
vicent marked this conversation as resolved
Review

there's only 1 test for the onResponse function but there are about 4 use cases for this function, 3 thrown errors and un success query. Some tests are missing

there's only 1 test for the onResponse function but there are about 4 use cases for this function, 3 thrown errors and un success query. Some tests are missing
describe('onResponse()', () => {
it('should return success message', () => {
vicent marked this conversation as resolved
Review

expense

expense
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`);
});
});
});
});

View File

@ -0,0 +1,7 @@
Create expense: Crear gasto
vicent marked this conversation as resolved Outdated

expense

expense
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!

View File

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