This is NOT production-ready, but this is what I've got going so far.
In particular: I don't really understand the db migration tasks, or how I would create a migration and hint for it to be run, so right now if you want to use this, you'll have to manually add discount fields to services, service_options, invoice_lines, and invoice_recur_lines. (In all cases, any-old-int type should be fine.)
What this is supposed to do: Allow per-item discounting. This is distinct from coupons in a couple of ways. One is that the discount can be distinct for each package option in a package. Another is that the discount is actually preserved as a trait of the line item, rather than being computed statically and stored as a separate line item. So if something changes that would change the cost of a given line (pricing or quantity, for instance), the discount reflects that.
I haven't fully tested this, I don't think I've gone through the recurring line item use case at all, and I haven't figured out all the GUI elements. I'd quite like to see this get merged into core, or something like it, and I'm aware that it'll need significant cleanup before that would be plausible. But I want to get it out there for people to look at. (I think @Tyson might be the person to look at something like this?)
It's a patch, not a plugin, because plugins can't alter invoice pricing computations.
discount.patch