Buscar en este blog

martes, 17 de febrero de 2015

Crear empleado, alta y baja por código x++ en Dynamics Ax 2012


Para crear un empleado por código en Ax necesitamos varias líneas, el siguiente código es útil cuando los empleados no se necesitan crear con dimensiones financieras. La primera parte es la creación, posteriormente agrego la forma de cómo usarlo en un job, que bien pudiera ser la salida de una lectura de un archivo de excel y finalmente el código cuando es necesario darlo de baja.

public void creaEmpleado(FirstName _nombre, MiddleName _segundoNombre, LastName _apellidos,
                         HcmPersonnelNumberId _ClaveTrabajador, Date _fechaIngreso,
                         Date _fechaBaja, Email _mail, HcmPositionId _positionId,
                         str _tipoAccion)
{
    HcmWorker               HcmWorker;
    dirPerson               dirPerson;
    dirPersonName           dirPersonName;
    HcmEmployment           HcmEmployment;
    HcmTitle                HcmTitle;
    HcmPersonnelNumberId    PersonnelNumber;
    Name                    firstName, middleName, lastName, name;
    dirPartyTable           dirPartyTable;
    HcmActionState          hcmActionState;
    HRMParameters           hcmParameters;
    HcmActionTypeSetup      hcmActionTypeSetup;
 
    LogisticsLocation LogisticsLocationElectronic;
    LogisticsElectronicAddress  LogisticsElectronicAddress;
    utcDateTime     fechaIngreso, fechaBaja;
    str             vProfessionalTitle;
    str             strEmail;
    ;
 
    try
    {
        hcmParameters = HRMParameters::find();

        PersonnelNumber = _ClaveTrabajador;
 
        ttsBegin;
        HcmWorker = hcmWorker::findByPersonnelNumber(PersonnelNumber, true);

        if(!HcmWorker)
            hcmWorker.PersonnelNumber = PersonnelNumber;
 
        firstName = strLRTrim(_nombre);
        middleName = strLRTrim(_segundoNombre);
        lastName  = strLRTrim(_apellidos);
        name  = firstName + " " + middleName + " " + lastName;

        //ajustando fechas
        if (_fechaIngreso)
            fechaIngreso = DateTimeUtil::newDateTime(_fechaIngreso, 0, DateTimeUtil::getCompanyTimeZone());
        else
            fechaIngreso = DateTimeUtil::minValue();
 
        if (_fechaBaja)
            fechaBaja = DateTimeUtil::newDateTime(_fechaBaja, 0, DateTimeUtil::getCompanyTimeZone());
        else
            fechaBaja = DateTimeUtil::maxValue();
 
        if (HcmWorker.Person)
        {
            dirPartyTable = dirPartyTable::find(dirPerson::find(HcmWorker.Person).PartyNumber);
            if (!dirPartyTable)
            {
                DirPartyTable = DirPartyTable::grwcreateNew(name, firstName, middleName, lastName);
            }
            else
            {
                dirPersonName   = DirPersonName::find(HcmWorker.Person, true);
                dirPersonName.ValidFrom = fechaIngreso;
                dirPersonName.ValidTo = fechaBaja;
                dirPersonName.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);
                dirPersonName.FirstName     = firstName;
                dirPersonName.MiddleName    = middleName;
                dirPersonName.LastName      = lastName;
                dirPersonName.write();
            }
        }
        else
        {
            DirPartyTable = DirPartyTable::grwcreateNew(name, firstName, middleName, lastName);
        }
 
        dirPerson = dirPerson::find(DirPartyTable.RecId, true);
 
        dirPerson.ProfessionalTitle = this.getPosition(strLRTrim(_positionId)).PositionId;
        vProfessionalTitle          = dirPerson.ProfessionalTitle;
        dirPerson.NameSequence      = DirNameSequence::find( "FirstMiddleLast").RecId;
        dirPerson.LanguageId        = "es-mx";
 
        dirPerson.write();
 
        HcmWorker.Person = dirPerson.RecId;
 
        HcmWorker.write();
 
        if(!HcmTitle::findByTitle(dirPerson.ProfessionalTitle))
        {
            HcmTitle.TitleId    = dirPerson.ProfessionalTitle;
            HcmTitle.insert();
        }
 
        HcmEmployment = HcmEmployment::findByWorkerLegalEntity(HcmWorker.RecId, CompanyInfo::find().RecId, DateTimeUtil::minValue(), DateTimeUtil::maxValue(), true);
 
        if(!HcmEmployment)
        {
            HcmEmployment.LegalEntity    = CompanyInfo::find().RecId;
            HcmEmployment.Worker         = HcmWorker.RecId;

            HcmEmployment.ValidFrom = fechaIngreso;
            HcmEmployment.ValidTo = fechaBaja;
        }
 
        HcmEmployment.EmploymentType = HcmEmploymentType::Employee;
 
        if(!HcmEmployment)
            HcmEmployment.write();
        else
            HcmWorkerTransition::newUpdateHcmEmployment(hcmEmployment, HcmEmployment.ValidFrom, HcmEmployment.ValidTo);

        /*//Estas líneas sirven en caso de que se requiera guardar registro de cada actividad
        //sobre los empleados, ya sea contrataciones, bajas, cambios de puesto
        select firstonly hcmActionTypeSetup
        where hcmActionTypeSetup.Name == hcmParameters.grwAltaEmpleado &&
              hcmActionTypeSetup.ActionType == HcmActionType::Hire;

        hcmActionState.clear();
        hcmActionState.Originator = hcmWorker.RecId;
        hcmActionState.ActionTypeSetup = hcmActionTypeSetup.RecId;
        hcmActionState.ApprovalStatus = HcmApprovalStatus::Completed;
        hcmActionState.insert();*/

        strEmail    = _mail;

        if (strEmail)
        {
            LogisticsLocationElectronic = LogisticsLocation::create( "Correo electrónico", NoYes::No);
            LogisticsElectronicAddress.clear();
            LogisticsElectronicAddress.Location = LogisticsLocationElectronic.RecId;
            LogisticsElectronicAddress.Description = name;
            LogisticsElectronicAddress.Type     = LogisticsElectronicAddressMethodType::Email;
            LogisticsElectronicAddress.Locator  = strEmail;
            LogisticsElectronicAddress.IsPrimary = NoYes::Yes;
            LogisticsElectronicAddress.insert();
 
            DirParty::addLocation(dirPerson.RecId, LogisticsLocationElectronic.RecId, false, true);
 
            DirPartyTable = DirPartyTable::find(DirPartyTable.PartyNumber, true);
            DirPartyTable.PrimaryContactEmail = LogisticsElectronicAddress.RecId;
            DirPartyTable.doUpdate();
        }

        ttsCommit;

    }
    catch (exception::Error)
    {
        error( "Proceso cancelado");
        ttsabort;
    }
}  

La llamada mediante job quedaría:

La llamada quedaría:

static void llamada(Args _args)
{
    date ingreso, fin;
    GRW_ServiceOperationEmpleados clase = new GRW_ServiceOperationEmpleados();

    ingreso = 01\01\2015;
    fin = 09\02\2016;

    clase.creaEmpleado( "Jose", "Luis" , "Lopez", "4300009", ingreso, fin, "joselopez@gmail.com" , "123", "ALTA MANUAL" );

    info( "termino");
}

Y en Ax, en el módulo de recursos humanos veríamos esto:



Baja de empleados


La baja de empleados básicamente es decirle a Ax la fecha de termino de actividades de empleado, es decir, hasta cuando son válidos los datos de ese empleado en particular y aquí debemos tomar en cuenta dos aspectos, el empleado y los datos de la persona, que en este caso son los mismos.
Entonces, basta con modificar la fecha de HcmEmployment y de DirPersonName, solo que debemos considerar ciertos puntos que se muestran en el código porque estas tablas tienen la propiedad de ValidTimeStateFieldType; este método también lo uso para volver a reactiar/contratar un empleado.

private void bajaEmpleado(FirstName _nombre, MiddleName _segundoNombre, LastName _apellidos,
                          HcmPersonnelNumberId _ClaveTrabajador, Date _fechaIngreso,
                          Date _fechaBaja, Email _mail, HcmPositionId _positionId,
                          str _tipoAccion)
{
    HcmEmployment           hcmEmployment;
    HcmWorker               hcmWorker;
    utcDateTime             fechaBaja, fechaUTCMin, fechaUTCMax;
    DirPersonName           dirPersonName;

    if (_fechaBaja)
        fechaBaja = DateTimeUtil::newDateTime(_fechaBaja, 0, DateTimeUtil::getCompanyTimeZone());
    else
        fechaBaja = DateTimeUtil::maxValue();

    ttsBegin;
    hcmWorker = HcmWorker::findByPersonnelNumber(_ClaveTrabajador);
   
    fechaUTCMin = DateTimeUtil::minValue();
    fechaUTCMax = DateTimeUtil::maxValue();
   
    //Para modificar la fecha de alta o baja de un empleado se deben modificar
    //dos tablas HcmEmploymetn y DirPersonName que son las tablas que tienen
    //fecha de validez para el empledo
    while select forUpdate firstOnly validTimeState(fechaUTCMin, fechaUTCMax)
                 hcmEmployment where HcmEmployment.Worker == hcmWorker.RecId
    {
        if(hcmEmployment)
        {
            //Cuando se hace modificación a fechas de una tabla con la propiedad ValidTimeStateFieldType
            //se debe indicar que se va a realizar una corrección a la fecha, para eso es la
            //siguiente instrucción
            hcmEmployment.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);
            hcmEmployment.ValidTo = fechaBaja;
            hcmEmployment.update();
        }
    }
   
    //validTimeState se debe poner para que podamos seleccionar los registros que
    //no son validos para la fecha actual, si solo ponemos un select normal
    //no nos va a regresar nada la consulta
    while select forUpdate firstOnly validTimeState(fechaUTCMin, fechaUTCMax)
                 dirPersonName where dirPersonName.Person == hcmWorker.Person
    {
        if(dirPersonName)
        {
            dirPersonName.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);
            dirPersonName.ValidTo = fechaBaja;
            dirPersonName.update();
        }
    }
   
    ttsCommit;
}


Y por cierto, acuerdate de darle click a algún anuncio si el post te sirvio de algo.


No olvides que te puedes unir a la página en Facebook Aprendiendo Dynamics Ax donde únicamente se tratan temas de desarrollo y se busca crear una comunidad de desarrollador@s de Ax en nuestro idioma. 


1 comentario:

  1. grwcreateNew es un método nuevo verdad? LO podrían poner también?

    ResponderEliminar