Is the above code vulnerable to any kinds (error,blind,union based) of SQL injection?
No, but only because
sha1() happens by luck to produce output that never contains any SQL metacharacters.
Your query-creating code should not need to know about that implementation detail. It should be escaping the
$password_hash as well, so that the line of code works on its own, and can be verified as correct and safe without having to look at the wider context. Otherwise, when you change how that
$password_hash is calculated (say, to store a more secure salted hash), you may find that you've just created a vulnerability in that query code. Creating unnecessary coupling between disparate bits of code, potentially in different files, is in general a bad idea.
If the above code is safe, why do people still go for Prepared Statements etc...?
Because prepared statements are typically easier to read, understand and verify; it is harder to accidentally omit an escape. Compare:
$query = "SELECT id,username FROM users WHERE username = '"
."' AND password ='"
$query = $mysqli->prepare('SELECT id,username FROM users WHERE username=? AND password=?')
$query->bind_param('ss', $username, $password_hash);
Although I'm not a huge fan of mysqli's particular brand of parameterised queries (especially binding to variables instead of values), the latter still seems simpler and more maintainable to me.