module.exports = Self => {
    Self.remoteMethodCtx('createInvoiceIn', {
        description: 'Creates an invoiceIn from one or more agency terms',
        accessType: 'WRITE',
        accepts: [{
            arg: 'rows',
            type: ['object'],
            required: true,
            description: `The rows from which the invoiceIn will be created`,
        },
        {
            arg: 'dms',
            type: ['object'],
            required: true,
            description: 'The dms file attached'
        }],
        returns: {
            type: 'object',
            root: true
        },
        http: {
            path: `/createInvoiceIn`,
            verb: 'POST'
        }
    });

    Self.createInvoiceIn = async(ctx, rows, dms, options) => {
        const models = Self.app.models;

        let tx;
        const myOptions = {userId: ctx.req.accessToken.userId};

        if (typeof options == 'object')
            Object.assign(myOptions, options);

        if (!myOptions.transaction) {
            tx = await Self.beginTransaction({});
            myOptions.transaction = tx;
        }

        try {
            const [firstRow] = rows;
            const [firstDms] = dms;

            const reference = await models.Dms.findById([firstDms.id], null, myOptions);

            const newInvoiceIn = await models.InvoiceIn.create({
                supplierFk: firstRow.supplierFk,
                supplierRef: reference.reference,
                issued: firstRow.created,
                booked: firstRow.created,
                operated: firstRow.created,
                bookEntried: firstRow.created,
                dmsFk: firstDms.id,
            }, myOptions);

            const expense = await models.AgencyTermConfig.findOne(null, myOptions);

            const [taxTypeSage] = await Self.rawSql(`
                SELECT IFNULL(s.taxTypeSageFk, CodigoIva) value
                    FROM vn.supplier s
                        JOIN sage.TiposIva ti ON TRUE
                        JOIN vn.agencyTermConfig atg
                    WHERE s.id = ?
                        AND ti.CuentaIvaSoportado = atg.vatAccountSupported
                        AND ti.PorcentajeIva = atg.vatPercentage
            `, [firstRow.supplierFk], myOptions);

            const [transactionTypeSage] = await Self.rawSql(`
                SELECT IFNULL(s.transactionTypeSageFk, tt.CodigoTransaccion) value
                    FROM vn.supplier s
                        JOIN sage.TiposTransacciones tt ON TRUE
                        JOIN vn.agencyTermConfig atg
                    WHERE s.id = ?
                        AND tt.Transaccion = atg.transaction
                `, [firstRow.supplierFk], myOptions);

            await models.InvoiceInTax.create({
                invoiceInFk: newInvoiceIn.id,
                taxableBase: firstRow.totalPrice,
                expenseFk: expense.expenseFk,
                taxTypeSageFk: taxTypeSage.value,
                transactionTypeSageFk: transactionTypeSage.value
            }, myOptions);

            await Self.rawSql(`CALL invoiceInDueDay_calculate(?)`, [newInvoiceIn.id], myOptions);

            for (let agencyTerm of rows) {
                const route = await models.Route.findById(agencyTerm.routeFk, null, myOptions);
                await Self.rawSql(`
                UPDATE vn.route SET invoiceInFk = ? WHERE id =  ?
                `, [newInvoiceIn.id, route.id], myOptions);
            }

            if (tx) await tx.commit();

            return newInvoiceIn;
        } catch (e) {
            if (tx) await tx.rollback();
            throw e;
        }
    };
};