const UserError = require('vn-loopback/util/user-error');
module.exports = Self => {
    Self.remoteMethodCtx('updateTracking', {
        description: 'Modify a saleTracking record and, if applicable, add a corresponding record in saleBuy.',
        accessType: 'WRITE',
        accepts: [
            {
                arg: 'saleFk',
                type: 'number',
                required: true
            },
            {
                arg: 'originalQuantity',
                type: 'number',
                required: true
            },
            {
                arg: 'code',
                type: 'string',
                required: true
            },
            {
                arg: 'isChecked',
                type: 'boolean',
                required: true
            },
            {
                arg: 'buyFk',
                type: 'number',
                required: true
            },
            {
                arg: 'isScanned',
                type: 'boolean',
            },
        ],
        http: {
            path: `/updateTracking`,
            verb: 'POST'
        }
    });

    Self.updateTracking = async(ctx, saleFk, originalQuantity, code, isChecked, buyFk, isScanned = null, options) => {
        const userId = ctx.req.accessToken.userId;
        const models = Self.app.models;
        const myOptions = {userId};
        let tx;

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

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

        try {
            const state = await models.State.findOne({
                where: {code},
            }, myOptions);

            if (!state) throw new UserError('this state does not exist');
            const uniqueAttributes = {
                saleFk,
                workerFk: userId,
                stateFk: state?.id,
            };
            const attributes = {
                isChecked,
                originalQuantity,
                isScanned
            };

            const saleTracking = await models.SaleTracking.findOne({
                where: uniqueAttributes,
            }, myOptions);

            if (!saleTracking) {
                await models.SaleTracking.create({
                    ...uniqueAttributes,
                    ...attributes
                }, myOptions);
            } else {
                await saleTracking.updateAttributes({
                    ...attributes
                }, myOptions);
            }

            let isBuy;
            if (buyFk) {
                isBuy = await models.Buy.findOne({
                    where: {
                        id: buyFk,
                        itemOriginalFk: {
                            neq: null
                        }
                    }
                }, myOptions);
            }

            if (isBuy)
                await models.SaleBuy.create({saleFk, buyFk}, myOptions);

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