There are a couple of approaches you could take with designing your table...
One would be to remove the auto increment and add your own value to the record.
Pros: You have full control over the id you're going to insert.
Cons: Concurrency is going to be an issue in that another process could have already written the ID you are about to write. Also you'd still have to keep a running counter somewhere or parse existing record ids.
Another approach is to create an additional identifier field on your table that you can populate based on the combined values you want.
Pros: The database is handling the incrementing identity fields for you.
Cons: You will have to make more than one call to the database to insert a new record. Assuming the deptid and batchid are not in the table (so you can't use a trigger) then you'll have to insert, get the identity, then run an update statement to populate the new identifier field.
Of course, you can always have Departments and Batches in separate tables with foreign keys in your Students table. The data is still preserved and you can use joins for reporting or whatever you need rather than parsing out identifier fields.
As for where this code belongs... that depends on the architecture of your application. If you have a nice repository then you could encapsulate that logic within your insert/create function. If not, then I'm afraid the controller is probably where you're going to have to keep this logic, which will be a little messy.
Hope this helps and good luck!