/* global QUnit*/

odoo.define("account_reconciliation_widget.reconciliation_tests.data", function (
    // eslint-disable-next-line no-unused-vars
    require
) {
    "use strict";

    /*
     * Debug tip:
     * To be able to "see" the test in the browser:
     *       var $body = $('body');
     *       $body.addClass('debug');
     *       clientAction.appendTo($body);
     */

    var Datas = {};

    var options = {
        context: {
            statement_line_ids: [4],
        },
        params: {
            limitMoveLines: 5,
        },
    };

    var db = {
        "res.company": {
            fields: {
                id: {string: "ID", type: "integer"},
                display_name: {string: "Displayed name", type: "char"},
            },
            records: [{id: 1, display_name: "company 1"}],
        },
        "res.partner": {
            fields: {
                id: {string: "ID", type: "integer"},
                display_name: {string: "Displayed name", type: "char"},
                image: {string: "image", type: "integer"},
                parent_id: {string: "Parent", type: "boolean"},
                is_company: {string: "Is company", type: "boolean"},
                property_account_receivable_id: {
                    string: "Account receivable",
                    type: "many2one",
                    relation: "account.account",
                },
                property_account_payable_id: {
                    string: "Account payable",
                    type: "many2one",
                    relation: "account.account",
                },
            },
            records: [
                {id: 1, display_name: "partner 1", image: "AAA"},
                {id: 2, display_name: "partner 2", image: "BBB"},
                {id: 3, display_name: "partner 3", image: "CCC"},
                {id: 4, display_name: "partner 4", image: "DDD"},
                {id: 8, display_name: "Agrolait", image: "EEE"},
                {
                    id: 12,
                    display_name: "Camptocamp",
                    image: "FFF",
                    property_account_receivable_id: 287,
                    property_account_payable_id: 287,
                },
                // Add more to have 'Search More' option
                {id: 98, display_name: "partner 98", image: "YYY"},
                {id: 99, display_name: "partner 99", image: "ZZZ"},
            ],
            mark_as_reconciled: function () {
                return Promise.resolve();
            },
        },
        "account.account": {
            fields: {
                id: {string: "ID", type: "integer"},
                code: {string: "code", type: "integer"},
                name: {string: "Displayed name", type: "char"},
                company_id: {
                    string: "Company",
                    type: "many2one",
                    relation: "res.company",
                },
                deprecated: {string: "Deprecated", type: "boolean"},
            },
            records: [
                {
                    id: 282,
                    code: 100000,
                    name: "100000 Fixed Asset Account",
                    company_id: 1,
                },
                {id: 283, code: 101000, name: "101000 Current Assets", company_id: 1},
                {
                    id: 284,
                    code: 101110,
                    name: "101110 Stock Valuation Account",
                    company_id: 1,
                },
                {
                    id: 285,
                    code: 101120,
                    name: "101120 Stock Interim Account (Received)",
                    company_id: 1,
                },
                {
                    id: 286,
                    code: 101130,
                    name: "101130 Stock Interim Account (Delivered)",
                    company_id: 1,
                },
                {
                    id: 287,
                    code: 101200,
                    name: "101200 Account Receivable",
                    company_id: 1,
                },
                {id: 288, code: 101300, name: "101300 Tax Paid", company_id: 1},
                {id: 308, code: 101401, name: "101401 Bank", company_id: 1},
                {id: 499, code: 499001, name: "499001 Suspense Account", company_id: 1},
                {id: 500, code: 500, name: "500 Account", company_id: 1},
                {id: 501, code: 501, name: "501 Account", company_id: 1},
                {id: 502, code: 502, name: "502 Account", company_id: 1},
                {id: 503, code: 503, name: "503 Account", company_id: 1},
                {id: 504, code: 504, name: "504 Account", company_id: 1},
            ],
            mark_as_reconciled: function () {
                return Promise.resolve();
            },
        },
        "account.account.tag": {
            fields: {
                id: {string: "ID", type: "integer"},
            },
            records: [{id: 1}, {id: 2}, {id: 3}, {id: 4}],
        },
        "account.tax.repartition.line": {
            fields: {
                id: {string: "ID", type: "integer"},
                repartition_type: {string: "Repartition Type", type: "selection"},
                account_id: {
                    string: "Account",
                    type: "many2one",
                    relation: "account.account",
                },
                factor_percent: {string: "%", type: "integer"},
                tag_ids: {
                    string: "Tax Grids",
                    type: "many2many",
                    relation: "account.account.tag",
                },
            },
            records: [
                {id: 1, factor_percent: 100, repartition_type: "base", tag_ids: [1]},
                {id: 2, factor_percent: 100, repartition_type: "tax", tag_ids: [2]},
                {id: 3, factor_percent: 100, repartition_type: "base", tag_ids: [3]},
                {
                    id: 4,
                    factor_percent: 100,
                    repartition_type: "tax",
                    tag_ids: [4],
                    account_id: 288,
                },
            ],
        },
        "account.tax": {
            fields: {
                id: {string: "ID", type: "integer"},
                display_name: {string: "Displayed name", type: "char"},
                amount: {string: "amout", type: "float"},
                price_include: {string: "Included in Price", type: "boolean"},
                company_id: {
                    string: "Company",
                    type: "many2one",
                    relation: "res.company",
                },
                amount_type: {string: "type", type: "selection"},
                invoice_repartition_line_ids: {
                    string: "Invoice Repartition",
                    type: "one2many",
                    relation: "account.tax.repartition.line",
                },
                // No need for refund repartition lines in our test; they're not used by reconciliation widget anyway
            },
            records: [
                {
                    id: 6,
                    display_name: "Tax 20.00%",
                    amount: 20,
                    amount_type: "percent",
                    price_include: false,
                    company_id: 1,
                    invoice_repartition_line_ids: [1, 2],
                },
                {
                    id: 7,
                    display_name: "Tax 10.00% include",
                    amount: 10,
                    amount_type: "percent",
                    price_include: true,
                    company_id: 1,
                    invoice_repartition_line_ids: [3, 4],
                },
            ],
            json_friendly_compute_all: function (args) {
                var tax = _.find(db["account.tax"].records, {id: args[0][0]});
                var amount = args[1];

                var tax_base = null;
                var base_tags = null;
                var taxes = [];

                for (let i = 0; i < tax.invoice_repartition_line_ids.length; i++) {
                    var rep_ln = _.find(db["account.tax.repartition.line"].records, {
                        id: tax.invoice_repartition_line_ids[i],
                    });

                    if (rep_ln.repartition_type == "base") {
                        tax_base =
                            (tax.price_include
                                ? (amount * 100) / (100 + tax.amount)
                                : amount) *
                            (rep_ln.factor_percent / 100);
                        base_tags = rep_ln.tag_ids;
                    } else if (rep_ln.repartition_type == "tax") {
                        /*
                    IMPORTANT :
                    For simplicity of testing, we assume there is ALWAYS a
                    base repartition line before the tax one, so tax_base is non-null
                    */
                        taxes.push({
                            id: tax.id,
                            amount: (tax_base * tax.amount) / 100,
                            base: tax_base,
                            name: tax.display_name,
                            analytic: false,
                            account_id: rep_ln.account_id,
                            price_include: tax.price_include,
                            tax_repartition_line_id: rep_ln.id,
                            tag_ids: rep_ln.tag_ids,
                            tax_ids: [tax.id],
                        });
                    }
                }

                return Promise.resolve({
                    base: amount,
                    taxes: taxes,
                    base_tags: base_tags,
                    total_excluded: (amount / 100) * (100 - tax.amount),
                    total_included: amount,
                });
            },
        },
        "account.journal": {
            fields: {
                id: {string: "ID", type: "integer"},
                display_name: {string: "Displayed name", type: "char"},
                company_id: {
                    string: "Company",
                    type: "many2one",
                    relation: "res.company",
                },
            },
            records: [{id: 8, display_name: "company 1 journal", company_id: 1}],
        },
        "account.analytic.account": {
            fields: {
                id: {string: "ID", type: "integer"},
                display_name: {string: "Displayed name", type: "char"},
            },
            records: [
                {id: 16, display_name: "Administrative"},
                {id: 7, display_name: "Agrolait - Agrolait"},
                {id: 8, display_name: "Asustek - ASUSTeK"},
                {id: 15, display_name: "Camp to Camp - Camptocamp"},
                {id: 6, display_name: "CampToCamp - Camptocamp"},
                {id: 17, display_name: "Commercial & Marketing"},
                {id: 23, display_name: "Data Import/Export Plugin - Delta PC"},
                {id: 9, display_name: "Delta PC - Delta PC"},
            ],
        },
        "account.analytic.tag": {
            fields: {
                id: {string: "id", type: "integer"},
                display_name: {string: "display_name", type: "char"},
            },
            records: [
                {id: 1, display_name: "Come together"},
                {id: 2, display_name: "Right now"},
            ],
        },
        "account.bank.statement": {
            fields: {},
        },
        "account.bank.statement.line": {
            fields: {
                id: {string: "ID", type: "integer"},
                display_name: {string: "Displayed name", type: "char"},
                partner_id: {
                    string: "partner",
                    type: "many2one",
                    relation: "res.partner",
                },
                company_id: {
                    string: "Company",
                    type: "many2one",
                    relation: "res.company",
                },
            },
            records: [
                {id: 5, display_name: "SAJ/2014/002 and SAJ/2014/003", company_id: 1},
                {id: 6, display_name: "Bank fees", company_id: 1},
                {id: 7, display_name: "Prepayment", company_id: 1},
                {
                    id: 8,
                    display_name: "First 2000 \u20ac of SAJ/2014/001",
                    company_id: 1,
                },
            ],
        },
        "account.move.line": {
            fields: {},
        },
        "account.reconcile.model": {
            fields: {
                id: {string: "ID", type: "integer"},
                name: {string: "Button Label", type: "char"},
                rule_type: {
                    string: "Type",
                    type: "selection",
                    selection: [
                        ["writeoff_button", "Create a Button"],
                        ["writeoff_suggestion", "Write off Suggestion"],
                        ["invoice_matching", "Invoice matching"],
                    ],
                    default: "writeoff_button",
                },
                has_second_line: {string: "Add a second line", type: "boolean"},
                account_id: {
                    string: "Account",
                    type: "many2one",
                    relation: "account.account",
                },
                journal_id: {
                    string: "Journal",
                    type: "many2one",
                    relation: "account.journal",
                },
                label: {string: "Journal Item Label", type: "char"},
                amount_type: {
                    string: "amount_type",
                    type: "selection",
                    selection: [
                        ["fixed", "Fixed"],
                        ["percentage", "Percentage of balance"],
                    ],
                    default: "percentage",
                },
                amount: {
                    string: "Amount",
                    type: "float",
                    digits: 0,
                    help:
                        "Fixed amount will count as a debit if it is negative, as a credit if it is positive.",
                    default: 100.0,
                },
                tax_ids: {string: "Tax", type: "many2many", relation: "account.tax"},
                analytic_account_id: {
                    string: "Analytic Account",
                    type: "many2one",
                    relation: "account.analytic.account",
                },
                second_account_id: {
                    string: "Second Account",
                    type: "many2one",
                    relation: "account.account",
                    domain: [("deprecated", "=", false)],
                },
                second_journal_id: {
                    string: "Second Journal",
                    type: "many2one",
                    relation: "account.journal",
                    help: "This field is ignored in a bank statement reconciliation.",
                },
                second_label: {string: "Second Journal Item Label", type: "char"},
                second_amount_type: {
                    string: "Second amount_type",
                    type: "selection",
                    selection: [
                        ["fixed", "Fixed"],
                        ["percentage", "Percentage of balance"],
                    ],
                    default: "percentage",
                },
                second_amount: {
                    string: "Second Amount",
                    type: "float",
                    digits: 0,
                    help:
                        "Fixed amount will count as a debit if it is negative, as a credit if it is positive.",
                    default: 100.0,
                },
                second_tax_ids: {
                    string: "Second Tax",
                    type: "many2many",
                    relation: "account.tax",
                },
                second_analytic_account_id: {
                    string: "Second Analytic Account",
                    type: "many2one",
                    relation: "account.analytic.account",
                },
                match_journal_ids: {
                    string: "Journal Ids",
                    type: "many2many",
                    relation: "account.journal",
                },
                analytic_tag_ids: {
                    string: "Analytic tags",
                    type: "many2many",
                    relation: "account.analytic.tag",
                },
            },
            records: [
                {
                    second_analytic_account_id: false,
                    second_amount_type: "percentage",
                    second_journal_id: false,
                    id: 4,
                    analytic_account_id: false,
                    display_name: "Int\u00e9rrets",
                    rule_type: "writeoff_button",
                    second_tax_ids: [],
                    has_second_line: false,
                    journal_id: false,
                    label: false,
                    second_label: false,
                    second_account_id: false,
                    account_id: 282,
                    company_id: [1, "Demo SPRL"],
                    tax_ids: [],
                    amount_type: "fixed",
                    name: "Int\u00e9rrets",
                    amount: 0.0,
                    second_amount: 100.0,
                    match_journal_ids: [],
                },
                {
                    second_analytic_account_id: false,
                    second_amount_type: "percentage",
                    second_journal_id: false,
                    id: 2,
                    analytic_account_id: false,
                    display_name: "Perte et Profit",
                    rule_type: "writeoff_button",
                    second_tax_ids: [],
                    has_second_line: false,
                    journal_id: false,
                    label: false,
                    second_label: false,
                    second_account_id: false,
                    account_id: 283,
                    company_id: [1, "Demo SPRL"],
                    tax_ids: [],
                    amount_type: "percentage",
                    name: "Perte et Profit",
                    amount: 100.0,
                    second_amount: 100.0,
                    match_journal_ids: [],
                },
                {
                    second_analytic_account_id: false,
                    second_amount_type: "percentage",
                    second_journal_id: false,
                    id: 5,
                    analytic_account_id: false,
                    display_name: "Fs bank",
                    rule_type: "writeoff_button",
                    second_tax_ids: [],
                    has_second_line: false,
                    journal_id: false,
                    label: false,
                    second_label: false,
                    second_account_id: false,
                    account_id: 284,
                    company_id: [1, "Demo SPRL"],
                    tax_ids: [],
                    amount_type: "percentage",
                    name: "Fs bank",
                    amount: 100.0,
                    second_amount: 100.0,
                },
                {
                    second_analytic_account_id: false,
                    second_amount_type: "percentage",
                    second_journal_id: false,
                    id: 8,
                    analytic_account_id: false,
                    display_name: "Caisse Sand.",
                    rule_type: "writeoff_button",
                    second_tax_ids: [],
                    has_second_line: false,
                    journal_id: false,
                    label: "Caisse Sand.",
                    second_label: false,
                    second_account_id: false,
                    account_id: 308,
                    company_id: [1, "Demo SPRL"],
                    tax_ids: [],
                    amount_type: "percentage",
                    name: "Caisse Sand.",
                    amount: 100.0,
                    second_amount: 100.0,
                    match_journal_ids: [],
                },
                {
                    second_analytic_account_id: false,
                    second_amount_type: "percentage",
                    second_journal_id: false,
                    id: 3,
                    analytic_account_id: false,
                    display_name: "ATOS",
                    rule_type: "writeoff_button",
                    second_tax_ids: [7],
                    has_second_line: true,
                    journal_id: false,
                    label: "ATOS Banque",
                    second_label: "ATOS Frais",
                    second_account_id: 286,
                    account_id: 285,
                    company_id: [1, "Demo SPRL"],
                    tax_ids: [6],
                    amount_type: "percentage",
                    name: "ATOS",
                    amount: 97.5,
                    second_amount: -14.75,
                },
                {
                    second_analytic_account_id: false,
                    second_amount_type: "percentage",
                    second_journal_id: false,
                    id: 10,
                    analytic_account_id: false,
                    display_name: "Double",
                    rule_type: "writeoff_button",
                    second_tax_ids: [],
                    has_second_line: true,
                    journal_id: false,
                    label: "Double Banque",
                    second_label: "Double Frais",
                    second_account_id: 286,
                    account_id: 285,
                    company_id: [1, "Demo SPRL"],
                    tax_ids: [],
                    amount_type: "percentage",
                    name: "Double",
                    amount: 97.5,
                    second_amount: 100,
                    match_journal_ids: [],
                    analytic_tag_ids: [1, 2],
                },
            ],
        },
        "account.reconciliation.widget": {
            fields: {},
            auto_reconcile: function () {
                return Promise.resolve(Datas.used.auto_reconciliation);
            },
            process_bank_statement_line: function (args) {
                var datas = args[1];
                var ids = _.flatten(
                    _.pluck(
                        _.pluck(datas, "counterpart_aml_dicts"),
                        "counterpart_aml_id"
                    )
                );
                ids = ids.concat(_.flatten(_.pluck(datas, "payment_aml_ids")));
                ids = _.compact(ids);

                for (var key in Datas.used.move_lines_for_manual_reconciliation) {
                    Datas.used.move_lines_for_manual_reconciliation[key] = _.filter(
                        Datas.used.move_lines_for_manual_reconciliation[key],
                        function (mv_line) {
                            return ids.indexOf(mv_line.id) === -1;
                        }
                    );
                }
                return Promise.resolve();
            },
            get_move_lines_for_bank_statement_line: function (args) {
                var partner_id = args.splice(1, 1)[0];
                var excluded_ids = args.splice(1, 1)[0];
                var mode = args.splice(-1, 1)[0];
                if (mode === "other") return Promise.resolve([]);
                args.splice(-1, 1); // Ignore limit
                var key = JSON.stringify(args);
                if (!Datas.used.mv_lines[key]) {
                    throw new Error(
                        "Unknown parameters for get_move_lines_for_bank_statement_line: '" +
                            key +
                            "'"
                    );
                }
                var lines = Datas.used.mv_lines[key]
                    .filter(function (line) {
                        return (
                            excluded_ids.indexOf(line.id) === -1 &&
                            (!partner_id || partner_id === line.partner_id)
                        );
                    })
                    .map(function (line, i, src) {
                        line.recs_count = src.length;
                        return line;
                    })
                    .slice(0, options.params.limitMoveLines);
                return Promise.resolve(lines);
            },
            get_bank_statement_line_data: function (args) {
                var ids = args[0];
                var results = {
                    value_min: 0,
                    value_max: ids.length,
                    lines: _.filter(Datas.used.data_widget, function (w) {
                        return _.contains(ids, w.st_line.id);
                    }),
                };
                return Promise.resolve(results);
            },
            get_bank_statement_data: function () {
                var results = Datas.used.data_preprocess;
                results.lines = _.filter(Datas.used.data_widget, function (w) {
                    return _.contains(results.st_lines_ids, w.st_line.id);
                });
                return Promise.resolve(results);
            },
            get_move_lines_for_manual_reconciliation: function (args) {
                var excluded_ids = args.splice(2, 1)[0];
                args.splice(-1, 1); // Ignore limit
                var key = JSON.stringify(args);
                if (!Datas.used.move_lines_for_manual_reconciliation[key]) {
                    throw new Error(
                        "Unknown parameters for get_move_lines_for_manual_reconciliation: '" +
                            key +
                            "'"
                    );
                }
                var lines = Datas.used.move_lines_for_manual_reconciliation[key]
                    .filter(function (line) {
                        return excluded_ids.indexOf(line.id) === -1;
                    })
                    .map(function (line, i, src) {
                        line.recs_count = src.length;
                        return line;
                    })
                    .slice(0, options.params.limitMoveLines);
                return Promise.resolve(lines);
            },
            get_all_data_for_manual_reconciliation: function (args) {
                var key = JSON.stringify(args);
                if (!Datas.used.data_for_manual_reconciliation_widget[key]) {
                    throw new Error(
                        "Unknown parameters for get_all_data_for_manual_reconciliation: '" +
                            key +
                            "'"
                    );
                }
                return Promise.resolve(
                    Datas.used.data_for_manual_reconciliation_widget[key]
                );
            },
            process_move_lines: function (args) {
                var datas = args[0];
                for (var i in datas) {
                    var data = datas[i];
                    for (var key in Datas.used.move_lines_for_manual_reconciliation) {
                        Datas.used.move_lines_for_manual_reconciliation[key] = _.filter(
                            Datas.used.move_lines_for_manual_reconciliation[key],
                            function (mv_line) {
                                return data.mv_line_ids.indexOf(mv_line.id) === -1;
                            }
                        );
                    }
                }
                return Promise.resolve();
            },
        },
    };

    var data_preprocess = {
        value_min: 0,
        value_max: 4,
        notifications: [],
        num_already_reconciled_lines: 0,
        st_lines_ids: [5, 6, 7, 8],
        statement_name: "BNK/2014/001",
    };

    var data_widget = [
        {
            st_line: {
                currency_id: 3,
                communication_partner_name: false,
                open_balance_account_id: 287,
                name: "SAJ/2014/002 and SAJ/2014/003",
                partner_name: "Agrolait",
                partner_id: 8,
                has_no_partner: false,
                journal_id: 84,
                account_name: "Bank",
                note: "",
                amount: 1175.0,
                amount_str: "$ 1,175.00",
                amount_currency_str: "",
                date: "2017-01-01",
                account_code: "101401",
                ref: "",
                id: 5,
                statement_id: 2,
                company_id: 1,
            },
            reconciliation_proposition: [],
        },
        {
            st_line: {
                currency_id: 3,
                communication_partner_name: false,
                name: "Bank fees",
                partner_name: false,
                partner_id: false,
                has_no_partner: true,
                journal_id: 84,
                account_name: "Bank",
                note: "",
                amount: -32.58,
                amount_str: "$ 32.58",
                amount_currency_str: "",
                date: "2017-01-01",
                account_code: "101401",
                ref: "",
                id: 6,
                statement_id: 2,
                company_id: 1,
            },
            reconciliation_proposition: [],
        },
        {
            st_line: {
                currency_id: 3,
                communication_partner_name: false,
                open_balance_account_id: 287,
                name: "Prepayment",
                partner_name: "Camptocamp",
                partner_id: 12,
                has_no_partner: false,
                journal_id: 84,
                account_name: "Bank",
                note: "",
                amount: 650.0,
                amount_str: "$ 650.00",
                amount_currency_str: "",
                date: "2017-01-01",
                account_code: "101401",
                ref: "",
                id: 7,
                statement_id: 2,
                company_id: 1,
            },
            reconciliation_proposition: [
                {
                    account_type: "receivable",
                    amount_currency_str: "",
                    currency_id: false,
                    date_maturity: "2017-02-07",
                    date: "2017-01-08",
                    total_amount_str: "$ 650.00",
                    partner_id: 12,
                    account_name: "101200 Account Receivable",
                    name: "INV/2017/0012",
                    partner_name: "Camptocamp",
                    total_amount_currency_str: "",
                    id: 133,
                    credit: 0.0,
                    journal_id: [1, "Customer Invoices"],
                    amount_str: "$ 650.00",
                    debit: 650.0,
                    account_id: [287, "101200 Account Receivable"],
                    account_code: "101200",
                    ref: "",
                    already_paid: false,
                },
            ],
        },
        {
            st_line: {
                currency_id: 3,
                communication_partner_name: false,
                open_balance_account_id: 285,
                name: "First 2000 \u20ac of SAJ/2014/001",
                partner_name: "Camptocamp",
                partner_id: 12,
                has_no_partner: false,
                journal_id: 84,
                account_name: "Bank",
                note: "",
                amount: 2000.0,
                amount_str: "$ 2,000.00",
                amount_currency_str: "",
                date: "2017-01-01",
                account_code: "101401",
                ref: "",
                id: 8,
                statement_id: 2,
                company_id: 1,
            },
            reconciliation_proposition: [],
        },
    ];

    var mv_lines = {
        "[]": [],
        '[5,"",0]': [
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-07",
                date: "2017-01-08",
                total_amount_str: "$ 650.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0002",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 109,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 650.00",
                debit: 650.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-07",
                date: "2017-01-08",
                total_amount_str: "$ 525.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0003",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 112,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 525.00",
                debit: 525.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-07",
                date: "2017-01-08",
                total_amount_str: "$ 650.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0012",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 134,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 650.00",
                debit: 650.0,
                account_id: [287, "101200 Account Receivable"],
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-01",
                total_amount_str: "$ 4,610.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0001",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 106,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 4,610.00",
                debit: 4610.0,
                account_id: [287, "101200 Account Receivable"],
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "payable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-01",
                total_amount_str: "$ 10,000.00",
                partner_id: 12,
                account_name: "Account Payable",
                name: "BILL/2017/0001",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 114,
                credit: 10000.0,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 10,000.00",
                debit: 0.0,
                account_id: [284, "101110 Stock Valuation Account"],
                account_code: "111100",
                ref: "",
                already_paid: false,
            },
        ],
        '[5,"b",0]': [
            {
                account_type: "liquidity",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-01-23",
                date: "2017-01-23",
                total_amount_str: "$ 100.00",
                partner_id: 8,
                account_name: "Bank",
                name: "BNK1/2017/0003: CUST.IN/2017/0001",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 394,
                credit: 0.0,
                journal_id: "Bank",
                amount_str: "$ 100.00",
                debit: 100.0,
                account_code: "101401",
                ref: "",
                already_paid: true,
            },
            {
                account_type: "liquidity",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-01-23",
                date: "2017-01-23",
                total_amount_str: "$ 525.50",
                partner_id: 8,
                account_name: "Bank",
                name: "BNK1/2017/0004: CUST.IN/2017/0002",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 396,
                credit: 0.0,
                journal_id: "Bank",
                amount_str: "$ 525.50",
                debit: 525.5,
                account_code: "101401",
                ref: "INV/2017/0003",
                already_paid: true,
            },
        ],
        '[6,"",0]': [
            {
                account_type: "liquidity",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-01-23",
                date: "2017-01-23",
                total_amount_str: "$ 376.00",
                partner_id: 7,
                account_name: "Bank",
                name: "BNK1/2017/0002: SUPP.OUT/2017/0002",
                partner_name: "ASUSTeK",
                total_amount_currency_str: "",
                id: 392,
                credit: 376.0,
                journal_id: "Bank",
                amount_str: "$ 376.00",
                debit: 0.0,
                account_code: "101401",
                ref: "BILL/2017/0003",
                already_paid: true,
            },
            {
                account_type: "liquidity",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-01-23",
                date: "2017-01-23",
                total_amount_str: "$ 100.00",
                partner_id: 8,
                account_name: "Bank",
                name: "BNK1/2017/0003: CUST.IN/2017/0001",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 394,
                credit: 0.0,
                journal_id: "Bank",
                amount_str: "$ 100.00",
                debit: 100.0,
                account_code: "101401",
                ref: "",
                already_paid: true,
            },
            {
                account_type: "payable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-01",
                total_amount_str: "$ 10,000.00",
                partner_id: 12,
                account_name: "Account Payable",
                name: "BILL/2017/0001",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 114,
                credit: 10000.0,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 10,000.00",
                debit: 0.0,
                account_code: "111100",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "liquidity",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-01-23",
                date: "2017-01-23",
                total_amount_str: "$ 525.50",
                partner_id: 8,
                account_name: "Bank",
                name: "BNK1/2017/0004: CUST.IN/2017/0002",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 396,
                credit: 0.0,
                journal_id: "Bank",
                amount_str: "$ 525.50",
                debit: 525.5,
                account_code: "101401",
                ref: "INV/2017/0003",
                already_paid: true,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-07",
                date: "2017-01-08",
                total_amount_str: "$ 650.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0002",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 109,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 650.00",
                debit: 650.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-22",
                date: "2017-01-23",
                total_amount_str: "$ 525.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0004",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 399,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 525.00",
                debit: 525.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-01",
                total_amount_str: "$ 4,610.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0001",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 106,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 4,610.00",
                debit: 4610.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "payable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-15",
                total_amount_str: "$ 5,749.99",
                partner_id: 7,
                account_name: "Account Payable",
                name: "BILL/2017/0002",
                partner_name: "ASUSTeK",
                total_amount_currency_str: "",
                id: 117,
                credit: 5749.99,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 5,749.99",
                debit: 0.0,
                account_code: "111100",
                ref: "",
                already_paid: false,
            },
        ],
        '[6,"",5]': [
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-01",
                total_amount_str: "$ 4,610.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0001",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 106,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 4,610.00",
                debit: 4610.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "payable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-01",
                total_amount_str: "$ 10,000.00",
                partner_id: 12,
                account_name: "Account Payable",
                name: "BILL/2017/0001",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 114,
                credit: 10000.0,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 10,000.00",
                debit: 0.0,
                account_code: "111100",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "payable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-15",
                total_amount_str: "$ 5,749.99",
                partner_id: 7,
                account_name: "Account Payable",
                name: "BILL/2017/0002",
                partner_name: "ASUSTeK",
                total_amount_currency_str: "",
                id: 117,
                credit: 5749.99,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 5,749.99",
                debit: 0.0,
                account_code: "111100",
                ref: "",
                already_paid: false,
            },
        ],
        '[7,"",0]': [
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-07",
                date: "2017-01-08",
                total_amount_str: "$ 650.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0012",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 133,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 650.00",
                debit: 650.0,
                account_id: [287, "101200 Account Receivable"],
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-01",
                total_amount_str: "$ 4,610.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0001",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 106,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 4,610.00",
                debit: 4610.0,
                account_id: [287, "101200 Account Receivable"],
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "payable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-28",
                date: "2017-01-01",
                total_amount_str: "$ 10,000.00",
                partner_id: 12,
                account_name: "Account Payable",
                name: "BILL/2017/0001",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 114,
                credit: 10000.0,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 10,000.00",
                debit: 0.0,
                account_id: [284, "101110 Stock Valuation Account"],
                account_code: "111100",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "liquidity",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-01-23",
                date: "2017-01-23",
                total_amount_str: "$ 376.00",
                partner_id: 7,
                account_name: "Bank",
                name: "BNK1/2017/0002: SUPP.OUT/2017/0002",
                partner_name: "ASUSTeK",
                total_amount_currency_str: "",
                id: 392,
                credit: 376.0,
                journal_id: "Bank",
                amount_str: "$ 376.00",
                debit: 0.0,
                account_code: "101401",
                ref: "BILL/2017/0003",
                already_paid: true,
            },
            {
                account_type: "liquidity",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-01-23",
                date: "2017-01-23",
                total_amount_str: "$ 100.00",
                partner_id: 8,
                account_name: "Bank",
                name: "BNK1/2017/0003: CUST.IN/2017/0001",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 394,
                credit: 0.0,
                journal_id: "Bank",
                amount_str: "$ 100.00",
                debit: 100.0,
                account_code: "101401",
                ref: "",
                already_paid: true,
            },
            {
                account_type: "liquidity",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-01-23",
                date: "2017-01-23",
                total_amount_str: "$ 525.50",
                partner_id: 8,
                account_name: "Bank",
                name: "BNK1/2017/0004: CUST.IN/2017/0002",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 396,
                credit: 0.0,
                journal_id: "Bank",
                amount_str: "$ 525.50",
                debit: 525.5,
                account_code: "101401",
                ref: "INV/2017/0003",
                already_paid: true,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-07",
                date: "2017-01-08",
                total_amount_str: "$ 650.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0002",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 109,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 650.00",
                debit: 650.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-22",
                date: "2017-01-23",
                total_amount_str: "$ 525.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0004",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 399,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 525.00",
                debit: 525.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
        ],
        '[8,"",0]': [],
    };

    var auto_reconciliation = {
        num_already_reconciled_lines: 1,
        notifications: [
            {
                message: "1 transaction was automatically reconciled.",
                type: "info",
                details: {
                    model: "account.move",
                    name: "Automatically reconciled items",
                    ids: [143],
                },
            },
        ],
        st_lines_ids: [5, 6, 8],
        statement_name: false,
    };

    var data_for_manual_reconciliation_widget = {
        "[null,[282,283,284,285,286,287,288,308,499,500,501,502,503,504]]": {
            customers: [
                {
                    account_id: 287,
                    partner_name: "Agrolait",
                    reconciliation_proposition: [],
                    currency_id: 3,
                    max_date: "2017-02-14 12:30:31",
                    last_time_entries_checked: null,
                    account_code: "101200",
                    partner_id: 8,
                    account_name: "101200 Account Receivable",
                    mode: "customers",
                },
                {
                    account_id: 7,
                    partner_name: "Camptocamp",
                    reconciliation_proposition: [],
                    currency_id: 3,
                    max_date: "2017-02-13 14:24:55",
                    last_time_entries_checked: null,
                    account_code: "101200",
                    partner_id: 12,
                    account_name: "101200 Account Receivable",
                    mode: "customers",
                },
            ],
            accounts: [
                {
                    account_id: 283,
                    account_name: "101000 Current Assets",
                    currency_id: 3,
                    max_date: "2017-02-16 14:32:04",
                    last_time_entries_checked: "2017-02-16",
                    account_code: "101000",
                    mode: "accounts",
                    reconciliation_proposition: [
                        {
                            account_id: 283,
                            account_type: "other",
                            amount_currency_str: "",
                            currency_id: false,
                            date_maturity: "2017-02-16",
                            date: "2017-02-16",
                            total_amount_str: "$ 1,000.00",
                            partner_id: 8,
                            account_name: "101000 Current Assets",
                            name: "BNK1/2017/0006: Customer Payment",
                            partner_name: "Agrolait",
                            total_amount_currency_str: "",
                            id: 399,
                            credit: 1000.0,
                            journal_id: [3, "Bank"],
                            amount_str: "$ 1,000.00",
                            debit: 0.0,
                            account_code: "101000",
                            ref: "",
                            already_paid: false,
                        },
                        {
                            account_id: 283,
                            account_type: "other",
                            amount_currency_str: "",
                            currency_id: false,
                            date_maturity: "2017-03-18",
                            date: "2017-02-16",
                            total_amount_str: "$ 1,000.00",
                            partner_id: 8,
                            account_name: "101000 Current Assets",
                            name: "INV/2017/0006",
                            partner_name: "Agrolait",
                            total_amount_currency_str: "",
                            id: 402,
                            credit: 0.0,
                            journal_id: [1, "Customer Invoices"],
                            amount_str: "$ 1,000.00",
                            debit: 1000.0,
                            account_code: "101000",
                            ref: "",
                            already_paid: false,
                        },
                    ],
                },
            ],
            suppliers: [
                {
                    account_id: 284,
                    partner_name: "Agrolait",
                    reconciliation_proposition: [
                        {
                            account_id: 284,
                            account_type: "other",
                            amount_currency_str: "",
                            currency_id: false,
                            date_maturity: "2017-02-16",
                            date: "2017-02-16",
                            total_amount_str: "$ 1,000.00",
                            partner_id: 8,
                            account_name: "101000 Current Assets",
                            name: "BNK1/999: Customer Payment",
                            partner_name: "Agrolait",
                            total_amount_currency_str: "",
                            id: 999,
                            credit: 1000.0,
                            journal_id: [3, "Bank"],
                            amount_str: "$ 1,000.00",
                            debit: 0.0,
                            account_code: "111100",
                            ref: "",
                            already_paid: false,
                        },
                        {
                            account_id: 284,
                            account_type: "other",
                            amount_currency_str: "",
                            currency_id: false,
                            date_maturity: "2017-03-18",
                            date: "2017-02-16",
                            total_amount_str: "$ 1,000.00",
                            partner_id: 8,
                            account_name: "101000 Current Assets",
                            name: "INV/998",
                            partner_name: "Agrolait",
                            total_amount_currency_str: "",
                            id: 998,
                            credit: 0.0,
                            journal_id: [1, "Customer Invoices"],
                            amount_str: "$ 1,000.00",
                            debit: 1000.0,
                            account_code: "111100",
                            ref: "",
                            already_paid: false,
                        },
                    ],
                    currency_id: 3,
                    max_date: "2017-02-14 12:36:05",
                    last_time_entries_checked: null,
                    account_code: "111100",
                    partner_id: 8,
                    account_name: "Account Payable",
                    mode: "suppliers",
                },
                {
                    account_id: 284,
                    partner_name: "Camptocamp",
                    reconciliation_proposition: [
                        {
                            account_id: 284,
                            account_type: "other",
                            amount_currency_str: "",
                            currency_id: false,
                            date_maturity: "2017-02-16",
                            date: "2017-02-16",
                            total_amount_str: "$ 1,000.00",
                            partner_id: 12,
                            account_name: "101000 Current Assets",
                            name: "BNK1/1999: Customer Payment",
                            partner_name: "Camptocamp",
                            total_amount_currency_str: "",
                            id: 1999,
                            credit: 1000.0,
                            journal_id: [3, "Bank"],
                            amount_str: "$ 1,000.00",
                            debit: 0.0,
                            account_code: "111100",
                            ref: "",
                            already_paid: false,
                        },
                        {
                            account_id: 284,
                            account_type: "other",
                            amount_currency_str: "",
                            currency_id: false,
                            date_maturity: "2017-03-18",
                            date: "2017-02-16",
                            total_amount_str: "$ 1,000.00",
                            partner_id: 12,
                            account_name: "101000 Current Assets",
                            name: "INV/1998",
                            partner_name: "Camptocamp",
                            total_amount_currency_str: "",
                            id: 1998,
                            credit: 0.0,
                            journal_id: [1, "Customer Invoices"],
                            amount_str: "$ 1,000.00",
                            debit: 1000.0,
                            account_code: "111100",
                            ref: "",
                            already_paid: false,
                        },
                    ],
                    currency_id: 3,
                    max_date: "2017-02-14 12:36:05",
                    last_time_entries_checked: null,
                    account_code: "111100",
                    partner_id: 12,
                    account_name: "Account Payable",
                    mode: "suppliers",
                },
            ],
        },
        '["partner",null,"receivable"]': [
            {
                account_id: 287,
                partner_name: "Agrolait",
                reconciliation_proposition: [],
                currency_id: 3,
                max_date: "2017-02-14 12:30:31",
                last_time_entries_checked: null,
                account_code: "101200",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                mode: "customers",
            },
            {
                account_id: 287,
                partner_name: "Camptocamp",
                reconciliation_proposition: [],
                currency_id: 3,
                max_date: "2017-02-13 14:24:55",
                last_time_entries_checked: null,
                account_code: "101200",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                mode: "customers",
            },
        ],
    };

    var move_lines_for_manual_reconciliation = {
        '[287,8,"",0]': [
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency_str: "10,222.00 €",
                currency_id: 1,
                date_maturity: "2017-02-08",
                date: "2017-02-08",
                total_amount_str: "$ 11,000.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0004: Customer Payment",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 17,
                credit: 11000.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 11,000.00",
                debit: 0.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [7, "101200 Account Receivable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-09",
                date: "2017-02-09",
                total_amount_str: "$ 1,000.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0005: Customer Payment",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 19,
                credit: 1000.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 1,000.00",
                debit: 0.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-09",
                date: "2017-02-09",
                total_amount_str: "$ 180.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "BILL/2017/0003: Customer Payment",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 21,
                credit: 180.0,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 180.00",
                debit: 0.0,
                account_code: "101200",
                ref: "fddfgfdgfdgsdfg",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-09",
                date: "2017-02-09",
                total_amount_str: "$ 90.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0006: Customer Payment",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 23,
                credit: 90.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 90.00",
                debit: 0.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-03-10",
                date: "2017-02-08",
                total_amount_str: "$ 650.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0012",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 6,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 1000.00",
                debit: 1000.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-03-10",
                date: "2017-02-08",
                total_amount_str: "$ 525.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0003",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 9,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 525.00",
                debit: 525.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
        ],
        '[7,12,"",0]': [
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-08",
                date: "2017-02-08",
                total_amount_str: "$ 11,000.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0004: Customer Payment",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 17,
                credit: 11000.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 11,000.00",
                debit: 0.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [7, "101200 Account Receivable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-09",
                date: "2017-02-09",
                total_amount_str: "$ 1,000.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0005: Customer Payment",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 19,
                credit: 1000.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 1,000.00",
                debit: 0.0,
                account_code: "101200",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency: 100,
                amount_currency_str: "100.00 €",
                currency_id: 1,
                date_maturity: "2017-02-09",
                date: "2017-02-09",
                total_amount_str: "$ 170.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0003: Customer Payment",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 21,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 170.00",
                debit: 170.0,
                account_code: "101200",
                ref: "INV fddfgfdgfdgsdfg",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency: 100,
                amount_currency_str: "100.00 €",
                currency_id: 1,
                date_maturity: "2017-02-10",
                date: "2017-02-10",
                total_amount_str: "$ 180.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "BILL/2017/0003: Customer Payment",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 22,
                credit: 180.0,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 180.00",
                debit: 0.0,
                account_code: "101200",
                ref: "fddfgfdgfdgsdfg",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency: 170,
                amount_currency_str: "170.00 €",
                currency_id: 1,
                date_maturity: "2017-02-09",
                date: "2017-02-09",
                total_amount_str: "$ 100.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0003: Customer Payment",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 23,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 100.00",
                debit: 100.0,
                account_code: "101200",
                ref: "INV fddfgfdgfdgsdfg",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [287, "101200 Account Receivable"],
                amount_currency: 180,
                amount_currency_str: "180.00 €",
                currency_id: 1,
                date_maturity: "2017-02-10",
                date: "2017-02-10",
                total_amount_str: "$ 100.00",
                partner_id: 12,
                account_name: "101200 Account Receivable",
                name: "BILL/2017/0003: Customer Payment",
                partner_name: "Camptocamp",
                total_amount_currency_str: "",
                id: 24,
                credit: 100.0,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 100.00",
                debit: 0.0,
                account_code: "101200",
                ref: "fddfgfdgfdgsdfg",
                already_paid: false,
            },
        ],
        '[284,8,"",0]': [
            {
                account_type: "receivable",
                account_id: [284, "111100 Account Payable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-08",
                date: "2017-02-08",
                total_amount_str: "$ 11,000.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0004: Customer Payment",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 17,
                credit: 11000.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 11,000.00",
                debit: 0.0,
                account_code: "111100",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [284, "111100 Account Payable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-09",
                date: "2017-02-09",
                total_amount_str: "$ 1,000.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "INV/2017/0005: Customer Payment",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 19,
                credit: 1000.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 1,000.00",
                debit: 0.0,
                account_code: "111100",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "receivable",
                account_id: [284, "111100 Account Payable"],
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-09",
                date: "2017-02-09",
                total_amount_str: "$ 180.00",
                partner_id: 8,
                account_name: "101200 Account Receivable",
                name: "BILL/2017/0003: Customer Payment",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 21,
                credit: 180.0,
                journal_id: [2, "Vendor Bills"],
                amount_str: "$ 180.00",
                debit: 0.0,
                account_code: "111100",
                ref: "fddfgfdgfdgsdfg",
                already_paid: false,
            },
        ],
        '[283,null,"",0]': [
            {
                account_type: "other",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-02-16",
                date: "2017-02-16",
                total_amount_str: "$ 1,000.00",
                partner_id: 8,
                account_name: "101000 Current Assets",
                name: "BNK1/2017/0006: Customer Payment",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 399,
                credit: 1000.0,
                journal_id: [3, "Bank"],
                amount_str: "$ 1,000.00",
                debit: 0.0,
                account_code: "101000",
                ref: "",
                already_paid: false,
            },
            {
                account_type: "other",
                amount_currency_str: "",
                currency_id: false,
                date_maturity: "2017-03-18",
                date: "2017-02-16",
                total_amount_str: "$ 1,000.00",
                partner_id: 8,
                account_name: "101000 Current Assets",
                name: "INV/2017/0006",
                partner_name: "Agrolait",
                total_amount_currency_str: "",
                id: 402,
                credit: 0.0,
                journal_id: [1, "Customer Invoices"],
                amount_str: "$ 1,000.00",
                debit: 1000.0,
                account_code: "101000",
                ref: "",
                already_paid: false,
            },
        ],
        '[284,12,"",0]': [],
    };

    var session = {
        currencies: {
            3: {
                digits: [69, 2],
                position: "before",
                symbol: "$",
            },
        },
    };

    Datas.params = {
        data: db,
        data_preprocess: data_preprocess,
        data_widget: data_widget,
        mv_lines: mv_lines,
        auto_reconciliation: auto_reconciliation,
        data_for_manual_reconciliation_widget: data_for_manual_reconciliation_widget,
        move_lines_for_manual_reconciliation: move_lines_for_manual_reconciliation,
        session: session,
        options: options,
    };
    // This is the main function for this module. Its job is to export (and clone) all data for a test.
    Datas.getParams = function () {
        return (this.used = $.extend(true, {}, this.params));
    };
    return Datas;
});

odoo.define("account_reconciliation_widget.reconciliation_tests", function (require) {
    "use strict";

    var ReconciliationClientAction = require("account.ReconciliationClientAction");
    var ReconciliationRenderer = require("account.ReconciliationRenderer");
    var demoData = require("account_reconciliation_widget.reconciliation_tests.data");

    var testUtils = require("web.test_utils");
    var testUtilsDom = require("web.test_utils_dom");
    var testUtilsMock = require("web.test_utils_mock");

    QUnit.module(
        "account_reconciliation_widget",
        {
            beforeEach: function () {
                this.params = demoData.getParams();
                testUtils.patch(ReconciliationRenderer.LineRenderer, {
                    MV_LINE_DEBOUNCE: 0,
                });
            },
            afterEach: function () {
                testUtils.unpatch(ReconciliationRenderer.LineRenderer);
            },
        },
        function () {
            QUnit.module("Reconciliation");

            QUnit.test("Reconciliation basic rendering", async function (assert) {
                assert.expect(10);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();
                var widget = clientAction.widgets[0];

                assert.hasClass(
                    widget.$el,
                    "o_reconciliation_line",
                    "should instance of widget reconciliation"
                );
                assert.containsOnce(widget, ".accounting_view", "should have one view");
                assert.containsN(
                    widget,
                    '[id*="notebook_page_match"]',
                    2,
                    "should have 'match_rp' and 'match_other' panel"
                );
                assert.containsOnce(widget, ".create", "should have 'create' panel");

                assert.strictEqual(
                    widget
                        .$("thead")
                        .text()
                        .replace(/[\n\r\s]+/g, " "),
                    " 101401 2017-01-01 SAJ/2014/002 and SAJ/2014/003 $ 1,175.00 ",
                    "should display the line information"
                );
                assert.ok(
                    widget.$("caption .o_field_many2one").length,
                    "should display the many2one with to select a partner"
                );

                assert.containsN(
                    clientAction,
                    '[data-mode="inactive"]',
                    3,
                    "should be as 'inactive' mode by default"
                );
                assert.strictEqual(
                    widget.$el.data("mode"),
                    "match_rp",
                    "the first one should automatically switch to match_rp mode"
                );

                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                );
                assert.strictEqual(
                    widget.$el.data("mode"),
                    "create",
                    "should switch to 'create' mode"
                );

                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_match_rp"]')
                );
                assert.strictEqual(
                    widget.$el.data("mode"),
                    "match_rp",
                    "should switch to 'match_rp' mode"
                );

                clientAction.destroy();
            });

            QUnit.test("Reconciliation fields", async function (assert) {
                assert.expect(6);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                        user_has_group: function (group) {
                            if (
                                group === "analytic.group_analytic_tags" ||
                                group === "analytic.group_analytic_accounting"
                            ) {
                                return $.when(true);
                            }
                            return this._super.apply(this, arguments);
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                var widget = clientAction.widgets[0];

                assert.strictEqual(
                    widget.$(".o_input_dropdown input").val(),
                    "Agrolait",
                    "the partner many2one should display agrolait"
                );
                assert.strictEqual(
                    clientAction.widgets[2].$(".o_input_dropdown input").val(),
                    "Camptocamp",
                    "the partner many2one should display Camptocamp"
                );
                await testUtils.dom.click(widget.$(".accounting_view tfoot td:first"));
                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                );
                assert.containsN(
                    widget,
                    ".create input.o_input",
                    8,
                    "create panel should contain 8 fields (account_id, tax_id, journal_id, analytic_account_id, analytic_tag_ids, label, amount, date)"
                );
                assert.containsN(
                    widget,
                    ".create .create_account_id .o_required_modifier, .create .create_label .o_required_modifier, .create .create_amount .o_required_modifier",
                    3,
                    "account_id, label and amount should be required fields"
                );
                assert.strictEqual(
                    widget.$(".create .create_label input").val(),
                    "SAJ/2014/002 and SAJ/2014/003",
                    "should use the name of the reconciliation line for the default label value"
                );
                assert.strictEqual(
                    widget.$(".create .create_amount input").val(),
                    "1175.00",
                    "should have the balance amout as default value for the amout field"
                );

                clientAction.destroy();
            });

            QUnit.test("Reconciliation basic data", async function (assert) {
                assert.expect(17);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });

                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();
                var widget = clientAction.widgets[0];

                assert.containsN(
                    widget,
                    ".match:first .mv_line",
                    2,
                    "should display 2 account move lines"
                );
                assert.strictEqual(
                    widget
                        .$(".match:first .mv_line")
                        .text()
                        .replace(/[\n\r\s]+/g, " ")
                        .replace(/[\u200B]/g, ""),
                    " 101200 2017-02-07 INV/2017/0002 $ 650.00 101200 2017-02-07 INV/2017/0003 $ 525.00 ",
                    "should display 4 account move lines who contains the account_code, due_date, label and the credit"
                );
                assert.strictEqual(
                    widget.$('.match:first .mv_line .cell_right:contains(".")').length,
                    2,
                    "should display only the credit account move lines (hide the debit)"
                );

                await testUtils.dom.click(
                    clientAction.widgets[1].$(".accounting_view thead td:first")
                );
                assert.containsN(
                    clientAction.widgets[1],
                    ".mv_line",
                    5,
                    "should display 5 account move lines"
                );
                assert.strictEqual(
                    clientAction.widgets[1].$('.mv_line .cell_right:contains(".")')
                        .length,
                    3,
                    "should display only the credit account move lines (hide the debit)"
                );
                assert.containsN(
                    clientAction.widgets[1],
                    ".mv_line.already_reconciled",
                    3,
                    "should display 3 already reconciled account move lines"
                );
                assert.strictEqual(
                    clientAction.widgets[1]
                        .$(".mv_line")
                        .text()
                        .replace(/[\n\r\s]+/g, " ")
                        .replace(/[\u200B]/g, ""),
                    " 101401 2017-01-23 ASUSTeK: BNK1/2017/0002: SUPP.OUT/2017/0002 : BILL/2017/0003 $ 376.00 101401 2017-01-23 Agrolait: BNK1/2017/0003: CUST.IN/2017/0001 $ 100.00 111100 2017-02-28 Camptocamp: BILL/2017/0001 $ 10,000.00 101401 2017-01-23 Agrolait: BNK1/2017/0004: CUST.IN/2017/0002 : INV/2017/0003 $ 525.50 101200 2017-02-07 Agrolait: INV/2017/0002 $ 650.00 ",
                    "should display 4 account move lines who contains the account_code, due_date, label and the credit"
                );
                assert.strictEqual(
                    clientAction.widgets[1].$('.mv_line .cell_left:contains(".")')
                        .length,
                    2,
                    "should display only 2 debit account move lines"
                );

                // Load more
                assert.ok(
                    clientAction.widgets[1].$(".match:first div.load-more a:visible")
                        .length,
                    "should display the 'load more' button"
                );
                assert.equal(
                    clientAction.widgets[1].$(".match:first div.load-more span").text(),
                    3,
                    "should display 3 items remaining"
                );
                await testUtils.dom.click(
                    clientAction.widgets[1].$(".match:first div.load-more a")
                );
                assert.containsN(
                    clientAction.widgets[1],
                    ".mv_line",
                    8,
                    "should load 3 more records"
                );
                assert.notOk(
                    clientAction.widgets[1].$(".match:first div.load-more a:visible")
                        .length,
                    "should not display the 'load more' button anymore"
                );

                assert.ok(
                    clientAction.widgets[0].$("caption button.btn-secondary:visible")
                        .length,
                    "should display the secondary 'Validate' button"
                );
                assert.equal(
                    clientAction.widgets[1].$("caption button:disabled:visible").length,
                    1,
                    "button should be disabled"
                );
                assert.ok(
                    clientAction.widgets[2].$("caption button.btn-primary:visible")
                        .length,
                    "should display the primary 'Validate' button"
                );

                await testUtils.dom.click(
                    clientAction.widgets[3].$(".accounting_view thead td:first")
                );
                assert.strictEqual(
                    clientAction.widgets[3].$el.data("mode"),
                    "create",
                    "should switch to 'create' mode instead of 'match_rp' mode when 'match_rp' mode is empty"
                );

                // Open the first line
                await testUtils.dom.click(widget.$(".accounting_view thead td:first"));
                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_match_rp"]')
                );
                // Select propositions
                await testUtils.dom.click(
                    widget.$(".match:first .cell_account_code:first")
                );
                await testUtils.dom.click(
                    widget.$(".match:first .cell_account_code:first")
                );

                // Await testUtils.dom.click(widget.$('caption')); //why is it inactive?

                testUtils.mock.intercept(clientAction, "call_service", function (
                    event
                ) {
                    if (event.data.args[1].method == "process_bank_statement_line") {
                        assert.deepEqual(
                            event.data.args[1].args,
                            [
                                [5],
                                [
                                    {
                                        partner_id: 8,
                                        counterpart_aml_dicts: [
                                            {
                                                counterpart_aml_id: 109,
                                                credit: 650,
                                                debit: 0,
                                                name: "INV/2017/0002",
                                                analytic_tag_ids: [[6, null, []]],
                                            },
                                            {
                                                counterpart_aml_id: 112,
                                                credit: 525,
                                                debit: 0,
                                                name: "INV/2017/0003",
                                                analytic_tag_ids: [[6, null, []]],
                                            },
                                        ],
                                        payment_aml_ids: [],
                                        new_aml_dicts: [],
                                        to_check: false,
                                    },
                                ],
                            ],
                            "Should call process_bank_statement_line with args"
                        );
                        var def = testUtils.makeTestPromise();
                        def.abort = function () {
                            // Do nothing.
                        };
                        event.data.callback(def);
                    }
                });

                // Click on reconcile button
                await testUtils.dom.click(widget.$(".o_reconcile:visible"));

                clientAction.destroy();
            });

            QUnit.test("Reconciliation validate without proposition", async function (
                assert
            ) {
                assert.expect(1);
                // Test added to prevent this issue happening again: https://github.com/odoo/odoo/commit/3549688b21eb65e16b9c3f2b6462eb8d8b52cd47
                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                var widget = clientAction.widgets[0];
                // Ensure that when we validate a line without any selection, it is the same
                // as when we manually create a line with the line.balance and that only one
                // line is send back to server.
                testUtils.mock.intercept(clientAction, "call_service", function (
                    event
                ) {
                    assert.deepEqual(
                        event.data.args[1].args,
                        [
                            [5],
                            [
                                {
                                    partner_id: 8,
                                    to_check: false,
                                    counterpart_aml_dicts: [],
                                    payment_aml_ids: [],
                                    new_aml_dicts: [
                                        {
                                            account_id: 287,
                                            credit: 1175,
                                            debit: 0,
                                            name: "SAJ/2014/002 and SAJ/2014/003",
                                            analytic_tag_ids: [[6, null, []]],
                                        },
                                    ],
                                },
                            ],
                        ],
                        "Should call process_bank_statement_line with ids"
                    );
                    var def = testUtils.makeTestPromise();
                    def.abort = function () {
                        // Do nothing.
                    };
                    event.data.callback(def);
                });

                // Click on validate button
                await testUtils.dom.click(widget.$("button.o_validate:not(:hidden)"));

                clientAction.destroy();
            });

            QUnit.test("Reconciliation validate with proposition", async function (
                assert
            ) {
                assert.expect(1);
                // Test added to check this functionality: https://github.com/odoo/odoo/commit/2f3b469dee6f18cbccce1cdf2a81cfe57960c533
                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });

                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();
                var widget = clientAction.widgets[0];
                // Add a line as proposition
                // open the first line
                await testUtils.dom.click(widget.$(".accounting_view thead td:first"), {
                    allowInvisible: true,
                });
                await testUtils.nextTick();
                // Select propositions
                await testUtils.dom.click(
                    widget.$(".match:first .cell_account_code:first"),
                    {allowInvisible: true}
                );
                await testUtils.nextTick();

                // Ensure that when we validate a line with propositions and that there is a remaining balance
                // We also create a line which is the open balance.
                testUtils.mock.intercept(clientAction, "call_service", function (
                    event
                ) {
                    assert.deepEqual(
                        event.data.args[1].args,
                        [
                            [5],
                            [
                                {
                                    partner_id: 8,
                                    to_check: false,
                                    counterpart_aml_dicts: [
                                        {
                                            counterpart_aml_id: 109,
                                            credit: 650,
                                            debit: 0,
                                            name: "INV/2017/0002",
                                            analytic_tag_ids: [[6, null, []]],
                                        },
                                    ],
                                    payment_aml_ids: [],
                                    new_aml_dicts: [
                                        {
                                            account_id: 287,
                                            credit: 525,
                                            debit: 0,
                                            name:
                                                "SAJ/2014/002 and SAJ/2014/003 : Open balance",
                                        },
                                    ],
                                },
                            ],
                        ],
                        "Should call process_bank_statement_line with ids"
                    );
                    var def = testUtils.makeTestPromise();
                    def.abort = function () {
                        // Do nothing.
                    };
                    event.data.callback(def);
                });

                // Click on validate button
                await testUtils.dom.click(widget.$("button.o_validate:not(:hidden)"));
                clientAction.destroy();
            });

            QUnit.test("Reconciliation partial [REQUIRE FOCUS]", async function (
                assert
            ) {
                assert.expect(8);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    mockRPC: function (route, args) {
                        console.log(args.method);
                        if (args.method === "process_bank_statement_line") {
                            var lines = args.args["1"];
                            console.log(args.arsg);
                            assert.deepEqual(
                                args.args,
                                [
                                    [6],
                                    [
                                        {
                                            partner_id:
                                                lines.length == 1
                                                    ? lines[0].partner_id
                                                    : false,
                                            counterpart_aml_dicts: [
                                                {
                                                    analytic_tag_ids: [[6, null, []]],
                                                    counterpart_aml_id: 114,
                                                    credit: 0,
                                                    debit: 32.58,
                                                    name: "BILL/2017/0001",
                                                },
                                            ],
                                            payment_aml_ids: [],
                                            new_aml_dicts: [],
                                            to_check: false,
                                        },
                                    ],
                                ],
                                "should call process_bank_statement_line with partial reconcile values"
                            );
                        }
                        return this._super(route, args);
                    },
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });

                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();
                var widget = clientAction.widgets[0];

                await testUtils.dom.click(
                    widget.$(".match:first .cell_account_code:first")
                );
                assert.equal(
                    widget.$(".cell_right .edit_amount").length,
                    1,
                    "should display the edition pencil"
                );

                widget = clientAction.widgets[1];

                await testUtils.dom.click(widget.$(".accounting_view thead td:first"));
                assert.strictEqual(
                    widget.$(
                        ".match:first .mv_line[data-line-id=114] .cell_account_code:first()"
                    ).length,
                    1,
                    "Should have line"
                );
                await testUtils.dom.click(
                    widget.$(
                        ".match:first .mv_line[data-line-id=114] .cell_account_code"
                    )
                );

                assert.equal(
                    widget.$(".accounting_view tbody .cell_left .edit_amount").length,
                    1,
                    "should display the edition pencil"
                );

                // The partner has been set automatically, remove it.
                await testUtils.dom.click(widget.$(".o_input_dropdown input"));
                await testUtils.fields.editAndTrigger(
                    widget.$(".o_input_dropdown input"),
                    "",
                    ["keyup", "blur"]
                );

                assert.equal(
                    clientAction.widgets[1].$("caption button:disabled:visible").length,
                    1,
                    "button should be disabled"
                );
                await testUtils.dom.click(
                    widget.$(".accounting_view .cell_left .edit_amount")
                );
                assert.strictEqual(
                    widget.$(
                        ".accounting_view .cell_left .edit_amount_input:not(.d-none)"
                    ).length,
                    1,
                    "should display the input field to edit amount"
                );
                // Edit amount
                await testUtils.fields.editAndTrigger(
                    widget.$(
                        ".accounting_view .cell_left .edit_amount_input:not(.d-none)"
                    ),
                    "32.58",
                    ["change", "blur"]
                );
                assert.strictEqual(
                    widget
                        .$(".accounting_view .cell_left .line_amount")
                        .text()
                        .replace(/[\n\r\s]+/g, " "),
                    " $ 10000.00 $ 32.58 ",
                    "should display previous amount and new amount"
                );

                assert.strictEqual(
                    widget.$("button.btn-primary:visible").length,
                    1,
                    "should display the reconcile button"
                );
                await testUtils.dom.click(widget.$("button.btn-primary:visible"));

                clientAction.destroy();
            });

            QUnit.test("Reconciliation currencies", async function (assert) {
                assert.expect(2);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );

                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: this.params.session,
                    translateParameters: {
                        date_format: "%m/%d/%Y",
                        direction: "ltr",
                        name: "English",
                        thousands_sep: ",",
                        time_format: "%H:%M:%S",
                        decimal_point: ".",
                        id: 1,
                        grouping: [3, 0],
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                assert.strictEqual(
                    clientAction
                        .$(
                            ".accounting_view tfoot .cell_right, .accounting_view tfoot .cell_left"
                        )
                        .text()
                        .replace(/[\n\r\s]+/g, " "),
                    "$ 1,175.00$ 32.58$ 2,000.00",
                    "should display the different amounts with the currency"
                );

                assert.strictEqual(
                    clientAction
                        .$(".accounting_view tbody")
                        .text()
                        .replace(/[\n\r\s]+/g, " ")
                        .replace(/[\u200B]/g, ""),
                    " 101200 2017-02-07 INV/2017/0012 $ 650.00 ",
                    "should display the created reconciliation line with the currency"
                );

                clientAction.destroy();
            });

            QUnit.test("Reconciliation change partner", async function (assert) {
                assert.expect(17);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );

                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    archs: {
                        "res.partner,false,list":
                            '<tree string="Partners"><field name="display_name"/></tree>',
                        "res.partner,false,search":
                            '<search string="Partners">' +
                            '<field name="display_name" string="Name"/>' +
                            "</search>",
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });

                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();
                var widget = clientAction.widgets[0];
                assert.strictEqual(
                    widget.$(".o_input_dropdown input").val(),
                    "Agrolait",
                    "the partner many2one should display agrolait"
                );
                assert.containsN(
                    widget,
                    ".match:first table tr",
                    2,
                    "agrolait should have 2 propositions for reconciliation"
                );

                // Adding the two propositions
                // This is in order to try that after changing partner the propositions are emptied
                await testUtils.dom.click(
                    widget.$(".match:first .cell_account_code:first")
                );
                await testUtils.dom.click(
                    widget.$(".match:first .cell_account_code:first")
                );
                assert.containsN(
                    widget,
                    ".accounting_view tbody tr",
                    2,
                    "Both proposition should be selected"
                );

                // Similate changing partner to one that does not have propositions to see if create mode is open after
                await testUtils.dom.click(widget.$(".o_input_dropdown input"));
                $(".ui-autocomplete .ui-menu-item a:contains(partner 1)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();
                clientAction._onAction({
                    target: widget,
                    name: "change_partner",
                    data: {data: {display_name: "partner 1", id: 1}},
                    stopped: false,
                });
                await testUtils.nextTick();
                assert.strictEqual(
                    widget.$(".o_input_dropdown input").val(),
                    "partner 1",
                    "the partner many2one should display partner 1"
                );
                assert.containsNone(
                    widget,
                    ".match:first table tr.mv_line",
                    "partner 1 should have 0 propositions for reconciliation"
                );
                assert.strictEqual(
                    widget.$el.data("mode"),
                    "create",
                    "widget should be in create mode"
                );

                // Simulate changing partner
                await testUtils.dom.clickFirst(widget.$(".o_input_dropdown input"));
                $(".ui-autocomplete .ui-menu-item a:contains(Camptocamp)")
                    .trigger("mouseenter")
                    .trigger("click");
                clientAction._onAction({
                    target: widget,
                    name: "change_partner",
                    data: {data: {display_name: "Camptocamp", id: 12}},
                    stopped: false,
                });
                await testUtils.nextTick();
                assert.strictEqual(
                    widget.$(".o_input_dropdown input").val(),
                    "Camptocamp",
                    "the partner many2one should display Camptocamp"
                );
                assert.containsN(
                    widget,
                    ".match:first table tr.mv_line",
                    3,
                    "camptocamp should have 3 propositions for reconciliation"
                );

                // Simulate changing partner with SelectCreateDialog
                widget = clientAction.widgets[1];
                assert.strictEqual(
                    $(".modal").length,
                    0,
                    "shouldn't have any opened modal"
                );
                await testUtils.dom.click(widget.$(".o_input_dropdown input"));
                $(".ui-autocomplete .ui-menu-item a:contains(Search More):eq(1)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();
                assert.strictEqual(
                    $(".modal").length,
                    1,
                    "should open a SelectCreateDialog"
                );
                await testUtils.dom.click(
                    $(".modal table.o_list_table td:contains(Camptocamp)")
                );
                assert.strictEqual(
                    widget.$(".o_input_dropdown input").val(),
                    "Camptocamp",
                    "the partner many2one should display Camptocamp"
                );

                widget = clientAction.widgets[2];
                await testUtils.dom.click(widget.$(".accounting_view thead td:first"));
                await testUtils.dom.click(
                    widget.$(".accounting_view .mv_line .cell_label")
                );
                assert.strictEqual(
                    widget.$(".o_input_dropdown input").val(),
                    "Camptocamp",
                    "the partner many2one should display agrolait"
                );
                assert.containsN(
                    widget,
                    ".match:first table tr",
                    3,
                    "Camptocamp should have 3 propositions for reconciliation"
                );
                assert.notOk(
                    widget.$(".match:first div.load-more a:visible").length,
                    "should not display the load more button"
                );

                // Simulate remove partner
                await testUtils.dom.click(widget.$(".o_input_dropdown input"));
                await testUtils.fields.editAndTrigger(
                    widget.$(".o_input_dropdown input"),
                    "",
                    ["keyup", "blur"]
                );

                assert.strictEqual(
                    widget.$(".o_input_dropdown input").val(),
                    "",
                    "the partner many2one should be empty"
                );
                assert.containsN(
                    widget,
                    ".match:first table tr.mv_line",
                    5,
                    "should have 5 propositions for reconciliation if partner is false"
                );
                assert.ok(
                    widget.$(".match:first div.load-more a:visible").length,
                    "should display the load more button"
                );

                clientAction.destroy();
            });

            QUnit.test("Reconciliation create line", async function (assert) {
                assert.expect(23);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );

                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                assert.strictEqual(
                    clientAction
                        .$(
                            ".accounting_view tfoot .cell_right, .accounting_view tfoot .cell_left"
                        )
                        .text()
                        .replace(/[$, ]+/g, ""),
                    " 1175.00 32.58 2000.00",
                    "should display the open balance values"
                );

                var widget = clientAction.widgets[0];

                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_label").text(),
                    "Open balance",
                    "should display 'Open Balance' line with the rest to reconcile"
                );

                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                );
                await testUtils.dom.click(widget.$(".create .create_account_id input"));
                $(
                    ".ui-autocomplete .ui-menu-item a:contains(101200 Account Receivable)"
                )
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();

                assert.notOk(
                    widget.$(".accounting_view tfoot .cell_label").text(),
                    "should not display 'Open Balance' line because the rest to reconcile is null"
                );
                assert.containsOnce(
                    widget,
                    ".accounting_view tbody tr",
                    "should have only the created reconcile line"
                );
                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody tr")
                        .text()
                        .replace(/[\n\r\s$,]+/g, " ")
                        .replace(/[\u200B]/g, ""),
                    " 101200 New SAJ/2014/002 and SAJ/2014/003 1175.00 ",
                    "the new line should have the selected account, name and amout"
                );
                assert.ok(
                    widget.$("caption button.btn-primary:visible").length,
                    "should display the 'Reconcile' button"
                );

                testUtils.mock.intercept(clientAction, "do_action", function (event) {
                    assert.strictEqual(
                        JSON.stringify(event.data.action),
                        '{"type":"ir.actions.act_window","res_model":"account.reconcile.model","views":[[false,"form"]],"target":"current"}',
                        "should open the reconcile model form view"
                    );
                });
                await testUtils.dom.click(widget.$(".create .reconcile_model_create"), {
                    allowInvisible: true,
                });

                testUtils.mock.intercept(clientAction, "do_action", function (event) {
                    assert.strictEqual(
                        JSON.stringify(event.data.action),
                        '{"type":"ir.actions.act_window","res_model":"account.reconcile.model","views":[[false,"list"],[false,"form"]],"view_mode":"list","target":"current"}',
                        "should open the reconcile model list view"
                    );
                });
                await testUtils.dom.click(widget.$(".create .reconcile_model_edit"), {
                    allowInvisible: true,
                });

                await testUtils.fields.editInput(
                    widget.$(".create .create_amount input"),
                    "1100.00"
                );

                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody .cell_right")
                        .text()
                        .trim()
                        .replace(/[\n\r\s\u00a0]+/g, " "),
                    "$ 1100.00",
                    "should display the value 1100.00 in right column"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_right").text(),
                    "$ 75.00",
                    "should display 'Open Balance' line because the rest to reconcile is 75.00"
                );
                assert.containsOnce(
                    widget,
                    ".accounting_view tbody tr",
                    "should have ever only the created reconcile line"
                );
                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody tr")
                        .text()
                        .replace(/[\n\r\s$,]+/g, " ")
                        .replace(/[\u200B]/g, ""),
                    " 101200 New SAJ/2014/002 and SAJ/2014/003 1100.00 ",
                    "the new line should be update the amout"
                );
                assert.ok(
                    widget.$("caption button.btn-secondary:visible").length,
                    "should display the 'validate' button"
                );

                await testUtils.dom.click(widget.$(".create .add_line"), {
                    allowInvisible: true,
                });
                await testUtils.fields.editInput(
                    widget.$(".create .create_amount input"),
                    "-100"
                );
                await testUtils.dom.click(widget.$(".create .create_account_id input"));
                $(".ui-autocomplete .ui-menu-item a:contains(101000 Current Assets)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();
                await testUtils.fields.editInput(
                    widget.$(".create .create_label input"),
                    "test0"
                );

                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody .cell_left:last")
                        .text()
                        .trim()
                        .replace(/[\n\r\s\u00a0]+/g, " "),
                    "$ 100.00",
                    "should display the value 100.00 in left column"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_label").text(),
                    "Open balance",
                    "should display 'Open Balance'"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_right").text(),
                    "$ 175.00",
                    "should display 'Open Balance' line because the rest to reconcile is 175.00"
                );
                assert.containsN(
                    widget,
                    ".accounting_view tbody tr",
                    2,
                    "should have 2 created reconcile lines"
                );
                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody tr:eq(1)")
                        .text()
                        .replace(/[\n\r\s$,]+/g, " ")
                        .replace(/[\u200B]/g, ""),
                    " 101000 New test0 100.00 ",
                    "the new line should have the selected account, name and amout"
                );

                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                );

                assert.strictEqual(
                    widget.$(".create .create_amount input").val(),
                    "175.00",
                    "should have '175.00' as default amount value"
                );

                await testUtils.fields.editInput(
                    widget.$(".create .create_amount input"),
                    "200"
                );
                widget.$(".create .create_account_id input").trigger("click");
                $(".ui-autocomplete .ui-menu-item a:contains(101000 Current Assets)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();
                await testUtils.fields.editInput(
                    widget.$(".create .create_label input"),
                    "test1"
                );

                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody .cell_right:last")
                        .text()
                        .trim()
                        .replace(/[\n\r\s\u00a0]+/g, " "),
                    "$ 200.00",
                    "should display the value 200.00 in left column"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_label").text(),
                    "Open balance",
                    "should display 'Open balance'"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_left").text(),
                    "$ 25.00",
                    "should display 'Open balance' with 25.00 in left column"
                );
                assert.containsN(
                    widget,
                    ".accounting_view tbody tr",
                    3,
                    "should have 3 created reconcile lines"
                );

                clientAction.destroy();
            });

            QUnit.test("Reconciliation create line (many2one test)", async function (
                assert
            ) {
                assert.expect(5);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                var def = testUtils.makeTestPromise();

                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.account,false,list":
                            '<tree string="Account"><field name="code"/><field name="name"/></tree>',
                        "account.account,false,search":
                            '<search string="Account"><field name="code"/></search>',
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                    mockRPC: function (route, args) {
                        if (args.method === "name_get") {
                            return def.then(this._super.bind(this, route, args));
                        }
                        return this._super(route, args);
                    },
                });

                await clientAction.prependTo($("#qunit-fixture"));
                await testUtils.nextTick();

                var widget = clientAction.widgets[0];

                // Open the first line in write-off mode
                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                );

                // Select an account with the many2one (drop down)
                await testUtils.dom.click(widget.$(".create .create_account_id input"));
                $(".ui-autocomplete .ui-menu-item a:contains(101200)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();
                assert.strictEqual(
                    widget.$(".create .create_account_id input").val(),
                    "101200 Account Receivable",
                    "Display the selected account"
                );
                assert.strictEqual(
                    widget
                        .$("tbody:first .cell_account_code")
                        .text()
                        .replace(/[\u200B]/g, ""),
                    "101200",
                    "Display the code of the selected account"
                );

                // Use the many2one select dialog to change the account
                await testUtils.dom.click(widget.$(".create .create_account_id input"));
                $(".ui-autocomplete .ui-menu-item a:contains(Search)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();
                // Select the account who does not appear in the drop drown
                await testUtils.dom.click($(".modal tr.o_data_row:contains(502)"));
                assert.strictEqual(
                    widget.$(".create .create_account_id input").val(),
                    "101200 Account Receivable",
                    "Selected account does not change"
                );
                // Wait the name_get to render the changes
                def.resolve();
                await testUtils.nextTick();
                assert.strictEqual(
                    widget.$(".create .create_account_id input").val(),
                    "502 Account",
                    "Display the selected account"
                );
                assert.strictEqual(
                    widget
                        .$("tbody:first .cell_account_code")
                        .text()
                        .replace(/[\u200B]/g, ""),
                    "502",
                    "Display the code of the selected account"
                );
                clientAction.destroy();
            });

            QUnit.test("Reconciliation create line with taxes", async function (
                assert
            ) {
                assert.expect(13);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );

                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                var widget = clientAction.widgets[0];

                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                );
                await testUtils.dom.click(widget.$(".create .create_account_id input"));
                $(".ui-autocomplete .ui-menu-item a:contains(101000 Current Assets)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();
                await testUtils.fields.editInput(
                    widget.$(".create .create_label input"),
                    "test1"
                );
                await testUtils.fields.editInput(
                    widget.$(".create .create_amount input"),
                    "1100"
                );

                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody .cell_right:last")
                        .text()
                        .trim()
                        .replace(/[\n\r\s\u00a0]+/g, " "),
                    "$ 1100.00",
                    "should display the value 1100.00 in left column"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_label").text(),
                    "Open balance",
                    "should display 'Open Balance'"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_right").text(),
                    "$\u00a075.00",
                    "should display 'Open Balance' with 75.00 in right column"
                );
                assert.containsOnce(
                    widget,
                    ".accounting_view tbody tr",
                    "should have 1 created reconcile lines"
                );

                await testUtils.dom.click(widget.$(".create .create_tax_id input"));
                $(".ui-autocomplete .ui-menu-item a:contains(10.00%)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();

                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody .cell_right")
                        .text()
                        .trim()
                        .replace(/[\n\r\s\u00a0]+/g, " "),
                    "$ 1000.00 $ 100.00",
                    "should have 2 created reconcile lines with right column values"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_label").text(),
                    "Open balance",
                    "should display 'Open Balance'"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_right").text(),
                    "$\u00a075.00",
                    "should display 'Open Balance' with 75.00 in right column"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_left").text(),
                    "",
                    "should display 'Open Balance' without any value in left column"
                );
                assert.containsN(
                    widget,
                    ".accounting_view tbody tr",
                    2,
                    "should have 2 created reconcile lines"
                );
                await testUtils.dom.click(widget.$('[name="tax_ids"] a.o_delete'));
                widget
                    .$(".create .create_tax_id input")
                    .val("")
                    .trigger("keyup")
                    .trigger("blur");
                await testUtils.dom.click(widget.$(".create .create_tax_id input"));
                $(".ui-autocomplete .ui-menu-item a:contains(20.00%)")
                    .trigger("mouseenter")
                    .trigger("click");
                await testUtils.nextTick();

                assert.strictEqual(
                    widget
                        .$(".accounting_view tbody .cell_right")
                        .text()
                        .trim()
                        .replace(/[\n\r\s\u00a0]+/g, " "),
                    "$ 1100.00 $ 220.00",
                    "should have 2 created reconcile lines with right column values"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_label").text(),
                    "Open balance",
                    "should display 'Open balance'"
                );
                assert.strictEqual(
                    widget.$(".accounting_view tfoot .cell_left").text(),
                    "$\u00a0145.00",
                    "should display 'Open balance' with 145.00 in right column"
                );
                assert.containsN(
                    widget,
                    ".accounting_view tbody tr",
                    2,
                    "should have 2 created reconcile lines"
                );

                clientAction.destroy();
            });

            QUnit.test(
                "Reconciliation create line from reconciliation model",
                async function (assert) {
                    assert.expect(6);

                    var clientAction = new ReconciliationClientAction.StatementAction(
                        null,
                        this.params.options
                    );

                    testUtils.mock.addMockEnvironment(clientAction, {
                        data: this.params.data,
                        archs: {
                            "account.bank.statement.line,false,search":
                                '<search string="Statement Line"><field name="display_name"/></search>',
                        },
                    });
                    await clientAction.appendTo($("#qunit-fixture"));
                    await testUtils.nextTick();

                    var widget = clientAction.widgets[0];

                    await testUtils.dom.click(
                        widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                    );
                    await testUtils.dom.click(
                        widget.$(".create .quick_add button:contains(ATOS)")
                    );

                    assert.strictEqual(
                        widget
                            .$(
                                ".accounting_view tbody .cell_label, .accounting_view tbody .cell_right"
                            )
                            .text()
                            .replace(/[\n\r\s$,]+/g, " "),
                        " ATOS Banque 1145.63 ATOS Banque Tax 20.00% 229.13 ATOS Frais 26.78 ATOS Frais Tax 10.00% include 2.68 ",
                        "should display 4 lines"
                    );
                    assert.strictEqual(
                        widget
                            .$(
                                ".accounting_view tfoot .cell_label, .accounting_view tfoot .cell_left"
                            )
                            .text()
                            .replace(/[\n\r\s$,]+/g, ""),
                        "Openbalance229.22",
                        "should display the 'Open balance' line with value in left column"
                    );

                    await testUtils.fields.editAndTrigger(
                        widget.$(".create .create_amount input"),
                        "100",
                        ["input"]
                    );

                    assert.strictEqual(
                        widget
                            .$(".accounting_view tbody")
                            .text()
                            .replace(/[\n\r\s$,]+/g, " ")
                            .replace(/[\u200B]/g, ""),
                        " 101120 New ATOS Banque 1145.63 101120 New ATOS Banque Tax 20.00% 229.13 101130 New ATOS Frais 90.91 101300 New ATOS Frais Tax 10.00% include 9.09 ",
                        "should update the value of the 2 lines (because the line + its tax must have 100% of the value)"
                    );
                    assert.strictEqual(
                        widget
                            .$(
                                ".accounting_view tfoot .cell_label, .accounting_view tfoot .cell_left"
                            )
                            .text()
                            .replace(/[\n\r\s$,]+/g, ""),
                        "Openbalance299.76",
                        "should change the 'Open balance' line because the 20.00% tax is not an include tax"
                    );

                    await testUtils.dom.click(
                        widget.$(".accounting_view tbody .cell_account_code:first")
                    );
                    await testUtils.dom.click(
                        widget.$(".accounting_view tbody .cell_label:first")
                    );

                    assert.strictEqual(
                        widget
                            .$(".accounting_view tbody")
                            .text()
                            .replace(/[\n\r\s$,]+/g, " "),
                        "",
                        "should removed every line"
                    );

                    await testUtils.dom.click(
                        widget.$(".create .quick_add button:contains(Double)")
                    );

                    assert.strictEqual(
                        widget
                            .$(".accounting_view tbody")
                            .text()
                            .replace(/[\n\r\s$,]+/g, " ")
                            .replace(/[\u200B]/g, ""),
                        " 101120 New Double Banque 1145.63 101130 New Double Frais 29.37 ",
                        "should have a sum of reconciliation proposition amounts equal to the line amount"
                    );

                    clientAction.destroy();
                }
            );

            QUnit.test(
                "Reconciliation fetch correct reconciliation models",
                async function (assert) {
                    assert.expect(1);

                    testUtilsMock.patch(this.params.options.context, {
                        active_model: "account.journal", // On account dashboard, click "Reconcile" on a journal
                        active_ids: [1, 2], // Active journals
                        company_ids: [3, 4], // Active companies
                    });

                    var clientAction = new ReconciliationClientAction.StatementAction(
                        null,
                        this.params.options
                    );

                    testUtils.addMockEnvironment(clientAction, {
                        data: this.params.data,
                        mockRPC: async function (route, args) {
                            if (
                                args.model === "account.reconcile.model" &&
                                args.method === "search_read"
                            ) {
                                assert.deepEqual(
                                    args.kwargs.domain,
                                    [
                                        ["company_id", "in", [3, 4]],
                                        "|",
                                        ["match_journal_ids", "=", false],
                                        ["match_journal_ids", "in", [1, 2]],
                                    ],
                                    "The domain to get reconcile models should contain the right fields and values"
                                );
                            }
                            return this._super.apply(this, arguments);
                        },
                    });
                    clientAction.appendTo($("#qunit-fixture"));
                    testUtilsMock.unpatch(this.params.options.context);

                    clientAction.destroy();
                }
            );

            QUnit.test("Reconciliation manual", async function (assert) {
                assert.expect(13);

                var clientAction = new ReconciliationClientAction.ManualAction(
                    null,
                    this.params.options
                );

                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: this.params.session,
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                assert.strictEqual(
                    clientAction
                        .$(".accounting_view:first thead")
                        .text()
                        .replace(/[\n\r\s]+/g, " "),
                    " 101000 Current AssetsLast Reconciliation: 2017-02-16 101000 ",
                    "should display the account as title"
                );
                assert.strictEqual(
                    clientAction.$(".o_reconciliation_line:first").data("mode"),
                    "inactive",
                    "should be in 'inactive' mode because no line to displayed and the balance amount is null"
                );
                assert.containsN(
                    clientAction,
                    ".accounting_view:first tbody tr",
                    2,
                    "should have 2 propositions"
                );
                assert.containsOnce(
                    clientAction,
                    ".accounting_view:first .o_reconcile:visible",
                    "should display the reconcile button"
                );

                await testUtils.dom.click(
                    clientAction.$(".accounting_view:first .o_reconcile:visible")
                );

                assert.strictEqual(
                    clientAction
                        .$(".accounting_view:first thead")
                        .text()
                        .replace(/[\n\r\s]+/g, " "),
                    " 101200 Account Receivable 101200 ",
                    "should display the account and the account code as title"
                );

                assert.strictEqual(
                    clientAction
                        .$(
                            ".o_reconciliation_line:first .match:first tr:first .cell_right"
                        )
                        .text()
                        .trim()
                        .replace(/[\n\r\s\u00a0]+/g, " "),
                    "$ 11,000.00",
                    "sould display the line in $"
                );
                assert.strictEqual(
                    clientAction
                        .$(
                            ".o_reconciliation_line:first .match:first tr:first .cell_right .o_multi_currency"
                        )
                        .data("content"),
                    "10,222.00 €",
                    "sould display the monetary information in €"
                );

                assert.containsOnce(
                    clientAction,
                    ".accounting_view:first .o_no_valid:visible",
                    "should display the skip button"
                );

                await testUtils.dom.click(
                    clientAction.$(".o_reconciliation_line:eq(1) .accounting_view")
                );
                await testUtils.dom.click(
                    clientAction.$(".accounting_view:eq(1) thead td:first")
                );
                // Debugger
                await testUtils.dom.click(
                    clientAction.$(
                        '.o_reconciliation_line:eq(1) [data-line-id="21"] .cell_label'
                    )
                );
                await testUtils.dom.click(
                    clientAction.$(
                        '.o_reconciliation_line:eq(1) [data-line-id="22"] .cell_label'
                    )
                );

                assert.strictEqual(
                    clientAction.$(".o_reconciliation_line:eq(1) tfoot tr").length,
                    0,
                    "should not display the 'Write-off' line because the balance is null in Euro"
                );
                assert.strictEqual(
                    clientAction.$(".o_reconciliation_line:eq(1) .o_reconcile:visible")
                        .length,
                    1,
                    "should display 'Reconcile' button in green"
                );

                await testUtils.dom.click(
                    clientAction.$(".o_reconciliation_line:eq(1) .o_reconcile:visible")
                );

                assert.containsOnce(
                    clientAction,
                    '.o_reconciliation_line[data-mode!="inactive"]',
                    "should have only one line open"
                );

                await testUtils.dom.click(
                    clientAction.$(
                        '.o_reconciliation_line:eq(1) [data-line-id="23"] .cell_label'
                    )
                );
                await testUtils.dom.click(
                    clientAction.$(
                        '.o_reconciliation_line:eq(1) [data-line-id="24"] .cell_label'
                    )
                );

                assert.strictEqual(
                    clientAction.$(".o_reconciliation_line:eq(1) tfoot tr").length,
                    1,
                    "should display the 'Write-off' line because the balance is not null in Euro"
                );
                assert.strictEqual(
                    clientAction.$(".o_reconciliation_line:eq(1) .o_validate:visible")
                        .length,
                    1,
                    "should display 'Reconcile' button"
                );

                clientAction.destroy();
            });

            QUnit.test(
                "Reconciliation: Payment < inv1 + inv2(partial)",
                async function (assert) {
                    assert.expect(3);

                    /*
                     * One payment: $1175
                     * Two Invoices
                     * The first invoice will be fully reconciled $650
                     * The second invoice will be partially paid with the rest of the payment $999
                     */

                    // modify the second line that is already in db to put it at $999
                    var indexModif = _.findIndex(
                        this.params.mv_lines['[5,"",0]'],
                        function (line) {
                            return line.id === 112;
                        }
                    );
                    this.params.mv_lines['[5,"",0]'][indexModif] = {
                        account_type: "receivable",
                        amount_currency_str: "",
                        currency_id: false,
                        date_maturity: "2017-02-07",
                        date: "2017-01-08",
                        total_amount_str: "$ 999.00",
                        partner_id: 8,
                        account_name: "101200 Account Receivable",
                        name: "INV/2017/0003",
                        partner_name: "Agrolait",
                        total_amount_currency_str: "",
                        id: 112,
                        credit: 0.0,
                        journal_id: [1, "Customer Invoices"],
                        amount_str: "$ 999.00",
                        debit: 999.0,
                        account_code: "101200",
                        ref: "",
                        already_paid: false,
                    };

                    var clientAction = new ReconciliationClientAction.StatementAction(
                        null,
                        this.params.options
                    );
                    testUtils.mock.addMockEnvironment(clientAction, {
                        data: this.params.data,
                        mockRPC: function (route, args) {
                            if (args.method === "process_bank_statement_line") {
                                assert.deepEqual(
                                    args.args,
                                    [
                                        [5], // Id of the bank statement line

                                        [
                                            {
                                                counterpart_aml_dicts: [
                                                    {
                                                        name: "INV/2017/0002",
                                                        debit: 0,
                                                        credit: 650,
                                                        analytic_tag_ids: [
                                                            [6, null, []],
                                                        ],
                                                        counterpart_aml_id: 109,
                                                    },

                                                    {
                                                        name: "INV/2017/0003",
                                                        debit: 0,
                                                        credit: 525,
                                                        analytic_tag_ids: [
                                                            [6, null, []],
                                                        ],
                                                        counterpart_aml_id: 112,
                                                    },
                                                ],

                                                payment_aml_ids: [],
                                                partner_id: 8,
                                                to_check: false,
                                                new_aml_dicts: [],
                                            },
                                        ],
                                    ],
                                    "should call process_bank_statement_line with partial reconcile values"
                                );
                            }
                            return this._super(route, args);
                        },
                        session: {
                            currencies: {
                                3: {
                                    digits: [69, 2],
                                    position: "before",
                                    symbol: "$",
                                },
                            },
                        },
                        archs: {
                            "account.bank.statement.line,false,search":
                                '<search string="Statement Line"><field name="display_name"/></search>',
                        },
                    });
                    await clientAction.appendTo($("#qunit-fixture"));
                    await testUtils.nextTick();

                    // The first reconciliation "line" is where it happens
                    var widget = clientAction.widgets[0];

                    // Add first invoice to reconcile fully
                    await testUtils.dom.click(
                        widget.$(".match:first .cell_account_code:first")
                    );
                    assert.ok(
                        widget.$(".cell_right .edit_amount").length,
                        "should display the pencil to edit amount"
                    );

                    // Add second invoice to reconcile partially
                    await testUtils.dom.click(
                        widget.$(".match:first .cell_account_code:first")
                    );

                    // Edit amount on last invoice
                    await testUtils.dom.click(widget.$(".edit_amount:last()"));
                    await testUtils.fields.editAndTrigger(
                        widget.$(".edit_amount_input:last()"),
                        "525",
                        ["blur"]
                    );

                    var $buttonReconcile = widget.$("button.o_reconcile:not(hidden)");

                    assert.equal(
                        $buttonReconcile.length,
                        1,
                        "The reconcile button must be visible"
                    );

                    await testUtils.dom.click($buttonReconcile);

                    clientAction.destroy();
                }
            );

            QUnit.test("Reconciliation: payment and 2 partials", async function (
                assert
            ) {
                assert.expect(6);

                /*
                 * One payment: $1175
                 * Two Invoices as Inv1 = 1200; Inv2 = 1200:
                 * Payment < Inv1 AND Payment < Inv2
                 * No partial reconcile is possible, as a write-off of 1225 is necessary
                 */

                // modify the invoice line to have their amount > payment
                var indexInv1 = _.findIndex(this.params.mv_lines['[5,"",0]'], function (
                    line
                ) {
                    return line.id === 109;
                });
                this.params.mv_lines['[5,"",0]'][indexInv1] = {
                    account_type: "receivable",
                    amount_currency_str: "",
                    currency_id: false,
                    date_maturity: "2017-02-07",
                    date: "2017-01-08",
                    total_amount_str: "$ 1200.00",
                    partner_id: 8,
                    account_name: "101200 Account Receivable",
                    name: "INV/2017/0002",
                    partner_name: "Agrolait",
                    total_amount_currency_str: "",
                    id: 109,
                    credit: 0.0,
                    journal_id: [1, "Customer Invoices"],
                    amount_str: "$ 1200.00",
                    debit: 1200.0,
                    account_code: "101200",
                    ref: "",
                    already_paid: false,
                };

                var indexInv2 = _.findIndex(this.params.mv_lines['[5,"",0]'], function (
                    line
                ) {
                    return line.id === 112;
                });
                this.params.mv_lines['[5,"",0]'][indexInv2] = {
                    account_type: "receivable",
                    amount_currency_str: "",
                    currency_id: false,
                    date_maturity: "2017-02-07",
                    date: "2017-01-08",
                    total_amount_str: "$ 1200.00",
                    partner_id: 8,
                    account_name: "101200 Account Receivable",
                    name: "INV/2017/0003",
                    partner_name: "Agrolait",
                    total_amount_currency_str: "",
                    id: 112,
                    credit: 0.0,
                    journal_id: [1, "Customer Invoices"],
                    amount_str: "$ 1200.00",
                    debit: 1200.0,
                    account_code: "101200",
                    ref: "",
                    already_paid: false,
                };

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    mockRPC: function (route, args) {
                        if (args.method === "process_bank_statement_line") {
                            assert.deepEqual(
                                args.args,
                                [
                                    [5], // Id of the bank statement line

                                    [
                                        {
                                            counterpart_aml_dicts: [
                                                {
                                                    name: "INV/2017/0002",
                                                    debit: 0,
                                                    credit: 1200,
                                                    analytic_tag_ids: [[6, null, []]],
                                                    counterpart_aml_id: 109,
                                                },

                                                {
                                                    name: "INV/2017/0003",
                                                    debit: 0,
                                                    credit: 1200,
                                                    analytic_tag_ids: [[6, null, []]],
                                                    counterpart_aml_id: 112,
                                                },
                                            ],

                                            payment_aml_ids: [],
                                            partner_id: 8,
                                            to_check: false,
                                            new_aml_dicts: [
                                                {
                                                    account_id: 282,
                                                    credit: 0,
                                                    debit: 1225,
                                                    analytic_tag_ids: [[6, null, []]],
                                                    name:
                                                        "SAJ/2014/002 and SAJ/2014/003",
                                                },
                                            ],
                                        },
                                    ],
                                ],
                                "should call process_bank_statement_line with new aml dict reconcile values"
                            );
                        }
                        return this._super(route, args);
                    },
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                // The first reconciliation "line" is where it happens
                var widget = clientAction.widgets[0];

                // Add first invoice
                // There should be the opportunity to reconcile partially
                await testUtils.dom.click(
                    widget.$(".match:first .cell_account_code:first")
                );
                assert.ok(
                    widget.$(".cell_right .edit_amount").length,
                    "should display the pencil to edit amount"
                );

                // Add second invoice
                await testUtils.dom.click(
                    widget.$(".match:first .cell_account_code:first")
                );
                assert.ok(
                    widget.$(".cell_right .edit_amount").length,
                    "should display the pencil to edit amount"
                );

                var writeOffCreate = widget.$("div.create");

                assert.equal(
                    writeOffCreate.length,
                    1,
                    "A write-off creation should be present"
                );

                assert.equal(
                    writeOffCreate.find("input[name=amount]").val(),
                    -1225,
                    "The right amount should be proposed for the write-off"
                );

                await testUtils.dom.click(
                    writeOffCreate.find(
                        ".create_account_id input.ui-autocomplete-input"
                    )
                );
                await testUtils.dom.click($("ul.ui-autocomplete li a:first"));

                var $buttonReconcile = widget.$("button.o_reconcile:not(hidden)");

                assert.equal(
                    $buttonReconcile.length,
                    1,
                    "The reconcile button must be visible"
                );

                await testUtils.dom.click($buttonReconcile);

                clientAction.destroy();
            });

            QUnit.test(
                "Reconciliation: partial payment of 2 invoices with one payment [REQUIRE FOCUS]",
                async function (assert) {
                    assert.expect(4);

                    /*
                     * One payment: $1175
                     * Two Invoices as Inv1 = 1200; Inv2 = 1200:
                     * Payment < Inv1 AND Payment < Inv2
                     * Assign 500 to inv1 and 675 to inv2
                     */

                    // modify the invoice line to have their amount > payment
                    var indexInv1 = _.findIndex(
                        this.params.mv_lines['[5,"",0]'],
                        function (line) {
                            return line.id === 109;
                        }
                    );
                    this.params.mv_lines['[5,"",0]'][indexInv1] = {
                        account_type: "receivable",
                        amount_currency_str: "",
                        currency_id: false,
                        date_maturity: "2017-02-07",
                        date: "2017-01-08",
                        total_amount_str: "$ 1200.00",
                        partner_id: 8,
                        account_name: "101200 Account Receivable",
                        name: "INV/2017/0002",
                        partner_name: "Agrolait",
                        total_amount_currency_str: "",
                        id: 109,
                        credit: 0.0,
                        journal_id: [1, "Customer Invoices"],
                        amount_str: "$ 1200.00",
                        debit: 1200.0,
                        account_code: "101200",
                        ref: "",
                        already_paid: false,
                    };

                    var indexInv2 = _.findIndex(
                        this.params.mv_lines['[5,"",0]'],
                        function (line) {
                            return line.id === 112;
                        }
                    );
                    this.params.mv_lines['[5,"",0]'][indexInv2] = {
                        account_type: "receivable",
                        amount_currency_str: "",
                        currency_id: false,
                        date_maturity: "2017-02-07",
                        date: "2017-01-08",
                        total_amount_str: "$ 1200.00",
                        partner_id: 8,
                        account_name: "101200 Account Receivable",
                        name: "INV/2017/0003",
                        partner_name: "Agrolait",
                        total_amount_currency_str: "",
                        id: 112,
                        credit: 0.0,
                        journal_id: [1, "Customer Invoices"],
                        amount_str: "$ 1200.00",
                        debit: 1200.0,
                        account_code: "101200",
                        ref: "",
                        already_paid: false,
                    };

                    var clientAction = new ReconciliationClientAction.StatementAction(
                        null,
                        this.params.options
                    );
                    testUtils.mock.addMockEnvironment(clientAction, {
                        data: this.params.data,
                        mockRPC: function (route, args) {
                            if (args.method === "process_bank_statement_line") {
                                assert.deepEqual(
                                    args.args,
                                    [
                                        [5], // Id of the bank statement line

                                        [
                                            {
                                                counterpart_aml_dicts: [
                                                    {
                                                        name: "INV/2017/0002",
                                                        debit: 0,
                                                        credit: 500,
                                                        analytic_tag_ids: [
                                                            [6, null, []],
                                                        ],
                                                        counterpart_aml_id: 109,
                                                    },

                                                    {
                                                        name: "INV/2017/0003",
                                                        debit: 0,
                                                        credit: 675,
                                                        analytic_tag_ids: [
                                                            [6, null, []],
                                                        ],
                                                        counterpart_aml_id: 112,
                                                    },
                                                ],

                                                payment_aml_ids: [],
                                                partner_id: 8,
                                                to_check: false,
                                                new_aml_dicts: [],
                                            },
                                        ],
                                    ],
                                    "should call process_bank_statement_line with correct counterpart_aml_dicts"
                                );
                            }
                            return this._super(route, args);
                        },
                        session: {
                            currencies: {
                                3: {
                                    digits: [69, 2],
                                    position: "before",
                                    symbol: "$",
                                },
                            },
                        },
                        archs: {
                            "account.bank.statement.line,false,search":
                                '<search string="Statement Line"><field name="display_name"/></search>',
                        },
                    });
                    await clientAction.appendTo($("#qunit-fixture"));
                    await testUtils.nextTick();

                    // The first reconciliation "line" is where it happens
                    var widget = clientAction.widgets[0];

                    // Add first invoice
                    // There should be the opportunity to reconcile partially
                    await testUtils.dom.click(
                        widget.$(".match:first .cell_account_code:first")
                    );
                    assert.ok(
                        widget.$(".cell_right .edit_amount").length,
                        "should display the pencil to edit amount"
                    );

                    // Add second invoice
                    await testUtils.dom.click(
                        widget.$(".match:first .cell_account_code:first")
                    );
                    assert.ok(
                        widget.$(".cell_right .edit_amount").length,
                        "should display the pencil to edit amount"
                    );

                    // Edit invoice first amount
                    await testUtils.dom.click(widget.$(".edit_amount:first()"));
                    await testUtils.fields.editAndTrigger(
                        widget.$(".edit_amount_input:first()"),
                        "500",
                        ["blur"]
                    );
                    // Edit invoice second amount
                    var $buttonReconcile = widget.$("button.o_reconcile:not(hidden)");
                    await testUtils.dom.click(widget.$(".edit_amount:last()"));
                    await testUtils.fields.editAndTrigger(
                        widget.$(".edit_amount_input:last()"),
                        "675",
                        ["blur"]
                    );

                    assert.equal(
                        $buttonReconcile.length,
                        1,
                        "The reconcile button must be visible"
                    );

                    await testUtils.dom.click($buttonReconcile, {allowInvisible: true});

                    clientAction.destroy();
                }
            );

            QUnit.test(
                "Manual Reconciliation: remove a prop to attain balance and reconcile",
                async function (assert) {
                    assert.expect(5);

                    // Tweak the data to fit our needs
                    this.params.data_for_manual_reconciliation_widget[
                        '[283, null, "", 0, 6]'
                    ] = _.extend(
                        {},
                        this.params.data_for_manual_reconciliation_widget[
                            "[null,[282,283,284,285,286,287,288,308,499,500,501,502,503,504]]"
                        ]
                    );
                    this.params.data_for_manual_reconciliation_widget[
                        '[283, null, "", 0, 6]'
                    ].accounts[0].reconciliation_proposition = [
                        {
                            account_id: 283,
                            account_type: "other",
                            amount_currency_str: "",
                            currency_id: false,
                            date_maturity: "2017-03-18",
                            date: "2017-02-16",
                            total_amount_str: "$ 500.00",
                            partner_id: 8,
                            account_name: "101000 Current Assets",
                            name: "INV/2017/0987",
                            partner_name: "Agrolait",
                            total_amount_currency_str: "",
                            id: 999,
                            credit: 0.0,
                            journal_id: [1, "Customer Invoices"],
                            amount_str: "$ 500.00",
                            debit: 500.0,
                            account_code: "101000",
                            ref: "",
                            already_paid: false,
                        },
                    ];

                    var clientAction = new ReconciliationClientAction.ManualAction(
                        null,
                        this.params.options
                    );
                    testUtils.mock.addMockEnvironment(clientAction, {
                        data: this.params.data,
                        mockRPC: function (route, args) {
                            if (args.method === "process_move_lines") {
                                assert.deepEqual(
                                    args.args,
                                    [
                                        [
                                            {
                                                id: null,
                                                type: null,
                                                mv_line_ids: [399, 402],
                                                new_mv_line_dicts: [],
                                            },
                                        ],
                                    ],
                                    "should call process_move_lines without the new mv line dict"
                                );
                            }

                            return this._super(route, args);
                        },
                        session: {
                            currencies: {
                                3: {
                                    digits: [69, 2],
                                    position: "before",
                                    symbol: "$",
                                },
                            },
                        },
                        archs: {
                            "account.bank.statement.line,false,search":
                                '<search string="Statement Line"><field name="display_name"/></search>',
                        },
                    });

                    await clientAction.appendTo($("#qunit-fixture"));
                    await testUtils.nextTick();

                    // The first reconciliation "line" is where it happens
                    var widget = clientAction.widgets[0];

                    // Add first prop
                    await testUtils.dom.click(
                        widget.$(".match:first .cell_account_code:first")
                    );
                    assert.equal(
                        widget.$(".cell_right .edit_amount").length,
                        0,
                        "should not display the pencil to edit amount"
                    );

                    // Add second prop
                    await testUtils.dom.click(
                        widget.$(".match:first .cell_account_code:first")
                    );
                    // Check that a create form is here

                    await testUtils.dom.click(
                        widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                    );
                    var writeOffCreate = widget.$("div.create");

                    assert.equal(
                        writeOffCreate.length,
                        1,
                        "A write-off creation should be present"
                    );

                    assert.equal(
                        writeOffCreate.find("input[name=amount]").val(),
                        500,
                        "The right amount should be proposed for the write-off"
                    );

                    // Remove the first line, the other two will balance one another
                    await testUtils.dom.click(
                        widget.$('tr[data-line-id="999"] td:first')
                    );

                    var $buttonReconcile = widget.$("button.o_reconcile:visible");
                    assert.equal(
                        $buttonReconcile.length,
                        1,
                        "The reconcile button must be visible"
                    );

                    await testUtils.dom.click($buttonReconcile);

                    clientAction.destroy();
                }
            );

            QUnit.test("Manual Reconciliation: No lines for account", async function (
                assert
            ) {
                assert.expect(2);

                var clientAction = new ReconciliationClientAction.ManualAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });

                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                // The second reconciliation "line" is where it happens
                var widget = clientAction.widgets[1];

                var emptyLine = widget.$("tr.mv_line");

                assert.notOk(
                    "data-line-id" in emptyLine.getAttributes(),
                    "Empty line should be empty"
                );

                await testUtils.dom.click(emptyLine.find("td:first"));

                // Check that a create form is here
                var writeOffCreate = widget.$("div.create .create_account_id");

                assert.equal(
                    writeOffCreate.length,
                    1,
                    "A write-off creation should be present"
                );

                clientAction.destroy();
            });

            QUnit.test("Tax on account receivable", async function (assert) {
                assert.expect(21);

                this.params.data_for_manual_reconciliation_widget[
                    "[null,[282,283,284,285,286,287,288,308,499,500,501,502,503,504]]"
                ].accounts = [];
                var clientAction = new ReconciliationClientAction.ManualAction(
                    null,
                    this.params.options
                );
                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {},
                    mockRPC: function (route, args) {
                        if (args.method === "name_search") {
                            switch (args.model) {
                                // Mock the default mock to do the minimal processing required
                                // to get the available values for the droplists.
                                case "account.account":
                                    assert.step("Account");
                                    return Promise.resolve(
                                        _.map(this.data[args.model].records, function (
                                            record
                                        ) {
                                            return [record.id, record.name];
                                        })
                                    );
                                case "account.tax":
                                    assert.step("Tax");
                                    return Promise.resolve(
                                        _.map(this.data[args.model].records, function (
                                            record
                                        ) {
                                            return [record.id, record.display_name];
                                        })
                                    );
                                case "account.journal":
                                    assert.step("Journal");
                                    return Promise.resolve(
                                        _.map(this.data[args.model].records, function (
                                            record
                                        ) {
                                            return [record.id, record.display_name];
                                        })
                                    );
                            }
                        }
                        if (args.method === "process_move_lines") {
                            var mv_line_ids = args.args[0][0].mv_line_ids.slice(0);
                            mv_line_ids.sort(function (a, b) {
                                return a - b;
                            });
                            assert.deepEqual(
                                mv_line_ids,
                                [6, 19, 21],
                                "Reconciliation rpc payload, mv_line_ids are correct"
                            );

                            // Index aiming at the correct object in the list
                            var idx = _.has(
                                args.args[0][0].new_mv_line_dicts[0],
                                "journal_id"
                            )
                                ? 0
                                : 1;
                            assert.deepEqual(
                                _.pick(
                                    args.args[0][0].new_mv_line_dicts[idx],
                                    "account_id",
                                    "name",
                                    "credit",
                                    "debit",
                                    "journal_id"
                                ),
                                {
                                    account_id: 287,
                                    name: "dummy text",
                                    credit: 0,
                                    debit: 180,
                                    journal_id: 8,
                                },
                                "Reconciliation rpc payload, new_mv_line_dicts.gift is correct"
                            );
                            assert.deepEqual(
                                _.pick(
                                    args.args[0][0].new_mv_line_dicts[1 - idx],
                                    "account_id",
                                    "name",
                                    "credit",
                                    "debit",
                                    "tax_repartition_line_id"
                                ),
                                {
                                    account_id: 287,
                                    name: "Tax 20.00%",
                                    credit: 0,
                                    debit: 36,
                                    tax_repartition_line_id: 2,
                                },
                                "Reconciliation rpc payload, new_mv_line_dicts.tax is correct"
                            );
                        }
                        return this._super.apply(this, arguments);
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });

                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                var widget = clientAction.widgets[0];

                // Select invoice of 1k$, payment of 1k$ and payment of 180$
                var $tableToReconcile = widget.$(".match");
                var defs = _.map([6, 19, 21], function (id) {
                    return testUtils.dom.click(
                        $tableToReconcile.find(
                            "tr.mv_line[data-line-id=" + id + "]:first td:first-child"
                        )
                    );
                });
                await Promise.all(defs);
                assert.verifySteps([], "No rpc done");

                // Store the money in excess to the "account receivable" account with 20% taxes
                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                );
                var $reconcileForm = widget.$(".create");
                await testUtils.dom.click(
                    $reconcileForm.find(".create_account_id input")
                );
                $(
                    ".ui-autocomplete .ui-menu-item a:contains(101200 Account Receivable)"
                )
                    .trigger("mouseover")
                    .trigger("click");
                await testUtils.nextTick();
                assert.verifySteps(["Account"], "Account rpc done");

                await testUtils.dom.click($reconcileForm.find(".create_tax_id input"));
                $(".ui-autocomplete .ui-menu-item a:contains(Tax 20.00%)")
                    .trigger("mouseover")
                    .trigger("click");
                await testUtils.nextTick();
                assert.verifySteps(["Tax"], "Tax rpc done");

                await testUtils.dom.click(
                    $reconcileForm.find(".create_journal_id input"),
                    {allowInvisible: true}
                );
                $(".ui-autocomplete .ui-menu-item a:contains(company 1 journal)")
                    .trigger("mouseover")
                    .trigger("click");
                await testUtils.nextTick();
                await testUtils.fields.editAndTrigger(
                    $reconcileForm.find(".create_label input"),
                    "dummy text",
                    "input"
                );
                await testUtils.dom.click($reconcileForm.find(".create_label input"));
                assert.verifySteps(["Journal"], "Journal rpc done");

                // Verify the two (gift + tax) lines were added to the list
                var $newLines = widget.$("tr.mv_line[data-line-id^=createLine]");
                var idx =
                    $($($newLines[0]).find("td")[3]).text().trim() === "dummy text"
                        ? 0
                        : 1;

                var $newLineGiftTds = $($newLines[1 - idx]).find("td");
                assert.equal(
                    $($newLineGiftTds[0])
                        .text()
                        .trim()
                        .replace(/[\u200B]/g, ""),
                    "101200",
                    "Gift line account number is valid"
                );
                assert.equal(
                    $($newLineGiftTds[1]).text().trim(),
                    "New",
                    "Gift line is flagged as new"
                );
                assert.equal(
                    $($newLineGiftTds[2]).text().trim(),
                    "dummy text",
                    "Gift line has the correct label"
                );
                assert.equal(
                    $($newLineGiftTds[3]).text().trim(),
                    "180.00",
                    "Gift line has the correct left amount"
                );
                assert.equal(
                    $($newLineGiftTds[4]).text().trim(),
                    "",
                    "Gift line has the correct right amount"
                );

                var $newLineTaxeTds = $($newLines[idx]).find("td");
                assert.equal(
                    $($newLineTaxeTds[0])
                        .text()
                        .trim()
                        .replace(/[\u200B]/g, ""),
                    "101200",
                    "Tax line account number is valid"
                );
                assert.equal(
                    $($newLineTaxeTds[1]).text().trim(),
                    "New",
                    "Tax line is flagged as new"
                );
                assert.equal(
                    $($newLineTaxeTds[2]).text().trim(),
                    "Tax 20.00%",
                    "Tax line has the correct label"
                );
                assert.equal(
                    $($newLineTaxeTds[3]).text().trim(),
                    "36.00",
                    "Tax line has the correct left amount"
                );
                assert.equal(
                    $($newLineTaxeTds[4]).text().trim(),
                    "",
                    "Tax line has the correct right amount"
                );

                // Reconcile
                await testUtils.dom.click(
                    widget.$("button.o_reconcile.btn.btn-primary:first")
                );
                assert.ok(true, "No error in reconciliation");

                clientAction.destroy();
            });

            QUnit.test("Reconcile temporarily and ask to check", async function (
                assert
            ) {
                assert.expect(4);
                this.params.options.context.to_check = true;
                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );

                testUtils.mock.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });
                await clientAction.appendTo($("#qunit-fixture"));
                var widget = clientAction.widgets[0];

                // Add a line as proposition
                // open the first line
                await testUtils.nextTick();
                await testUtils.dom.click(
                    widget.$(".accounting_view tfoot td.cell_label")
                );
                await testUtils.dom.click(
                    widget.$('.o_notebook .nav-link[href*="notebook_page_create"]')
                );

                var $reconcileForm = widget.$(".create");
                $reconcileForm
                    .find(".create_account_id input")
                    .val("499001 Suspense Account")
                    .keydown()
                    .keyup();
                await testUtils.dom.click(
                    $reconcileForm.find(".create_account_id input")
                );
                $(".ui-autocomplete .ui-menu-item a:contains(499001 Suspense Account)")
                    .trigger("mouseover")
                    .trigger("click");
                await testUtils.nextTick();

                assert.equal(
                    $("button.o_validate.btn.btn-secondary.text-warning:first").length,
                    0,
                    "should not display reconcile button in orange"
                );
                await testUtils.dom.click(
                    $reconcileForm.find(".create_to_check input")
                );
                assert.equal(
                    $("button.o_validate.btn.btn-secondary.text-warning:first").length,
                    1,
                    "should display reconcile button in orange"
                );

                testUtils.mock.intercept(clientAction, "call_service", function (
                    event
                ) {
                    assert.deepEqual(
                        event.data.args[1].args,
                        [
                            [5],
                            [
                                {
                                    partner_id: 8,
                                    counterpart_aml_dicts: [],
                                    payment_aml_ids: [],
                                    new_aml_dicts: [
                                        {
                                            account_id: 499,
                                            credit: 1175,
                                            debit: 0,
                                            analytic_tag_ids: [[6, null, []]],
                                            name: "SAJ/2014/002 and SAJ/2014/003",
                                        },
                                    ],
                                    to_check: true,
                                },
                            ],
                        ],
                        "Should call process_bank_statement_line with to_check set to true"
                    );
                    var def = testUtils.makeTestPromise();
                    def.abort = function () {
                        // Do nothing.
                    };
                    event.data.callback(def);
                });

                await testUtils.dom.click(
                    widget.$("button.o_validate.btn.btn-secondary:first")
                );
                assert.ok(true, "No error in reconciliation");

                clientAction.destroy();
            });

            QUnit.test("Reconciliation Models handle analytic tags", async function (
                assert
            ) {
                assert.expect(6);

                var clientAction = new ReconciliationClientAction.StatementAction(
                    null,
                    this.params.options
                );
                testUtils.addMockEnvironment(clientAction, {
                    data: this.params.data,
                    mockRPC: function (route, args) {
                        if (args.method === "process_bank_statement_line") {
                            var new_aml_dicts = args.args[1][0].new_aml_dicts;
                            assert.strictEqual(new_aml_dicts.length, 2);
                            // I personnally judge the following use case rotten, since
                            // the first and the second line wouldn't have the same tags
                            assert.deepEqual(new_aml_dicts[0].analytic_tag_ids, [
                                [6, null, [1, 2]],
                            ]);
                            assert.deepEqual(new_aml_dicts[1].analytic_tag_ids, [
                                [6, null, [2]],
                            ]);
                        }
                        return this._super(route, args);
                    },
                    session: {
                        currencies: {
                            3: {
                                digits: [69, 2],
                                position: "before",
                                symbol: "$",
                            },
                        },
                        user_has_group: function (group) {
                            if (
                                group === "analytic.group_analytic_tags" ||
                                group === "analytic.group_analytic_accounting"
                            ) {
                                return $.when(true);
                            }
                            return this._super.apply(this, arguments);
                        },
                    },
                    archs: {
                        "account.bank.statement.line,false,search":
                            '<search string="Statement Line"><field name="display_name"/></search>',
                    },
                });

                await clientAction.appendTo($("#qunit-fixture"));
                await testUtils.nextTick();

                // The first reconciliation "line" is where it happens
                var widget = clientAction.widgets[0];

                await testUtilsDom.click(widget.$(".nav-create:visible"));
                await testUtilsDom.click(
                    widget.$('.quick_add button:contains("Double")')
                );
                assert.containsN(
                    widget,
                    ".create_analytic_tag_ids .o_field_many2manytags .badge",
                    2,
                    "Two tags are loaded"
                );
                assert.containsOnce(
                    widget,
                    '.create_analytic_tag_ids .o_field_many2manytags .badge:contains("Come together")',
                    "Tags should have a name"
                );
                assert.containsOnce(
                    widget,
                    '.create_analytic_tag_ids .o_field_many2manytags .badge:contains("Right now")',
                    "Tags should have a name"
                );

                await testUtilsDom.click(
                    widget.$(
                        ".create_analytic_tag_ids .o_field_many2manytags .badge a.o_delete:first()"
                    )
                );

                await testUtilsDom.click(widget.$(".o_reconcile:visible"));

                clientAction.destroy();
            });
        }
    );
});
