Regarding your question about grouping by aliased columns, see this question.
Regarding your question about the query you're trying to write, you've got two closely related errors that I see. First, when you group by the employee's name, that means you want exactly one record per distinct name. This means that you can't use fields like p.UnitPrice and p.UnitsInStock in your SELECT list, because there is no guarantee that there will be exactly one value of those fields per employee. SQL Server will report this issue with an error like the following.
Msg 8120, Level 16, State 1, Line 4
Column 'p.UnitPrice' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
When you want to select data that is not in your GROUP BY clause, you need to use an aggregate function, i.e. a function that transforms the collection of values that apply to a single record into a single value. In this case, you should look into the SUM function.
The second problem is that you're using HAVING to do something that ought to be done by your WHERE clause. The difference between the two is that the conditions in your WHERE clause are applied to individual records to determine whether or not they'll be included in the result set, before any grouping is done, whereas HAVING conditions are applied to groups as a whole, and will typically use aggregate functions. So for instance, if you wanted to limit your result set to employees whose total order value is above a certain threshold, HAVING would be appropriate. But if you just try to check a single value of ShippedDate in the HAVING clause, you'll get an error like this:
Msg 8121, Level 16, State 1, Line 7
Column 'ShippedDate' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
Use the WHERE clause instead.