2612-create-supplier #1089
|
@ -0,0 +1,2 @@
|
||||||
|
INSERT INTO `vn`.`payDem` (id,payDem)
|
||||||
pau marked this conversation as resolved
Outdated
|
|||||||
|
VALUES (7,'0');
|
|
@ -0,0 +1,2 @@
|
||||||
|
INSERT INTO `salix`.`ACL` (model,property,accessType,principalId)
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Poner el nombre del esquema y la tabla entre template string (``), de lo contrario fallará al importar los cambios en producción. Poner el nombre del esquema y la tabla entre template string (``), de lo contrario fallará al importar los cambios en producción.
|
|||||||
|
VALUES ('Supplier','newSupplier','WRITE','administrative');
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `vn`.`supplier` MODIFY COLUMN payMethodFk tinyint(3) unsigned NULL;
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Nombre de esquema y tabla entre template strings `` Nombre de esquema y tabla entre template strings ``
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `vn`.`supplier` MODIFY COLUMN supplierActivityFk varchar(45) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL NULL;
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Nombre de esquema y tabla entre template strings `` Nombre de esquema y tabla entre template strings ``
|
|
@ -95,8 +95,8 @@ module.exports = Self => {
|
||||||
pm.name AS payMethod,
|
pm.name AS payMethod,
|
||||||
pd.payDem AS payDem
|
pd.payDem AS payDem
|
||||||
FROM vn.supplier s
|
FROM vn.supplier s
|
||||||
JOIN vn.payMethod pm ON pm.id = s.payMethodFk
|
LEFT JOIN vn.payMethod pm ON pm.id = s.payMethodFk
|
||||||
JOIN vn.payDem pd ON pd.id = s.payDemFk`
|
LEFT JOIN vn.payDem pd ON pd.id = s.payDemFk`
|
||||||
);
|
);
|
||||||
|
|
||||||
stmt.merge(conn.makeSuffix(filter));
|
stmt.merge(conn.makeSuffix(filter));
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
module.exports = Self => {
|
||||||
|
Self.remoteMethod('newSupplier', {
|
||||||
|
description: 'Creates a new supplier and returns it',
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Corregir descripción Corregir descripción
|
|||||||
|
accessType: 'WRITE',
|
||||||
|
accepts: [{
|
||||||
|
arg: 'params',
|
||||||
|
type: 'object',
|
||||||
|
http: {source: 'body'}
|
||||||
|
}],
|
||||||
|
returns: {
|
||||||
|
type: 'string',
|
||||||
|
root: true
|
||||||
|
},
|
||||||
|
http: {
|
||||||
|
path: `/newSupplier`,
|
||||||
|
verb: 'POST'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Self.newSupplier = async params => {
|
||||||
|
const models = Self.app.models;
|
||||||
|
const myOptions = {};
|
||||||
|
|
||||||
|
if (typeof(params) == 'string')
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Esta propiedad no especificarla Esta propiedad no especificarla
|
|||||||
|
params = JSON.parse(params);
|
||||||
|
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Únicamente debería asignar la transacción si se la pasan a la función newSupplier(). No debe crear una transacción para una sola consulta. Únicamente debería asignar la transacción si se la pasan a la función newSupplier(). No debe crear una transacción para una sola consulta.
|
|||||||
|
params.nickname = params.name;
|
||||||
|
|
||||||
|
if (!myOptions.transaction) {
|
||||||
|
tx = await Self.beginTransaction({});
|
||||||
|
myOptions.transaction = tx;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const supplier = await models.Supplier.create(params, myOptions);
|
||||||
|
|
||||||
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
|
return supplier;
|
||||||
|
} catch (e) {
|
||||||
|
if (tx) await tx.rollback();
|
||||||
|
return params;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
|
@ -10,7 +10,7 @@ describe('Supplier filter()', () => {
|
||||||
|
|
||||||
let result = await app.models.Supplier.filter(ctx);
|
let result = await app.models.Supplier.filter(ctx);
|
||||||
|
|
||||||
expect(result.length).toEqual(1);
|
expect(result.length).toBeGreaterThanOrEqual(1);
|
||||||
expect(result[0].id).toEqual(1);
|
expect(result[0].id).toEqual(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
const app = require('vn-loopback/server/server');
|
||||||
|
const LoopBackContext = require('loopback-context');
|
||||||
|
|
||||||
|
describe('Supplier newSupplier()', () => {
|
||||||
|
const newSupp = {
|
||||||
|
name: 'TestSupplier-1'
|
||||||
|
};
|
||||||
|
const administrativeId = 5;
|
||||||
|
|
||||||
|
it('should create a new supplier containing only the name', async() => {
|
||||||
|
const activeCtx = {
|
||||||
|
accessToken: {userId: administrativeId},
|
||||||
|
};
|
||||||
|
spyOn(LoopBackContext, 'getCurrentContext').and.returnValue({
|
||||||
|
active: activeCtx
|
||||||
|
});
|
||||||
|
|
||||||
|
let result = await app.models.Supplier.newSupplier(JSON.stringify(newSupp));
|
||||||
|
|
||||||
|
expect(result.name).toEqual('TestSupplier-1');
|
||||||
|
expect(result.id).toEqual(443);
|
||||||
|
|
||||||
|
const createdSupplier = await app.models.Supplier.findById(result.id);
|
||||||
|
|
||||||
|
expect(createdSupplier.id).toEqual(result.id);
|
||||||
|
expect(createdSupplier.name).toEqual(result.name);
|
||||||
|
expect(createdSupplier.payDemFk).toEqual(7);
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Mantener únicamente los expects de los valores que esperas que estén rellenados (id, name, socialName) Mantener únicamente los expects de los valores que esperas que estén rellenados (id, name, socialName)
|
|||||||
|
expect(createdSupplier.nickname).toEqual(result.name);
|
||||||
|
});
|
||||||
|
});
|
|
@ -10,6 +10,7 @@ module.exports = Self => {
|
||||||
require('../methods/supplier/freeAgencies')(Self);
|
require('../methods/supplier/freeAgencies')(Self);
|
||||||
require('../methods/supplier/campaignMetricsPdf')(Self);
|
require('../methods/supplier/campaignMetricsPdf')(Self);
|
||||||
require('../methods/supplier/campaignMetricsEmail')(Self);
|
require('../methods/supplier/campaignMetricsEmail')(Self);
|
||||||
|
require('../methods/supplier/newSupplier')(Self);
|
||||||
|
|
||||||
Self.validatesPresenceOf('name', {
|
Self.validatesPresenceOf('name', {
|
||||||
message: 'The social name cannot be empty'
|
message: 'The social name cannot be empty'
|
||||||
|
@ -19,13 +20,17 @@ module.exports = Self => {
|
||||||
message: 'The supplier name must be unique'
|
message: 'The supplier name must be unique'
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.validatesPresenceOf('city', {
|
if (this.city) {
|
||||||
message: 'City cannot be empty'
|
Self.validatesPresenceOf('city', {
|
||||||
});
|
message: 'City cannot be empty'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Self.validatesPresenceOf('nif', {
|
if (this.nif) {
|
||||||
message: 'The nif cannot be empty'
|
Self.validatesPresenceOf('nif', {
|
||||||
});
|
message: 'The nif cannot be empty'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Self.validatesUniquenessOf('nif', {
|
Self.validatesUniquenessOf('nif', {
|
||||||
message: 'TIN must be unique'
|
message: 'TIN must be unique'
|
||||||
|
@ -57,6 +62,9 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function tinIsValid(err, done) {
|
async function tinIsValid(err, done) {
|
||||||
|
if (!this.countryFk)
|
||||||
|
return done();
|
||||||
|
|
||||||
const filter = {
|
const filter = {
|
||||||
fields: ['code'],
|
fields: ['code'],
|
||||||
where: {id: this.countryFk}
|
where: {id: this.countryFk}
|
||||||
|
@ -80,6 +88,7 @@ module.exports = Self => {
|
||||||
});
|
});
|
||||||
|
|
||||||
async function hasSupplierAccount(err, done) {
|
async function hasSupplierAccount(err, done) {
|
||||||
|
if (!this.payMethodFk) return done();
|
||||||
const payMethod = await Self.app.models.PayMethod.findById(this.payMethodFk);
|
const payMethod = await Self.app.models.PayMethod.findById(this.payMethodFk);
|
||||||
const supplierAccount = await Self.app.models.SupplierAccount.findOne({where: {supplierFk: this.id}});
|
const supplierAccount = await Self.app.models.SupplierAccount.findOne({where: {supplierFk: this.id}});
|
||||||
const hasIban = supplierAccount && supplierAccount.iban;
|
const hasIban = supplierAccount && supplierAccount.iban;
|
||||||
|
@ -92,6 +101,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
|
|
||||||
Self.observe('before save', async function(ctx) {
|
Self.observe('before save', async function(ctx) {
|
||||||
|
if (ctx.isNewInstance) return;
|
||||||
const loopbackContext = LoopBackContext.getCurrentContext();
|
const loopbackContext = LoopBackContext.getCurrentContext();
|
||||||
const changes = ctx.data || ctx.instance;
|
const changes = ctx.data || ctx.instance;
|
||||||
const orgData = ctx.currentInstance;
|
const orgData = ctx.currentInstance;
|
||||||
|
@ -101,7 +111,7 @@ module.exports = Self => {
|
||||||
const isPayMethodChecked = changes.isPayMethodChecked || orgData.isPayMethodChecked;
|
const isPayMethodChecked = changes.isPayMethodChecked || orgData.isPayMethodChecked;
|
||||||
const hasChanges = orgData && changes;
|
const hasChanges = orgData && changes;
|
||||||
const isPayMethodCheckedChanged = hasChanges
|
const isPayMethodCheckedChanged = hasChanges
|
||||||
&& orgData.isPayMethodChecked != isPayMethodChecked;
|
&& orgData.isPayMethodChecked != isPayMethodChecked;
|
||||||
|
|
||||||
if (isNotFinancial && isPayMethodCheckedChanged)
|
if (isNotFinancial && isPayMethodCheckedChanged)
|
||||||
throw new UserError('You can not modify is pay method checked');
|
throw new UserError('You can not modify is pay method checked');
|
||||||
|
@ -114,7 +124,7 @@ module.exports = Self => {
|
||||||
const socialName = changes.name || orgData.name;
|
const socialName = changes.name || orgData.name;
|
||||||
const hasChanges = orgData && changes;
|
const hasChanges = orgData && changes;
|
||||||
const socialNameChanged = hasChanges
|
const socialNameChanged = hasChanges
|
||||||
&& orgData.socialName != socialName;
|
&& orgData.socialName != socialName;
|
||||||
|
|
||||||
if ((socialNameChanged) && !isAlpha(socialName))
|
if ((socialNameChanged) && !isAlpha(socialName))
|
||||||
throw new UserError('The social name has an invalid format');
|
throw new UserError('The social name has an invalid format');
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<vn-watcher
|
||||||
|
vn-id="watcher"
|
||||||
|
url="suppliers/newSupplier"
|
||||||
|
data="$ctrl.supplier"
|
||||||
|
insert-mode="true"
|
||||||
|
form="form">
|
||||||
|
</vn-watcher>
|
||||||
|
<form name="form" ng-submit="$ctrl.onSubmit()" class="vn-w-md">
|
||||||
pau marked this conversation as resolved
joan
commented
Este crud model parece que no se utiliza Este crud model parece que no se utiliza
|
|||||||
|
<vn-card class="vn-pa-lg">
|
||||||
|
<vn-horizontal>
|
||||||
|
<vn-textfield
|
||||||
|
label="Supplier name"
|
||||||
|
ng-model="$ctrl.supplier.name"
|
||||||
|
vn-focus>
|
||||||
|
</vn-textfield>
|
||||||
|
</vn-horizontal>
|
||||||
|
</vn-card>
|
||||||
|
<vn-button-bar>
|
||||||
|
<vn-submit
|
||||||
|
disabled="!watcher.dataChanged()"
|
||||||
|
label="Create">
|
||||||
|
</vn-submit>
|
||||||
|
<vn-button
|
||||||
|
class="cancel"
|
||||||
|
label="Cancel"
|
||||||
|
ui-sref="supplier.index">
|
||||||
|
</vn-button>
|
||||||
|
</vn-button-bar>
|
||||||
|
</form>
|
|
@ -0,0 +1,23 @@
|
||||||
|
import ngModule from '../module';
|
||||||
|
import Section from 'salix/components/section';
|
||||||
|
|
||||||
|
class Controller extends Section {
|
||||||
|
constructor($element, $) {
|
||||||
|
super($element, $);
|
||||||
|
}
|
||||||
|
|
||||||
|
onSubmit() {
|
||||||
|
this.$.watcher.submit().then(
|
||||||
|
json => {
|
||||||
|
this.$state.go(`supplier.card.fiscalData`, {id: json.data.id});
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Supplier fiscaldata Supplier fiscaldata
|
|||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Se debería utilizar únicamente el $state.go(), la función de abajo no es necesaria. Se debería utilizar únicamente el $state.go(), la función de abajo no es necesaria.
|
|||||||
|
|
||||||
|
Controller.$inject = ['$element', '$scope'];
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnSupplierCreate', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: Controller
|
||||||
|
});
|
|
@ -20,3 +20,4 @@ import './address/create';
|
||||||
import './address/edit';
|
import './address/edit';
|
||||||
import './agency-term/index';
|
import './agency-term/index';
|
||||||
import './agency-term/create';
|
import './agency-term/create';
|
||||||
|
import './create/index';
|
||||||
|
|
|
@ -59,3 +59,6 @@
|
||||||
supplier="$ctrl.supplierSelected">
|
supplier="$ctrl.supplierSelected">
|
||||||
</vn-supplier-summary>
|
</vn-supplier-summary>
|
||||||
</vn-popup>
|
</vn-popup>
|
||||||
|
<a vn-acl-action="remove" vn-acl="administrative" ui-sref="supplier.create" vn-tooltip="New supplier" vn-bind="+" fixed-bottom-right>
|
||||||
|
<vn-float-button icon="add"></vn-float-button>
|
||||||
|
</a>
|
|
@ -3,3 +3,4 @@ Pay day: Dia de pago
|
||||||
Account: Cuenta
|
Account: Cuenta
|
||||||
Pay method: Metodo de pago
|
Pay method: Metodo de pago
|
||||||
Tax number: Nif
|
Tax number: Nif
|
||||||
|
New supplier: Nuevo proveedor
|
|
@ -52,6 +52,13 @@
|
||||||
"supplier": "$ctrl.supplier"
|
"supplier": "$ctrl.supplier"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"url": "/create",
|
||||||
|
"state": "supplier.create",
|
||||||
|
"component": "vn-supplier-create",
|
||||||
|
"acl": ["administrative"],
|
||||||
pau marked this conversation as resolved
Outdated
joan
commented
Falta especificar el ACL administrative Falta especificar el ACL administrative
|
|||||||
|
"description": "New supplier"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "/basic-data",
|
"url": "/basic-data",
|
||||||
"state": "supplier.card.basicData",
|
"state": "supplier.card.basicData",
|
||||||
|
|
Loading…
Reference in New Issue
Nombre de esquema y tabla entre template strings ``