Auto-Assigning all warehouses to part

,

I’ve been trying to figure out how to assign all warehouses to each newly created part via a BPM but not sure where to begin on doing so.

I know this can be done via DMT, but we want the assignment to happen automatically upon the creation of new parts, having to update warehouses via DMT each time is too time consuming.

Thanks in advance.

If when adding a new part you duplicate it from a part that has all the warehouses attached, the new part will have them as well.

That was an option, but it was requested that it just auto-assigns on the creation of a new part.

I asked this a while ago (but with adding sites too). But got no help then :frowning:

I do it in code post processing, but I am going to try to do it in wizards, but am 0 for 3 tries so far. This is my first attempt are using the widgets so if anyone has a starter guide that would be great.

Here is a post processing widget bpm that will add two warehouses. You would just repeat the GetNewWhse, Set PartWhse.WareHouseCode, Part.Update as needed. The custom code at the end refreshes the screen so the user doesn’t have to.

Thanks to @markdamen for his post and picture I mimicked.

Greg

image new part add whse.bpm (53.4 KB)

2 Likes

Has anyone tried or got any ideas to generate this functionality by scanning down all the warehouses and adding any PartWarehouse records that are missing as opposed to having to hard code the Warehouses into the Directive?

@rdcrozier If you look at the code generated by the widget in the source directory on the server it is calling GetNewPartWhse, setting the WarehouseCode and updating. You could a foreach on Warehse then use an .any to check for that warehouse on a part. On a single part this would be post processing on add just like the version here. This could also be done using a UD update to kick off a process to cover all existing parts.

Greg,
Unfortunately we are on Public Cloud and as far as I know personally we can’t have access to the generated code, unless of course you have a way of doing it, in which case, please share!

@rdcrozier Sorry, I am onprem and have no idea about the cloud.

Greg

Hi,

I not strong in C#, so the question would, maybe some one has C# custom code for addindg multy whse for part(or something similar for learning). I mean I want to make a loop and add from like WhseList, but I think that is not so simple as seting one field, in this I think I need to call BO to GetNewWhse, but have no idea how the code should look like.

@Justas Download the bpm above and do it with widgets. That is the best way to do things in Epicor going forward.

Yes this is good option and the best way is to use widgets. But this works when we creating part manually, but we also use QBUID to import parts and boms in to system and some how this BPM block QBUILD import. So the other option would be to make scheduled BPM from function which once a week would pick a list of parts by creation date and then using loop would add WHSES for a list of parts. The bad thing that I can not figure out how to make a loop with widgets or how to store a list of parts in variable. I know how to do all this with C# except how to add 5 new whses for the part becouse it needs to call BO.

Long back I prepared C# code for Same, May be helpful.

	//--------------------------------------warehouse loop------------------------------------------
								DataSet dsNewPart=adapterPart.GetData(PartNum);
								whereClause=String.Empty;
								DataTable dtWareList= GetBAQ("IIT_PartSubscription_WhseList"); 
								DataView dvw = new DataView(dtWareList);
								whereClause +="Warehse_Company = '"+itemCompany+"'";
								whereClause += " AND ";
								whereClause += "Warehse_Plant = '"+itemPlant.Substring(itemPlant.IndexOf("~")+1).Substring(0,(itemPlant.Substring(itemPlant.IndexOf("~")+1)).IndexOf("~"))+"'"; 
								dvw.RowFilter =whereClause;  
								dtWareList=dvw.ToTable();
								
									
								for(int l=0; l< Convert.ToInt32(dtWareList.Rows.Count);l++ )
								{
									string WarehouseCode="";
									try{
										
										WarehouseCode=Convert.ToString(dtWareList.Rows[l]["Warehse_WarehouseCode"]);				    
										string wareFilter="WarehouseCode = \'" + WarehouseCode + "\' ";					
										DataRow[] drWare=dsNewPart.Tables["PartWhse"].Select(wareFilter,"WarehouseCode ASC");
										if(Convert.ToInt32(drWare.Length)<=0)
										{						
											adapterPart.GetNewPartWhse(PartNum,itemPlant.Substring(itemPlant.IndexOf("~")+1).Substring(0,(itemPlant.Substring(itemPlant.IndexOf("~")+1)).IndexOf("~")));
											DataTable dtPartware=adapterPart.PartData.PartWhse;
											dtPartware.Rows[dtPartware.Rows.Count -1]["PartNum"]=PartNum;
											dtPartware.Rows[dtPartware.Rows.Count -1]["WarehouseCode"]=WarehouseCode;
											dtPartware.Rows[dtPartware.Rows.Count -1]["PlantOwner"]=itemPlant.Substring(itemPlant.IndexOf("~")+1).Substring(0,(itemPlant.Substring(itemPlant.IndexOf("~")+1)).IndexOf("~"));		
											adapterPart.Update();

											whereClause=String.Empty;
											DataTable dtBinList= GetBAQ("IIT_PartSubscription_Bins"); 
											DataView dvb = new DataView(dtBinList);
											whereClause +="WhseBin_Company = '"+itemCompany+"'";
											whereClause += " AND ";
											whereClause += "WhseBin_WarehouseCode = '"+WarehouseCode+"'"; 
											dvb.RowFilter =whereClause;  
											dtBinList=dvb.ToTable();	
											string Bin="";
											if(dtBinList.Rows.Count>0)
											{
												Bin=Convert.ToString(dtBinList.Rows[0]["WhseBin_BinNum"]);			
												dtPartware.Rows[dtPartware.Rows.Count -1]["PrimBinNum"]=Bin;	
											}
											adapterPart.Update();
										}

										adapterPart.Update();
										
									}catch(Exception e)
										{
											
											
											LoadErrorLog();
										}
								}
	//-----------------------------------------------warehouse code loop close---------------------------------------------------------------------------

@fakhruddin , what’s in your Usings and References?

Old post, but wanted to throw this out there. This worked for me in a Pre-Processing Custom Code BPM.

 foreach(var part in ds.Part)
 {
    foreach(string wh in whseList)
    {
        var pw = ds.PartWhse.Where(w => w.WarehouseCode == wh).FirstOrDefault();
        if(pw == null)
        {
            var row = ds.PartWhse.NewRow();
            row["Company"] = "NMI";
            row["Plant"] = "MfgSys";
            row["PartNum"] = part.PartNum;
            row["WarehouseCode"] = wh;
            row.RowMod = "A";
            ds.PartWhse.Add(row);
        }
    }
 }
1 Like

Thanks @gpayne for this post and BPM file. Exactly what I was looking for, tweaked for my purposes and working like a charm!

Love delving the forum and finding old treasures like this!

Find Treasure

There are a couple of Kinetic Ideas as well, so please vote for them.
There should be a tickbox in Warehouse or Part, maybe Plant to allow ALL warehouses on a Part. Lame that we have to specify them all on every part.
We have a Warehouse IN/OUT Bin for each CNC Area as well as stockrooms so AMM creates Moves between them. We also need to be able to move parts around at-will and this is a big issue. If you don’t put all parts in all warehouses, you can’t select the one you want from the list to move inventory to and from. Fail.
Thanks for the code, it really will help with adding new parts!