<commit_before>import Accesses from '../../models/accesses';
import Categories from '../../models/categories';
import Settings from '../../models/settings';
import { asyncErr, KError, translate as $t } from '../../helpers';

import {
    createAndRetrieveData as createAndRetrieveAccessData,
    destroyWithData as destroyAccessWithData
} from './accesses';

import DefaultCategories from '../../shared/default-categories.json';

export async function isEnabled(userId) {
    return await Settings.findOrCreateDefaultBooleanValue(userId, 'demo-mode');
}

export async function enable(req, res) {
    try {
        let { id: userId } = req.user;

        let isDemoEnabled = await isEnabled(userId);
        if (isDemoEnabled) {
            throw new KError('Demo mode is already enabled, not enabling it.', 400);
        }

        // Set the demo mode to true.
        isDemoEnabled = await Settings.findOrCreateByKey(userId, 'demo-mode', 'true');
        if (isDemoEnabled.value !== 'true') {
            // The setting already existed and has the wrong value.
            await Settings.updateByKey(userId, 'demo-mode', 'true');
        }

        // Create default categories.
        for (let category of DefaultCategories) {
            await Categories.create(userId, {
                label: $t(category.label),
                color: category.color
            });
        }

        const data = await createAndRetrieveAccessData(userId, {
            vendorId: 'demo',
            login: 'mylogin',
            password: '<PASSWORD>',
            customLabel: 'Demo bank'
        });
        res.status(201).json(data);
    } catch (err) {
        return asyncErr(res, err, 'when enabling demo mode');
    }
}

export async function disable(req, res) {
    try {
        let { id: userId } = req.user;

        const isDemoEnabled = await isEnabled(userId);
        if (!isDemoEnabled) {
            throw new KError('Demo mode was not enabled, not disabling it.', 400);
        }

        // Reset everything.
        await Settings.updateByKey(userId, 'demo-mode', 'false');

        const accesses = await Accesses.all(userId);
        for (let acc of accesses) {
            await destroyAccessWithData(userId, acc);
        }

        const categories = await Categories.all(userId);
        for (let cat of categories) {
            await Categories.destroy(userId, cat.id);
        }

        res.status(200).end();
    } catch (err) {
        return asyncErr(res, err, 'when disabling demo mode');
    }
}<commit_msg>[server] Remove budgets when disabling demo mode;<commit_after>import Accesses from '../../models/accesses';
import Budgets from '../../models/budgets';
import Categories from '../../models/categories';
import Settings from '../../models/settings';
import { asyncErr, KError, translate as $t } from '../../helpers';

import {
    createAndRetrieveData as createAndRetrieveAccessData,
    destroyWithData as destroyAccessWithData
} from './accesses';

import DefaultCategories from '../../shared/default-categories.json';

export async function isEnabled(userId) {
    return await Settings.findOrCreateDefaultBooleanValue(userId, 'demo-mode');
}

export async function enable(req, res) {
    try {
        let { id: userId } = req.user;

        let isDemoEnabled = await isEnabled(userId);
        if (isDemoEnabled) {
            throw new KError('Demo mode is already enabled, not enabling it.', 400);
        }

        // Set the demo mode to true.
        isDemoEnabled = await Settings.findOrCreateByKey(userId, 'demo-mode', 'true');
        if (isDemoEnabled.value !== 'true') {
            // The setting already existed and has the wrong value.
            await Settings.updateByKey(userId, 'demo-mode', 'true');
        }

        // Create default categories.
        for (let category of DefaultCategories) {
            await Categories.create(userId, {
                label: $t(category.label),
                color: category.color
            });
        }

        const data = await createAndRetrieveAccessData(userId, {
            vendorId: 'demo',
            login: 'mylogin',
            password: '<PASSWORD>',
            customLabel: 'Demo bank'
        });
        res.status(201).json(data);
    } catch (err) {
        return asyncErr(res, err, 'when enabling demo mode');
    }
}

export async function disable(req, res) {
    try {
        let { id: userId } = req.user;

        const isDemoEnabled = await isEnabled(userId);
        if (!isDemoEnabled) {
            throw new KError('Demo mode was not enabled, not disabling it.', 400);
        }

        const accesses = await Accesses.all(userId);
        for (let acc of accesses) {
            await destroyAccessWithData(userId, acc);
        }

        // Delete categories and associated budgets.
        const categories = await Categories.all(userId);
        for (let cat of categories) {
            await Budgets.destroyForCategory(userId, cat.id /* no replacement category */);
            await Categories.destroy(userId, cat.id);
        }

        // Only reset the setting value if all the destroy operations
        // succeeded.
        await Settings.updateByKey(userId, 'demo-mode', 'false');

        res.status(200).end();
    } catch (err) {
        return asyncErr(res, err, 'when disabling demo mode');
    }
}
{'fraction_non_alphanumeric': 0.11753731343283583, 'fraction_numerical': 0.004477611940298508, 'mean_word_length': 2.26691042047532, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6318682', 'n_tokens_mistral': 1452, 'n_tokens_neox': 1438, 'n_words': 428}