With BOM.CSV containing
MOD001,SA201,1
MOD001,PA402,1
MOD002,SA200,2
SA222,SA600,2
SA222,SA601,3
SA201,PA401,2
SA201,PA702,1
PA401,R2345,2
PA402,R5544,10
and Demand.CSV containing
MOD001,5
MOD002,3
this is one way of trying to calculate your result
In[1]:= ClearAll["Global`*"];(*Clear all existing assignments*)
w = Import["BOM.CSV"];
x = GatherBy[w, First];(*Group entries by ParentID*)
y = MapThread[SetDelayed, {Map[ToExpression[#[[1,1]]]&, x],
Map[Plus@@Table[ToExpression[#[[i,2]]]*#[[i,3]], {i,1,Length[#]}]&, x]}];(*Create BOM assignments*)
z = Import["Demand.CSV"];
List@@Plus@@Expand[Map[ToExpression[First[#]]*Last[#]&, z]]
Out[4]= {5 PA702, 20 R2345, 50 R5544, 6 SA200}
Please test this on a smaller, but actual, example before throwing 4000*108000 at it.
Note: This depends on all your item identifiers beginning with a letter and having only letters and digits in the identifier.
Perhaps someone can see a way to make the definition of y half as complicated or find another far simpler method of doing all this.
What y does is evaluate ParentID:=ChildID*ChildQty+ChildID*ChildQty+... for each unique ParentID in the build of materials file.