Probably another way to do this, but I have to run out of the office for a bit; however, wanted to share what should work for you. Basically use derived tables to aggregate values so that you are always joining one for one OR in cases where there may not be any results you use left join and coalesce()/isnull().
If for example, you may not have any records in inventory master for an item that is on order, you may need a full outer join but assuming that you always have an inventory location defined even if it is at 0 qty.
select i.itemid, i.boh as onhand
, 0 as onorder -- add join to your PO/WO table to get this value
, coalesce(b.allocated, 0) as allocated
, i.boh - coalesce(b.allocated, 0) as freestock
from (
select itemid, sum(physicalavailable) as boh
from inventorymaster
group by itemid
) i
left outer join (
select b.itemid, sum((o.orderqty - coalesce(e.executedqty, 0))* b.req_unit) as allocated
from billofmaterialstransactions b
inner join ordermaster o on o.orderno = b.usedfor
left outer join (
select itemid, usedfor, sum(executedqty) as executedqty
from executed
group by itemid, usedfor
) e on e.itemid = b.itemid and e.usedfor = b.usedfor
group by b.itemid
) b on b.itemid = i.itemid
;
If you need further explanation, I will most certainly offer it when I return so just post any questions you have on what I am doing.