Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Microsoft Dynamics AX (Archived)

Reserve SalesLine throughcode

(0) ShareShare
ReportReport
Posted on by 135

Hi everyone,

I have to deploy a new functionality on AX. I need to do a reservation with X++ of a SalesTable selected record and select a specific pallet to do it. That its not important, the thing is i don't know what method use to do it. I find InventOnHandReserve.reserveNow() but i can't get it to work. 

I have the next code on a clicked() method. (its not complete)

void clicked()
{
    Args                        args;
    SalesTable                  salesTableLocal;
    SalesLine                   salesLine;
    InventTable                 inventTable;
    InventDim                   inventDim;
    InventSum                   inventSum;
    InventTransOrigin           inventTransOrigin;
    InventTrans                 inventTrans;
    InventQty                   qty;
    VSSPriorityLocation         vssPriorityLocation;
    WMSStandardPalletQuantity   qtyPallet;
    TmpPdsBatchSelect           tmpPdsBatchSelect;
    InventOnhandReserve         inventOnHandReserve;



    args = new Args();

    salesTableLocal = getFirstSelection(SalesTable_ds); //lo recoge bien
    //búsqueda la de las líneas de pedido de compra, Puede haber más de una línea de pedido de compra
    while select salesLine
        where salesLine.SalesId == salesTableLocal.SalesId
    {
        //búsqueda de la InventTable
        select inventTable
            where inventTable.ItemId == salesLine.ItemId;

        qtyPallet = inventTable.standardPalletQuantity; //cantidad que ocupa el artículo en el pallet

        inventTransOrigin   = InventTransOrigin::findByInventTransId(salesLine.InventTransId);
        select inventTrans
            where inventTrans.InventTransOrigin == inventTransOrigin.RecId;

        qty = inventTrans.Qty; //la cantidad del pedido

        //Si el estado de la linea es "en pedido"
        if (inventTrans.StatusIssue == StatusIssue::OnOrder)
        {
            //recorrer la tabla de prioridades para saber qué almacén/pallet usar
            while select vssPriorityLocation order by Prioridad
                where vssPriorityLocation.Tipo == PalletMode::Pallet

            {
                //si enceuntra una localización con el pallet completo
                select inventDim
                    where inventDim.InventLocationId == vssPriorityLocation.InventLocationId;

                select inventSum
                    where inventSum.InventDimId == inventDim.inventDimId;
                /*select tmpPdsBatchSelect
                    where tmpPdsBatchSelect.InventBatchId == inventDim.inventBatchId;*/

                inventOnHandReserve.reserveNow(true, inventSum, qty, inventDim);

            }

        }

    }

}


I have a few problems. 

  • InventSum its not initialized and i don't know how to do it.
  • I don't know where i should put the logical to select a specific pallet
  • I don't know if im using the right method.

VSSPriorityLocation is a table with pallet with priority, i should use the record who has the higher priority. (FYI)

Anybody knows what method i should use? this one? Where can find another method to reserve? 

Thanks.


*This post is locked for comments

  • Verified answer
    MartaDiazVila Profile Picture
    MartaDiazVila 135 on at
    RE: Reserve SalesLine throughcode

    Ok, i find a solution for my problem. 

    I search the correct record to do the reserve. 

        Query           query;
        QueryRun        queryRun;
        inventDimParm   inventDimParmCriteria;
        inventDimParm   inventDimParmGroupby;
        InventDim       inventDim;
        InventSum       inventSum;
        InventOnhandReserve inventOnHandReserve;
    
        ;
    
    while select priorityLocation order by Prioridad
            where priorityLocation.Tipo == PalletMode::Pallet
        {
    
                // Códido de artículo
                inventDimParmGroupby.ItemIdFlag             = NoYes::Yes;
                // Sitio
                inventDimParmGroupby.InventSiteIdFlag       = NoYes::Yes;
                // Almacén
                inventDimParmGroupby.InventLocationIdFlag   = NoYes::Yes;
                // Ubicación
                inventDimParmGroupby.WMSLocationIdFlag      = NoYes::Yes;
                // Transacciones cerradas
                inventDimParmCriteria.ClosedFlag            = NoYes::No;
                // Cantidad <> 0
                inventDimParmCriteria.ClosedQtyFlag         = NoYes::Yes;
                //Pallet
                inventDimParmGroupby.WMSPalletIdFlag        =NoYes::Yes;
    
                // La propia tabla InventSum nos monta una Query que podremos iterar
                // con los parámetros que hemos configurado
    
                query = InventSum::newQuery(query, _inventTable.ItemId, null, inventDimParmCriteria, inventDimParmGroupby);
    
                //Filtramos por la prioridad
                query.dataSourceTable(tablenum(InventDim)).addRange(fieldnum(inventDim, InventLocationId)).value(priorityLocation.InventLocationId);
    
                // A la query podemos añadir nuestros propios filtros
                // (igual que al formulario), por ejemplo: Física disponible > 0
    
                query.dataSourceTable(tablenum(Inventsum)).addRange(fieldnum(inventsum, AvailPhysical)).value('>0');
                query.dataSourceTable(tablenum(Inventsum)).addRange(fieldnum(inventsum, ItemId)).value(_inventTable.ItemId);
    
                // Para consultar los datos ejecutamos la query
                queryRun = new QueryRun(query);
                while (queryRun.next())
                {
                    // Podemos extraer los valores del queryRun ...
                    inventDim = queryRun.get(tableNum(InventDim));
                    inventSum = queryRun.get(tableNum(InventSum));
    
                    //reserva si la cantidad concuerda
                    if (inventDim.InventLocationId == priorityLocation.InventLocationId)
                    {
                        //choose the correct inventDim for my logic
    
                    // ... utilizarlos como queramos
    
                    info(strfmt("Alm: %1, Ubi: %2, Prod: %3, Disp: %4, Pallet:%5",
                                    inventdim.InventLocationId,
                                    inventdim.wMSLocationId,
                                    inventsum.ItemId,
                                    inventsum.AvailPhysical,
                                    inventDim.wMSPalletId));
                    }
    
                }//while queryRun
        }//while prioridad tipo Pallet


    To do the reservation step by step:

    1. In the correct InventSum, i modify InventSum.availReservationUnit to 0 (its the qty i reserve)
    2. Create a new transaction of the SaleLine with StatusIssue::ReservPhyscal and the QTY i reserved
    3. On the original transaction (StasusIssue::OnOrder) rest the qty reserved and if !=0 repeat the logic. If qty == 0 delete the OnOrder transaction.

    I hope this help someone.

  • Suggested answer
    Hossein.K Profile Picture
    Hossein.K 6,646 on at
    RE: Reserve SalesLine throughcode

    First,reverse all of Qty and then recreate new SO as you want.

  • MartaDiazVila Profile Picture
    MartaDiazVila 135 on at
    RE: Reserve SalesLine throughcode

    Hi Hossein,

    the problem with these solutions are that it makes the reservation of the entire QTY. I want to do it step by step.

    e.g.:

    i have qty = -172.

    1) search in InventLocation the required location (in my case, i have Locations with priorities)

    2) with the selected location, search (inventDim, InventSum...) the availPhysical that match with the standartQuantity of the Item (eg 84 uds).

    3)Now my problem--> i want to ONLY select 84 uds from qty (172), make a reservation for ONLY this selected 84 uds. Then i have one new transaction with 84uds, and the original qty =-172 will be qty = -88.

    4)back to 1)

    Its important do it step by step cause i have to do things inbetween. So thats my problem, i don't know how to do it.

  • Hossein.K Profile Picture
    Hossein.K 6,646 on at
    RE: Reserve SalesLine throughcode

    Hi MartaDiazVila,

    Did you get this issue fixed in the meantime?

  • Suggested answer
    Hossein.K Profile Picture
    Hossein.K 6,646 on at
    RE: Reserve SalesLine throughcode
    Reserving inventory by code:
    
    static void ReserveQty(Args _args)
    {
    SalesLine SalesLine = SalesLine::findRecId(35522);
    InventDim InventDim = SalesLine.inventDim();
    InventUpd_Reservation reservation;
    ;
    reservation = InventUpd_Reservation::newMovement(InventMovement::construct(SalesLine,true,inventDim),-5,true);
    reservation.updateNow();
    
    }
    
  • Suggested answer
    Hossein.K Profile Picture
    Hossein.K 6,646 on at
    RE: Reserve SalesLine throughcode

    Hi MartaDiazVila,

    server static void inventReservation(InventTransId   _inventTransId,
           InventSerialId  _inventSerialId,
           Qty             _qty ,
           boolean         _unreserve=false)
    {
        InventUpd_Reservation   inventUpd_Reservation;
        inventMovement            inventMovement;
        InventSerial                   invserial;
        inventdim                      inventDim,iDimNew;
        SalesLine                       salesLine;
        ;
        try
        {
            ttsbegin;
            salesLine = SalesLine::findInventTransId(_inventTransId);
            if (!salesline)
                throw error(‘Sales Order Line could not be found !’);
            invSerial = InventSerial::find(_inventSerialId,salesLine.ItemId);
            if (!invSerial)
                throw error(‘Inventory Serial Number could not be found !’);
            inventDim                = salesLine.inventDim();
            inventdim.inventSerialId = _inventSerialId;
            iDimNew                  = inventDim::findOrCreate(inventDim);
            inventMovement = InventTrans::findTransId(salesLine.InventTransId).inventMovement(true);
            inventUpd_Reservation = InventUpd_Reservation::newInventDim(inventMovement,iDimNew,_unreserve ? _qty : -_qty);
            inventUpd_Reservation.updateNow();
            ttscommit;
        }
        catch (Exception::Deadlock)
        {
            retry;
        }
    }


  • MartaDiazVila Profile Picture
    MartaDiazVila 135 on at
    RE: Reserve SalesLine throughcode

    Hi Rustem, thanks for your answer,

    I saw this on internet, but in this case, where can i choose the correct pallet??

  • Suggested answer
    Rustem Galiamov Profile Picture
    Rustem Galiamov 8,072 on at
    RE: Reserve SalesLine throughcode

    Hi MartaDiazVila!

    Try to use InventUpd_Reservation class like this example:

    reservation = InventUpd_Reservation::newMovement(inventMovement, inventTrans.Qty, false, true, false, 0);
    reservation.parmInventDimCriteria(inventDim);
    localInventDimParm.initFromInventDim(inventDim);
    reservation.parmInventDimParm(localInventDimParm);
    reservation.parmInventDimFixed(InventDimFixedClass::inventDimParm2InventDimFixed(localInventDimParm));
    reservation.updateNow();


Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Announcing Our 2025 Season 1 Super Users!

A new season of Super Users has arrived, and we are so grateful for the daily…

Vahid Ghafarpour – Community Spotlight

We are excited to recognize Vahid Ghafarpour as our February 2025 Community…

Tip: Become a User Group leader!

Join the ranks of valued community UG leaders

Leaderboard

#1
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 292,494 Super User 2025 Season 1

#2
Martin Dráb Profile Picture

Martin Dráb 231,305 Most Valuable Professional

#3
nmaenpaa Profile Picture

nmaenpaa 101,156

Leaderboard

Featured topics

Product updates

Dynamics 365 release plans