cancel
Showing results for 
Search instead for 
Did you mean: 

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

0 Kudos

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())); 
    }
}

Accepted Solutions (1)

Accepted Solutions (1)

0 Kudos

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.'));
                }
            }
        }
    }
}

Answers (1)

Answers (1)

Johan_H
Active Contributor
0 Kudos

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

0 Kudos

Hi Johan,

Thank you for the suggestion.

I've set the default warehouse for the item and attempted again. Same error message.

I'm a little confused as Master Item setup has not been something I usually handle and I'm using a "test" item that I created. It's entirely possible that I have incorrectly set or not set something on the item. The fact that the B1 Client allows me to do the transfer without a complaint is additionally confusing.

Your statement, "...the given warehouse was simply not determined for one of the items." Can you explain how this would be "determined" for the item?

FYI: I'm running 9.3 PL9 and I am upgrading to PL13 tonight.

Thanks again.

Johan_H
Active Contributor
0 Kudos

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