Skip to Content

B1 9.3 DI API Inventory Transfer Error: -10::Enter a valid value in "Whse" field [??????? 0-0]

Hello Experts,

I am receiving this error "-10::Enter a valid value in "Whse" field [??????? 0-0]" when calling the Add method of the Stock Transfer Object. I have verified and re-verified that both the Stock Transfer object and the Stock Transfer Lines object have the warehouse codes set for both To & From warehouses. The warehouses and these codes are correct and do exist. Some similar posts for this error message have stated information regarding item cost or unit price but that doesn't correlate with the error message. However, when I perform this action within SAP itself, I do not have issues.

For this item, the valuation method is set to Standard and the Item Cost is not set. As well, "Allow Stock Release Without Item Cost" is checked.

Any and all help that can be provided is greatly appreciated.

$bPass = true;
$trfnObj = $this->Useful->apiConfig->GetBusinessObject($this->Useful->aSAPB1Objects['Inventory Transfer']);
//Let's add to the obj
$trfnObj->CardCode = $request->CardCode;
$trfnObj->CardName = $request->CardName;
$trfnObj->ContactPerson = (int) $request->CntctCode;
$trfnObj->Address = $request->Address;
$trfnObj->PriceList = $request->GroupNum;
$trfnObj->Comments = "Service Call ".$request->U_JC1_PrintJob;
$trfnObj->FromWarehouse = $request->FromWhsCode;
$trfnObj->ToWarehouse = $request->ToWhsCode;
$trfnObj->DocDate = date('m/d/Y');
$trfnObj->JournalMemo = 'Inventory Transfers - '.$request->CardCode;
$trfnObj->UserFields->Fields->Item('U_NB_PortalCreateUser')->Value = $this->getRequest()->getSession()->read('Auth.User.full_name');
$trfnObj->UserFields->Fields->Item('U_NB_PortalUpdateUser')->Value = $this->getRequest()->getSession()->read('Auth.User.full_name');
 
$linesObj = $trfnObj->Lines;
 
$binAllocatObj = $linesObj->BinAllocations;
$binAllocatObj->BinAbsEntry = $getData['bin'];
$binAllocatObj->Quantity = $trnLine['Quantity'];
$binAllocatObj->BinActionType =  1;
$binAllocatObj->AllowNegativeQuantity = 1;
 
$linesObj->BaseEntry = $request->DocEntry;
$linesObj->BaseType = 5;
$linesObj->ItemCode = $trnLine['ItemCode'];
$linesObj->ItemDescription = $trnLine['Dscription'];
$linesObj->Quantity = $trnLine['Quantity'];
$linesObj->WarehouseCode = $request->ToWhsCode;
$linesObj->FromWarehouseCode = $request->FromWhsCode;

if ($linesObj->Add() != 0)
{
    $this->Flash->error(__(__LINE__.'::The items could not be transfered because of SAP criteria: '.$this->Useful->apiConfig->GetLastErrorCode()."::".$this->Useful->apiConfig->GetLastErrorDescription()));
    $bPass = false;
}

if ($bPass)
{
    if ($trfnObj->Add() == 0) //this is where the failure is occurring
    {
        //proceed on 
        $this->Flash->error(__('Inventory Transfer successfully created.'));
    }
    else
    {
        $this->Flash->error(__(__LINE__.'::The transfer could not be saved because of SAP criteria: '.$this->Useful->apiConfig->GetLastErrorCode()."::".$this->Useful->apiConfig->GetLastErrorDescription())); 
    }
}
Add a comment
10|10000 characters needed characters exceeded

Related questions

2 Answers

  • Best Answer
    Posted on Jul 29, 2020 at 09:54 PM

    Hi Johan,
    I did set the default warehouse as you suggested and that solved the problem of non-serialized inventory transfer. As well, you are correct about the "extra" ->Add(). Newbie mistake it was!
    However, I also needed to solve transferring serialized items with a binned warehouse on 1 side of the transfer. And then ultimately, attach that transfer to a service call.

    I saw plenty of examples for batches instead of serial numbers and where both warehouses were binned (therefore needing both a To & From bin allocation). Most I couldn't make work.


    It took me quite a bit. I received the following errors at various times: "-10 - 1470000341 - Fully allocate item", "Cannot add row without complete selection of batch/serial numbers", "1470000307 - Duplicate bin locations have been removed", "1470000838 - Invalid SerialAndBatchNumbersBaseLine".

    I include them here for others to find as well as my solution. It's PHP but I think it will get the idea across to others.

    Thank you very much for your help.

    $trfnObj = $this->Useful->apiConfig->GetBusinessObject($this->Useful->aSAPB1Objects['Inventory Transfer']);
    //Let's add the values to the object
    $this->Useful->buildAPISet($trfnObj, $postData, $this->Transfers->apiProps);
    
    $linesObj = $trfnObj->Lines; $bPass = true; 
    //loop through the line items. Do serialized separate from non-serialized. Handle the bins for both
    foreach($postData['TransferLines'] as $trnLine)
    {
        //add values to the Lines Object
        $this->Useful->buildAPISet($linesObj, $trnLine, $this->Transfers->TransferLines->apiProps); 
        if (!empty($trnLine['serials'])) //handle the serials
        {
            $serObj = $linesObj->SerialNumbers;
            for ($x = 0; $x < $trnLine['Quantity']; $x++)
            {
                $aSer = $this->Useful->getSerialRecord(strtoupper($trnLine['serials'][$x]), $trnLine['ItemCode']); //doesn't exist in a bin yet
                if (!empty($aSer))
                {
                    $serData = ['IntrSerial' => strtoupper($trnLine['serials'][$x]), 'SysSerial' => $aSer['SysNumber'], 'U_NB_PortalUpdateUser' => $this->getRequest()->getSession()->read('Auth.User.full_name')];
                    $serApiProps = ['InternalSerialNumber' => 'IntrSerial',  'SystemSerialNumber' => 'SysSerial', 'U_NB_PortalUpdateUser' => 'U_NB_PortalUpdateUser'];
                    //add the values to the Serials Object
                    $this->Useful->buildAPISet($serObj, $serData, $serApiProps); 
                    
                    $binAllocatObj = $linesObj->BinAllocations; //Remember, Add() has already been called once. 
                    //add the values to the Bin Allocation object
                    //SerialAndBatchNumbersBaseLine needs to increment by 1 for each serial # processed
                    $this->Useful->buildAPISet($binAllocatObj, ['BinAbs' => $trnLine['bin'], 'Quantity' => 1, 'BaseLine' => $x, 'BinAct' => 1], ['BinAbsEntry' => 'BinAbs', 'Quantity' => 'Quantity', 'SerialAndBatchNumbersBaseLine' => 'BaseLine', 'BinActionType' => 'BinAct']);
                    
                    //do I need to call $serObj->Add() & $binObj->Add() again
                    if ($x < $trnLine['Quantity'])
                    {
                        $serObj->Add();
                        $binAllocatObj->Add();
                    }
                }
                else //the serial # record MUST already exist in the system
                {
                    $bPass = false;
                    $this->Flash->error(__(__LINE__.'::The transfer on serialized item '.$trnLine['serials'][$x].' could not be saved. The serial # does not already exist in the system or is not assigned to this warehouse.'));
                    break; //get out of the for loop and stop processing
                }
            }
        }
        else
        {
            $binAllocatObj = $linesObj->BinAllocations; //Remember, Add() has already been called once, 
            $this->Useful->buildAPISet($binAllocatObj, ['BinAbs' => $trnLine['bin'], 'Quantity' => $trnLine['Quantity'], 'BinAct' => 1, 'AllowNeg' => 1], 
                                                       ['BinAbsEntry' => 'BinAbs', 'Quantity' => 'Quantity', 'BinActionType' => 'BinAct', 'AllowNegativeQuantity' => 'AllowNeg']); //to line
        }
        //do we need to Add() another line
        if (count($postData['TransferLines']) > 1) //Remember, Add() has already been called once,
        {
            if ($linesObj->Add() != 0)
            {
                $bPass = false;
                $this->Flash->error(__(__LINE__.'::The items could not be transfered because of SAP criteria: '.$this->Useful->apiConfig->GetLastErrorCode()."::".$this->Useful->apiConfig->GetLastErrorDescription()));
                break; //stop everything, get out of the foreach loop
            }
        }
    }
    if ($bPass) //ok, everything line-wise should be good. Let's create the actual transfer and then attach it to a service call
    {
        if ($trfnObj->Add() == 0)
        {
            $trfnKey = $this->Useful->apiConfig->GetNewObjectKey();
            if (!empty($trfnKey))
            {
                $newTrfnObj = $this->Useful->apiConfig->GetBusinessObject($this->Useful->aSAPB1Objects['Inventory Transfer']);
                $newTransfer = $newTrfnObj->GetByKey($trfnKey);
                
                if ($newTransfer)
                {
                    $service = $this->Transfers->ServiceDocs->Services->get($request->U_NB_ServiceCallNum);
                    $svcCallObj =  $this->Useful->apiConfig->GetBusinessObject($this->Useful->aSAPB1Objects['Service Calls']);
                    $svcCall = $svcCallObj->getByKey($service->callID);
                    if ($svcCall)
                    {
                        $data['DocAbs'] = $newTrfnObj->DocEntry; 
                        $data['DocNumber'] = $newTrfnObj->DocNum; 
                        $scl4 = $svcCallObj->Expenses; 
                        if ($scl4->DocEntry != 0) //do we need to add a new doc?
                        {
                            $scl4->Add(); 
                        }
                        //add values to the service docs object
                        $this->Useful->buildAPISet($scl4, ['Object' => 67, 'DocAbs' => $newTrfnObj->DocEntry, 'DocNumber' => $newTrfnObj->DocNum, 'StckTrnDir' => 0], $this->Transfers->ServiceDocs->apiProps);
                        //add values to the service call object
                        //set the "Handled By" b/c SAP has Handled By & Queue being mutually exclusive. Never know when SAP user has "de-set" this field
                        $this->Useful->buildAPISet($svcCallObj, ['isQueue' => 0, 'assignee' => $this->sap_usercode, 'U_NB_PortalCallUpdateUser' => $this->getRequest()->getSession()->read('Auth.User.full_name')], $this->Transfers->ServiceDocs->Services->apiProps);
                        if ($svcCallObj->Update() == 0)
                        {
                            $this->Useful->disconnectSAP();
                            $this->Flash->success(__('The transfer has been saved.'));
                            $this->redirect(array('controller'=>'Services', 'action' => 'view', $request->U_JC1_PrintJob));
                        }
                        else
                        {
                            $this->Flash->error(__(__LINE__."::The transfer could not be associated to the service call because of SAP criteria: ".$this->Useful->apiConfig->GetLastErrorCode()."::".$this->Useful->apiConfig->GetLastErrorDescription()."<br/>svcCallStatus: ".$svcCallObj->Status." and DocNum:".$svcCallObj->DocNum." and CallID:".$svcCallObj->ServiceCallID));
                        }
                    }
                    else
                    {
                        $this->Flash->error(__(__LINE__.'::The transfer could not be associated because the parent record in SAP could not be found. Please, try again.'));
                    }
                }
            }
        }
    }
    Add a comment
    10|10000 characters needed characters exceeded

  • Posted on Jul 23, 2020 at 05:35 AM

    Hi Todd,

    I have had a similar issue twice, and found in the end that in the first case the given warehouse was simply not determined for one of the items, and in the second case, there was no default warehouse determined for one of the items.

    For what it is worth.

    Regards,

    Johan

    Add a comment
    10|10000 characters needed characters exceeded

    • Hi Todd,

      When you look at the inventory data tab of the item master data card of an item, one of the rows, i.e. warehouses, should be bolded. If none of the rows is bolded, select one, and click the 'Set Default Whse' button.

      What I meant was, in my second case this had not been done for one of the items.

      Anyway, just took a closer look at your code, and I noticed a common "newbie" mistake. The DI API handles documents the same way as the client. That means that the first empty line of the document is provided. You fill this line, then if necessary, you add a new empty line, and fill it, etc. The line.Add() method adds this new empty line. Once you are done you only need to add the document.

      I also noticed that you are using BinAllocations this may also be the cause. I have no experience with this mechanism, but considering that the error message says 'Whse', which is not a field in either header or lines, my guess is. Please check if the BinAllocations object needs a warehouse code.

      Regards,

      Johan

Before answering

You should only submit an answer when you are proposing a solution to the poster's problem. If you want the poster to clarify the question or provide more information, please leave a comment instead, requesting additional details. When answering, please include specifics, such as step-by-step instructions, context for the solution, and links to useful resources. Also, please make sure that you answer complies with our Rules of Engagement.
You must be Logged in to submit an answer.

Up to 10 attachments (including images) can be used with a maximum of 1.0 MB each and 10.5 MB total.