/* testowe punkty "przegiecia" dla placy brutto w 2008:
        <= 427  zdrowotne = 0,    zaliczka = 0
   428  -  726  zdrowotne rosnie, zaliczka = 0
   727  -       placi sie zdrowotne i zaliczke
*/

function zarobki_getRentoweRatePracownik(year, month)
{
    if (year < 2007) return 0.065;
    if (year == 20076)
    {
        return 0.035;
    }
    if (year == 2007)
    {
        if (month <= 5) return 0.065;
        return 0.035;
    }
    if (year == 2008) return 0.015;
    if (year == 2009) return 0.015;    
    return -1; /* error */
}

function zarobki_getRentoweRatePracodawca(year, month)
{
    if (year <= 2007) return 0.065;
    if (year == 2008) return 0.045;
    if (year == 2009) return 0.045;    
    return -1; /* error */
}

function zarobki_getZdrowotneRate(year)
{
    if (year <= 2000) return 0.075;
    if (year <= 2002) return 0.0775;
    if (year == 2003) return 0.08;
    if (year == 2004) return 0.0825;
    if (year == 2005) return 0.085;
    if (year == 2006) return 0.0875;
    if (year == 2007) return 0.09;
    if (year == 2008) return 0.09;
    if (year == 2009) return 0.09;    
    return -1; /* error */
}

function zarobki_getFGSP(year)
{
    if (year <= 2002) return 0.0008;
    if (year <= 2005) return 0.0015;
    if (year <= 2009) return 0.001;
    return -1; /* error */
}

function zarobki_getBruttoMinimalne(year, month)
{
    if (year < 1999) return -1;
    if ((year == 1999) && (month < 10)) return 650;
    if ((year == 1999) || ((year == 2000) && (month < 2))) return 670;
    if (year == 2000) return 700;
    if (year <= 2002) return 760;
    if (year == 2003) return 800;
    if (year == 2004) return 824;
    if (year == 2005) return 849;
    if (year == 2006) return 899.10;
    if (year == 2007) return 936;
    if (year == 2008) return 1126;
    if (year == 2009) return 1276;    
    return -1;
}

function ZarobkiObject()
{
    /* globals */
        this.inYear = 2008;
        this.inConsiderIncomeAdvance = 0; /* czy uwzględniać kwote wolna od podatku i koszty (nie robi sie tego,
                                             gdy zatrudniony wiecej niz w jednym miejscu, ma nagrody, inne wplywy itp.) */
        this.inMarriedTax            = 0; /* czy rozlicza się wspólnie z małżonkiem ? */
        this.inProfitCorrectionOn    = 0; /* czy liczymy kwote zmniejszajaca podatek co miesiac (tylko na etacie?) */

    /* koszty uzyskania przychodu */
        this.inStandardWorkCost      = 0; /* etat: czy zwykłe koszty uzyskania przychodu */
        this.inIncreasedWorkCost     = 0; /* etat: czy podwyższone koszty uzyskania przychodu (dojazd z innej miejscowości) */

        this.inAuthorWorkCost        = 0; /* umowa o dzielo, umowa zlecenie: czy autorskie koszty uzyskania przychodu */
        this.inPercentWorkCost       = 0; /* umowa o dzielo, umowa zlecenie: koszty uzyskania przychodu */

    /* ubezpieczenia */
        this.inZUS_pracownikEROn     = 0; /* czy liczyc skladki ZUS na emeryture-rente placone przez pracownika */
        this.inZUS_pracodawcaZUSOn   = 0; /* czy liczyc skladki ZUS na emeryture-rente placone przez pracodawce */
        this.inZUS_wypadkoweOn       = 0; /* czy liczyc ubezpieczenie wypadkowe */
        this.inZUS_wypadkowePercent  = 0.018; /* stawka ubezpieczenia wypadkowego - default: 1.8 % */
        this.inZUS_choroboweOn       = 0; /* ubezpieczenie chorobowe */
        this.inZUS_zdrowotneOn       = 0; /* ubezpieczenie zdrowotne */

    /* placa */
        this.inPAY_netto             = new Array();
        this.inPAY_brutto            = new Array();
        this.outPracownikEmerytalne  = new Array();
        this.outPracownikRentowe     = new Array();
        this.outPracownikChorobowe   = new Array();
        this.outPracownikZUS         = new Array();
        this.outPracownikZdrowotne   = new Array();
        this.outPracownikZdrowotneDoOdliczenia = new Array();
        this.outZaliczka             = new Array();
        this.outNetto                = new Array();

        this.outPracodawcaEmerytalne = new Array();
        this.outPracodawcaRentowe    = new Array();
        this.outPracodawcaWypadkowe  = new Array();
        this.outPracodawcaZUS        = new Array();
        this.outPracodawcaPracy      = new Array();
        this.outPracodawcaFGSP       = new Array();
        this.outPracodawcaFundusze   = new Array();

        this.outAll                  = new Array();

        var monthIdx = 0;
        for (monthIdx = 0; monthIdx < 12; monthIdx++)
        {
            this.inPAY_brutto[monthIdx]            = 0;
            this.inPAY_netto[monthIdx]             = 0;
            this.outPracownikEmerytalne[monthIdx]  = 0;
            this.outPracownikRentowe[monthIdx]     = 0;
            this.outPracownikChorobowe[monthIdx]   = 0;
            this.outPracownikZUS[monthIdx]         = 0;
            this.outPracownikZdrowotne[monthIdx]   = 0;
            this.outPracownikZdrowotneDoOdliczenia[monthIdx] = 0;
            this.outZaliczka[monthIdx]             = 0;
            this.outNetto[monthIdx]                = 0;

            this.outPracodawcaEmerytalne[monthIdx] = 0;
            this.outPracodawcaRentowe[monthIdx]    = 0;
            this.outPracodawcaWypadkowe[monthIdx]  = 0;
            this.outPracodawcaZUS[monthIdx]        = 0;
            this.outPracodawcaPracy[monthIdx]      = 0;
            this.outPracodawcaFGSP[monthIdx]       = 0;
            this.outPracodawcaFundusze[monthIdx]   = 0;

            this.outAll[monthIdx]                  = 0;
        }
}

function ZAROBKI_getTaxFromSkala(podatekYearObj, taxAcc, profit, correctionsOn)
{
    var skalaPointIdx = 0;
    for (var i = 0; i < podatekYearObj.skala.length; i++)
    {
        if (taxAcc >= podatekYearObj.skala[i].base)
        {
            skalaPointIdx = i;
        }
    }

    var correction = (correctionsOn) ? MONEY_roundToGroszy(podatekYearObj.skala[0].correction/12) : 0;

    return MONEY_roundToGroszy(profit * podatekYearObj.skala[skalaPointIdx].rate * 0.01)
        + correction;
}

function zarobki_process()
{
    var taxBaseAcc      = 0;
    var zusPodstawaAcc  = 0;
    var marriageDivider = this.inMarriedTax ? 2 : 1;
    var taxYear = (this.inYear == 20076) ? 2007 : (this.inYear);
    var podatekConsts = PODATEK.year[taxYear - PODATEK.yearStart];

    for (monthIdx = 0; monthIdx < 12; monthIdx++)
    {
        var brutto           = this.inPAY_brutto[monthIdx];
        var zusPodstawaMonth = brutto;

        /* korekta ZUS jesli przekracza roczna podstawe wymiaru */
        if (zusPodstawaAcc + zusPodstawaMonth > podatekConsts.ZUS_baseMax)
        {
            zusPodstawaMonth = podatekConsts.ZUS_baseMax - zusPodstawaAcc;
        }
        zusPodstawaAcc = zusPodstawaAcc + zusPodstawaMonth;

        /* licz emerytury, renty - zalezne od ograniczonej podstawy */
        if (this.inZUS_pracownikEROn)
        {
            this.outPracownikEmerytalne[monthIdx] = MONEY_roundToGroszy(zusPodstawaMonth * 0.0976);
            this.outPracownikRentowe[monthIdx]    = MONEY_roundToGroszy(zusPodstawaMonth * zarobki_getRentoweRatePracownik(this.inYear, monthIdx));
        }
        else
        {
            this.outPracownikEmerytalne[monthIdx] = 0;
            this.outPracownikRentowe[monthIdx]    = 0;
        }

        /* licz chorobowe - zalezne od rzeczywistej podstawy */
        if (this.inZUS_choroboweOn)
        {
            this.outPracownikChorobowe[monthIdx]  = MONEY_roundToGroszy(brutto * 0.0245);
        }
        else
        {
            this.outPracownikChorobowe[monthIdx]  = 0;
        }

        /* podstawa bez ZUS */
        this.outPracownikZUS[monthIdx]  = MONEY_roundToGroszy(this.outPracownikEmerytalne[monthIdx] + this.outPracownikRentowe[monthIdx] + this.outPracownikChorobowe[monthIdx]);
        var bruttoNoZUS = MONEY_roundToGroszy(brutto - this.outPracownikZUS[monthIdx], 2);

        /* koszty */
        var kosztyMonth = 0;
        if (this.inStandardWorkCost)
        {
            kosztyMonth = podatekConsts.cost.homeOneJob;
        }
        if (this.inIncreasedWorkCost)
        {
            kosztyMonth = podatekConsts.cost.awayOneJob;
        }
        if ((this.inStandardWorkCost) && (this.inIncreasedWorkCost))
        {
            kosztyMonth = -999999;
        }

        /* liczymy podatek, korygujemy zdrowotne */
        var zdrowotne     = 0;
        var netto         = 0;
        var zaliczka      = 0;
        var zdrowotneDoOdliczenia = 0;
        var zdrowotneFull = 0;
        var taxBase       = bruttoNoZUS - kosztyMonth - MONEY_roundToGroszy(bruttoNoZUS * this.inPercentWorkCost * 0.01);
        var taxValue      = ZAROBKI_getTaxFromSkala(
            podatekConsts,
            taxBaseAcc/marriageDivider,
            taxBase,
            this.inProfitCorrectionOn);

        if (taxValue <= 0)
        {
            netto    = bruttoNoZUS;
            taxValue = 0;
        }
        else
        {
            var zdrowotneDoOdliczenia = (this.inZUS_zdrowotneOn) ? MONEY_roundToGroszy(bruttoNoZUS * 0.0775) : 0;

            if (zdrowotneDoOdliczenia > taxValue)
            {
                /* zdrowotne przekracza zaliczke - korekta */
                zdrowotneFull         = (this.inZUS_zdrowotneOn) ? taxValue : 0;
                zaliczka              = 0;
                zdrowotneDoOdliczenia = taxValue;
            }
            else
            {
                /* zdrowotne nie przekracza zaliczki, liczymy rozklad miedzy zaliczka, a obciazeniem netto */
                zdrowotneFull = (this.inZUS_zdrowotneOn) ? MONEY_roundToGroszy(bruttoNoZUS * zarobki_getZdrowotneRate(taxYear)) : 0;
                zaliczka      = MONEY_roundToZloty(taxValue - zdrowotneDoOdliczenia);
            }

            netto      = bruttoNoZUS - zdrowotneFull - zaliczka;
            taxBaseAcc = taxBaseAcc + taxBase;
        }

        this.outPracownikZdrowotneDoOdliczenia[monthIdx] = MONEY_roundToGroszy(zdrowotneDoOdliczenia);
        this.outPracownikZdrowotne[monthIdx]             = MONEY_roundToGroszy(zdrowotneFull);
        this.outZaliczka[monthIdx]                       = MONEY_roundToGroszy(zaliczka);
        this.outNetto[monthIdx]                          = MONEY_roundToGroszy(netto);

        /* koszty pracodawcy */
        this.outPracodawcaWypadkowe[monthIdx]  = this.inZUS_wypadkoweOn ? (MONEY_roundToGroszy(brutto * this.inZUS_wypadkowePercent)) : (0);
        if (this.inZUS_pracodawcaZUSOn)
        {
            this.outPracodawcaEmerytalne[monthIdx] = MONEY_roundToGroszy(zusPodstawaMonth * 0.0976);
            this.outPracodawcaRentowe[monthIdx]    = MONEY_roundToGroszy(zusPodstawaMonth * zarobki_getRentoweRatePracodawca(taxYear, monthIdx))
            this.outPracodawcaPracy[monthIdx]      = (brutto >= zarobki_getBruttoMinimalne(taxYear, monthIdx)) ? MONEY_roundToGroszy(brutto * 0.0245) : 0;
            this.outPracodawcaFGSP[monthIdx]       = MONEY_roundToGroszy(brutto * zarobki_getFGSP(taxYear));
        }
        else
        {
            this.outPracodawcaEmerytalne[monthIdx] = 0;
            this.outPracodawcaRentowe[monthIdx]    = 0;
            this.outPracodawcaPracy[monthIdx]      = 0;
            this.outPracodawcaFGSP[monthIdx]       = 0;
        }

        this.outPracodawcaZUS[monthIdx]        = MONEY_roundToGroszy(
            this.outPracodawcaEmerytalne[monthIdx] + this.outPracodawcaRentowe[monthIdx]
            + this.outPracodawcaWypadkowe[monthIdx]);
        this.outPracodawcaFundusze[monthIdx]   = MONEY_roundToGroszy(this.outPracodawcaPracy[monthIdx] + this.outPracodawcaFGSP[monthIdx]);

        /* suma */
        this.outAll[monthIdx] = MONEY_roundToGroszy(brutto + this.outPracodawcaZUS[monthIdx] + this.outPracodawcaFundusze[monthIdx]);
    }
}

function zarobki_getDebugString()
{
    var dbg = '<br/><br/>debugs START<br/>'
        + '<br/>'
        + 'year:' + this.inYear + '<br/>'
        + 'married:' + this.inMarriedTax + '<br/>'
        + 'considerIncomeAdvance:' + this.inConsiderIncomeAdvance + '<br/>'
        + '<br/>'
        + 'inStandardWorkCost:' + this.inStandardWorkCost + '<br/>'
        + 'inIncreasedWorkCost:' + this.inIncreasedWorkCost + '<br/>'
        + 'inAuthorWorkCost:' + this.inAuthorWorkCost + '<br/>'
        + 'inPercentWorkCost:' + this.inPercentWorkCost + '<br/>'
        + '<br/>'
        + 'inZUS_pracownikEROn:' + this.inZUS_pracownikEROn + '<br/>'
        + 'inZUS_pracodawcaZUSOn:' + this.inZUS_pracodawcaZUSOn + '<br/>'
        + 'inZUS_wypadkoweOn:' + this.inZUS_wypadkoweOn + '<br/>'
        + 'inZUS_wypadkowePercent:' + this.inZUS_wypadkowePercent + '<br/>'
        + 'inZUS_choroboweOn:' + this.inZUS_choroboweOn + '<br/>'
        + 'inZUS_zdrowotneOn:' + this.inZUS_zdrowotneOn + '<br/>'
        + '<br/>'
        + 'debugs END<br/><br/>';
        //+ PODATEK.years[0];

    return dbg;
}

ZarobkiObject.prototype.getDebugString = zarobki_getDebugString;
ZarobkiObject.prototype.process        = zarobki_process;


