refs #5914 fix: transferInvoice
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
This commit is contained in:
parent
37555cbb63
commit
37f8369849
|
@ -24,7 +24,7 @@ describe('InvoiceOut tranferInvoice()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
const args = {
|
const args = {
|
||||||
id: '1',
|
id: '1',
|
||||||
ref: 'T4444444',
|
refFk: 'T4444444',
|
||||||
newClientFk: 1,
|
newClientFk: 1,
|
||||||
cplusRectificationId: 1,
|
cplusRectificationId: 1,
|
||||||
siiTypeInvoiceOutId: 1,
|
siiTypeInvoiceOutId: 1,
|
||||||
|
@ -49,7 +49,7 @@ describe('InvoiceOut tranferInvoice()', () => {
|
||||||
const options = {transaction: tx};
|
const options = {transaction: tx};
|
||||||
const args = {
|
const args = {
|
||||||
id: '1',
|
id: '1',
|
||||||
ref: 'T1111111',
|
refFk: 'T1111111',
|
||||||
newClientFk: 1101,
|
newClientFk: 1101,
|
||||||
cplusRectificationId: 1,
|
cplusRectificationId: 1,
|
||||||
siiTypeInvoiceOutId: 1,
|
siiTypeInvoiceOutId: 1,
|
||||||
|
|
|
@ -12,7 +12,7 @@ module.exports = Self => {
|
||||||
description: 'Issued invoice id'
|
description: 'Issued invoice id'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'ref',
|
arg: 'refFk',
|
||||||
type: 'string',
|
type: 'string',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
@ -22,17 +22,17 @@ module.exports = Self => {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'cplusRectificationId',
|
arg: 'cplusRectificationFk',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'siiTypeInvoiceOutId',
|
arg: 'siiTypeInvoiceOutFk',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
arg: 'invoiceCorrectionTypeId',
|
arg: 'invoiceCorrectionTypeFk',
|
||||||
type: 'number',
|
type: 'number',
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
@ -50,14 +50,14 @@ module.exports = Self => {
|
||||||
Self.transferInvoice = async(ctx, options) => {
|
Self.transferInvoice = async(ctx, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const myOptions = {userId: ctx.req.accessToken.userId};
|
const myOptions = {userId: ctx.req.accessToken.userId};
|
||||||
const args = ctx.args;
|
const {id, refFk, newClientFk, cplusRectificationFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk} = ctx.args;
|
||||||
let tx;
|
let tx;
|
||||||
if (typeof options == 'object')
|
if (typeof options == 'object')
|
||||||
Object.assign(myOptions, options);
|
Object.assign(myOptions, options);
|
||||||
|
|
||||||
const {clientFk} = await models.InvoiceOut.findById(args.id);
|
const {clientFk} = await models.InvoiceOut.findById(id);
|
||||||
|
|
||||||
if (clientFk == args.newClientFk)
|
if (clientFk == newClientFk)
|
||||||
throw new UserError(`Select a different client`);
|
throw new UserError(`Select a different client`);
|
||||||
|
|
||||||
if (!myOptions.transaction) {
|
if (!myOptions.transaction) {
|
||||||
|
@ -65,10 +65,10 @@ module.exports = Self => {
|
||||||
myOptions.transaction = tx;
|
myOptions.transaction = tx;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const filterRef = {where: {refFk: args.ref}};
|
const filterRef = {where: {refFk: refFk}};
|
||||||
const tickets = await models.Ticket.find(filterRef, myOptions);
|
const tickets = await models.Ticket.find(filterRef, myOptions);
|
||||||
const ticketsIds = tickets.map(ticket => ticket.id);
|
const ticketsIds = tickets.map(ticket => ticket.id);
|
||||||
await models.Ticket.refund(ctx, ticketsIds, null, myOptions);
|
const refundTickets = await models.Ticket.refund(ctx, ticketsIds, null, myOptions);
|
||||||
|
|
||||||
const filterTicket = {where: {ticketFk: {inq: ticketsIds}}};
|
const filterTicket = {where: {ticketFk: {inq: ticketsIds}}};
|
||||||
|
|
||||||
|
@ -82,20 +82,16 @@ module.exports = Self => {
|
||||||
const clonedTicketIds = [];
|
const clonedTicketIds = [];
|
||||||
|
|
||||||
for (const clonedTicket of clonedTickets) {
|
for (const clonedTicket of clonedTickets) {
|
||||||
await clonedTicket.updateAttribute('clientFk', args.newClientFk, myOptions);
|
await clonedTicket.updateAttribute('clientFk', newClientFk, myOptions);
|
||||||
clonedTicketIds.push(clonedTicket.id);
|
clonedTicketIds.push(clonedTicket.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
const invoiceIds = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions);
|
const invoiceCorrection =
|
||||||
const [invoiceId] = invoiceIds;
|
{correctedFk: id, cplusRectificationFk, siiTypeInvoiceOutFk, invoiceCorrectionTypeFk};
|
||||||
|
const refundTicketIds = refundTickets.map(ticket => ticket.id);
|
||||||
|
|
||||||
await models.InvoiceCorrection.create({
|
await models.Ticket.invoiceTickets(ctx, refundTicketIds, invoiceCorrection, myOptions);
|
||||||
correctingFk: invoiceId,
|
const [[invoiceId]] = await models.Ticket.invoiceTickets(ctx, clonedTicketIds, myOptions);
|
||||||
correctedFk: args.id,
|
|
||||||
cplusRectificationTypeFk: args.cplusRectificationId,
|
|
||||||
siiTypeInvoiceOutFk: args.siiTypeInvoiceOutId,
|
|
||||||
invoiceCorrectionTypeFk: args.invoiceCorrectionTypeId
|
|
||||||
}, myOptions);
|
|
||||||
|
|
||||||
if (tx) {
|
if (tx) {
|
||||||
await tx.commit();
|
await tx.commit();
|
||||||
|
|
|
@ -16,13 +16,16 @@
|
||||||
"type": "number"
|
"type": "number"
|
||||||
},
|
},
|
||||||
"cplusRectificationTypeFk": {
|
"cplusRectificationTypeFk": {
|
||||||
"type": "number"
|
"type": "number",
|
||||||
|
"required": true
|
||||||
},
|
},
|
||||||
"siiTypeInvoiceOutFk": {
|
"siiTypeInvoiceOutFk": {
|
||||||
"type": "number"
|
"type": "number",
|
||||||
|
"required": true
|
||||||
},
|
},
|
||||||
"invoiceCorrectionTypeFk": {
|
"invoiceCorrectionTypeFk": {
|
||||||
"type": "number"
|
"type": "number",
|
||||||
|
"required": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
"type": "number",
|
"type": "number",
|
||||||
"description": "Identifier"
|
"description": "Identifier"
|
||||||
},
|
},
|
||||||
|
"code": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
auto-load="true"
|
auto-load="true"
|
||||||
url="SiiTypeInvoiceOuts"
|
url="SiiTypeInvoiceOuts"
|
||||||
data="siiTypeInvoiceOut">
|
data="siiTypeInvoiceOuts"
|
||||||
|
where="{code: {like: 'R%'}}">
|
||||||
</vn-crud-model>
|
</vn-crud-model>
|
||||||
<vn-crud-model
|
<vn-crud-model
|
||||||
auto-load="true"
|
auto-load="true"
|
||||||
|
@ -185,64 +186,69 @@
|
||||||
vn-id="transferInvoice"
|
vn-id="transferInvoice"
|
||||||
title="transferInvoice"
|
title="transferInvoice"
|
||||||
on-accept="$ctrl.transferInvoice()">
|
on-accept="$ctrl.transferInvoice()">
|
||||||
|
<tpl-title translate>
|
||||||
|
transferInvoice
|
||||||
|
</tpl-title>
|
||||||
<tpl-body>
|
<tpl-body>
|
||||||
<section class="transferInvoice">
|
<section class="transferInvoice">
|
||||||
<vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-autocomplete
|
<vn-autocomplete
|
||||||
vn-one
|
vn-one
|
||||||
vn-id="client"
|
vn-id="client"
|
||||||
required="true"
|
required="true"
|
||||||
url="Clients"
|
url="Clients"
|
||||||
label="Client"
|
label="Client"
|
||||||
show-field="name"
|
show-field="name"
|
||||||
value-field="id"
|
value-field="id"
|
||||||
search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
|
search-function="{or: [{id: $search}, {name: {like: '%'+ $search +'%'}}]}"
|
||||||
ng-model="$ctrl.invoiceOut.client.id"
|
ng-model="$ctrl.clientId"
|
||||||
initial-data="$ctrl.invoiceOut.client.id"
|
order="id">
|
||||||
order="id">
|
<tpl-item>
|
||||||
<tpl-item>
|
#{{id}} - {{::name}}
|
||||||
#{{id}} - {{::name}}
|
</tpl-item>
|
||||||
</tpl-item>
|
</vn-autocomplete>
|
||||||
</vn-autocomplete>
|
<vn-autocomplete
|
||||||
<vn-autocomplete
|
vn-one
|
||||||
vn-one
|
vn-id="cplusRectificationType"
|
||||||
vn-id="cplusRectificationType"
|
required="true"
|
||||||
required="true"
|
data="cplusRectificationTypes"
|
||||||
data="cplusRectificationTypes"
|
show-field="description"
|
||||||
show-field="description"
|
value-field="id"
|
||||||
value-field="id"
|
ng-model="$ctrl.cplusRectificationType"
|
||||||
ng-model="$ctrl.cplusRectificationType"
|
search-function="{or: [{id: $search}, {description: {like: '%'+ $search +'%'}}]}"
|
||||||
search-function="{or: [{id: $search}, {description: {like: '%'+ $search +'%'}}]}"
|
label="Rectificative type">
|
||||||
label="Cplus Type">
|
<tpl-item>
|
||||||
<tpl-item>
|
{{::description}}
|
||||||
{{::description}}
|
</tpl-item>
|
||||||
</tpl-item>
|
</vn-autocomplete>
|
||||||
</vn-autocomplete>
|
</vn-horizontal>
|
||||||
</vn-horizontal>
|
<vn-horizontal>
|
||||||
<vn-horizontal>
|
<vn-autocomplete
|
||||||
<vn-autocomplete
|
vn-one
|
||||||
vn-one
|
vn-id="siiTypeInvoiceOut"
|
||||||
vn-id="cplusInvoiceType"
|
data="siiTypeInvoiceOuts"
|
||||||
data="siiTypeInvoiceOut"
|
show-field="code"
|
||||||
show-field="description"
|
value-field="id"
|
||||||
value-field="id"
|
fields="['id','code','description']"
|
||||||
required="true"
|
required="true"
|
||||||
ng-model="$ctrl.siiTypeInvoiceOut"
|
ng-model="$ctrl.siiTypeInvoiceOut"
|
||||||
search-function="{or: [{id: $search}, {description: {like: '%'+ $search +'%'}}]}"
|
label="Class">
|
||||||
label="Class">
|
<tpl-item>
|
||||||
</vn-autocomplete>
|
{{::code}} - {{::description}}
|
||||||
<vn-autocomplete
|
</tpl-item>
|
||||||
vn-one
|
</vn-autocomplete>
|
||||||
vn-id="invoiceCorrectionType"
|
<vn-autocomplete
|
||||||
data="invoiceCorrectionTypes"
|
vn-one
|
||||||
ng-model="$ctrl.invoiceCorrectionType"
|
vn-id="invoiceCorrectionType"
|
||||||
show-field="description"
|
data="invoiceCorrectionTypes"
|
||||||
value-field="id"
|
ng-model="$ctrl.invoiceCorrectionType"
|
||||||
required="true"
|
show-field="description"
|
||||||
label="Type">
|
value-field="id"
|
||||||
</vn-autocomplete>
|
required="true"
|
||||||
</vn-horizontal>
|
label="Type">
|
||||||
</section>
|
</vn-autocomplete>
|
||||||
|
</vn-horizontal>
|
||||||
|
</section>
|
||||||
</tpl-body>
|
</tpl-body>
|
||||||
<tpl-buttons>
|
<tpl-buttons>
|
||||||
<button response="accept" translate>Transfer client</button>
|
<button response="accept" translate>Transfer client</button>
|
||||||
|
|
|
@ -129,11 +129,11 @@ class Controller extends Section {
|
||||||
transferInvoice() {
|
transferInvoice() {
|
||||||
const params = {
|
const params = {
|
||||||
id: this.invoiceOut.id,
|
id: this.invoiceOut.id,
|
||||||
ref: this.invoiceOut.ref,
|
refFk: this.invoiceOut.ref,
|
||||||
newClientFk: this.invoiceOut.client.id,
|
newClientFk: this.clientId,
|
||||||
cplusRectificationId: this.cplusRectificationType,
|
cplusRectificationFk: this.cplusRectificationType,
|
||||||
siiTypeInvoiceOutId: this.siiTypeInvoiceOut,
|
siiTypeInvoiceOutFk: this.siiTypeInvoiceOut,
|
||||||
invoiceCorrectionTypeId: this.invoiceCorrectionType
|
invoiceCorrectionTypeFk: this.invoiceCorrectionType
|
||||||
};
|
};
|
||||||
this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => {
|
this.$http.post(`InvoiceOuts/transferInvoice`, params).then(res => {
|
||||||
const invoiceId = res.data;
|
const invoiceId = res.data;
|
||||||
|
|
|
@ -22,4 +22,4 @@ The email can't be empty: El correo no puede estar vacío
|
||||||
The following refund tickets have been created: "Se han creado los siguientes tickets de abono: {{ticketIds}}"
|
The following refund tickets have been created: "Se han creado los siguientes tickets de abono: {{ticketIds}}"
|
||||||
Refund...: Abono...
|
Refund...: Abono...
|
||||||
Transfer invoice to...: Transferir factura a...
|
Transfer invoice to...: Transferir factura a...
|
||||||
Cplus Type: Cplus Tipo
|
Rectificative type: Tipo rectificativa
|
||||||
|
|
|
@ -19,7 +19,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['number'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
@ -54,7 +54,7 @@ module.exports = Self => {
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
|
|
||||||
return refundsTicket[0];
|
return refundsTicket;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (tx) await tx.rollback();
|
if (tx) await tx.rollback();
|
||||||
throw e;
|
throw e;
|
||||||
|
|
|
@ -10,7 +10,13 @@ module.exports = function(Self) {
|
||||||
description: 'The tickets id',
|
description: 'The tickets id',
|
||||||
type: ['number'],
|
type: ['number'],
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'invoiceCorrection',
|
||||||
|
description: 'The invoice correction',
|
||||||
|
type: 'object',
|
||||||
}
|
}
|
||||||
|
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['object'],
|
type: ['object'],
|
||||||
|
@ -22,7 +28,7 @@ module.exports = function(Self) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.invoiceTickets = async(ctx, ticketsIds, options) => {
|
Self.invoiceTickets = async(ctx, ticketsIds, invoiceCorrection, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
const date = Date.vnNew();
|
const date = Date.vnNew();
|
||||||
date.setHours(0, 0, 0, 0);
|
date.setHours(0, 0, 0, 0);
|
||||||
|
@ -68,9 +74,9 @@ module.exports = function(Self) {
|
||||||
|
|
||||||
const addressIds = result.map(address => address.addressFk);
|
const addressIds = result.map(address => address.addressFk);
|
||||||
for (const address of addressIds)
|
for (const address of addressIds)
|
||||||
await createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, myOptions);
|
await createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, invoiceCorrection, myOptions);
|
||||||
} else
|
} else
|
||||||
await createInvoice(ctx, companyId, ticketsIds, null, invoicesIds, myOptions);
|
await createInvoice(ctx, companyId, ticketsIds, null, invoicesIds, invoiceCorrection, myOptions);
|
||||||
|
|
||||||
if (tx) await tx.commit();
|
if (tx) await tx.commit();
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -85,9 +91,9 @@ module.exports = function(Self) {
|
||||||
return invoicesIds;
|
return invoicesIds;
|
||||||
};
|
};
|
||||||
|
|
||||||
async function createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, myOptions) {
|
async function createInvoice(ctx, companyId, ticketsIds, address, invoicesIds, invoiceCorrection, myOptions) {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
|
console.log(ticketsIds, address);
|
||||||
await models.Ticket.rawSql(`
|
await models.Ticket.rawSql(`
|
||||||
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice
|
CREATE OR REPLACE TEMPORARY TABLE tmp.ticketToInvoice
|
||||||
(PRIMARY KEY (id))
|
(PRIMARY KEY (id))
|
||||||
|
@ -98,7 +104,8 @@ module.exports = function(Self) {
|
||||||
${address ? `AND addressFk = ${address}` : ''}
|
${address ? `AND addressFk = ${address}` : ''}
|
||||||
`, [ticketsIds], myOptions);
|
`, [ticketsIds], myOptions);
|
||||||
|
|
||||||
const invoiceId = await models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), myOptions);
|
const invoiceId =
|
||||||
|
await models.Ticket.makeInvoice(ctx, 'R', companyId, Date.vnNew(), invoiceCorrection, myOptions);
|
||||||
invoicesIds.push(invoiceId);
|
invoicesIds.push(invoiceId);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,6 +22,11 @@ module.exports = function(Self) {
|
||||||
description: 'The invoice date',
|
description: 'The invoice date',
|
||||||
type: 'date',
|
type: 'date',
|
||||||
required: true
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
arg: 'invoiceCorrection',
|
||||||
|
description: 'The invoice correction',
|
||||||
|
type: 'object',
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
|
@ -34,7 +39,7 @@ module.exports = function(Self) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
Self.makeInvoice = async(ctx, invoiceType, companyFk, invoiceDate, options) => {
|
Self.makeInvoice = async(ctx, invoiceType, companyFk, invoiceDate, invoiceCorrection, options) => {
|
||||||
const models = Self.app.models;
|
const models = Self.app.models;
|
||||||
invoiceDate.setHours(0, 0, 0, 0);
|
invoiceDate.setHours(0, 0, 0, 0);
|
||||||
|
|
||||||
|
@ -66,8 +71,8 @@ module.exports = function(Self) {
|
||||||
|
|
||||||
const [firstTicket] = tickets;
|
const [firstTicket] = tickets;
|
||||||
const clientId = firstTicket.clientFk;
|
const clientId = firstTicket.clientFk;
|
||||||
const clientCanBeInvoiced = await models.Client.canBeInvoiced(clientId, companyFk, myOptions);
|
const clientCanBeInvoiced = await models.Client.canBeInvoiced(clientId, companyFk, invoiceCorrection, myOptions);
|
||||||
if (!clientCanBeInvoiced)
|
if (!clientCanBeInvoiced && !invoiceCorrection)
|
||||||
throw new UserError(`This client can't be invoiced`);
|
throw new UserError(`This client can't be invoiced`);
|
||||||
|
|
||||||
const query = `SELECT vn.invoiceSerial(?, ?, ?) AS serial`;
|
const query = `SELECT vn.invoiceSerial(?, ?, ?) AS serial`;
|
||||||
|
@ -90,6 +95,13 @@ module.exports = function(Self) {
|
||||||
if (!resultInvoice)
|
if (!resultInvoice)
|
||||||
throw new UserError('No tickets to invoice', 'notInvoiced');
|
throw new UserError('No tickets to invoice', 'notInvoiced');
|
||||||
|
|
||||||
|
if (invoiceCorrection) {
|
||||||
|
await models.InvoiceCorrection.create(
|
||||||
|
Object.assign(invoiceCorrection, {correctingFk: resultInvoice.id}),
|
||||||
|
myOptions
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (serial != 'R' && resultInvoice.id)
|
if (serial != 'R' && resultInvoice.id)
|
||||||
await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions);
|
await Self.rawSql('CALL invoiceOutBooking(?)', [resultInvoice.id], myOptions);
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ module.exports = Self => {
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
returns: {
|
returns: {
|
||||||
type: ['number'],
|
type: ['object'],
|
||||||
root: true
|
root: true
|
||||||
},
|
},
|
||||||
http: {
|
http: {
|
||||||
|
|
Loading…
Reference in New Issue