I don't think your UDF will do what you intend.
SELECT @Duration = datediff(day,StartDate, EndDate) FROM CompanyWorking.WorkCompleted
Will perform the DATEDIFF on every row in CompanyWorking.WorkCompleted ... and then the last row processed (which will be random) will be stored in @Duration (well ... all the rows will be, but when the SELECT finishes just the result of the last one will remain)
If you just want the DEFAULT for [Duration] to be the difference between [StartDate] and [EndDate], in Days, then you could just put that "formula" in the DEFAULT CONSTRAINT
ALTER TABLE [CompanyWorking].[WorkCompleted]
ADD CONSTRAINT [DF_WorkCompleted_Duration]
DEFAULT datediff(day, StartDate, EndDate) FOR [Duration]
Are you OK that this is just the default, when the row is very first INSERTed, provided that the INSERT statement does not, also, provide a value for [Duration]?
And also that the value of [Duration] is not automatically changed if the row is UPDATEd (and [StartDate] or [EndDate] are changed)?
Also, that [Duration] can be changed in an UPDATE without [StartDate] and/or [EndDate] being changed to match?
All that might be fine, I just wanted to check.
If you want a column for [Duration] in the table which always reflects the DataDiff of [StartDate] and [EndDate] then you might be better off with a computed column. You'll still have your [Duration] column in the table, but it won't be updatable and will always reflect the DateDiff() value.
Given that your [StartDate] and [EndDate] are DateTIME one other thing to be aware of is what "rounding" DateDiff(Day, ...) will perform. I expect it will be fine for your purpose, but worth just considering that
SELECT DateDiff(Day, '20170311 23:59:59', '20170312 00:00:01')
SELECT DateDiff(Day, '20170311 00:00:01', '20170312 23:59:59')
both return "one day"