What is the appropriate algorithm for bipartite matching with constraints?
The problem as described still seems amenable to doing a bipartite matching with weighted edges if you adapt the graph setup as follows.

If an employee must do four jobs, represent the employee with four vertices in the graph.  Each job should be represented as four vertices in the graph, one for each needed skill level plus one repeated skill level.  Connect each employee vertex with the job vertex corresponding to the highest skill level the employee is capable of performing.  Don't connect an employee to more than one skill level within a job.  Example: if a job has two high skill phases, connect all the employee vertices for a given qualified employee to one phase or the other, not both.  The edge weights between the employee and job vertices should be the employee preference score for the job.

With this graph, a maximal bipartite matching should produce proper job assignments maximizing employee preferences while matching skills.