First, the procedure as such does not time out. The timeout occurs client-side. Most client APIs have a default timeout of 30 seconds, and if your sole problem is the timeout, you can change the timeout to be for instance 0, which means "wait forever". The timeout is a property on the command object.
Next, it is little unclear if you have a stored procedure, or if you are submitting the code from the client code. Whatever, I don't think the actual code starts off:
declare @orgid int=3,
@salesperson int=0
Rather I will assume that they are parameters.
Also, tuning a query only from the query text is not that easy, since I don't have any knowledge about tables, indexes and the data. I can only remark on things that stand out. As it happens, there is one such thing in your query:
where pd.organizationId=@orgId
and (@salesperson=0 or cp.personId=@salesperson)
The OR condition here is problematic. If @salesperson has a non-zero value, you want to use an index on PersonID to locate the sales person, but this does not work when @salesperson is 0. And when you have a static query, you have a static plan that returns correct values for both cases, but which does not give the best performance for any of the cases.
There is more than one way to deal with this problem, but the easiest as long as the query is not called several times per second is to add this line at the end:
OPTION (RECOMPILE)
This forces a recompile every time of the query, so that you get a plan fits the value of @salesperson.
Keep in mind what I said above. This advice may work for you. But understand that it is a bit of a shot in the dark. If it does not work out, we need more information, particularly query plans.