text:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package erp.mod.hrs.db;

import erp.mod.SModConsts;
import erp.mod.SModSysConsts;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.HashSet;
import sa.lib.SLibTimeUtils;
import sa.lib.SLibUtils;
import sa.lib.db.SDbRegistry;

/**
 *
 * @author Juan Barajas, Néstor Ávalos, Edwin Carmona, Sergio Flores
 */
public class SHrsPayroll {

    protected SHrsPayrollDataProvider moHrsPayrollDataProvider;
    protected SDbConfig moConfig;
    protected SDbWorkingDaySettings moWorkingDaySettings;
    protected SDbPayroll moPayroll;

    protected ArrayList<SDbLoanTypeAdjustment> maLoanTypeAdjustments;
    protected ArrayList<SDbUma> maUmas;
    protected ArrayList<SDbUmi> maUmis;
    protected ArrayList<SDbHoliday> maHolidays;
    protected ArrayList<SDbTaxTable> maTaxTables;
    protected ArrayList<SDbTaxSubsidyTable> maTaxSubsidyTables;
    protected ArrayList<SDbSsContributionTable> maSsContributionTables;
    protected ArrayList<SDbBenefitTable> maBenefitTables;
    protected ArrayList<SHrsBenefitTableAnniversary> maBenefitTablesAnniversarys;
    protected ArrayList<SDbMwzTypeWage> maMwzTypeWages;
    protected ArrayList<SDbEarning> maEarnigs;
    protected ArrayList<SDbDeduction> maDeductions;
    protected ArrayList<SDbAutomaticEarning> maAutomaticEarnings;
    protected ArrayList<SDbAutomaticDeduction> maAutomaticDeductions;
    protected ArrayList<SDbEmployee> maEmployees;
    protected ArrayList<SHrsReceipt> maHrsReceipts;
    protected HashMap<Integer, String> moEarningComputationTypesMap;
    protected HashMap<Integer, String> moDeductionComputationTypesMap;

    public SHrsPayroll(SHrsPayrollDataProvider dataProvider, SDbConfig config, SDbWorkingDaySettings workingDaySettings, SDbPayroll payroll) {
        moHrsPayrollDataProvider = dataProvider;
        moConfig = config;
        moWorkingDaySettings = workingDaySettings;
        moPayroll = payroll;

        maLoanTypeAdjustments = new ArrayList<>();
        maUmas = new ArrayList<>();
        maUmis = new ArrayList<>();
        maHolidays = new ArrayList<>();
        maTaxTables = new ArrayList<>();
        maTaxSubsidyTables = new ArrayList<>();
        maSsContributionTables = new ArrayList<>();
        maBenefitTables = new ArrayList<>();
        maBenefitTablesAnniversarys = new ArrayList<>();
        maMwzTypeWages = new ArrayList<>();
        maEarnigs = new ArrayList<>();
        maDeductions = new ArrayList<>();
        maAutomaticEarnings = new ArrayList<>();
        maAutomaticDeductions = new ArrayList<>();
        maEmployees = new ArrayList<>();
        maHrsReceipts = new ArrayList<>();
        moEarningComputationTypesMap = new HashMap<>();
        moDeductionComputationTypesMap = new HashMap<>();
    }

    /*
     * Private methods:
     */

    private ArrayList<SDbAutomaticEarning> getAutomaticEarnings(final int employeeId, final int paysheetType, final Date dateStart, final Date dateEnd) {
        ArrayList<SDbAutomaticEarning> automaticEarnings = new ArrayList<>();

        for (SDbAutomaticEarning automaticEarning : maAutomaticEarnings) {
            if ((automaticEarning.getFkEmployeeId_n() == employeeId || automaticEarning.getFkEmployeeId_n() == 0) && automaticEarning.getFkPaysheetTypeId() == paysheetType &&
                    SLibTimeUtils.isBelongingToPeriod(automaticEarning.getDateStart(), automaticEarning.getDateEnd_n(), dateStart, dateEnd)) {
                automaticEarnings.add(automaticEarning);
            }
        }

        return automaticEarnings;
    }

    private ArrayList<SDbAutomaticDeduction> getAutomaticDeductions(final int employeeId, final int paysheetType, final Date dateStart, final Date dateEnd) {
        ArrayList<SDbAutomaticDeduction> aAutomaticDeductions = new ArrayList<>();

        for (SDbAutomaticDeduction automaticDeduction : maAutomaticDeductions) {
            if ((automaticDeduction.getFkEmployeeId_n() == employeeId || automaticDeduction.getFkEmployeeId_n() == 0) && automaticDeduction.getFkPaysheetTypeId() == paysheetType &&
                    SLibTimeUtils.isBelongingToPeriod(automaticDeduction.getDateStart(), automaticDeduction.getDateEnd_n(), dateStart, dateEnd)) {
                aAutomaticDeductions.add(automaticDeduction);
            }
        }

        return aAutomaticDeductions;
    }

    public SDbPayrollReceiptEarning createPayrollReceiptEarning(final SHrsReceipt hrsReceipt, final SDbEarning earning, final SHrsEmployeeDays hrsEmployeeDays, final SHrsBenefitBase hrsBenefitBase,
            final double unitsAlleged, final double amountUnitAlleged, final boolean isAutomatic, final int loanEmployeeId_n, final int loanLoanId_n, final int moveId) {
        double amountUnit = 0;

        switch (earning.getFkEarningComputationTypeId()) {
            case SModSysConsts.HRSS_TP_EAR_COMP_AMT:
                amountUnit = amountUnitAlleged;
                break;
            case SModSysConsts.HRSS_TP_EAR_COMP_DAYS:
                amountUnit = hrsReceipt.getPayrollReceipt().getPaymentDaily();
                break;
            case SModSysConsts.HRSS_TP_EAR_COMP_HRS:
                amountUnit = hrsReceipt.getPayrollReceipt().getPaymentHourly();
                break;
            case SModSysConsts.HRSS_TP_EAR_COMP_PCT_DAY:
                amountUnit = hrsReceipt.getPayrollReceipt().getPaymentDaily() * earning.getPayPercentage();
                break;
            case SModSysConsts.HRSS_TP_EAR_COMP_PCT_HR:
                amountUnit = hrsReceipt.getPayrollReceipt().getPaymentHourly() * earning.getPayPercentage();
                break;
            case SModSysConsts.HRSS_TP_EAR_COMP_PCT_INCOME:
                amountUnit = hrsReceipt.getTotalEarningsDependentsDaysWorked();
                break;
            default:
        }

        double units = hrsEmployeeDays.computeEarningUnits(unitsAlleged, earning);
        double amount = SHrsEmployeeDays.computeEarningAmount(units, amountUnit, earning);

        SDbPayrollReceiptEarning payrollReceiptEarning = new SDbPayrollReceiptEarning();

        payrollReceiptEarning.setPkPayrollId(hrsReceipt.getPayrollReceipt().getPkPayrollId());
        payrollReceiptEarning.setPkEmployeeId(hrsReceipt.getHrsEmployee().getEmployee().getPkEmployeeId());
        payrollReceiptEarning.setPkMoveId(moveId);
        payrollReceiptEarning.setUnitsAlleged(unitsAlleged);
        payrollReceiptEarning.setUnits(units);

        payrollReceiptEarning.setAmountUnitary(amountUnit);
        payrollReceiptEarning.setAmountSystem_r(amount);
        payrollReceiptEarning.setAmount_r(amount);
        //payrollReceiptEarning.setAmountExempt(...);
        //payrollReceiptEarning.setAmountTaxable(...);
        //payrollReceiptEarning.setAuxiliarAmount(...);

        if (hrsBenefitBase == null) {
            payrollReceiptEarning.setFactorAmount(earning.getUnitsFactor());
            //...
            payrollReceiptEarning.setBenefitYear(0);
            payrollReceiptEarning.setBenefitAnniversary(0);
            //...
            payrollReceiptEarning.setFkBenefitTypeId(earning.getFkBenefitTypeId());
        }
        else {
            payrollReceiptEarning.setFactorAmount(hrsBenefitBase.getFactorAmount());
            //...
            payrollReceiptEarning.setBenefitYear(hrsBenefitBase.getBenefitYear());
            payrollReceiptEarning.setBenefitAnniversary(hrsBenefitBase.getBenefitAnn());
            //...
            payrollReceiptEarning.setFkBenefitTypeId(hrsBenefitBase.getBenefitTypeId());
        }

        payrollReceiptEarning.setAlternativeTaxCalculation(earning.isAlternativeTaxCalculation());
        payrollReceiptEarning.setUserEdited(false);
        payrollReceiptEarning.setAutomatic(isAutomatic);
        /*
        payrollReceiptEarning.setDeleted(...);
        payrollReceiptEarning.setSystem(...);
        */
        payrollReceiptEarning.setFkEarningTypeId(earning.getFkEarningTypeId());
        payrollReceiptEarning.setFkEarningId(earning.getPkEarningId());
        payrollReceiptEarning.setFkBonusId(SModSysConsts.HRSS_BONUS_NA);
        payrollReceiptEarning.setFkLoanEmployeeId_n(loanEmployeeId_n);
        payrollReceiptEarning.setFkLoanLoanId_n(loanLoanId_n);
        payrollReceiptEarning.setFkLoanTypeId_n(loanEmployeeId_n != 0 && loanLoanId_n != 0 ? earning.getFkLoanTypeId() : 0);
        payrollReceiptEarning.setFkOtherPaymentTypeId(earning.getFkOtherPaymentTypeId());
        /*
        payrollReceiptEarning.setFkUserInsertId(...);
        payrollReceiptEarning.setFkUserUpdateId(...);
        payrollReceiptEarning.setTsUserInsert(...);
        payrollReceiptEarning.setTsUserUpdate(...);
        */

        return payrollReceiptEarning;
    }

    public SDbPayrollReceiptDeduction createPayrollReceiptDeduction(final SHrsReceipt hrsReceipt, final SDbDeduction deduction,
            final double unitsAlleged, final double amountUnitAlleged, final boolean isAutomatic, final int loanEmployeeId_n, final int loanLoanId_n, final int moveId) {
        double units = 0;
        double amountUnit = 0;

        switch (deduction.getFkDeductionComputationTypeId()) {
            case SModSysConsts.HRSS_TP_DED_COMP_AMT:
                units = 1;
                amountUnit = amountUnitAlleged;
                break;
            case SModSysConsts.HRSS_TP_DED_COMP_PCT_INCOME:
                units = unitsAlleged;
                amountUnit = hrsReceipt.getTotalEarningsDependentsDaysWorked();
                break;
            default:
        }

        double amount = SLibUtils.roundAmount(amountUnit * units);

        SDbPayrollReceiptDeduction payrollReceiptDeduction = new SDbPayrollReceiptDeduction();

        payrollReceiptDeduction.setPkPayrollId(hrsReceipt.getPayrollReceipt().getPkPayrollId());
        payrollReceiptDeduction.setPkEmployeeId(hrsReceipt.getHrsEmployee().getEmployee().getPkEmployeeId());
        payrollReceiptDeduction.setPkMoveId(moveId);
        payrollReceiptDeduction.setUnitsAlleged(unitsAlleged);
        payrollReceiptDeduction.setUnits(units);
        payrollReceiptDeduction.setFactorAmount(1);
        payrollReceiptDeduction.setAmountUnitary(amountUnit);
        payrollReceiptDeduction.setAmountSystem_r(amount);
        payrollReceiptDeduction.setAmount_r(amount);
        /*
        payrollReceiptDeduction.setBenefitYear(...);
        payrollReceiptDeduction.setBenefitAnniversary(...);
        payrollReceiptDeduction.setUserEdited(...);
        */
        payrollReceiptDeduction.setAutomatic(isAutomatic);
        /*
        payrollReceiptDeduction.setDeleted(...);
        payrollReceiptDeduction.setSystem(...);
        */
        payrollReceiptDeduction.setFkDeductionTypeId(deduction.getFkDeductionTypeId());
        payrollReceiptDeduction.setFkDeductionId(deduction.getPkDeductionId());
        payrollReceiptDeduction.setFkBonusId(SModSysConsts.HRSS_BONUS_NA);
        payrollReceiptDeduction.setFkBenefitTypeId(deduction.getFkBenefitTypeId());
        payrollReceiptDeduction.setFkLoanEmployeeId_n(loanEmployeeId_n);
        payrollReceiptDeduction.setFkLoanLoanId_n(loanLoanId_n);
        payrollReceiptDeduction.setFkLoanTypeId_n(loanEmployeeId_n != 0 && loanLoanId_n != 0 ? deduction.getFkLoanTypeId() : 0);
        payrollReceiptDeduction.setFkBonusId(1);
        /*
        payrollReceiptDeduction.setFkUserInsertId(...);
        payrollReceiptDeduction.setFkUserUpdateId(...);
        payrollReceiptDeduction.setTsUserInsert(...);
        payrollReceiptDeduction.setTsUserUpdate(...);
        */

        return payrollReceiptDeduction;
    }

    public ArrayList<SHrsReceiptEarning> createHrsReceiptEarnings(final SHrsReceipt hrsReceipt, final Date dateStart, final Date dateEnd) throws Exception {
        int moveId = 0;
        SDbEmployee employee = hrsReceipt.getHrsEmployee().getEmployee();
        ArrayList<SHrsReceiptEarning> hrsReceiptEarnings = new ArrayList<>();

        // prepare employee days:

        SHrsEmployeeDays hrsEmployeeDays = hrsReceipt.getHrsEmployee().createEmployeeDays();

        // add automatic earnings:

        HashSet<Integer> processedEarnings = new HashSet<>();
        ArrayList<SDbAutomaticEarning> automaticEarnings = getAutomaticEarnings(employee.getPkEmployeeId(), moPayroll.getFkPaysheetTypeId(), dateStart, dateEnd);

        for (SDbAutomaticEarning automaticEarning : automaticEarnings) {
            SDbEarning earning = getEarning(automaticEarning.getPkEarningId());

            if (earning != null && (earning.isLoan() || !processedEarnings.contains(earning.getPkEarningId()))) { // loan earnings only at employee level
                SDbPayrollReceiptEarning payrollReceiptEarning = createPayrollReceiptEarning(
                        hrsReceipt, earning, hrsEmployeeDays, null,
                        automaticEarning.getUnits(), automaticEarning.getAmountUnitary(), true,
                        automaticEarning.getFkLoanEmployeeId_n(), automaticEarning.getFkLoanLoanId_n(), ++moveId);

                SHrsReceiptEarning hrsReceiptEarning = new SHrsReceiptEarning();
                hrsReceiptEarning.setHrsReceipt(hrsReceipt);
                hrsReceiptEarning.setEarning(earning);
                hrsReceiptEarning.setPayrollReceiptEarning(payrollReceiptEarning);

                hrsReceiptEarnings.add(hrsReceiptEarning);
                processedEarnings.add(earning.getPkEarningId()); // prevent from adding same earning twice (except for loan ones)
            }
        }

        if (moPayroll.isPayrollNormal()) {
            // add wages and salaries:

            if (hrsEmployeeDays.getDaysWorked() > 0) {
                SDbEarning earning = getEarning(moConfig.getFkEarningEarningId_n());

                SDbPayrollReceiptEarning payrollReceiptEarning = createPayrollReceiptEarning(
                        hrsReceipt, earning, hrsEmployeeDays, null,
                        hrsEmployeeDays.getDaysWorked(), 0, true,
                        0, 0, ++moveId);

                SHrsReceiptEarning hrsReceiptEarning = new SHrsReceiptEarning();
                hrsReceiptEarning.setHrsReceipt(hrsReceipt);
                hrsReceiptEarning.setEarning(earning);
                hrsReceiptEarning.setPayrollReceiptEarning(payrollReceiptEarning);

                hrsReceiptEarnings.add(hrsReceiptEarning);
            }

            // add absences, including vacation:
            for (SHrsReceiptEarning hrsReceiptEarning : createHrsReceiptEarningsAbsence(hrsReceipt, hrsEmployeeDays)) {
                hrsReceiptEarnings.add(hrsReceiptEarning);
            }

            // add automatic vacation bonus, if required:
            if (moConfig.isAutoVacationBonus() && SHrsUtils.isAnniversaryBelongingToPeriod(employee.getDateBenefits(), dateStart, dateEnd)) {
                Date dateCutOff;

                if (!employee.isActive()) {
                    dateCutOff = employee.getDateLastDismissal_n();

                    if (!SLibTimeUtils.isBelongingToPeriod(dateCutOff, dateStart, dateEnd)) {
                        dateCutOff = dateEnd;
                    }
                }
                else {
                    dateCutOff = dateEnd;
                }

                SDbEarning earning = getEarningByType(SModSysConsts.HRSS_TP_EAR_VAC_BONUS);
                SDbBenefitTable dbBenefitTableVacBon = getBenefitTable(SModSysConsts.HRSS_TP_BEN_VAC_BON, dateEnd, moPayroll.getFkPaymentTypeId());
                SDbBenefitTable deBenefitTableVac = getBenefitTable(SModSysConsts.HRSS_TP_BEN_VAC, dateEnd, moPayroll.getFkPaymentTypeId());
                ArrayList<SHrsBenefitTableAnniversary> hrsBenefitTableAnniversarysVacBon = getBenefitTableAnniversary(dbBenefitTableVacBon.getPkBenefitId());
                ArrayList<SHrsBenefitTableAnniversary> hrsBenefitTableAnniversarysVac = getBenefitTableAnniversary(deBenefitTableVac.getPkBenefitId());
                SHrsBenefitTableAnniversary hrsBenefitTableAnniversaryVacBon = null;
                SHrsBenefitTableAnniversary hrsBenefitTableAnniversaryVac = null;
                int benefitAnniv = SHrsUtils.getEmployeeSeniority(employee.getDateBenefits(), dateCutOff);
                int benefitYear = SLibTimeUtils.digestDate(dateCutOff)[0] - 1;

                for (SHrsBenefitTableAnniversary anniversary : hrsBenefitTableAnniversarysVacBon) {
                    if (anniversary.getBenefitAnn() <= benefitAnniv) {
                        hrsBenefitTableAnniversaryVacBon = anniversary;
                    }
                    else {
                        break;
                    }
                }

                for (SHrsBenefitTableAnniversary anniversary : hrsBenefitTableAnniversarysVac) {
                    if (anniversary.getBenefitAnn() <= benefitAnniv) {
                        hrsBenefitTableAnniversaryVac = anniversary;
                    }
                    else {
                        break;
                    }
                }

                double days = hrsBenefitTableAnniversaryVac == null ? 0d : hrsBenefitTableAnniversaryVac.getValue();
                double perc = hrsBenefitTableAnniversaryVacBon == null ? 1d : hrsBenefitTableAnniversaryVacBon.getValue();
                double benefit = hrsReceipt.calculateBenefit(earning, hrsEmployeeDays, days, perc);

                ArrayList<SHrsBenefit> hrsBenefits = SHrsUtils.readHrsBenefits(moHrsPayrollDataProvider.getSession(), employee, SModSysConsts.HRSS_TP_BEN_VAC_BON, benefitAnniv, benefitYear, moPayroll.getPkPayrollId(), hrsBenefitTableAnniversarysVacBon, hrsBenefitTableAnniversarysVac, hrsReceipt.getPayrollReceipt().getPaymentDaily());

                double daysPayed = 0;
                double benefitPayed = 0;

                for (SHrsBenefit hrsBenefit : hrsBenefits) {
                    if (SLibUtils.compareKeys(hrsBenefit.getBenefitKey(), new int[] { SModSysConsts.HRSS_TP_BEN_VAC_BON, benefitAnniv, benefitYear })) {
                        daysPayed = hrsBenefit.getValuePayed();
                        benefitPayed = hrsBenefit.getAmountPayed();
                        break;
                    }
                }

                if (days > daysPayed || benefit > benefitPayed) {
                    double daysToPay;
                    double benefitToPay;
                    SHrsBenefitBase hrsBenefitBase = new SHrsBenefitBase(SModSysConsts.HRSS_TP_BEN_VAC_BON, benefitAnniv, benefitYear, perc);

                    if (earning.isBasedOnUnits()) {
                        daysToPay = SLibUtils.round(days <= daysPayed ? 0d : days - daysPayed, SLibUtils.DecimalFormatPercentage8D.getMaximumFractionDigits());
                        benefitToPay = 0;
                    }
                    else {
                        daysToPay = 1;
                        benefitToPay = SLibUtils.roundAmount(benefit <= benefitPayed ? 0d : benefit - benefitPayed);
                    }

                    SDbPayrollReceiptEarning payrollReceiptEarning = createPayrollReceiptEarning(
                            hrsReceipt, earning, hrsEmployeeDays, hrsBenefitBase,
                            daysToPay, benefitToPay, true,
                            0, 0, ++moveId);

                    SHrsReceiptEarning hrsReceiptEarning = new SHrsReceiptEarning();
                    hrsReceiptEarning.setHrsReceipt(hrsReceipt);
                    hrsReceiptEarning.setEarning(earning);
                    hrsReceiptEarning.setPayrollReceiptEarning(payrollReceiptEarning);

                    hrsReceiptEarnings.add(hrsReceiptEarning);
                }
            }
        }

        return hrsReceiptEarnings;
    }

    public ArrayList<SHrsReceiptDeduction> createHrsReceiptDeductions(final SHrsReceipt hrsReceipt, final Date dateStart, final Date dateEnd) throws Exception {
        int moveId = 0;
        SDbEmployee employee = hrsReceipt.getHrsEmployee().getEmployee();
        ArrayList<SHrsReceiptDeduction> hrsReceiptDeductions = new ArrayList<>();

        if (moPayroll.isPayrollNormal()) {
            // Get deductions that are withholding ones (deductions by law):

            for (SDbDeduction deduction : maDeductions) {
                if (deduction.isWithholding()) {
                    // check if current deduction matches configuration settings:

                    boolean matchesConfig = false;

                    switch (deduction.getFkDeductionTypeId()) {
                        case SModSysConsts.HRSS_TP_DED_TAX:
                            matchesConfig = deduction.getPkDeductionId() == moConfig.getFkDeductionTaxId_n();
                            break;
                        case SModSysConsts.HRSS_TP_DED_SSC:
                            matchesConfig = deduction.getPkDeductionId() == moConfig.getFkDeductionSsContributionId_n();
                            break;
                        default:
                            // to nothing
                    }

                    if (matchesConfig) {
                        SDbPayrollReceiptDeduction payrollReceiptDeduction = createPayrollReceiptDeduction(
                                hrsReceipt, deduction,
                                1, 0, true,
                                0, 0, ++moveId);

                        SHrsReceiptDeduction hrsReceiptDeduction = new SHrsReceiptDeduction();
                        hrsReceiptDeduction.setHrsReceipt(hrsReceipt);
                        hrsReceiptDeduction.setDeduction(deduction);
                        hrsReceiptDeduction.setPayrollReceiptDeduction(payrollReceiptDeduction);

                        hrsReceiptDeductions.add(hrsReceiptDeduction);
                    }
                }
            }
        }

        // Get automatic deductions:

        HashSet<Integer> processedDeductions = new HashSet<>();
        ArrayList<SDbAutomaticDeduction> automaticDeductions = getAutomaticDeductions(employee.getPkEmployeeId(), moPayroll.getFkPaysheetTypeId(), dateStart, dateEnd);

        for (SDbAutomaticDeduction automaticDeduction : automaticDeductions) {
            SDbDeduction deduction = getDeduction(automaticDeduction.getPkDeductionId());

            if (deduction != null && (deduction.isLoan() || !processedDeductions.contains(deduction.getPkDeductionId()))) { // loan deductions only at employee level
                SDbPayrollReceiptDeduction payrollReceiptDeduction = createPayrollReceiptDeduction(
                        hrsReceipt, deduction,
                        automaticDeduction.getUnits(), automaticDeduction.getAmountUnitary(), true,
                        automaticDeduction.getFkLoanEmployeeId_n(), automaticDeduction.getFkLoanLoanId_n(), ++moveId);

                SHrsReceiptDeduction hrsReceiptDeduction = new SHrsReceiptDeduction();
                hrsReceiptDeduction.setHrsReceipt(hrsReceipt);
                hrsReceiptDeduction.setDeduction(deduction);
                hrsReceiptDeduction.setPayrollReceiptDeduction(payrollReceiptDeduction);

                hrsReceiptDeductions.add(hrsReceiptDeduction);
                processedDeductions.add(deduction.getPkDeductionId()); // prevent from adding same deduction twice (except for loan ones)
            }
        }

        if (moPayroll.isPayrollNormal()) {
            hrsReceipt.computePayrollReceiptDays();

            // Get employee loans:

            for (SDbLoan loan : hrsReceipt.getHrsEmployee().getLoans()) {
                if (SLibTimeUtils.isBelongingToPeriod(loan.getDateStart(), loan.getDateEnd_n() == null ? dateEnd : loan.getDateEnd_n(), dateStart, dateEnd)) {
                    double loanAmount = SHrsUtils.computeLoanAmount(loan, hrsReceipt, null, null);

                    if (loanAmount > 0) {
                        SDbDeduction deductionLoan = null;

                        for (SDbDeduction deduction : maDeductions) {
                            if (deduction.getFkLoanTypeId() == loan.getFkLoanTypeId()) {
                                deductionLoan = deduction;
                                break;
                            }
                        }

                        if (deductionLoan == null) {
                            throw new Exception("No se encontró ninguna deducción para agregar el préstamo '" + loan.composeLoanDescription() + "'.");
                        }
                        else {
                            SDbPayrollReceiptDeduction payrollReceiptDeduction = createPayrollReceiptDeduction(
                                    hrsReceipt, deductionLoan,
                                    1, loanAmount, true,
                                    loan.getPkEmployeeId(), loan.getPkLoanId(), ++moveId);

                            SHrsReceiptDeduction hrsReceiptDeduction = new SHrsReceiptDeduction();
                            hrsReceiptDeduction.setHrsReceipt(hrsReceipt);
                            hrsReceiptDeduction.setDeduction(deductionLoan);
                            hrsReceiptDeduction.setPayrollReceiptDeduction(payrollReceiptDeduction);

                            hrsReceiptDeductions.add(hrsReceiptDeduction);
                        }
                    }
                }
            }
        }

        return hrsReceiptDeductions;
    }

    /*
     * Public methods:
     */

    public void setPayroll(SDbPayroll payroll) { moPayroll = payroll; }

    public SDbConfig getConfig() { return moConfig; }
    public SDbWorkingDaySettings getWorkingDaySettings() { return moWorkingDaySettings; }
    public SDbPayroll getPayroll() { return moPayroll; }

    public ArrayList<SDbLoanTypeAdjustment> getLoanTypeAdjustments() { return maLoanTypeAdjustments; }
    public ArrayList<SDbUma> getUmas() { return maUmas; }
    public ArrayList<SDbUmi> getUmis() { return maUmis; }
    public ArrayList<SDbHoliday> getHolidays() { return maHolidays; }
    public ArrayList<SDbTaxTable> getTaxTables() { return maTaxTables; }
    public ArrayList<SDbTaxSubsidyTable> getTaxSubsidyTables() { return maTaxSubsidyTables; }
    public ArrayList<SDbSsContributionTable> getSsContributionTables() { return maSsContributionTables; }
    public ArrayList<SDbBenefitTable> getBenefitTables() { return maBenefitTables; }
    public ArrayList<SHrsBenefitTableAnniversary> getHrsBenefitTablesAnniversarys() { return maBenefitTablesAnniversarys; }
    public ArrayList<SDbMwzTypeWage> getMwzTypeWages() { return maMwzTypeWages; }
    public ArrayList<SDbEarning> getEarnings() { return maEarnigs; }
    public ArrayList<SDbDeduction> getDeductions() { return maDeductions; }
    public ArrayList<SDbAutomaticEarning> getAutomaticEarnings() { return maAutomaticEarnings; }
    public ArrayList<SDbAutomaticDeduction> getAutomaticDeductions() { return maAutomaticDeductions; }
    public ArrayList<SDbEmployee> getEmployees() { return maEmployees; }
    public ArrayList<SHrsReceipt> getHrsReceipts() { return maHrsReceipts; }
    public HashMap<Integer, String> getEarningComputationTypesMap() { return moEarningComputationTypesMap; }
    public HashMap<Integer, String> getDeductionComputationTypesMap() { return moDeductionComputationTypesMap; }

    public double getLoanTypeMonthlyAdjustment(final Date date, final int loanType) {
        double monthlyAdjustment = 0;
        ArrayList<SDbLoanTypeAdjustment> matchingAdjustments = new ArrayList<>();

        // first, filter only matching adjustments:

        for (SDbLoanTypeAdjustment adjustment : maLoanTypeAdjustments) {
            if (adjustment.getPkLoanTypeId() == loanType && !date.before(adjustment.getDateStart())) {
                matchingAdjustments.add(adjustment);
            }
        }

        // find the more recent matching adjustment, to take from it the requested monthly adjustment:

        SDbLoanTypeAdjustment moreRecentAdjustment = null;

        for (SDbLoanTypeAdjustment adjustment : matchingAdjustments) {
            if (moreRecentAdjustment == null) {
                moreRecentAdjustment = adjustment;
            }
            else if (adjustment.getDateStart().compareTo(moreRecentAdjustment.getDateStart()) >= 0) {
                moreRecentAdjustment = adjustment;
            }
        }

        if (moreRecentAdjustment != null) {
            monthlyAdjustment = moreRecentAdjustment.getAdjustment();
        }

        return monthlyAdjustment;
    }

    /**
     * Obtain amount UMA most appropriate for date indicated.
     * @param date Date for required UMA.
     * @return
     */
    public double getUma(final Date date) {
        double amount = 0;

        for (SDbUma uma : maUmas) {
            if (!date.before(uma.getDateStart())) {
                amount = uma.getAmount();
                break;
            }
        }

        return amount;
    }

    /**
     * Obtain amount UMI most appropriate for date indicated.
     * @param date Date for required UMI.
     * @return
     */
    public double getUmi(final Date date) {
        double amount = 0;

        for (SDbUmi umi : maUmis) {
            if (!date.before(umi.getDateStart())) {
                amount = umi.getAmount();
                break;
            }
        }

        return amount;
    }

    /**
     * Checks if given date is a holiday.
     * @param date
     * @return <code>true</code> if given date is a holiday.
     */
    public boolean isHoliday(final Date date) {
        boolean isHolyday = false;

        for (SDbHoliday holiday : maHolidays) {
            if (SLibTimeUtils.isSameDate(holiday.getDate(), date)) {
                isHolyday = true;
                break;
            }
        }

        return isHolyday;
    }

    /**
     * Checks if given date is a non-working day: non-working by default according to applying working day settings, or a holiday.
     * @param date
     * @return <code>true</code> if given date is a non-working day.
     */
    public boolean isNonWorkingDay(final Date date) {
        GregorianCalendar calendar = new GregorianCalendar();
        calendar.setTime(date);
        return !moWorkingDaySettings.isWorkingDay(calendar.get(Calendar.DAY_OF_WEEK)) || isHoliday(date);
    }

    public SDbTaxTable getTaxTable(final int tableId) {
        SDbTaxTable taxTable = null;

        for (SDbTaxTable table : maTaxTables) {
            if (table.getPkTaxTableId() == tableId) {
                taxTable = table;
                break;
            }
        }

        return taxTable;
    }

    public SDbTaxTable getTaxTableByDate(final Date date) {
        SDbTaxTable taxTable = null;

        for (SDbTaxTable table : maTaxTables) {
            if (!date.before(table.getDateStart())) {
                taxTable = table;
                break;
            }
        }

        return taxTable;
    }

    public SDbTaxSubsidyTable getTaxSubsidyTable(final int tableId) {
        SDbTaxSubsidyTable taxSubsidyTable = null;

        for (SDbTaxSubsidyTable table : maTaxSubsidyTables) {
            if (table.getPkTaxSubsidyTableId() == tableId) {
                taxSubsidyTable = table;
                break;
            }
        }

        return taxSubsidyTable;
    }

    public SDbTaxSubsidyTable getTaxSubsidyTableByDate(final Date date) {
        SDbTaxSubsidyTable taxSubsidyTable = null;

        for (SDbTaxSubsidyTable table : maTaxSubsidyTables) {
            if (!date.before(table.getDateStart())) {
                taxSubsidyTable = table;
                break;
            }
        }

        return taxSubsidyTable;
    }

    public SDbSsContributionTable getSsContributionTable(final int tableId) {
        SDbSsContributionTable ssContributionTable = null;

        for (SDbSsContributionTable table : maSsContributionTables) {
            if (table.getPkSsContributionTableId() == tableId) {
                ssContributionTable = table;
                break;
            }
        }

        return ssContributionTable;
    }

    public SDbSsContributionTable getSsContributionTableByDate(final Date date) {
        SDbSsContributionTable ssContributionTable = null;

        for (SDbSsContributionTable table : maSsContributionTables) {
            if (!date.before(table.getDateStart())) {
                ssContributionTable = table;
                break;
            }
        }

        return ssContributionTable;
    }

    public SDbBenefitTable getBenefitTable(final int tableId) {
        SDbBenefitTable benefitTable = null;

        for (SDbBenefitTable table : maBenefitTables) {
            if (table.getPkBenefitId() == tableId) {
                benefitTable = table;
                break;
            }
        }

        return benefitTable;
    }

    /**
     * Gets benefit table according to cut off date and payment type.
     * @param benefitType
     * @param cutOff
     * @param paymentType_n Can be undefined, i. e., zero.
     * @return
     */
    public SDbBenefitTable getBenefitTable(final int benefitType, final Date cutOff, final int paymentType_n) {
        SDbBenefitTable benefitTable = null;

        // get table with matching benefit type, cut off date and payment type, if any:
        for (SDbBenefitTable table : maBenefitTables) {
            if (table.getFkBenefitTypeId() == benefitType && !cutOff.before(table.getDateStart()) && table.getFkPaymentTypeId_n() == paymentType_n) {
                benefitTable = table;
                break;
            }
        }

        // if no table found, get table with matching only benefit type and cut off date, if any:
        if (benefitTable == null) {
            for (SDbBenefitTable table : maBenefitTables) {
                if (table.getFkBenefitTypeId() == benefitType && !cutOff.before(table.getDateStart()) && table.getFkPaymentTypeId_n() == 0) {
                    benefitTable = table;
                    break;
                }
            }
        }

        return benefitTable;
    }

    public ArrayList<SHrsBenefitTableAnniversary> getBenefitTableAnniversary(final int tableId) {
        ArrayList<SHrsBenefitTableAnniversary> aBenefitTableByAnniversary = new ArrayList<>();

        for (SHrsBenefitTableAnniversary anniversary : maBenefitTablesAnniversarys) {
            if (anniversary.getBenefitId() == tableId) {
                aBenefitTableByAnniversary.add(anniversary);
            }
        }

        return aBenefitTableByAnniversary;
    }

    public SDbMwzTypeWage getMwzTypeWage(final int mwzType, final int wageId) {
        SDbMwzTypeWage mwzTypeWage = null;

        for (SDbMwzTypeWage wage : maMwzTypeWages) {
            if (wage.getPkMwzTypeId() == mwzType && wage.getPkWageId() == wageId) {
                mwzTypeWage = wage;
                break;
            }
        }

        return mwzTypeWage;
    }

    public SDbMwzTypeWage getMwzTypeWageByDate(final int mwzType, final Date date) {
        SDbMwzTypeWage oMwzTypeWage = null;

        for (SDbMwzTypeWage mwzTypeWage : maMwzTypeWages) {
            if (mwzTypeWage.getPkMwzTypeId() == mwzType && !date.before(mwzTypeWage.getDateStart())) {
                oMwzTypeWage = mwzTypeWage;
                break;
            }
        }

        return oMwzTypeWage;
    }

    /**
     * Gets the requested earning by ID.
     * @param earningId
     * @return
     */
    public SDbEarning getEarning(final int earningId) {
        SDbEarning earning = null;

        for (SDbEarning entry : maEarnigs) {
            if (entry.getPkEarningId() == earningId) {
                earning = entry;
                break;
            }
        }

        return earning;
    }

    /**
     * Gets the requested first-found earning by earning type.
     * @param earningType
     * @return
     */
    public SDbEarning getEarningByType(final int earningType) {
        SDbEarning earning = null;

        for (SDbEarning entry : maEarnigs) {
            if (entry.getFkEarningTypeId() == earningType) {
                earning = entry;
                break;
            }
        }

        return earning;
    }

    /**
     * Gets the requested deduction by ID.
     * @param deductionId
     * @return
     */
    public SDbDeduction getDeduction(final int deductionId) {
        SDbDeduction deduction = null;

        for (SDbDeduction entry : maDeductions) {
            if (entry.getPkDeductionId() == deductionId) {
                deduction = entry;
                break;
            }
        }

        return deduction;
    }

    /**
     * Gets the requested first-found deduction by deduction type.
     * @param deductionType
     * @return
     */
    public SDbDeduction getDeductionByType(final int deductionType) {
        SDbDeduction deduction = null;

        for (SDbDeduction entry : maDeductions) {
            if (entry.getFkDeductionTypeId() == deductionType) {
                deduction = entry;
                break;
            }
        }

        return deduction;
    }

    public SDbEmployee getEmployee(final int employeeId) {
        SDbEmployee employee = null;

        for (SDbEmployee entry : maEmployees) {
            if (entry.getPkEmployeeId() == employeeId) {
                employee = entry;
                break;
            }
        }

        return employee;
    }

    private SDbPayrollReceipt createPayrollReceipt(final SHrsEmployee hrsEmployee, final int recruitmentSchemaType) {
        SDbPayrollReceipt payrollReceipt = new SDbPayrollReceipt();

        //payrollReceipt.setPkPayrollId();
        payrollReceipt.setPkEmployeeId(hrsEmployee.getEmployee().getPkEmployeeId());
        payrollReceipt.setDateBenefits(hrsEmployee.getEmployee().getDateBenefits());
        payrollReceipt.setDateLastHire(hrsEmployee.getEmployee().getDateLastHire());
        payrollReceipt.setDateLastDismissal_n(hrsEmployee.getEmployee().getDateLastDismissal_n());
        payrollReceipt.setSalary(hrsEmployee.getEmployee().getSalary());
        payrollReceipt.setWage(hrsEmployee.getEmployee().getWage());
        payrollReceipt.setSalarySscBase(hrsEmployee.getEmployee().getSalarySscBase());
        payrollReceipt.setWorkingHoursDay(hrsEmployee.getEmployee().getWorkingHoursDay());
        payrollReceipt.setPaymentDaily(hrsEmployee.getEmployee().getEffectiveSalary(moPayroll.isFortnightStandard()));
        payrollReceipt.setPaymentHourly(hrsEmployee.getEmployee().getWorkingHoursDay() > 0 ? payrollReceipt.getPaymentDaily() / hrsEmployee.getEmployee().getWorkingHoursDay() : 0);
        //payrollReceipt.setFactorCalendar();
        //payrollReceipt.setFactorDaysPaid();
        //payrollReceipt.setReceiptDays();
        //payrollReceipt.setWorkingDays();
        //payrollReceipt.setDaysWorked();
        //payrollReceipt.setDaysHiredPayroll();
        //payrollReceipt.setDaysHiredAnnual();
        //payrollReceipt.setDaysIncapacityNotPaidPayroll();
        //payrollReceipt.setDaysIncapacityNotPaidAnnual();
        //payrollReceipt.setDaysNotWorkedButPaid();
        //payrollReceipt.setDaysNotWorkedNotPaid();
        //payrollReceipt.setDaysNotWorked_r();
        //payrollReceipt.setDaysToBePaid_r();
        //payrollReceipt.setDaysPaid();
        //payrollReceipt.setEarningsExemption_r();
        //payrollReceipt.setEarningsTaxable_r();
        //payrollReceipt.setEarnings_r();
        //payrollReceipt.setDeductions_r();
        //payrollReceipt.setPayment_r();
        //payrollReceipt.setPayrollTaxableDays_r();
        //payrollReceipt.setPayrollFactorTax();
        //payrollReceipt.setPayrollTaxAssessed();
        //payrollReceipt.setPayrollTaxCompensated();
        //payrollReceipt.setPayrollTaxPending_r();
        //payrollReceipt.setPayrollTaxPayed();
        //payrollReceipt.setPayrollTaxSubsidyAssessedGross();
        //payrollReceipt.setPayrollTaxSubsidyAssessed();
        //payrollReceipt.setPayrollTaxSubsidyCompensated();
        //payrollReceipt.setPayrollTaxSubsidyPending_r();
        //payrollReceipt.setPayrollTaxSubsidyPayed();
        //payrollReceipt.setAnnualTaxableDays_r();
        //payrollReceipt.setAnnualFactorTax();
        //payrollReceipt.setAnnualTaxAssessed();
        //payrollReceipt.setAnnualTaxCompensated();
        //payrollReceipt.setAnnualTaxPayed();
        //payrollReceipt.setAnnualTaxSubsidyAssessed();
        //payrollReceipt.setAnnualTaxSubsidyCompensated();
        //payrollReceipt.setAnnualTaxSubsidyPayed();
        payrollReceipt.setActive(hrsEmployee.getEmployee().isActive());
        //payrollReceipt.setDaysAdjustment();
        //payrollReceipt.setCfdRequired();
        //payrollReceipt.setDeleted();
        payrollReceipt.setFkPaymentTypeId(hrsEmployee.getEmployee().getFkPaymentTypeId());
        payrollReceipt.setFkEmployeeTypeId(hrsEmployee.getEmployee().getFkEmployeeTypeId());
        payrollReceipt.setFkMwzTypeId(hrsEmployee.getEmployee().getFkMwzTypeId());
        payrollReceipt.setFkDepartmentId(hrsEmployee.getEmployee().getFkDepartmentId());
        payrollReceipt.setFkPositionId(hrsEmployee.getEmployee().getFkPositionId());

        if (recruitmentSchemaType == SModSysConsts.HRSS_TP_REC_SCHE_NA || SHrsCfdUtils.isTypeRecruitmentSchemaForEmployment(recruitmentSchemaType)) {
            payrollReceipt.setFkRecruitmentSchemaTypeId(hrsEmployee.getEmployee().getFkRecruitmentSchemaTypeId());

            payrollReceipt.setFkSalaryTypeId(hrsEmployee.getEmployee().getFkSalaryTypeId());
            payrollReceipt.setFkWorkerTypeId(hrsEmployee.getEmployee().getFkWorkerTypeId());
            payrollReceipt.setFkShiftId(hrsEmployee.getEmployee().getFkShiftId());
            payrollReceipt.setFkContractTypeId(hrsEmployee.getEmployee().getFkContractTypeId());
            payrollReceipt.setFkPositionRiskTypeId(hrsEmployee.getEmployee().getFkPositionRiskTypeId());
            payrollReceipt.setFkWorkingDayTypeId(hrsEmployee.getEmployee().getFkWorkingDayTypeId());
        }
        else {
            payrollReceipt.setFkRecruitmentSchemaTypeId(recruitmentSchemaType);

            payrollReceipt.setFkSalaryTypeId(SModSysConsts.HRSS_TP_SAL_FIX);
            payrollReceipt.setFkWorkerTypeId(SModSysConsts.HRSU_TP_WRK_NA);
            payrollReceipt.setFkShiftId(SModSysConsts.HRSU_SHT_NA);
            payrollReceipt.setFkContractTypeId(SModSysConsts.HRSS_TP_CON_OTH);
            payrollReceipt.setFkPositionRiskTypeId(SModSysConsts.HRSS_TP_POS_RISK_NA);
            payrollReceipt.setFkWorkingDayTypeId(SModSysConsts.HRSS_TP_WORK_DAY_NA);
        }
        //payrollReceipt.setFkUserInsertId();
        //payrollReceipt.setFkUserUpdateId();
        //payrollReceipt.setTsUserInsert();
        //payrollReceipt.setTsUserUpdate();

        return payrollReceipt;
    }

    public ArrayList<SDbAbsenceConsumption> crateAbsenceConsumptions(final SHrsReceipt hrsReceipt) throws Exception {
        ArrayList<SDbAbsenceConsumption> absenceConsumptions = new ArrayList<>();

        // prepare for absence consumptions:

        double receiptConsumedDays = 0; // consumed days added to this receipt
        Date payrollDateEnd = hrsReceipt.getHrsPayroll().getPayroll().getDateEnd();
        SHrsEmployeeDays hrsEmployeeDays = hrsReceipt.getHrsEmployee().createEmployeeDays(); // calendar and business days available for this receipt

        // go through all absences for current employee to check which ones are elegible to be added to this receipt:

        for (SDbAbsence absence : hrsReceipt.getHrsEmployee().getAbsences()) {
            if (!absence.isClosed() && !absence.getDateStart().after(payrollDateEnd)) { // is current absence elegible?
                /*
                 * START of algorithm #ABS001. IMPORTANT: Please find in proyect this code to sync up any changes!
                 */

                // estimate absence remaining-days to be consumed:

                int absenceConsumedDays = absence.getActualConsumedDays(hrsReceipt.getHrsEmployee());
                int absenceRemainingDays = absence.getEffectiveDays() - absenceConsumedDays;

                if (absenceRemainingDays > 0) {
                    Date lastConsumptionDate = absenceConsumedDays == 0 ? null : absence.getActualLastConsumptionDate(hrsReceipt.getHrsEmployee());
                    Date consumptionStart = lastConsumptionDate == null ? absence.getDateStart() : SLibTimeUtils.addDate(lastConsumptionDate, 0, 0, 1);

                    // adjust consumption start-date, if neccesary:

                    if (!absence.consumesCalendarDays() && absenceConsumedDays > 0) { // preserve original absence start-date when there aren't previous consumptions
                        while (isNonWorkingDay(consumptionStart)) {
                            consumptionStart = SLibTimeUtils.addDate(consumptionStart, 0, 0, 1); // move to next day
                        }
                    }

                    /*
                     * END of algorithm #ABS001. IMPORTANT: Please find in proyect this code to sync up any changes!
                     */

                    // check if consumption does not start after payroll end-date:

                    if (!consumptionStart.after(payrollDateEnd)) {
                        // prepare absence elegible-days to be consumed:

                        int absenceElegibleDays = absenceRemainingDays;

                        // check if absence does start after payroll end-date:

                        if (absence.getDateEnd().after(payrollDateEnd)) {
                            // adjust absence elegible-days to be consumed:

                            int consumableDays;

                            if (absence.consumesCalendarDays() || (absenceConsumedDays == 0 && isNonWorkingDay(consumptionStart))) {
                                consumableDays = SLibTimeUtils.countPeriodDays(consumptionStart, payrollDateEnd);
                            }
                            else {
                                consumableDays = SHrsUtils.countBusinessDays(consumptionStart, payrollDateEnd, moWorkingDaySettings, maHolidays);
                            }

                            if (absenceElegibleDays > consumableDays) {
                                absenceElegibleDays = consumableDays;
                            }
                        }

                        // prepare consumption effective days:

                        if (absenceElegibleDays > 0) {
                            int consumptionEffectiveDays = absenceElegibleDays;
                            int receiptRemainingDays = (int) ((absence.consumesCalendarDays() ? hrsEmployeeDays.getReceiptDays() : hrsEmployeeDays.getBusinessDays()) - receiptConsumedDays);

                            if (consumptionEffectiveDays > receiptRemainingDays) {
                                consumptionEffectiveDays = receiptRemainingDays;
                            }

                            if (consumptionEffectiveDays > 0) {
                                // prepare consumption:

                                boolean adjustingConsumptionEnd = true;
                                Date consumptionEnd;

                                // iterate until necessary to set consumption end-date:

                                do {
                                    consumptionEnd = SLibTimeUtils.addDate(consumptionStart, 0, 0, consumptionEffectiveDays - 1);
                                    int consumptionBusinessDays = SHrsUtils.countBusinessDays(consumptionStart, consumptionEnd, moWorkingDaySettings, maHolidays);

                                    // check very first consumption for absences that consume business days:

                                    if (!absence.consumesCalendarDays() && absenceConsumedDays == 0) {
                                        if (consumptionBusinessDays < consumptionEffectiveDays) {
                                            // grant non-working days at the beginning of consumption period:

                                            int nonBusinessDaysGranted = 0; // non-business days considered as business days

                                            for (int day = 0; day < consumptionEffectiveDays; day++) {
                                                Date date = SLibTimeUtils.addDate(consumptionStart, 0, 0, day);

                                                if (isNonWorkingDay(date)) {
                                                    nonBusinessDaysGranted++;
                                                }
                                                else {
                                                    break;
                                                }
                                            }

                                            consumptionBusinessDays += nonBusinessDaysGranted;
                                        }
                                    }

                                    // confirm consumption end-date:

                                    if (absence.consumesCalendarDays() || consumptionBusinessDays == consumptionEffectiveDays) {
                                        /* Consumption end-date does not need any adjustment:
                                         * absence consumes calendar days OR
                                         * absences consumes business days and consumption effective-days are equal to consumption period business-days.
                                         */

                                        if (absenceRemainingDays - consumptionEffectiveDays == 0) {
                                            // force consumption end-date to be equal to absence end-date when last consumption ocurrs:
                                            consumptionEnd = absence.getDateEnd();
                                        }

                                        // stop iterations:
                                        adjustingConsumptionEnd = false;
                                    }
                                    else {
                                        /* Consumption end-date does need some adjustments:
                                         * absence consumes business days AND
                                         * consumption effective-days are not equal to consumption period business-days.
                                         */

                                        int businessDaysToPayrollEnd = SHrsUtils.countBusinessDays(consumptionEnd, payrollDateEnd, moWorkingDaySettings, maHolidays);

                                        if (businessDaysToPayrollEnd == 0) {
                                            // split consumption end backwards:

                                            if (SLibTimeUtils.addDate(consumptionEnd, 0, 0, -1).before(absence.getDateStart())) {
                                                adjustingConsumptionEnd = false;
                                            }
                                            else {
                                                consumptionEnd = SLibTimeUtils.addDate(consumptionEnd, 0, 0, -1);
                                                consumptionEffectiveDays--;
                                            }

                                            // go to next iteration!
                                        }
                                        else {
                                            // split consumptino end forward:

                                            int nonBusinessDaysBurned = 0;
                                            int nonBusinessDaysConsumed = consumptionEffectiveDays - consumptionBusinessDays;

                                            while (nonBusinessDaysBurned < businessDaysToPayrollEnd && nonBusinessDaysBurned < nonBusinessDaysConsumed && !SLibTimeUtils.addDate(consumptionEnd, 0, 0, 1).after(absence.getDateEnd())) {
                                                consumptionEnd = SLibTimeUtils.addDate(consumptionEnd, 0, 0, 1);

                                                if (!isNonWorkingDay(consumptionEnd)) {
                                                    nonBusinessDaysBurned++;
                                                }
                                            }

                                            // stop iterations:
                                            adjustingConsumptionEnd = false;
                                        }
                                    }
                                } while (adjustingConsumptionEnd && consumptionEffectiveDays > 0);

                                if (consumptionEffectiveDays > 0) {
                                    // create consumption:

                                    SDbAbsenceConsumption absenceConsumption = hrsReceipt.createAbsenceConsumption(absence, consumptionStart, consumptionEnd, consumptionEffectiveDays);

                                    if (hrsReceipt.validateAbsenceConsumption(absenceConsumption)) {
                                        // process consumption:

                                        absenceConsumptions.add(absenceConsumption);

                                        receiptConsumedDays += consumptionEffectiveDays;
                                        if (receiptConsumedDays >= hrsEmployeeDays.getReceiptDays()) {
                                            break; // there is no way to add more consumptions!
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        return absenceConsumptions;
    }

    /**
     * Create receipt.
     * @param employeeId
     * @param payrollYear
     * @param payrollYearPeriod
     * @param fiscalYear
     * @param dateStart
     * @param dateEnd
     * @param recruitmentSchemaType
     * @return
     * @throws Exception
     */
    public SHrsReceipt createHrsReceipt(final int employeeId, int payrollYear, int payrollYearPeriod, int fiscalYear, Date dateStart, Date dateEnd, final int recruitmentSchemaType) throws Exception {
        SHrsReceipt hrsReceipt = new SHrsReceipt();
        hrsReceipt.setHrsPayroll(this);

        SHrsEmployee hrsEmployee = moHrsPayrollDataProvider.createHrsEmployee(
                this, moPayroll.getPkPayrollId(), employeeId, payrollYear, payrollYearPeriod, fiscalYear, dateStart, dateEnd);
        hrsEmployee.setHrsReceipt(hrsReceipt);
        hrsReceipt.setHrsEmployee(hrsEmployee);

        SDbPayrollReceipt payrollReceipt = createPayrollReceipt(hrsEmployee, recruitmentSchemaType);
        hrsReceipt.setPayrollReceipt(payrollReceipt);

        if (moPayroll.isPayrollNormal()) {
            hrsReceipt.getAbsenceConsumptions().addAll(crateAbsenceConsumptions(hrsReceipt));
        }

        hrsReceipt.getHrsReceiptEarnings().addAll(createHrsReceiptEarnings(hrsReceipt, dateStart, dateEnd));
        hrsReceipt.getHrsReceiptDeductions().addAll(createHrsReceiptDeductions(hrsReceipt, dateStart, dateEnd));

        hrsReceipt.renumberHrsReceiptEarnings();
        hrsReceipt.renumberHrsReceiptDeductions();
        hrsReceipt.computeReceipt();

        // Add new payroll receipt:
        maHrsReceipts.add(hrsReceipt);

        return hrsReceipt;
    }

    public void replaceHrsReceipt(final SHrsReceipt hrsReceiptNew, final boolean compute) {
        for (int i = 0; i < maHrsReceipts.size(); i++) {
            SHrsReceipt hrsReceipt = maHrsReceipts.get(i);

            if (hrsReceipt.getPayrollReceipt().getPkEmployeeId() == hrsReceiptNew.getPayrollReceipt().getPkEmployeeId()) {
                maHrsReceipts.set(i, hrsReceiptNew);
                break;
            }
        }

        if (compute) {
            try {
                hrsReceiptNew.renumberHrsReceiptEarnings();
                hrsReceiptNew.renumberHrsReceiptDeductions();
                hrsReceiptNew.computeReceipt();
            }
            catch (Exception e) {
                SLibUtils.showException(this, e);
            }
        }
    }

    public void removeHrsReceipt(final int employeeId) {
        for (int i = 0; i < maHrsReceipts.size(); i++) {
            SHrsReceipt hrsReceipt = maHrsReceipts.get(i);

            if (hrsReceipt.getPayrollReceipt().getPkEmployeeId() == employeeId) {
                maHrsReceipts.remove(i);
                break;
            }
        }
    }

    public void computeEmployees(final boolean isCopy) {
        try {
            for (SHrsReceipt hrsReceipt : maHrsReceipts) {
                hrsReceipt.setHrsEmployee(moHrsPayrollDataProvider.computeEmployee(hrsReceipt.getHrsEmployee(), isCopy ? 0 : moPayroll.getPkPayrollId(), hrsReceipt.getHrsEmployee().getEmployee().getPkEmployeeId(),
                        moPayroll.getPeriodYear(), moPayroll.getPeriod(), moPayroll.getFiscalYear(), moPayroll.getDateStart(), moPayroll.getDateEnd()));
            }
        }
        catch (Exception e) {
            SLibUtils.showException(this, e);
        }
    }

    public void computeReceipts() {
        try {
            for (SHrsReceipt hrsReceipt : maHrsReceipts) {
                hrsReceipt.computeReceipt();
            }
        }
        catch (Exception e) {
            SLibUtils.showException(this, e);
        }
    }

    public double getFactorDaysPaid() {
        return moPayroll.getWorkingDays() == 0 ? 0 : (double) moPayroll.getReceiptDays() / moPayroll.getWorkingDays();
    }

    public double getTotalEarnings() {
        double total = 0;

        for (SHrsReceipt hrsReceipt : maHrsReceipts) {
            for (SHrsReceiptEarning hrsReceiptEarning : hrsReceipt.getHrsReceiptEarnings()) {
                total = SLibUtils.roundAmount(total + hrsReceiptEarning.getPayrollReceiptEarning().getAmount_r());
            }
        }

        return total;
    }

    public double getTotalDeductions() {
        double total = 0;

        for (SHrsReceipt hrsReceipt : maHrsReceipts) {
            for (SHrsReceiptDeduction hrsReceiptDeduction : hrsReceipt.getHrsReceiptDeductions()) {
                total = SLibUtils.roundAmount(total + hrsReceiptDeduction.getPayrollReceiptDeduction().getAmount_r());
            }
        }

        return total;
    }

    public ArrayList<SHrsReceiptEarning> createHrsReceiptEarningsAbsence(final SHrsReceipt hrsReceipt, final SHrsEmployeeDays hrsEmployeeDays) throws Exception {
        int moveId = 0;
        ArrayList<SHrsReceiptEarning> hrsReceiptEarnings = new ArrayList<>();

        for (SDbAbsenceConsumption absenceConsumption : hrsReceipt.getAbsenceConsumptions()) {
            if (absenceConsumption.getParentAbsence().isXtaAbsenceTypePayable()) {
                SDbEarning earningAbsence = null;

                if (absenceConsumption.getParentAbsence().isVacation()) {
                    // corresponding earning should be set in configuration of module:
                    earningAbsence = getEarning(moConfig.getFkEarningVacationId_n());
                }
                else {
                    // corresponding earning should be set in earnings catalog itself:
                    for (SDbEarning earning : maEarnigs) {
                        if (SLibUtils.compareKeys(earning.getAbsenceTypeKey(), absenceConsumption.getParentAbsence().getAbsenceTypeKey())) {
                            earningAbsence = earning;
                            break;
                        }
                    }
                }

                if (earningAbsence == null) {
                    throw new Exception("No se pudo determinar cuál es la percepción para "
                            + "'" + moHrsPayrollDataProvider.getSession().readField(SModConsts.HRSU_TP_ABS, absenceConsumption.getParentAbsence().getAbsenceTypeKey(), SDbRegistry.FIELD_NAME) + "' "
                            + (absenceConsumption.getParentAbsence().isVacation() ? "en la configuración del módulo" : "en el catálogo de percepciones") + ".");
                }
                else {
                    SHrsBenefitBase hrsBenefitBase = null;

                    if (earningAbsence.isBenefit()) {
                        hrsBenefitBase = new SHrsBenefitBase(earningAbsence.getFkBenefitTypeId(), absenceConsumption.getParentAbsence().getBenefitsAnniversary(), absenceConsumption.getParentAbsence().getBenefitsYear());
                    }

                    SDbPayrollReceiptEarning payrollReceiptEarning = createPayrollReceiptEarning(
                            hrsReceipt, earningAbsence, hrsEmployeeDays, hrsBenefitBase,
                            absenceConsumption.getEffectiveDays(), 0, true,
                            0, 0, ++moveId);

                    payrollReceiptEarning.setSystem(true); // key setting in absence earnings control, preserve it!

                    SHrsReceiptEarning hrsReceiptEarning = new SHrsReceiptEarning();
                    hrsReceiptEarning.setHrsReceipt(hrsReceipt);
                    hrsReceiptEarning.setEarning(earningAbsence);
                    hrsReceiptEarning.setPayrollReceiptEarning(payrollReceiptEarning);

                    hrsReceiptEarnings.add(hrsReceiptEarning);
                }
            }
        }

        return hrsReceiptEarnings;
    }
}


text:
Q: select DataFrame Rows Based on multiple conditions on columns when column name are in a list I need to filter rows on certain conditions on some columns.
Those columns are present in a list. Condition will be same for all columns or can be different. For my work, condition is same.
Not working
labels = ['one', 'two', 'three']

df = df [df [x] == 1 for x in labels]

Below code works:
df_list = []

for x in labels:

  df_list.append(df[(df [x] == 1)])

df5 = pd.concat(df_list).drop_duplicates()

Creating different dataframes and concating them by avoiding duplicates works.
Expected:
It should filter out those rows where value of those column is 1.
Actual:
ValueError: too many values to unpack (expected 1)
I understand the reason for the error. Is there any way I can construct the condition by modifying the not working code ?

A: I think you are able to re-write this using the following.
labels = ['one','two','three']

df5 = df[(df[labels] == 1).any(1)]

Let's test with this MCVE:
#Create test data
df = pd.DataFrame(np.random.randint(1,5,(10,5)), columns=[*'ABCDE'])
labels = ['A','B','E']

#Your code
df_list = []
for x in labels:

  df_list.append(df[(df [x] == 1)])

df5 = pd.concat(df_list).drop_duplicates()

#Suggested modification
df6 = df[(df[labels] == 1).any(1)]

Are they equal?
df5.eq(df6)

Output:
      A     B     C     D     E
1  True  True  True  True  True
4  True  True  True  True  True
6  True  True  True  True  True
7  True  True  True  True  True
8  True  True  True  True  True

A: Do you need this ?
new_df = df[(df['one'] == 1) & (df['two']== 1) & (df['three'] == 1)].drop_duplicates()

redpajama_set_name: RedPajamaStackExchange


text:
Reggie Bender Music
Unsealed Files
Contact Reggie
Tag: producers
Joe Meek: Britain's First Independent Producer
Music, Story, The Giddy Statues
JOE MEEK (Born April 5, 1929 in Gloucestershire, England. Died February 3, 1967, in London, England.) Joe Meek was Britain's first independent producer and a believer in the occult, Meek was not above holding séances in the recording studio to summon assistance from beyond the veil from his leading inspiration, BUDDY HOLLY (died, February 3, 1959). Besides being England's first indie record producer, he was a songwriter who helped bring Britain's nascent recording industry into the modern age.
August 25, 2016 by reggieadmin
Search Bender's World
ANDY WARHOL directs BENDER in 1982 music video March 3, 2017
Parallel Universes January 27, 2017
Music Map: PSYCHEDELIC ROCK November 9, 2016
Memory Rewind: The Giddy Statues US tour with JIMI HENDRIX: 1967 September 14, 2016
ME, MY THEREMIN, and THE BEACH BOYS September 14, 2016
Joe Meek: Britain's First Independent Producer August 25, 2016
WORRY-FREE SHOPPING
The Unsealed Files
"Is our government covering up his story, or is he schizophrenic? I don't know. It could be both."
-Fred Alan Wolf, physicist and author of "Parallel Universes" speaking about Reggie Bender
Delve deeper into these files by clicking right here...
COPYRIGHT © 2016 REGGIE BENDER

redpajama_set_name: RedPajamaCommonCrawl


text:
The insignia of orders of chivalry, orders and certain decorations are usually accompanied by information cards which detail how the individual insignia should be worn.
These notes are a guide on how the various insignia should be mounted for wearing.
Awards worn on the left breast
When in possession of two or more awards designed to be worn on the left breast they should be mounted in the following fashion:
Worn in accordance with the approved 'Order of Wear of Orders, Decorations and Medals' in a horizontal line suspended from a brooch (pin-back metal bar) which should not be visible. The length of the bar is usually not more than 16.5 cm (6½ inches), i.e. approximately five awards not overlapped. The length of the award (i.e., from top of ribbon to base of award) should be equal and be not less than 8.9 cm (3½ inches) and not more than 9.5 cm (3¾ inches) unless the size of the award or the number of clasps or bars attached to the ribbon of any award necessitates additional length.
If awards, on account of their number, cannot be suspended from the brooch so as to be fully seen, they should overlap and be arranged with the first fully exposed and with each succeeding ribbon and award underlaid by an equal amount.
Some individual awards issued to women are mounted on a bow (with or without tails). When in possession of two or more awards, a woman would normally wear her awards mounted in the same fashion as that prescribed above (without the bows) when in civilian dress or uniform of a military pattern.
Awards are worn with the obverse (usually the Sovereign's head, Royal Cypher or Coat of Arms) showing or to the front.
Mounted similar to full-size awards, except length of brooch should not normally exceed 14.7 cm (5¾ inches), i.e. approximately nine miniatures not overlapped unless the number of miniatures necessitates additional length.
The length of the miniature (i.e. from top of the ribbon to the base of the miniature) should be equal and not exceed 5.7 cm (2¼ inches) in overall length irrespective of size of miniature, unless the number of clasps or bars attached to the ribbon of any miniature necessitates additional length.
Styles of mounting
The awards may be mounted in "free-style" (i.e. the awards swing freely) or "court-style" (i.e. where the ribbon comes down behind the award and the actual award is tied to the backing ribbon and mounting frame). Court-style prevents damage to awards especially those containing enamel work.
The brooch (pin-back metal bar) should be moulded or stitched into the mounting frame which may be made of a variety of products. The awards may be attached to the frame by stitching or glue.
For court-style, the backing ribbon should extend and cover approximately half of the back of the award. The backing ribbon should not protrude below the award.
Awards worn on the right breast
Awards which may be worn on the right breast should be mounted and in the same fashion as those worn on the left breast.
Breast stars
Breast stars of Orders may be attached to the left side by sewing small loops of thread on the coat or garment at the appropriate position through which the pin on the back of the star passes. This avoids damage to the fabric. (Another quick convenient method is to make two small loops by passing suitably sized safety pins from the inside of the coat to the outside, and back).
Neck badges
At an investiture a man receives a neck badge suspended from a long ribbon of full-size width. This investiture ribbon is replaced by a shorter ribbon of miniature width which is usually supplied with most insignia.
The correct length of the short neck ribbon (of miniature width) is usually the shirt size plus 5 cm (2 inches) for wearing with a bow tie or 7.5 cm (3 inches) for wearing with a necktie. With a bow tie the ribbon is worn round the neck under the collar and the badge should hang close-up below the tie. With a necktie the badge should hang about 2 cm (¾ inch) below and in front of the tie knot.
The equivalent of a neck badge for a woman is issued mounted on a bow. At her discretion, however, a woman may wear the badge from a bow on the left shoulder of the dress or from a ribbon round the neck. In uniform of a military pattern the badge is worn in the manner prescribed for a man.
Ribbon bars
The length and width of ribbons when worn without medals should be 1 cm (⅜ inch) in length, with full width of ribbon exposed.
The number of ribbons worn in one complete row is governed largely by the physique of the wearer. In general, not more than five or less than two ribbons are worn in any one row e.g. the holder of 6 awards would wear 2 over 4 ribbons rather than 1 over 5 ribbons.
Ribbon bars are usually worn only on jackets or shirts of a military pattern and should be worn above the left breast pocket (or thereabouts) and no ribbon should be obscured by the lapel of the jacket. The ribbon of the most senior award should be nearest to the centre of the chest (or left to right from a viewer).
Contact the Honours Unit
Honours Unit
Email: honours@dpmc.govt.nz
Making an honours nomination
How the Honours system works
Honours Nomination Guidelines
Bravery Nomination Guidelines
New Zealand honours nomination form


Please note the original data does not always provide full information.
This database is an invaluable tool for those researching family history death records in the state of California.
- Issuing certified copies of California fetal death and still birth certificates.
All other requestors can only obtain informational copies.
Familyrelatives.com - California, Death Index Records, 1940-1997.


Enjoy your anniversary dinner at any number of first-rate restaurants in North Myrtle Beach. Perfectly situated between the Atlantic Ocean and scenic inlet waterways, North Myrtle Beach has some of the freshest seafood in the country that comes with complimentary breathtaking views. During your romantic getaway, make sure to visit a couple of our local upscale favorites, such as 21 Main and Parson's Table. Their menus have the best of everything, from juicy steaks and tender rack of lamb to delicious sushi and fresh catches.
What's more romantic than riding horses on the beach? At Inlet Point Plantation, you can ride horses on the beach year-round. Upon arrival, their experts will get you checked in and ready for the ride of a lifetime. Once you've saddled up, you'll ride to beautiful, undeveloped Waites Island with a knowledgeable guide. For an excursion right out of a fairy-tale, book their exclusive Special Occasion Ride, where you and your loved one will have a private ride along the shore of the island.
Savor your time together by sipping on exceptional wines at two beautiful venues, La Belle Amie Vineyard and Duplin Winery. These charming wineries have a wide variety of local wines and outdoor patios with gorgeous scenery to indulge your senses even more. Both La Belle Amie and Duplin offer affordable wine tastings, so spend an afternoon discovering your new favorite label.
Enjoy a peaceful early morning as you and your companion paddleboard through North Myrtle Beach's beautiful waterways and inlets. Calm, gently rippling water surrounded by tall grass on either side creates the perfect atmosphere for a romantic moment on your anniversary trip.
The spa is the perfect place to sit back, unwind and just enjoy being together. At Touch MedSpa, share your relaxing experience with each other by indulging in a couples' treatment, where your mind and body will be soothed with hot towels, aromatherapy and massages.
Make your anniversary trip the most memorable yet by booking now and reconnecting with your special someone!


text:
Eskom load shedding times: Stage 4 rotational load shedding implemented
Port Elizabeth - After initially announcing that it would implement Stage 2 load shedding on Monday morning, Eskom again escalated to Stage 4 load shedding.
"We regret that due to additional loss of units at our power stations, Stage 2 loadshedding will move to Stage 4 as from 10:00 to 23:00," the power utility Tweeted.
"Eskom has lost additional generation units this morning, increasing unplanned breakdowns (UCLF) to 14 200MW as at 09:25. Along with a higher demand of about 600MW, necessitates loadshedding to move up from Stage 2 to Stage 4 from 10:00 today until 23:00.
"In addition, with the incessant rains we are beginning to experience flooding at some power stations, which have further led to load losses and has impacted supply as the rainy weather persists."
Eskom said that loadshedding is intended, among other things, to cater for unplanned further trips and to create capacity to replenish water reserves for our pumped storage schemes.
"We continue to utilise diesel and water resources at our open cycle gas turbines and pumped storage schemes respectively, to supplement capacity.
"We remind customers that loadshedding at Stage 4 is no cause for alarm as the system is being effectively controlled. Loadshedding is a responsible act and highly controlled process, implemented to protect the country form a national blackout," it added.
"During Stage 4, 4000MW is rotationally loadshed nationally at a given period. Even during this stage, approximately 80% of the country's demand is still being met.
"We continue to ask customers to reduce demand as a concerted collective effort can help to avoid or lessen the level of loadshedding. As we are experiencing rainy and cooler weather conditions in some parts of the country, we ask that you use efficient heating to keep warm and switch off your geysers over peak periods.
"We will keep South Africans informed about the status of the electricity system and our recovery efforts throughout this period.
"We sincerely apologise for the inconvenience during this difficult period."
Eskom load shedding times
Eskom customers can check their loadshedding schedules on the Eskom website (loadshedding.eskom.co.za) or through the customer contact centre on 0860037566.
For other Eskom load shedding times, see below:
Dear Customer, Please note: Load Shedding Stage 4 declared from 10:00 until 23:00.
Please visit https://t.co/RXdAfF87Wo for more information.
Thanks pic.twitter.com/Ca7toM3VDz
— eThekwini Municipality (@eThekwiniM) December 9, 2019
UPDATE: Stage 4 #Loadshedding has been implemented. Additions to the already load shed blocks (4A & 8A) are 1A and 5B. All to be restored at 12:30^BP pic.twitter.com/v8IrVmuS2v
— @CityPowerJhb (@CityPowerJhb) December 9, 2019
ESKOM has escalated loadshedding to STAGE 4 from 10H00. Stage 4 schedule for today:
* 10H00 - 14H30: Groups 6, 7, 8, 1
* 18H00 - 22H30: geysers, Groups 7, 8, 1
— Nelson Mandela Bay Municipality (@NMandelaBaymuni) December 9, 2019
Here are tips on how to be safe on the road during Eskom loadshedding. You are also advised to check your security system before the lights go out.
Follow more RNEWS articles, subscribe to our YouTube channel and for breaking news LIKE us on Facebook. For news on the Western Cape click here.
For great savings on life's little pleasures visit Bargain Buys! Know somebody who is getting married, Wedding and Function can assist. Have kids, then you need to visit Kids Connection. Enjoy food and travel, then visit Home Food and Travel. Need assistance with an online presence, visit Agency One.


THE Cub Report- 04.18.2011- Version- Vettel Finally Gets Beat! « Big Squid RC – RC Car and Truck News, Reviews, Videos, and More!
THE Cub Report- 04.18.2011- Version- Vettel Finally Gets Beat!
Red Bull Racings Seb Vettel has simply pwn'd the entire F1 field this season, well at least until last weekend! Thankfully Lewis "Moons Over My" Hamilton stepped it up to take the win Sunday in China. Unfortunately for me I'm a big Michael Schumacher fan, and once again it was another weekend without Schu on the podium. Here's to hoping Schu and his Mercedes put it on the box, and soon!
The Supercross series went through Seattle Washington over the weekend, a stop where most sx fans thought Washington State native Ryan Villopodium was a shoe-in for the win. Well… a very soft and rutted Seattle track made even the worlds best riders look like they were human, everyone except James Stewart who won handily. Villopodium didn't make the podium, which featured Bubba on top, K-Dub on the second step, and "The Rage'n Australian" Chad Reed finished third. So… with only two rounds left in the series- Villopotto still leads the series, Speedy Reedy is only 6 points down in second, Dungey sits third 7 points down, and Stewart is putting on one hell of a charge for fourth 9 points down. Without doubt the 2011 Supercross series will go down in history as one of the closest and most exciting in history. Never before has the SX series went into the final round with 4 guys right in the hunt. If you live anywhere near Salt Lake City or Las Vegas get your tickets now before they are sold out.
While on the topic of Supercross…. we got word last week that a company out west is look'n to shake up the rc racing scene by attempting to go burly with an annual rc supercross. It sounds like it's still in the planning stages, but if it does come to fruition you'll see major "outside the industry" sponsorship of the event, a huge venue, rc racing up on the JumboTron, and a true Supercross style race format. And just where is this event look'n to be held? Right around the good ole' 909. More info to come on this one….
So how about some inside scoop-age from around the BSRC office? One of the biggest issues of debate around our office is the look of our front page. We are a web company, so that might sound like a no brainer, but…. some of the crew want to see a minimal amount of advertising on the site (sold at a higher rate), while others are fine with a dozen ads littering the front page (sold at a lower rate). I'm from the school of "less is more", and while I dig sites like RedRC, the amount of ads they sport freak'n irritates the hell out of me. And from my industry perspective, if I'm an advertiser on BigSquid (or RedRC, or RcTech etc) I'd much rather have my logo seen on each page view- not have my ad pop up once every 80 views, or stuck so far at the bottom of the page it only gets seen by bots. So the debate rages on around the office, but I'm hoping we cut the number of ads back- sponsors will get better exposure, and it's a lot less irritating for those that view our site. Do you have an opinion on this one? If so, shoot us an email, don't be shy! Brian at BigSquidRC dot com or Cubby at BigSquidRC dot com, let'r rip!
Another "issue" floating around the office- what to do about RCX Chicago in August. Rc Car Action Magazine are the people behind the show and they are direct "competition" to us, so maybe we shouldn't support the show. But… we are based out of Chicago, and it should be a good chance to get our name out there even more. Not to mention how can we resist any chance we get to hang out with other core rc'ers? Looks like it's still up in the air if we'll be "all in" for RCCA's RCX Chicago or not.
The "hot mag rumor" of the week- that overseas rc retailer HobbyKing has bought up a lot of ad space in upcoming issues, like 20+ pages worth per issue. If that is true I can't think of a faster way to alienate long time advertisers, but then the mags gotta due what they gotta do to keep the lights on. And while I know there aren't that many people that still read (or can even find) rc mags, wouldn't you rather see 20 more pages of content instead of HobbyKing ads?
In "real" rc news- I gotta say Horizon/Losi's announcement that AKA will be the tire supplier for their short course team is pretty interesting. Tires are a lucrative market as they can haul in a lot of cash for a manufacture, so it's quite interesting to see a company that was/is one of the best tire makers in the history of our hobby hand the ball off to AKA. Not to mention short course is the hottest class in the country right now, so there is a lot of money to be made selling SC tires. Interesting to see Horizon/Losi choosing to leave money on the table in the form of the SC tire market.
That's it for this week ya bunch of double helix rc addicts. Support your LHS, local tracks and bash spots!


text:
The Future Diary
The Future Diary Season 1 Episode 24
Yuno expresses her disgust at how this state of affairs prevents her and Yuki from ever surviving together. She states that since Yuki won't kill her, she will kill him and travel back in time again to meet another Yuki. Murmur shoves Yuki off a cliff, but he is saved by the sudden reappearance of Uryu, who displays powers similar to Murmur's. Cornered, Murmur and Yuno travel two years back in time to a "third world", followed by Uryu and Yuki. Uryu explains to Yuki that when Deus realised Murmur was favouring Yuno, he suspected them of being from another timeline. In order to ensure the fair running of the game, he imparted Uryu with part of his power, although she did not know so at the time. Knowing that Yuno intends to kill her past self in this world as well, Yuki rushes to her house with Uryu. When Yuki finds the third Yuno locked in a cage and choking on a mat she tried to eat, he calls for an ambulance, despite Uryu's warnings about interfering with the past. Yuno and Murmur arrive with the third world's Yuki's parents and Uryu, Yuki and the third Yuno flee.
Serie: The Future Diary
Episode Title: Searching
Mitsudomoe is a gag manga series by manga creator Norio Sakurai about the adventures of the Marui triplets in sixth grade and their newly hired teacher Satoshi Yabe as he…
37-year-old corporate worker Mikami Satoru is stabbed by a random killer, and is reborn to an alternate world. But he turns out to be reborn a slime! Thrown into this…
Genre: Action & Adventure, Animation, Comedy, Sci-Fi & Fantasy
The Morose Mononokean
Ashiya has spent the first seven days of high school stuck in the infirmary because of a youkai attaching itself to him. He ends up asking the owner of a…
Genre: Animation, Comedy, Sci-Fi & Fantasy
The adventures of seven fish-tailed kids- Molly, Gil, Oona, Deema, Nonny, Goby, and Zooli! KissAnime Review: This TV show is one of my favorite animation TV shows last time. The…
Angel Beats takes place in the afterlife and focuses on Otonashi, a boy who lost his memories of his life after dying. He is enrolled into the afterlife school and…
Genre: Action & Adventure, Animation, Comedy, Drama, Sci-Fi & Fantasy
Hanada Shounen-shi
Hanada Shōnen Shi is a Japanese manga series written and illustrated by Makoto Isshiki about a mischievous young boy, called Hanada Ichiro, who attains the ability to see and talk…
Genre: Animation, Comedy, Drama, Sci-Fi & Fantasy
Kiba, a fantasy anime by Madhouse and Aniplex, began broadcasting on TV Tokyo on April 5, 2006. The series is directed by Hiroshi Kōjina with Upper Deck Japan, a trading…
Genre: Animation, Sci-Fi & Fantasy
In the distant future, two groups of soldiers battle for control of the least desirable piece of real estate in the known universe: a box canyon in the middle of…
KissAnime Review: Marsupilami – one of the best animationTV series, I ever seen. I accept that my expectations are very low before I see this TV series. I was so…
Barbie: Life in the Dreamhouse
The series is set as a reality TV-esque show following Barbie, her sisters and her friends in the day-to-day activities that take place in the Dreamhouse and surrounding areas. Much…
Max and Ruby
Meet two funny bunny siblings, the energetic and mischievous Max, and the patient, smart and goal-oriented Ruby. The show models empowering messages by showing Max and Ruby playing together and…
To Love-Ru is a Japanese manga series written by Saki Hasemi, and illustrated by Kentaro Yabuki, creator of Black Cat. The manga was serialized in Shueisha's manga magazine Weekly Shōnen…


Along with an ever before enhancing and also tremendously increasing seepage fee of cellular phone customers in India, the SMS text is actually coming to be a crucial method of inter-personal interaction. Delivering SMS notifications to a minimum lot of consumers might come yet delivering bulk SMS information by means of a cellular phone will be actually a funny activity. The ideal component of this advancement is actually that it is actually entirely free of charge for everybody that makes use of a mobile phone and also a pc. 2 apps, the mobile phone messaging companies and the Microsoft Excel, have actually been actually linked to make a brand new user interface for sending out bulk SMS notifications in one try.
Along With SMS XL 1.5 connect – in you perform virtually absolutely nothing. Whatever information you possess simply import it into Microsoft Excel. You receive therefore lots of SMS information layouts. The software application is going to carry out the remainder of whatever. Your SMS notification is going to instantly be actually included to the mobile phone varieties of your phone-list. The SMS plug-in, in fact, connects the SMS notification and also the mobile phone amounts.
Through this unanticipated free of charge software application, you will certainly be actually doing sending out functionalities within a couple of few seconds merely. It promotes you along with simple accessibility to a substantial lot of cellular phone customers just about promptly. If you are actually a consumer of desktop and job often on MS Excel after that this energy is actually of severe relevance for you." Bulk SMS text messaging plug-in for Excel" is actually an ingenious principle and also you can easily send out bulk SMS within a handful of secs along with its own treatment. In your workplace, the entire of your personnel will be actually profited using this electrical as it saves opportunity greatly.
Many striking components of the free of charge software application and SMS plug-in feature its own convenience of utilization, the simplicity of producing SMS notification themes, uncomplicated established, and also customization of each SMS information. Delivering SMS notifications straight coming from the MS Excel spreadsheets is actually an included benefit for all those that are actually energetic in straight advertising, multi-level-marketing (MLM), and multi-level marketing organizations.


text:
Playdead co-founder unveils new sci-fi adventure called Somerville
By Andy Chalk 2017-06-27T17:45:38.177Z
Dino Patti previously worked on atmospheric platformers Limbo and Inside.
Dino Patti, the co-founder of Limbo and Inside studio Playdead, left the company in 2016 to "seek new challenges". Today, as reported by GamesIndustry, he revealed that one of those challenges is a new studio called Jumpship, founded with feature film animator Chris Olsen, which is currently working on a new "sci-fi action adventure" called Somerville.
"It's taken many early rises and late nights crafting this passion project of mine, and it's a dream come true to be given the opportunity to bring others on who can help to make Somerville everything it can be," Olsen said in a statement. "Dino is a great collaborator and his pedigree challenges every facet of the process. We're excited to show you what Jumpship has to offer."
Alas, there isn't much to show at this point. Jumpship.co.uk describes Somerville as "a Sci-Fi Action Adventure that chronicles the lives of key individuals in the wake of a global catastrophe," and bears a cryptic, vaguely ominous header warning that, "In neon sky our kin are lost, till future has returned to dust." Aside from that, however, it's just platitudes about the new studio's overarching goals.
"Our philosophy is to break preconceived notions of what games can be by exploring the creative possibilities of the medium," the site says. "We believe in games as a legitimate and positive endeavor; with potential not only as an entertainment medium, but as a tool to question the human condition. We strive to support our intent with an unwavering ethic in all facets of the process."
There's a little more to see over at the Somerville Tumblr, which features quite a number of very "work in progress" animations and short video clips. Most of it is relatively old, but the visual style is strongly reminiscent of Limbo and Inside: More colorful, perhaps, but with the same sort of shadowy, solitary ambiance.
The teaser video that accompanied today's announcement is striking too, particularly the bit at the end where alien shenanigans appear to be afoot, and as one of the head guys on both Limbo and Inside Patti brings undeniable credibility to the project. At the very least, it's one worth paying attention to, although it'll likely be awhile before the concept becomes reality: Patti and Olsen currently appear to be the only permanent members of the new studio, although they hope to get that number up to eight by the end of the year.


text:
Q: Tikz surface should conceal markers I want to recreate a plot I originally did in Matlab.
It is an opaque surface with additionally plotted lines including markers.
The matlab picture I want to recreate with a concealed and unconcealed marker:

Some of these markers are "below" and some "above" the surface from the viewpoint. I also want this difference to be visible in Latex, but I dont know how. I tried with different layers "clip mode=individual", but then all points were concealed.
The surface in latex:

The surface in latex with clip mode = individual:

I know it is a slight different data set than in Matlab, but with view={0}{0}, I can verify that some points should be above and some below the surface aswell.
Hopefully my question is understandable and would be thankful, if someone could help.
I tried with the following code:
\begin{figure}
        \centering
\begin{tikzpicture}
\begin{axis}[height = 10cm,
            width = 0.8\textwidth,
            axis x line*=bottom,
            axis y line*=left,
            view={20}{20},
   clip mode=individual,
            grid=both]

  \addplot3+[]table[x=y1, y=x, z=z1 ]{data/TsurfLines.txt};
  \addlegendentry{Row 1}
  \addplot3+[]table[x=y2, y=x, z=z2 ]{data/TsurfLines.txt};
  \addlegendentry{Row 2}
  \addplot3+[]table[x=y3, y=x, z=z3 ]{data/TsurfLines.txt};
  \addlegendentry{Row 3}
  \addplot3+[]table[x=y4, y=x, z=z4 ]{data/TsurfLines.txt};
  \addlegendentry{Row 4}
  \addplot3+[]table[x=y5, y=x, z=z5 ]{data/TsurfLines.txt};
  \addlegendentry{Row 5}
  \addplot3[surf,shader=interp,opacity=0.7] file {data/Tsurf.txt};
  \addlegendentry{Model}

\end{axis}
\end{tikzpicture}
\caption{...}
\end{figure}

A: PGFPlots does not have a z buffer extending outside of the individual plots, so what you want can not be done without manual work. You can pick the points yourself or if you have a threshold number or formula, you can use a filter like this:
\documentclass[tikz, border=1cm]{standalone}
\usepackage{pgfplots}
\pgfplotsset{compat=1.18}
\begin{document}
\begin{tikzpicture}
\begin{axis}[
view={20}{20},
xmin=0, xmax=1,
ymin=0, ymax=1,
zmin=0, zmax=1,
clip mode=individual,
]
\addplot3[
only marks, domain=0.01:1, samples=10, samples y=1,
z filter/.expression={0.2+0.1*sin(1000*y)<0.2?z:nan},
] (0.5,x,{0.2+0.1*sin(1000*x)});
\addplot3[surf, shader=interp, opacity=0.8, domain=0.01:1, samples=100, samples y=2] (x,y,{(x-1)^2-0.01/x});
\addplot3[
only marks, domain=0.01:1, samples=10, samples y=1,
z filter/.expression={0.2+0.1*sin(1000*y)>0.2?z:nan},
] (0.5,x,{0.2+0.1*sin(1000*x)});
\end{axis}
\end{tikzpicture}
\end{document}


Today we add the snowflake wall. We placed the mini trees and added the star of the show deer! Tomorrow is wiring the whole thing so we can add the green grass. The yard is becoming harder and harder to walk in. I will be painting a new sign tomorrow it looks like!


If you take a look at my picture, what types of results can I expect from a chin augmentation? Will it really look that different? I don't really know how the procedure will work but it would be amazing to get a more defined chin. Are there different sizes of chin that a person can get? Or do you just have to somewhat guess the size you need?
Are chin fillers as effective as a chin implant?


Estate planning and estate administration deceased person's assets will be distributed. Other planning tools can assist an individual plan for incapacitation through medical and financial powers of attorney. Whether you are interested in creating a will or trust or you need to probate a will on behalf of a loved one, it is necessary that you consult with an experienced and skilled estate planning and probate attorney to protect your finances and legal rights.
At Thomas & Thomas Attorneys At Law, our estate planning and administration attorneys routinely assist our clients in the drafting of simple wills and trusts. We also help clients create living wills and power of attorney documents in order to secure financial stability and proper medical care for later in life.
Creating a will and taking time to prepare for the future will protect you and your family members from future disputes. Our attorneys will assist you in making the legal preparations to ensure your intentions are legally enforceable.
Our lawyers will take the time to understand your needs and fully explain your options and alternatives when drafting a will or trust. We are also experienced in revising older wills to accommodate life changes or new directives. We listen to our clients and ensure that their objectives with regard to other family members are appropriately addressed and advocate on behalf of our clients to ensure that their rights are protected and that their intentions are legally viable.
If you are interested in creating a power of attorney, we can assist you in completing and filing the appropriate documentation to protect your rights and interests. We also assist individuals create living wills to assert their medical and health care directives should they become incapacitated.
We routinely represent executors or beneficiaries in probate or in will contests and are experienced in the number of complex issues that may arise during the administration of a will. In estate administration, our attorneys will work with you to handle inheritance tax, facilitate the planned distribution of assets according to the will, and manage existing bank accounts and other assets including savings, retirement, and life insurance.
If you are seeking accomplished and effective advocacy in estate administration or probate, please contact our firm for an initial consultation or case evaluation.
Contact Thomas & Thomas Attorneys At Law at 610-559-9271 or contact us online to schedule your free consultation or case evaluation with our experienced estate administration and probate lawyers. Our office is conveniently located in Easton, Pennsylvania, and we represent clients in probate throughout the state.


The proposed park over Ga. 400 in Buckhead received a blow as a survey of potential park donors came back showing many are not bullish on the idea. The report recommended scaling back the donation expectations.
Initial planning has suggested that $75 million of the $250 million projected construction costs be funded by philanthropic donations. The philanthropic feasibility study, conducted by Coxe Curry & Associates, suggested that be scaled back to $25 million, with more funding coming from public sources.
A rendering shows an aerial view of the proposed park over Ga. 400.
Several potential donors interviewed questioned the worthiness of the park for philanthropic donations, as it would benefit surrounding private businesses. They also questioned if it is worth the large investment given that other infrastructure projects are needed in the city.
The proposed park would cap Ga. 400 between Peachtree and Lenox roads, provide green space and bring a redesigned Buckhead MARTA Station.
The Buckhead Community Improvement District, which originally envisioned the idea, set up a nonprofit to manage the park's formation after questions over the appropriateness of the CID's involvement as a group set up to reduce traffic congestion. However, the Coxe Curry report and other feedback suggested the CID be more closely involved because of its capacity and history of handling large-scale infrastructure projects, said Jim Durrett, the CID's executive director.
Twenty-one potential donors were interviewed and, despite their concerns, 17 said they would consider donating to the park, according to a summary of the report read by Durrett at the May 23 CID board meeting. The names of the entities or individuals interviewed were not released.
Grants and funds are planned to be requested from several public entities, including the city of Atlanta, the Georgia Department of Transportation and MARTA. New special taxes were once floated to help fund the park, but the CID and nonprofit have since said they don't want or expect to use taxes.
Some interviewees suggested naming rights and other sponsorships be considered to help fund the park.
Several of the concerns have been previously expressed by two CID board members, District 7 Councilmember Howard Shook and Lenox Square mall manager Robin Suggs. No comments were made by board members at the meeting. Shook was not present.
The concept and park design was viewed positively by most interviewees, but they questioned if it would help solve what they see as Buckhead's biggest problem, which is traffic, Durrett said.
Some interviewees expressed that, although the park would connected to MARTA with the Buckhead Station located inside it, the park would likely be perceived as park for Buckhead, not the city or region as a whole, the report said.
Some wanted to know what the CID's involvement in the project will look like going forward, which Durrett said will be determined by the board using the feedback from the report.
"Some questioned if the nonprofit was the most appropriate entity to take on the technical things that needed to be taken on in order to deliver a big capital project," the report said.
The nonprofit board is chaired by Barbara Kaufman Fleming, an entrepreneur. Other members include business owners, an engineer and real estate attorney.
The report recommended the nonprofit serve as more of a park advocate and fundraising arm rather the project manager.
Concerns that the park would be seen as an economic benefit to the adjacent property owners hurts the case that it is "a community asset worth of philanthropic support," the report said.
Many said the expected $250 million is a "huge investment" and questioned if it was appropriate given the other needed infrastructure investments around the city, according to the report.
Many argued that large philanthropic donations for parks are often made when the park will serve to revitalize an area. The park over 400 would be in an area already developed and economically stable.
Durrett said the consulting team is reviewing the project to see if some proposed parts, such as streetscaping, can be scaled back to lessen the costs.