﻿function formatCurrencyUsd(value) { return "$" + value.toFixed(2); }
function formatCurrencyEur(value) { return value.toFixed(2) + "€"; }
function formatCurrency(value) { return "kr " + value.toFixed(2); }
function formatCurrencyGbp(value) { return "£" + value.toFixed(2); }
function formatCurrencyNok(value) { return "kr " + value.toFixed(2); }

var baseUrl = document.getElementById('baseurl').href;

var fakturaViewModel = function () {
    this.items = ko.observableArray([]);
    this.products = ko.observableArray([]);
    this.contacts = ko.observableArray([]);
    this.vats = ko.observableArray([{ name: "0%", value: "0.00" }, { name: "8%", value: "0.08" }, { name: "15%", value: "0.15" }, { name: "25%", value: "0.25"}]);
    this.user = ko.observable();
    this.forfallsdato = ko.observable();
    this.fakturadato = ko.observable();
    this.deresref = ko.observable();
    this.varref = ko.observable();
    this.ordreref = ko.observable();
    this.gjelderfaktura = ko.observable();
    this.addmessagetopdf = ko.observable();
    this.remembermessage = ko.observable();
    this.shouldShowMessage = ko.observable();
    this.message = ko.observable();
    this.template = ko.observable(1);
    this.ContactName = ko.observable();
    this.ContactPerson = ko.observable();
    this.ContactAddress = ko.observable();
    this.ContactZip = ko.observable();
    this.ContactCity = ko.observable();
    this.ContactEmail = ko.observable();
    this.ContactId = ko.observable();
    this.ContactCurrencyCulture = ko.observable('nb-NO');
    this.contact = ko.observable();
    this.contact.subscribe(function () {
        if (this.contact() == undefined) {
            //formatCurrency = formatCurrencyNok;
        } else {
            if (this.contact().CurrencyCulture == "en-US") {
                formatCurrency = formatCurrencyUsd;
                this.template(2);
            }
            if (this.contact().CurrencyCulture == "de-DE") {
                formatCurrency = formatCurrencyEur;
                this.template(2);
            }
            if (this.contact().CurrencyCulture == "en-GB") {
                formatCurrency = formatCurrencyGbp;
                this.template(2);
            }
            if (this.contact().CurrencyCulture == "nb-NO") {
                formatCurrency = formatCurrencyNok;
                this.template(1);
            }

            this.setContact(this.contact());

            ko.utils.arrayForEach(this.items(), function (row) {
                row.updated(new Date());
            });
        }
    } .bind(this));

    this.addNewRow = function () {
        this.items.push(new fakturaRow(this.vats(), this.products(), 0.00, 1.00, 0.00, 0.25, '', ''));
    };

    this.addRow = function (row) {
        this.items.push(row);
    };

    this.removeRow = function (row) {
        this.items.remove(row);
    };

    this.setContact = function (contact) {
        this.ContactName(contact.Name);
        this.ContactId(contact.Id);
        this.ContactAddress(contact.Address);
        this.ContactZip(contact.Zip);
        this.ContactCity(contact.City);
        this.ContactEmail(contact.Email);
        this.ContactCurrencyCulture(contact.CurrencyCulture);
        this.ContactPerson(contact.ContactPerson);
    };

    this.load = function (fakturaId, contactId) {
        var $this = this;
        $mvc.Script.GetFakturaPageData({ id: fakturaId, contactId: contactId }).success(function (data) {

            var selectedcontact;
            ko.utils.arrayForEach(data.Contacts, function (contact) {
                if (data.Contact != undefined) {
                    if (data.Contact.Id == contact.Id)
                        selectedcontact = contact;
                }
            });

            $this.contacts(data.Contacts);
            $this.products(data.Products);
            $this.user(data.User);
            $this.contact(selectedcontact);
            $this.ContactId(data.ContactId);
            $this.ContactName(data.ContactName);
            $this.ContactAddress(data.ContactAddress);
            $this.ContactZip(data.ContactZip);
            $this.ContactCity(data.ContactCity);
            $this.ContactEmail(data.ContactEmail);
            $this.ContactPerson(data.ContactPerson);
            $this.ContactCurrencyCulture(data.ContactCurrencyCulture);
            $this.forfallsdato(new Date(parseInt(data.ForfallsDato.substr(6))).format("dd.mm.yyyy"));
            $this.fakturadato(new Date(parseInt(data.FakturaDato.substr(6))).format("dd.mm.yyyy"));
            $this.deresref(data.DeresRef);
            $this.varref(data.VarRef);
            $this.ordreref(data.OrdreRef);
            $this.addmessagetopdf(data.ShowCommentOnPdf);
            $this.message(data.Message);
            $this.template(data.Template);
            $this.shouldShowMessage(data.Message != undefined && data.Message.length > 0);
            $.each(data.FakturaLinjer, function (i, row) {
                $this.addRow(new fakturaRow($this.vats(), $this.products(), row.Price, row.Count, (row.Discount * 100), row.Vat, row.Description, row.ProductNr));
            });
        })
        .error(function () {
            alert('Error loading faktura');
        });
    };

    this.loadcreditnote = function (creditnoteId, fakturaId) {
        var $this = this;
        $mvc.Script.GetCreditnote({ id: creditnoteId, fakturaId: fakturaId }).success(function (data) {

            var selectedcontact;
            ko.utils.arrayForEach(data.Contacts, function (contact) {
                if (data.Contact != undefined) {
                    if (data.Contact.Id == contact.Id)
                        selectedcontact = contact;
                }
            });

            $this.contacts(data.Contacts);
            $this.products(data.Products);
            $this.user(data.User);
            $this.contact(selectedcontact);
            $this.forfallsdato(new Date(parseInt(data.ForfallsDato.substr(6))).format("dd.mm.yyyy"));
            $this.fakturadato(new Date(parseInt(data.FakturaDato.substr(6))).format("dd.mm.yyyy"));
            $this.deresref(data.DeresRef);
            $this.varref(data.VarRef);
            $this.ordreref(data.OrdreRef);
            $this.addmessagetopdf(data.ShowCommentOnPdf);
            $this.message(data.Message);
            $this.template(data.Template);
            $.each(data.FakturaLinjer, function (i, row) {
                $this.addRow(new fakturaRow($this.vats(), $this.products(), row.Price, row.Count, (row.Discount * 100), row.Vat, row.Description, row.ProductNr));
            });
        })
        .error(function () {
            alert('Error loading faktura');
        });
    };

    this.grandTotal = ko.dependentObservable(function () {
        var total = 0;
        for (var i = 0; i < this.items().length; i++)
            total += this.items()[i].subtotal();
        return total;
    } .bind(this));

    this.grandTotalMva = ko.dependentObservable(function () {
        var total = 0;
        for (var i = 0; i < this.items().length; i++)
            total += this.items()[i].subtotalmva();
        return total;
    } .bind(this));

    this.grandTotalVat = ko.dependentObservable(function () {
        return this.grandTotalMva() - this.grandTotal();
    } .bind(this));

    this.save = function (faktura) {

        var webMethod = baseUrl + 'mobil/faktura/save';

        $.ajax({ type: "POST",
            url: webMethod,
            data: "{fakturaViewModel:" + JSON.stringify(faktura) + "}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (msg) {
                var fakturaId = msg;
                location.href = baseUrl + 'mobil/faktura';
            },
            error: function (xhr, status, error) {
                // Boil the ASP.NET AJAX error down to JSON.
                var err = eval("(" + xhr.responseText + ")");

                // Display the specific error raised by the server (e.g. not a
                //   valid value for Int32, or attempted to divide by zero).
                alert(err.Message);
            }
        });
    };

    this.getLinjer = function () {
        var linjer = [];
        ko.utils.arrayForEach(this.items(), function (item) {
            var fakturaLinje = new Object();
            fakturaLinje.ProductNr = item.productnr();
            fakturaLinje.Count = parseFloat(item.count()).toFixed(2).toString().replace(".", ",");
            fakturaLinje.Discount = parseFloat(item.discount() / 100).toFixed(2).toString().replace(".", ",");
            fakturaLinje.Price = parseFloat(item.price()).toFixed(2).toString().replace(".", ",");
            fakturaLinje.Description = item.description();
            fakturaLinje.Vat = parseFloat(item.vat()).toFixed(2).toString().replace(".", ",");
            linjer.push(fakturaLinje);
        });
        return linjer;
    };

    this.saveCreditnote = function (fakturaId, goNext) {

        var validationResults = regula.validate();

        var errors = [];

        for (var index in validationResults) {
            var validationResult = validationResults[index];
            errors.push(validationResult.message);
        };

        if (this.items().length == 0) errors.push('Du må ha minst en faktura linje');
        if (this.grandTotalMva() < 0) errors.push('Kreditnota må sendes med positivt fortegn');

        if (errors.length > 0) {

            var error = '';
            $.each(errors, function (i, row) {
                error += '<li>' + row + '</li>';
            });

            $('#c_savedfakturas').hide();
            $('.errormessage').html('<ul>' + error + '</ul>');
            $('.errormessage').show();
            return false;
        }
        else {
            $('.errormessage').hide();
            $('#btnNext').attr("disabled", "disabled");
            $('#btnNext').attr("value", "Vennligst vent...");
        }

        var webMethod = baseUrl + 'faktura/savecreditnote';

        var linjer = this.getLinjer();

        var params = {
            'fakturaId': fakturaId,
            'lines': linjer,
            'send': goNext
        };

        $.ajax({ type: "POST",
            url: webMethod,
            data: JSON.stringify(params),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (msg) {
                if (goNext)
                    location.href = baseUrl + 'faktura';
            },
            error: function (xhr, status, error) {
                // Boil the ASP.NET AJAX error down to JSON.
                var err = eval("(" + xhr.responseText + ")");

                // Display the specific error raised by the server (e.g. not a
                //   valid value for Int32, or attempted to divide by zero).
                alert(err.Message);
            }
        });
    };

    this.saveFaktura = function (fakturaId, goNext, preview, previewType) {

        var validationResults = regula.validate();

        var errors = [];

        for (var index in validationResults) {
            var validationResult = validationResults[index];
            errors.push(validationResult.message);
        };
        
        if (this.ContactName() == undefined) errors.push('Navn på mottaker mangler');
        if (this.ContactAddress() == undefined) errors.push('Adresse på mottaker mangler');
        if (this.ContactZip() == undefined) errors.push('Postkode på mottaker mangler');
        if (this.ContactCity() == undefined) errors.push('Poststed på mottaker mangler');
        if (this.items().length == 0) errors.push('Du må ha minst en faktura linje');

        if (errors.length > 0) {

            var error = '';
            $.each(errors, function (i, row) {
                error += '<li>' + row + '</li>';
            });

            $('#c_savedfakturas').hide();
            $('.errormessage').html('<ul>' + error + '</ul>');
            $('.errormessage').show();
            return false;
        }
        else {
            $('.errormessage').hide();
        }

        var webMethod = baseUrl + 'faktura/SaveFaktura';

        var faktura = new Object();
        faktura.ContactId = this.ContactId;
        faktura.ContactName = this.ContactName();
        faktura.ContactEmail = this.ContactEmail();
        faktura.ContactCurrencyCulture = this.ContactCurrencyCulture();
        faktura.ContactAddress = this.ContactAddress();
        faktura.ContactZip = this.ContactZip();
        faktura.ContactCity = this.ContactCity();
        faktura.ContactPerson = this.ContactPerson();
        faktura.ForfallsDato = this.forfallsdato();
        faktura.FakturaDato = this.fakturadato();
        faktura.DeresRef = this.deresref();
        faktura.VarRef = this.varref();
        faktura.OrdreRef = this.ordreref();
        faktura.FakturaLinjer = this.getLinjer();
        faktura.Message = this.message();
        faktura.ShowMessageOnPdf = this.addmessagetopdf();
        faktura.RememberMessage = this.remembermessage();
        faktura.FakturaId = fakturaId;

        var template = this.template();

        $.ajax({ type: "POST",
            url: webMethod,
            data: "{saveFakturaViewModel: " + JSON.stringify(faktura) + "}",
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function (msg) {
                if (preview) {
                    var controller = 'faktura/previewpdf/';

                    if (template == 2)
                        controller = 'invoice/preview/';
                    if (previewType != undefined) {
                        controller = 'faktura/previewkjopskontrakt/';
                    }

                    var pdfPreviewLink = baseUrl + controller + msg.DocumentGuid;

                    if (previewType != undefined) {
                        pdfPreviewLink += '?type=' + previewType;
                        $('#kjopekontraktlink').text('Forhåndsvis kjøpekontrakt');
                        $('#kjopekontraktlink').attr('href', pdfPreviewLink);
                    } else {
                        $('#previewlink').text('Forhåndsvis pdf');
                        $('#previewlink').attr('href', pdfPreviewLink);
                    }

                    window.open(pdfPreviewLink, '_blank');

                } else {
                    if (goNext)
                        location.href = baseUrl + 'faktura/send/?fakturaId=' + msg.FakturaId;
                    else {
                        location.href = baseUrl + 'faktura/create/' + msg.FakturaId;
                    }
                }
            },
            error: function (xhr, status, error) {
                // Boil the ASP.NET AJAX error down to JSON.
                var err = eval("(" + xhr.responseText + ")");

                // Display the specific error raised by the server (e.g. not a
                //   valid value for Int32, or attempted to divide by zero).
                alert(err.Message);
            }
        });
    };
};

var fakturaRow = function (vats, products, price, count, discount, vat, description, productnr) {

    this.description = ko.observable(description);
    this.productnr = ko.observable(productnr);
    this.product = ko.observable();
    this.price = ko.observable(price);
    this.count = ko.observable(count);
    this.discount = ko.observable(discount);
    this.vat = ko.observable(vat);
    this.updated = ko.observable(new Date());

    this.subtotal = ko.dependentObservable(function () {
        var o = this.updated();
        return this.price() * this.count() * (1.0 - (this.discount() / 100));
    } .bind(this));

    this.subtotalmva = ko.dependentObservable(function () {
        var o = this.updated();
        return this.price() * (this.count() * (1.0 - (this.discount() / 100)) * (1 + parseFloat(this.vat())));
    } .bind(this));

    this.vats = vats;
    this.products = products;
    // when product changes set the propriate values
    this.product.subscribe(function () {
        this.price(this.product().Price);
        this.description(this.product().Name);
        this.productnr(this.product().ProductNr);
        this.vat(this.product().Vat);
    } .bind(this));
};

function deleteFaktura(fakturaId) {
    $.getJSON(baseUrl + "faktura/DeleteFaktura/" + fakturaId, function (data) {
    });
}

function deleteCreditnote(id) {
    $.getJSON(baseUrl + "faktura/DeleteCreditnote/" + id, function (data) {
    });
}

function loadSavedFakturas() {
    $('#savedfakturatable').empty();
    $.ajaxSetup({ cache: false });
    $.getJSON(baseUrl + "faktura/GetSavedFakturas", function (data) {
        if (data.length > 0) {
            $('#c_savedfakturas').show();
            $.each(data, function (i, row) {
                $('#savedfakturatable').append('<tr><td>' + row.Til + '</td><td>' + new Date(parseInt(row.DateCreated.substr(6))).format("dd.mm.yyyy") + '</td><td>' + row.Total.toFixed(2) + '</td><td><a href="' + baseUrl + 'faktura/create/' + row.FakturaId + '">Fortsett med denne</a></td><td><a href="#" onclick="deleteFaktura(' + row.FakturaId + ');$(this).parent().parent().fadeOut(300, function(){ $(this).remove();});return false;">Slett</a></td></tr>');
            });
        }
    });
}

function loadSavedCreditnotes(fakturaId) {
    $('#savedfakturatable').empty();
    $.getJSON(baseUrl + "faktura/GetSavedCreditnotes/?fakturaId=" + fakturaId, function (data) {
        if (data.length > 0) {
            $('#c_savedfakturas').show();
            $.each(data, function (i, row) {
                $('#savedfakturatable').append('<tr><td>' + row.Til + '</td><td>' + new Date(parseInt(row.Date.substr(6))).format("dd.mm.yyyy") + '</td><td>' + row.Total.toFixed(2) + '</td><td><a href="' + baseUrl + 'faktura/createkreditnota/' + row.Id + '">Fortsett med denne</a></td><td><a href="#" onclick="deleteCreditnote(' + row.Id + ');$(this).parent().parent().fadeOut(300, function(){ $(this).remove();});return false;">Slett</a></td></tr>');
            });
        }
    });
}

function createDropDown(dropdown) {
    var selected = dropdown.find("option[selected]");
    var options = $("option", dropdown);

    $("body").append('<dl id="target" class="dropdown"></dl>');
    $("#target").append('<dt><a href="#">' + selected.text() +
            '<span class="value">' + selected.val() +
            '</span></a></dt>');
    $("#target").append('<dd><ul></ul></dd>');

    options.each(function () {
        $("#target dd ul").append('<li><a href="#">' +
                    $(this).text() + '<span class="value">' +
                    $(this).val() + '</span></a></li>');
    });

    $(".dropdown dt a").click(function () {
        $(".dropdown dd ul").toggle();
    });

    $(document).bind('click', function (e) {
        var $clicked = $(e.target);
        if (!$clicked.parents().hasClass("dropdown"))
            $(".dropdown dd ul").hide();
    });

    $(".dropdown dd ul li a").click(function () {
        var text = $(this).html();
        $(".dropdown dt a").html(text);
        $(".dropdown dd ul").hide();

        dropdown.val($(this).find("span.value").html());
    });
}

