//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package psdi.app.person;

import java.rmi.RemoteException;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Vector;
import psdi.app.common.AncMbo;
import psdi.app.common.AvailCalc;
import psdi.app.labor.LaborRemote;
import psdi.app.labor.LaborSetRemote;
import psdi.app.signature.MaxUserRemote;
import psdi.app.signature.MaxUserSetRemote;
import psdi.mbo.Mbo;
import psdi.mbo.MboRemote;
import psdi.mbo.MboSet;
import psdi.mbo.MboSetRemote;
import psdi.mbo.MboValueInfo;
import psdi.mbo.SqlFormat;
import psdi.mbo.StatefulMbo;
import psdi.mbo.StatusHandler;
import psdi.mbo.Translate;
import psdi.security.SecurityService;
import psdi.security.UserInfo;
import psdi.server.MXServer;
import psdi.util.BidiUtils;
import psdi.util.MXApplicationException;
import psdi.util.MXApplicationYesNoCancelException;
import psdi.util.MXException;
import psdi.util.MXFormat;
import psdi.util.MXSystemException;
import psdi.util.RandomGenerator;
import psdi.workflow.WorkflowPersonDeletionMonitor;

public class Person extends StatefulMbo implements PersonRemote, AncMbo {
    private MboRemote primaryPhone = null;
    private MboRemote primaryEmail = null;
    private String PERSONDATA_DELROW = "DELROW";
    private String PERSONDATA_NULL = "NULL";
    private String PERSONDATA_RANDOMIZE = "RANDOMIZE";
    private String PERSONDATA_MAXTYPE_UPPER = "UPPER";
    MboRemote primaryCal = null;
    public boolean toChangeStatus = true;
    public Date dateTo = null;

    public Person(MboSet ms) throws MXException, RemoteException {
        super(ms);
    }

    public void init() throws MXException {
        super.init();
//        this.setFieldFlag("status", 7L, true);
        if (!this.getMboValue("location").isNull() || !this.getMboValue("shiptoaddress").isNull() || !this.getMboValue("billtoaddress").isNull()) {
            this.setFieldFlag("locationsite", 128L, true);
        }

        try {
            if (this.getString("LOCATIONORG") != null && this.getString("LOCATIONORG") != "") {
                this.setValue("ORGID", this.getString("LOCATIONORG"), 11L);
            }

            if (this.getString("LOCATIONSITE") != null && this.getString("LOCATIONSITE") != "") {
                this.setValue("SITEID", this.getString("LOCATIONSITE"), 11L);
            }

            if (MXServer.isMTEnabled()) {
                SecurityService secServ = (SecurityService)MXServer.getMXServer().lookup("SECURITY");
                if (this.toBeAdded()) {
                    secServ.processConsultant(this, false, false);
                } else {
                    secServ.processConsultant(this, this.getBoolean("isconsultant"), false);
                }
            }

        } catch (RemoteException var2) {
            throw new MXSystemException("system", "unknownobject", var2);
        }
    }

    protected MboSetRemote getStatusHistory() throws MXException, RemoteException {
        return this.getMboSet("PERSONSTATUS");
    }

    protected StatusHandler getStatusHandler() {
        return new PersonStatusHandler(this);
    }

    public String getStatusListName() {
        return "PERSONSTATUS";
    }

    public String getDefaultDisplayName() throws MXException, RemoteException {
        return ((PersonService)this.getMboServer()).getDefaultDisplayName(this.getString("firstname"), this.getString("firstname"), this.getUserInfo());
    }

    public void add() throws MXException, RemoteException {
        super.add();
        this.setValue("status", this.getTranslator().toExternalDefaultValue("personstatus", "ACTIVE", this), 11L);
        this.setValue("transemailelection", this.getTranslator().toExternalDefaultValue("TRANSEMAILELECTION", "NEVER", this), 11L);
        this.setValue("statusdate", MXServer.getMXServer().getDate());
        this.setValue("wfmailelection", this.getTranslator().toExternalDefaultValue("WFMAILELECTION", "PROCESS", this), 11L);
    }

    public void appValidate() throws MXException, RemoteException {
        super.appValidate();
        if (!this.isNull("delegate")) {
            this.isDelegateLoopCreated();
        }

        if (MXServer.isMTEnabled()) {
            SecurityService secServ = (SecurityService)MXServer.getMXServer().lookup("SECURITY");
            secServ.processConsultant(this, this.getBoolean("isconsultant"), true);
        }

        if (!this.isNull("usernotftype") && MXServer.getMXServer().getMaximoDD().getTranslator().toInternalString("NOTFTYPE", this.getString("usernotftype")).equals("SMS")) {
            this.validateSMSTwilio();
        }

    }

    private void validateSMSTwilio() throws RemoteException, MXException {
        MboSetRemote eventSet = null;

        try {
            eventSet = MXServer.getMXServer().getMboSet("MAXENDPOINTDTL", this.getUserInfo());
            eventSet.setQbeExactMatch(true);
            eventSet.setQbe("endpointname", "TWILIOSMS");
            eventSet.setQbe("property", "ACCOUNT_SID");
            MboRemote mbo = eventSet.moveFirst();
            if (mbo != null && mbo.getString("property").equalsIgnoreCase("ACCOUNT_SID") && mbo.isNull("value")) {
                throw new MXApplicationException("oslc", "nosmsaccount");
            }
        } finally {
            if (eventSet != null) {
                eventSet.close();
            }

        }

    }

    public void canDelete() throws MXException, RemoteException {
        super.canDelete();
        WorkflowPersonDeletionMonitor.doCheck(this);
        if (!this.getMboSet("USER").isEmpty()) {
            throw new MXApplicationException("person", "CannotDeleteForUser");
        } else if (!this.getMboSet("LABOR").isEmpty()) {
            throw new MXApplicationException("person", "CannotDeleteForLabor");
        } else if (!this.getMboSet("ASSUPERVISOR").isEmpty()) {
            throw new MXApplicationException("person", "CannotDeleteForSupervisor");
        } else if (!this.getMboSet("ASDELEGATE").isEmpty()) {
            throw new MXApplicationException("person", "CannotDeleteForDelegate");
        } else {
            SqlFormat sqfJP = new SqlFormat("supervisor=:1");
            sqfJP.setObject(1, "JOBPLAN", "SUPERVISOR", this.getMboValue("personid").getString());
            MboSetRemote jpSet = this.getMboSet("$JOBPLAN", "JOBPLAN", sqfJP.format());
            if (!jpSet.isEmpty()) {
                throw new MXApplicationException("person", "CannotDeleteForJPSupervisor");
            } else {
                SqlFormat sqfPersonGroup = new SqlFormat("respparty=:1");
                sqfPersonGroup.setObject(1, "PERSONGROUPTEAM", "RESPPARTY", this.getMboValue("personid").getString());
                MboSetRemote personGroupSet = this.getMboSet("$PERSONGROUPTEAM", "PERSONGROUPTEAM", sqfPersonGroup.format());
                if (!personGroupSet.isEmpty()) {
                    throw new MXApplicationException("person", "CannotDeleteForPersonGroup");
                } else {
                    SqlFormat sqfTicket = new SqlFormat("owner=:1");
                    sqfTicket.setObject(1, "TICKET", "OWNER", this.getMboValue("personid").getString());
                    MboSetRemote ticketSet = this.getMboSet("$TICKET", "TICKET", sqfTicket.format());
                    if (!ticketSet.isEmpty()) {
                        throw new MXApplicationException("person", "CannotDeleteForTicketOwner");
                    } else {
                        SqlFormat sqfTicketTemplate = new SqlFormat("owner=:1");
                        sqfTicketTemplate.setObject(1, "TKTEMPLATE", "OWNER", this.getMboValue("personid").getString());
                        MboSetRemote ticketTemplateSet = this.getMboSet("$TKTEMPLATE", "TKTEMPLATE", sqfTicketTemplate.format());
                        if (!ticketTemplateSet.isEmpty()) {
                            throw new MXApplicationException("person", "CannotDeleteForTicketTemplateOwner");
                        } else {
                            SqlFormat sqfCommTemp = new SqlFormat("sendtovalue=:1 and type ='PERSON'");
                            sqfCommTemp.setObject(1, "COMMTMPLTSENDTO", "SENDTOVALUE", this.getString("personid"));
                            MboSetRemote commTempSet = this.getMboSet("$COMMTMPLTSENDTO", "COMMTMPLTSENDTO", sqfCommTemp.format());
                            if (!commTempSet.isEmpty()) {
                                throw new MXApplicationException("person", "CannotDeleteForCommTemp");
                            } else {
                                SqlFormat sqfBilltoShipto = new SqlFormat("(shiptocontact=:1 and shipto=1) or (billtocontact=:1 and billto=1)");
                                sqfBilltoShipto.setObject(1, "BILLTOSHIPTO", "BILLTOCONTACT", this.getMboValue("personid").getString());
                                MboSetRemote billtoShiptoSet = this.getMboSet("$BILLTOSHIPTO", "BILLTOSHIPTO", sqfBilltoShipto.format());
                                if (!billtoShiptoSet.isEmpty()) {
                                    throw new MXApplicationException("person", "CannotDeleteForSite");
                                } else {
                                    MboSetRemote assetCustSet = this.getMboSet("ASSETUSERCUST");
                                    if (!assetCustSet.isEmpty()) {
                                        throw new MXApplicationException("person", "CannotDeleteForAssetCust");
                                    } else {
                                        MboSetRemote locCustSet = this.getMboSet("LOCATIONUSERCUST");
                                        if (!locCustSet.isEmpty()) {
                                            throw new MXApplicationException("person", "CannotDeleteForLocCust");
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public void delete(long accessModifier) throws MXException, RemoteException {
        super.delete(accessModifier);
        this.getMboSet("PERSONSTATUS").deleteAll(2L);
        this.getMboSet("PERSONCAL").deleteAll(2L);
        this.getMboSet("EMAIL").deleteAll(2L);
        this.getMboSet("PHONE").deleteAll(2L);
        this.getMboSet("PERSCOMMODITY").deleteAll(2L);
    }

    protected boolean skipCopyField(MboValueInfo mvi) throws MXException, RemoteException {
        if (mvi.getName().equalsIgnoreCase("personid")) {
            return true;
        } else {
            return mvi.getName().equalsIgnoreCase("personuid");
        }
    }

    protected void inactivate(String status, Date asOfDate, String memo) throws MXException, RemoteException {
        this.toChangeStatus = true;
        PersonSetRemote personSet = (PersonSetRemote)this.getMboSet("ASDELEGATE");
        if (!personSet.isEmpty()) {
            throw new MXApplicationException("PERSON", "FailInactivateDelegate");
        } else {
            personSet = (PersonSetRemote)this.getMboSet("ASSUPERVISOR");
            if (!personSet.isEmpty()) {
                throw new MXApplicationException("PERSON", "FailInactivateSupervisor");
            } else {
                MboSetRemote personMboSet = this.getMboSet("USER");
                if (!personMboSet.isEmpty() && personMboSet.getUserName().equalsIgnoreCase(this.getString("personid"))) {
                    throw new MXApplicationException("PERSON", "CannotInactivateUser");
                } else {
                    SqlFormat sqf = new SqlFormat("supervisor=:1 and status  in (select value from synonymdomain where domainid='JOBPLANSTATUS' and maxvalue not in('REVISED','CANCEL'))");
                    sqf.setObject(1, "PERSON", "PERSONID", this.getMboValue("personid").getString());
                    MboSetRemote jpSet = this.getMboSet("$JOBPLAN", "JOBPLAN", sqf.format());
                    if (!jpSet.isEmpty()) {
                        throw new MXApplicationException("PERSON", "FailInactivateJPSupervisor");
                    } else {
                        SqlFormat sqfTicket = new SqlFormat("owner=:1 and status  in (select value from synonymdomain where domainid in ('SRSTATUS','INCIDENTSTATUS','PROBLEMSTATUS') and maxvalue not in('CLOSED','RESOLVED'))");
                        sqfTicket.setObject(1, "PERSON", "PERSONID", this.getMboValue("personid").getString());
                        MboSetRemote ticketSet = this.getMboSet("$TICKET", "TICKET", sqfTicket.format());
                        if (!ticketSet.isEmpty()) {
                            int index = 0;

                            for(MboRemote ticketMbo = ticketSet.getMbo(index); ticketMbo != null; ticketMbo = ticketSet.getMbo(index)) {
                                String statuslistname = this.getTranslator().toInternalString("TKCLASS", ticketMbo.getString("class")) + "STATUS";
                                String ticketStatus = this.getTranslator().toInternalString(statuslistname, ticketMbo.getString("status"));
                                if (!ticketStatus.equalsIgnoreCase("CLOSED")) {
                                    throw new MXApplicationException("person", "FailInactivateTicketOwner");
                                }

                                ++index;
                            }
                        }

                        SqlFormat sqfBilltoShipto = new SqlFormat("(shiptocontact=:1 and shipto=1) or (billtocontact=:1 and billto=1)");
                        sqfBilltoShipto.setObject(1, "BILLTOSHIPTO", "BILLTOCONTACT", this.getMboValue("personid").getString());
                        MboSetRemote billtoShiptoSet = this.getMboSet("$BILLTOSHIPTO", "BILLTOSHIPTO", sqfBilltoShipto.format());
                        if (!billtoShiptoSet.isEmpty()) {
                            throw new MXApplicationException("person", "FailInactivateSite");
                        } else {
                            SqlFormat sqfPersonGroup = new SqlFormat("respparty=:1");
                            sqfPersonGroup.setObject(1, "PERSON", "PERSONID", this.getMboValue("personid").getString());
                            MboSetRemote personGroupSet = this.getMboSet("$PERSONGROUPTEAM", "PERSONGROUPTEAM", sqfPersonGroup.format());
                            if (!personGroupSet.isEmpty()) {
                                throw new MXApplicationException("person", "FailInactivatePersonGroup");
                            } else {
                                String commTempList = "PERSON";
                                SqlFormat sqfCommTemp = new SqlFormat("sendtovalue=:1 and type in ('" + commTempList + "')");
                                sqfCommTemp.setObject(1, "COMMTMPLTSENDTO", "SENDTOVALUE", this.getString("personid"));
                                MboSetRemote commTempSet = this.getMboSet("$COMMTMPLTSENDTO", "COMMTMPLTSENDTO", sqfCommTemp.format());
                                if (!commTempSet.isEmpty()) {
                                    throw new MXApplicationException("person", "FailInactivateCommTemp");
                                } else {
                                    LaborSetRemote labors = (LaborSetRemote)this.getMboSet("LABOR");
                                    StringBuffer statusLabList = new StringBuffer(this.getTranslator().toExternalList("laborstatus", "INACTIVE", this));
                                    LaborRemote labor = null;

                                    for(int i = 0; (labor = (LaborRemote)labors.getMbo(i)) != null; ++i) {
                                        if (!this.getTranslator().toInternalString("laborstatus", labor.getString("status")).equals(this.getTranslator().toInternalString("personstatus", status))) {
                                            if (statusLabList.indexOf(status) > -1) {
                                                labor.changeStatus(status, asOfDate, memo);
                                            } else {
                                                labor.changeStatus(this.getTranslator().toInternalString("personstatus", status), asOfDate, memo);
                                            }
                                        }
                                    }

                                    MaxUserSetRemote users = (MaxUserSetRemote)this.getMboSet("USER");
                                    StringBuffer statusUserList = new StringBuffer(this.getTranslator().toExternalList("maxuserstatus", "INACTIVE", this));
                                    MaxUserRemote user = null;

                                    for(int i = 0; (user = (MaxUserRemote)users.getMbo(i)) != null; ++i) {
                                        if (!this.getTranslator().toInternalString("maxuserstatus", user.getString("status")).equals(this.getTranslator().toInternalString("maxuserstatus", status))) {
                                            if (statusUserList.indexOf(status) > -1) {
                                                user.changeStatus(status, asOfDate, memo);
                                            } else {
                                                user.changeStatus(this.getTranslator().toInternalString("personstatus", status), asOfDate, memo);
                                            }
                                        }
                                    }

                                    String decomList = this.getTranslator().toExternalList("LOCASSETSTATUS", "DECOMMISSIONED");
                                    String sql = " personid = :personid and assetnum in (select assetnum from asset where asset.assetnum=assetusercust.assetnum  and asset.siteid=assetusercust.siteid and  asset.status not in (" + decomList + "))";
                                    MboSetRemote assetCustSetNonDecom = this.getMboSet("$_validAssetUserCust", "ASSETUSERCUST", sql);
                                    UserInfo userInfo = this.getUserInfo();
                                    if (!assetCustSetNonDecom.isEmpty()) {
                                        throw new MXApplicationException("person", "FailInactivateAssetCust");
                                    } else {
                                        sql = " personid = :personid and assetnum in (select assetnum from asset where asset.assetnum=assetusercust.assetnum  and asset.siteid=assetusercust.siteid and asset.status in (" + decomList + "))";
                                        MboSetRemote assetCustSetDecomOnly = this.getMboSet("$_validAssetUserCust", "ASSETUSERCUST", sql);
                                        if (!assetCustSetDecomOnly.isEmpty()) {
                                            int userInput = MXApplicationYesNoCancelException.getUserInput("deleteAssetUserCustDecomAssets", MXServer.getMXServer(), this.getUserInfo());
                                            switch(userInput) {
                                                case -1:
                                                    Object[] obj = new Object[]{this.getString("personid")};
                                                    if (BidiUtils.isBidiEnabled()) {
                                                        obj[0] = BidiUtils.buildAndPush("PERSON", "PERSONID", (String)obj[0], userInfo.getLangCode());
                                                    }

                                                    throw new MXApplicationYesNoCancelException("deleteAssetUserCustDecomAssets", "person", "deleteAssetUserCust", obj);
                                                case 2:
                                                    assetCustSetDecomOnly.deleteAll(2L);
                                                    this.toChangeStatus = true;
                                                    break;
                                                case 4:
                                                    this.toChangeStatus = false;
                                                    return;
                                            }
                                        }

                                        sql = " personid = :personid and location in (select location from locations where locations.location=locationusercust.location  and locations.siteid=locationusercust.siteid and locations.status not in (" + decomList + "))";
                                        assetCustSetDecomOnly = this.getMboSet("$_validLocationUserCust", "LOCATIONUSERCUST", sql);
                                        if (!assetCustSetDecomOnly.isEmpty()) {
                                            throw new MXApplicationException("person", "FailInactivateLocCust");
                                        } else {
                                            sql = " personid = :personid and location in (select location from locations where locations.location=locationusercust.location  and locations.siteid=locationusercust.siteid and locations.status  in (" + decomList + "))";
                                            MboSetRemote locCustSetDecomOnly = this.getMboSet("$_validLocUserCust", "LOCATIONUSERCUST", sql);
                                            if (!locCustSetDecomOnly.isEmpty()) {
                                                int userInput = MXApplicationYesNoCancelException.getUserInput("deleteAssetUserCustDecomAssets", MXServer.getMXServer(), this.getUserInfo());
                                                switch(userInput) {
                                                    case -1:
                                                        Object[] obj = new Object[]{this.getString("personid")};
                                                        if (BidiUtils.isBidiEnabled()) {
                                                            obj[0] = BidiUtils.buildAndPush("PERSON", "PERSONID", (String)obj[0], userInfo.getLangCode());
                                                        }

                                                        throw new MXApplicationYesNoCancelException("deleteAssetUserCustDecomAssets", "person", "deleteAssetUserCust", obj);
                                                    case 2:
                                                        locCustSetDecomOnly.deleteAll(2L);
                                                        this.toChangeStatus = true;
                                                        break;
                                                    case 4:
                                                        this.toChangeStatus = false;
                                                        return;
                                                }
                                            }

                                            this.toChangeStatus = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public void isDelegateLoopCreated() throws MXException, RemoteException {
        MboRemote currPerson = this;
        String thisPersonID = this.getString("personid");
        Vector personVector = new Vector();
        personVector.add(this);
        Vector personKeyVector = new Vector();
        String personKey = null;
        personKey = this.getString("personid");
        personKeyVector.addElement(personKey);

        do {
            currPerson = ((MboRemote)currPerson).getMboSet("DELEGATE").getMbo(0);
            if (currPerson == null || ((MboRemote)currPerson).isNull("delegate")) {
                return;
            }

            personKey = ((MboRemote)currPerson).getString("personid");
            if (personKeyVector.contains(personKey)) {
                return;
            }

            personKeyVector.addElement(personKey);
            personVector.add(currPerson);
        } while(!((MboRemote)currPerson).getString("delegate").equals(thisPersonID));

        this.checkDelegateDateLoop(personVector);
    }

    private void checkDelegateDateLoop(Vector personVector) throws MXException, RemoteException {
        String thisPersonID = this.getString("personid");
        GregorianCalendar startCurrent = new GregorianCalendar();
        GregorianCalendar endCurrent = new GregorianCalendar();
        GregorianCalendar startRange = new GregorianCalendar();
        GregorianCalendar endRange = new GregorianCalendar();
        Date sr = ((PersonRemote)personVector.get(0)).getDate("delegatefromdate");
        Date er = ((PersonRemote)personVector.get(0)).getDate("delegatetodate");
        if (sr != null) {
            startRange.setTime(sr);
            startRange.set(10, 0);
            startRange.set(12, 0);
            startRange.set(13, 0);
            startRange.set(14, 0);
        } else {
            startRange = null;
        }

        if (er != null) {
            endRange.setTime(er);
            endRange.set(10, 0);
            endRange.set(12, 0);
            endRange.set(13, 0);
            endRange.set(14, 0);
        } else {
            endRange = null;
        }

        for(int i = 1; i < personVector.size(); ++i) {
            Date sc = ((PersonRemote)personVector.get(i)).getDate("delegatefromdate");
            Date ec = ((PersonRemote)personVector.get(i)).getDate("delegatetodate");
            if (sc != null) {
                startCurrent.setTime(sc);
                startCurrent.set(10, 0);
                startCurrent.set(12, 0);
                startCurrent.set(13, 0);
                startCurrent.set(14, 0);
            } else {
                startCurrent = null;
            }

            if (ec != null) {
                endCurrent.setTime(ec);
                endCurrent.set(10, 0);
                endCurrent.set(12, 0);
                endCurrent.set(13, 0);
                endCurrent.set(14, 0);
            } else {
                endCurrent = null;
            }

            if (startRange == null || startCurrent == null) {
                Object[] p = new Object[]{thisPersonID, ((PersonRemote)personVector.get(i)).getString("personid")};
                throw new MXApplicationException("person", "DelegateLoop", p);
            }

            if (endRange == null && endCurrent == null) {
                if (startCurrent.after(startRange)) {
                    startRange = (GregorianCalendar)startCurrent.clone();
                }
            } else if (endRange == null) {
                if (!startCurrent.before(startRange)) {
                    startRange = (GregorianCalendar)startCurrent.clone();
                    endRange = (GregorianCalendar)endCurrent.clone();
                } else {
                    if (endCurrent.before(startRange)) {
                        return;
                    }

                    endRange = (GregorianCalendar)endCurrent.clone();
                }
            } else if (endCurrent == null) {
                if (startCurrent.after(endRange)) {
                    return;
                }

                if (!startCurrent.before(startRange) && !startCurrent.after(endRange)) {
                    startRange = (GregorianCalendar)startCurrent.clone();
                }
            } else if (startCurrent.after(startRange) || endCurrent.before(endRange)) {
                if (!startCurrent.after(startRange) && !endCurrent.after(endRange) && !endCurrent.before(startRange)) {
                    endRange = (GregorianCalendar)endCurrent.clone();
                } else if (!startCurrent.before(startRange) && !startCurrent.after(endRange) && !endCurrent.before(endRange)) {
                    startRange = (GregorianCalendar)startCurrent.clone();
                } else {
                    if (startCurrent.before(startRange) || startCurrent.after(endRange) || endCurrent.before(startRange) || endCurrent.after(endRange)) {
                        return;
                    }

                    startRange = (GregorianCalendar)startCurrent.clone();
                    endRange = (GregorianCalendar)endCurrent.clone();
                }
            }
        }

        Object[] p = new Object[]{thisPersonID, this.getString("personid")};
        throw new MXApplicationException("person", "DelegateLoop", p);
    }

    public String getSupervisees() throws MXException, RemoteException {
        MboSetRemote superviseeSet = this.getMboSet("ASSUPERVISOR");
        PersonRemote supervisee = null;
        String superviseeList = "";
        if (superviseeSet.isEmpty()) {
            return "";
        } else {
            int count = superviseeSet.count();

            for(int i = 0; i < count; ++i) {
                supervisee = (PersonRemote)superviseeSet.getMbo(i);
                if (!superviseeList.equals("")) {
                    superviseeList = superviseeList + ",";
                }

                superviseeList = superviseeList + supervisee.getString("personid");
                String children = supervisee.getSupervisees();
                if (!children.equals("")) {
                    superviseeList = superviseeList + "," + children;
                }
            }

            return superviseeList;
        }
    }

    public void setPrimaryPhone(MboRemote inPhone) throws MXException, RemoteException {
        this.primaryPhone = inPhone;
    }

    public void setPrimaryEmail(MboRemote inEmail) throws MXException, RemoteException {
        this.primaryEmail = inEmail;
    }

    public MboRemote getPrimaryPhone() throws MXException, RemoteException {
        return this.primaryPhone;
    }

    public MboRemote getPrimaryEmail() throws MXException, RemoteException {
        return this.primaryEmail;
    }

    public Date getEndDateFromCalendar(Date startDate, String duration, String orgid) throws MXException, RemoteException {
        AvailCalc availCalc = new AvailCalc();
        double remainingDuration = MXFormat.durationToDouble(duration);
        String sql = "personid=:1 and orgid=:2";
        SqlFormat sqf = new SqlFormat(sql);
        sqf.setObject(1, "PERSONCAL", "PERSONID", this.getString("personid"));
        sqf.setObject(2, "PERSONCAL", "ORGID", orgid);
        MboRemote personCal = this.getMboSet("$PERSONCAL", "PERSONCAL", sqf.format()).getMbo(0);
        if (personCal == null) {
            return null;
        } else {
            String calnum = personCal.getString("calnum");
            String shiftnum = personCal.getString("shiftnum");
            String person = this.getString("personid");

            while(true) {
                String availCalendars = availCalc.checkAvailableCalendar(startDate, startDate, (String)null);
                if (availCalendars.indexOf(personCal.getString("calnum")) <= 0) {
                    return null;
                }

                double availHours = availCalc.checkAvailableHours(startDate, (PersonCalRemote)personCal);
                if (availHours > remainingDuration) {
                    GregorianCalendar returnCal = new GregorianCalendar();
                    returnCal.setTime(startDate);
                    returnCal.add(10, (int)remainingDuration);
                    returnCal.add(12, (int)((remainingDuration - (double)((int)remainingDuration)) * 60.0D));
                    return returnCal.getTime();
                }

                Date nextdate = availCalc.getNextWorkDateForCal(startDate, person, calnum, shiftnum, orgid);
                if (nextdate == null) {
                    return null;
                }

                remainingDuration -= availHours;
                startDate = availCalc.getStartDateTime(nextdate, (PersonCalRemote)personCal);
            }
        }
    }

    public double getTodaysHours(Date startDate, String orgid) throws MXException, RemoteException {
        GregorianCalendar currCal = new GregorianCalendar();
        GregorianCalendar startCal = new GregorianCalendar();
        double workhours = 0.0D;
        new ArrayList();
        List modvailmbos = this.getAvailableMboList(startDate, (String)orgid, (AvailCalc)null);

        for(int i = 0; i < modvailmbos.size(); ++i) {
            MboRemote availMbo = (MboRemote)modvailmbos.get(i);
            if (availMbo == null) {
                workhours += 0.0D;
            } else {
                currCal.setTime(MXServer.getMXServer().getDate());
                startCal.setTime(availMbo.getDate("starttime"));
                workhours += availMbo.getDouble("workhours");
            }
        }

        if (workhours == 0.0D) {
            return workhours;
        } else {
            currCal.add(11, -startCal.get(11));
            currCal.add(12, -startCal.get(12));
            double currhours = (double)currCal.get(11) + (double)currCal.get(12) / 60.0D;
            return currhours < 0.0D ? 0.0D : workhours - currhours;
        }
    }

    public double getAvailableHours(Date startDate, String orgid) throws MXException, RemoteException {
        return this.getAvailableHours(startDate, (String)orgid, (AvailCalc)null);
    }

    public double getAvailableHours(Date startDate, String orgid, AvailCalc availCalc) throws MXException, RemoteException {
        MboRemote personCal;
        String sql;
        SqlFormat sqf;
        if (orgid != null && !orgid.equals("")) {
            sql = "personid=:1 and orgid=:2";
            sqf = new SqlFormat(sql);
            sqf.setObject(1, "PERSONCAL", "PERSONID", this.getString("personid"));
            sqf.setObject(2, "PERSONCAL", "ORGID", orgid);
            personCal = this.getMboSet("$PERSONCAL", "PERSONCAL", sqf.format()).getMbo(0);
            if (personCal == null) {
                return 0.0D;
            }
        } else {
            sql = "personid=:1 and isprimary=:yes";
            sqf = new SqlFormat(sql);
            sqf.setObject(1, "PERSONCAL", "PERSONID", this.getString("personid"));
            personCal = this.getMboSet("$PERSONCAL", "PERSONCAL", sqf.format()).getMbo(0);
            if (personCal == null) {
                return 0.0D;
            }
        }

        return this.getAvailableHours(startDate, (PersonCalRemote)personCal, availCalc);
    }

    public double getAvailableHours(Date startDate, PersonCalRemote personCal, AvailCalc availCalc) throws MXException, RemoteException {
        if (availCalc == null) {
            availCalc = new AvailCalc();
        }

        return availCalc.checkAvailableHours(startDate, personCal);
    }

    public MboRemote getAvailableMbo(Date startDate, String orgid) throws MXException, RemoteException {
        return this.getAvailableMbo(startDate, (String)orgid, (AvailCalc)null);
    }

    public List<MboRemote> getAvailableMboList(Date startDate, String orgid) throws MXException, RemoteException {
        return this.getAvailableMboList(startDate, (String)orgid, (AvailCalc)null);
    }

    public MboRemote getAvailableMbo(Date startDate, String orgid, AvailCalc availCalc) throws MXException, RemoteException {
        MboSetRemote personCalSet = null;

        MboRemote personCal;
        try {
            String sql;
            SqlFormat sqf;
            Object var8;
            if (orgid != null && !orgid.equals("")) {
                sql = "personid=:1 and orgid=:2";
                sqf = new SqlFormat(sql);
                sqf.setObject(1, "PERSONCAL", "PERSONID", this.getString("personid"));
                sqf.setObject(2, "PERSONCAL", "ORGID", orgid);
                personCalSet = this.getMboSet("$PERSONCAL", "PERSONCAL", sqf.format());
                personCalSet.reset();
                personCal = personCalSet.getMbo(0);
                if (personCal == null) {
                    var8 = null;
                    return (MboRemote)var8;
                }
            } else {
                sql = "personid=:1 and isprimary=:yes";
                sqf = new SqlFormat(sql);
                sqf.setObject(1, "PERSONCAL", "PERSONID", this.getString("personid"));
                personCalSet = this.getMboSet("$PERSONCAL", "PERSONCAL", sqf.format());
                personCalSet.reset();
                personCal = personCalSet.getMbo(0);
                if (personCal == null) {
                    var8 = null;
                    return (MboRemote)var8;
                }
            }
        } finally {
            if (personCalSet != null) {
                personCalSet.close();
            }

        }

        return this.getAvailableMbo(startDate, (PersonCalRemote)personCal, availCalc);
    }

    public List<MboRemote> getAvailableMboList(Date startDate, String orgid, AvailCalc availCalc) throws MXException, RemoteException {
        MboSetRemote personCalSet = null;

        MboRemote personCal;
        try {
            String sql;
            SqlFormat sqf;
            Object var8;
            if (orgid != null && !orgid.equals("")) {
                sql = "personid=:1 and orgid=:2";
                sqf = new SqlFormat(sql);
                sqf.setObject(1, "PERSONCAL", "PERSONID", this.getString("personid"));
                sqf.setObject(2, "PERSONCAL", "ORGID", orgid);
                personCalSet = this.getMboSet("$PERSONCAL", "PERSONCAL", sqf.format());
                personCalSet.reset();
                personCal = personCalSet.getMbo(0);
                if (personCal == null) {
                    var8 = null;
                    return (List)var8;
                }
            } else {
                sql = "personid=:1 and isprimary=:yes";
                sqf = new SqlFormat(sql);
                sqf.setObject(1, "PERSONCAL", "PERSONID", this.getString("personid"));
                personCalSet = this.getMboSet("$PERSONCAL", "PERSONCAL", sqf.format());
                personCalSet.reset();
                personCal = personCalSet.getMbo(0);
                if (personCal == null) {
                    var8 = null;
                    return (List)var8;
                }
            }
        } finally {
            if (personCalSet != null) {
                personCalSet.close();
            }

        }

        return this.getAvailableMboList(startDate, (PersonCalRemote)personCal, availCalc);
    }

    public MboRemote getAvailableMbo(Date startDate, PersonCalRemote personCal, AvailCalc availCalc) throws MXException, RemoteException {
        if (availCalc == null) {
            availCalc = new AvailCalc();
        }

        MboRemote mbo = availCalc.checkAvailableMbo(startDate, personCal);
        availCalc = null;
        return mbo;
    }

    public List<MboRemote> getAvailableMboList(Date startDate, PersonCalRemote personCal, AvailCalc availCalc) throws MXException, RemoteException {
        if (availCalc == null) {
            availCalc = new AvailCalc();
        }

        List<MboRemote> mbos = availCalc.checkAvailableMboList(startDate, personCal);
        availCalc = null;
        return mbos;
    }

    public boolean isActive() throws MXException, RemoteException {
        Translate tr = this.getTranslator();
        return tr.toInternalString("PERSONSTATUS", this.getString("status")).equals("ACTIVE");
    }

    public void changeStatus(String status, Date date, String memo) throws MXException, RemoteException {
        super.changeStatus(status, date, memo);
        Object[] param = new Object[]{this.getString("personid")};
        if (BidiUtils.isBidiEnabled()) {
            param[0] = BidiUtils.buildAndPush(this.getMboSetInfo(), "personid", (String)param[0], this.getUserInfo().getLangCode());
        }

        ((MboSet)this.getThisMboSet()).addWarning(new MXApplicationException("person", "StatusChangeSuccess", param));
    }

    public PersonRemote getDelegate(Date asof) throws MXException, RemoteException {
        if (this.isNull("DELEGATE")) {
            return null;
        } else {
            Date deleDate;
            if (asof == null) {
                deleDate = MXServer.getMXServer().getDate();
            } else {
                deleDate = asof;
            }

            return !this.isNull("DELEGATEFROMDATE") && !deleDate.after(this.getDate("DELEGATEFROMDATE")) || !this.isNull("DELEGATETODATE") && !deleDate.before(this.endOfDay(this.getDate("DELEGATETODATE"))) ? null : (PersonRemote)this.getMboSet("DELEGATE").getMbo(0);
        }
    }

    public PersonRemote getLastDelegate(PersonRemote person, Date asof) throws RemoteException, MXException {
        PersonRemote delegate = null;
        delegate = person.getDelegate(asof);
        if (delegate == null) {
            return person;
        } else {
            delegate.isDelegateLoopCreated();
            return this.getLastDelegate(delegate, asof);
        }
    }

    private Date endOfDay(Date date) {
        GregorianCalendar g = new GregorianCalendar();
        g.setTime(date);
        g.set(11, 23);
        g.set(12, 59);
        g.set(13, 59);
        return g.getTime();
    }

    public String getCalType() throws MXException, RemoteException {
        return this.isNull("caltype") ? "" : this.getString("caltype");
    }

    public String getLocaleStr() throws MXException, RemoteException {
        return this.isNull("locale") ? "" : this.getString("locale");
    }

    public String getTimezoneStr() throws MXException, RemoteException {
        return this.isNull("timezone") ? "" : this.getTranslator().toInternalString("timezone", this.getString("timezone"), this);
    }

    public void updatePrimaryCalendar() throws MXException, RemoteException {
        MboSetRemote primaryCalSet = null;
        if (this.primaryCal == null || this.primaryCal.toBeDeleted()) {
            primaryCalSet = this.getMboSet("PERSONCAL");
            if (!primaryCalSet.isEmpty() && !primaryCalSet.getMbo(0).toBeDeleted()) {
                this.primaryCal = primaryCalSet.getMbo(0);
            } else {
                this.primaryCal = primaryCalSet.add();
            }
        }

        this.primaryCal.setValue("orgid", this.getString("primarycalorg"), 11L);
        this.primaryCal.setValue("calnum", this.getString("primarycalnum"), 11L);
        this.primaryCal.setValue("shiftnum", this.getString("primaryshiftnum"), 11L);
        this.setFieldFlag(new String[]{"primarycalorg", "primarycalnum"}, 128L, true);
    }

    public void deletePrimaryCalendar() throws MXException, RemoteException {
        if (this.primaryCal == null) {
            this.primaryCal = this.getMboSet("PERSONCAL").getMbo(0);
        }

        if (this.primaryCal != null) {
            this.primaryCal.delete();
            this.setValueNull("primarycalorg", 11L);
            this.setValueNull("primarycalnum", 11L);
            this.setValueNull("primaryshiftnum", 11L);
            this.setFieldFlag(new String[]{"primarycalorg", "primarycalnum"}, 128L, false);
            this.setFieldFlag("primarycalorg", 7L, false);
        }

    }

    public String[] getValidateOrder() {
        return new String[]{"locationsite", "location"};
    }

    public String getStartApp() throws RemoteException, MXException {
        return this.isNull("dfltapp") ? "" : this.getString("dfltapp");
    }

    public boolean toChangeStatusAfterInactive() throws MXException, RemoteException {
        return this.toChangeStatus;
    }

    public void setDateTo(Date dateTo) throws MXException, RemoteException {
        this.dateTo = dateTo;
    }

    public Date getDateTo() throws MXException, RemoteException {
        return this.dateTo;
    }

    public void deletePersonData() throws MXException, RemoteException {
        List<String> singleValueTables = new ArrayList();
        MboSetRemote singleValueTableSet = this.getMboSet("$MAXPDSVTABLES_DOMAIN", "ALNDOMAIN", "domainid='MAXPDSVTABLES'");

        for(Mbo table = (Mbo)singleValueTableSet.moveFirst(); table != null; table = (Mbo)singleValueTableSet.moveNext()) {
            singleValueTables.add(table.getString("value"));
        }

        singleValueTables.size();
        List<String> unProcessedFields = new ArrayList();
        MboSetRemote pdFieldSet = MXServer.getMXServer().getMboSet("MAXPDATA", this.getUserInfo());
        pdFieldSet.setOrderBy("deltype asc");

        for(Mbo field = (Mbo)pdFieldSet.moveFirst(); field != null; field = (Mbo)pdFieldSet.moveNext()) {
            String objectName = field.getString("object");
            String attributeName = field.getString("attribute");
            String relationship = field.getString("relationship");
            String removalType = field.getString("deltype");
            MboSet fieldObjectSet = (MboSet)this.getMboSet("$" + objectName + "-" + attributeName, objectName, relationship);
            boolean isSingleValueObject = false;
            if (singleValueTables.contains(objectName.toUpperCase())) {
                isSingleValueObject = true;
            }

            for(Mbo fieldObject = (Mbo)fieldObjectSet.moveFirst(); fieldObject != null; fieldObject = (Mbo)fieldObjectSet.moveNext()) {
                MboValueInfo mvi = fieldObjectSet.getMboSetInfo().getMboValueInfo(attributeName);
                String maxType = mvi.getMaxType();
                Boolean required = mvi.isRequired();
                boolean isInteger = false;
                if (maxType.toLowerCase().contains("int")) {
                    isInteger = true;
                }

                String value = fieldObject.getString(attributeName);
                int valueLength = value.length();
                String[] params;
                if (removalType.equals(this.PERSONDATA_DELROW)) {
                    if (!isSingleValueObject) {
                        unProcessedFields.add(objectName + "." + attributeName);
                        params = new String[]{objectName, attributeName};
                        throw new MXApplicationException("maxpdata", "cannotDeleteNonSingleValueTableData", params);
                    }

                    fieldObjectSet.setWhere("isPrimary=0");
                    fieldObjectSet.deleteAll(3L);
                    fieldObjectSet.save();
                    fieldObjectSet = (MboSet)this.getMboSet("$" + objectName + "-" + attributeName, objectName, relationship);
                    fieldObjectSet.deleteAll(3L);
                    fieldObjectSet.save();
                } else if (removalType.equals(this.PERSONDATA_NULL)) {
                    if (required) {
                        unProcessedFields.add(objectName + "." + attributeName);
                        params = new String[]{objectName, attributeName};
                        throw new MXApplicationException("maxpdata", "cannotNullARequiredAttribute", params);
                    }

                    fieldObject.setValue(attributeName, "", 3L);
                } else {
                    if (!removalType.equals(this.PERSONDATA_RANDOMIZE)) {
                        throw new MXApplicationException("maxpdata", "cannotDetermineRemovalType");
                    }

                    params = null;
                    String stringValue;
                    if (maxType.equals(RandomGenerator.UPPER)) {
                        stringValue = RandomGenerator.randomize(valueLength, RandomGenerator.UPPER);
                    } else if (maxType.equals(RandomGenerator.INTEGER)) {
                        stringValue = RandomGenerator.randomize(valueLength, RandomGenerator.INTEGER);
                    } else {
                        stringValue = RandomGenerator.randomize(valueLength, "");
                    }

                    if (isInteger) {
                        int integerValue = Integer.parseInt(stringValue);
                        fieldObject.setValue(attributeName, integerValue, 3L);
                    } else {
                        fieldObject.setValue(attributeName, stringValue, 3L);
                    }
                }
            }

            fieldObjectSet.save();
        }

        if (unProcessedFields.size() == 0) {
            throw new MXApplicationException("maxpdata", "completeNoFindings");
        } else {
            throw new MXApplicationException("maxpdata", "completeWithFindings", unProcessedFields.toArray());
        }
    }
}
