cursor.execute('SELECT group_id FROM user_groups WHERE user_id=%s ORDER BY (group_id=%s) DESC, group_id',(c['user_id'],dates[scope].get('assigned_group_id')))
group=cursor.fetchone()
ifnotgroup:fail('Medarbejderen mangler en gruppe')
cursor.execute('INSERT INTO sag_relationer (kilde_sag_id,målsag_id,relationstype) VALUES (%s,%s,%s)',(case['id'],child,'undersag'))
cursor.execute('INSERT INTO sag_kontakter (sag_id,contact_id,role,is_primary) SELECT %s,contact_id,role,is_primary FROM sag_kontakter WHERE sag_id=%s AND deleted_at IS NULL',(child,case['id']))
cursor.execute('DELETE FROM sag_case_assignees a WHERE sag_id=%s AND NOT EXISTS (SELECT 1 FROM user_groups ug WHERE ug.user_id=a.user_id AND ug.group_id=%s)',(cid,gid))
ifuid:cursor.execute('INSERT INTO sag_case_assignees (sag_id,user_id,assigned_by_user_id) VALUES (%s,%s,%s) ON CONFLICT (sag_id,user_id) DO NOTHING',(cid,uid,actor['id']))
cursor.execute('UPDATE sag_sager SET assigned_group_id=%s,ansvarlig_bruger_id=%s WHERE id=%s',(gid,uid,cid))
cursor.execute('INSERT INTO sag_command_mail_drafts (sag_id,actor_id,subject,body) VALUES (%s,%s,%s,%s) RETURNING id',(cid,actor['id'],case['titel'],c['description']));item['id']=cursor.fetchone()['id']
elifkind=='timer':
cursor.execute('SELECT user_id FROM users WHERE user_id=%s FOR UPDATE',(actor['id'],))
ifc['action']=='pause':
cursor.execute('UPDATE tmodule_times SET aktiv_timer=false,paused_at=CURRENT_TIMESTAMP WHERE medarbejder_id=%s AND sag_id=%s AND aktiv_timer=true AND slut_tid IS NULL RETURNING id',(actor['id'],cid))
paused=cursor.fetchone()
ifnotpaused:fail('Ingen aktiv timer på denne sag')
item['id']=paused['id']
else:
cursor.execute('SELECT id FROM tmodule_times WHERE medarbejder_id=%s AND aktiv_timer=true AND slut_tid IS NULL',(actor['id'],))
ifcursor.fetchone():raiseHTTPException(409,detail='Du har allerede en aktiv timer. Pause den først.')
cursor.execute("INSERT INTO tmodule_times (sag_id,customer_id,description,original_hours,worked_date,user_name,status,billable,billing_method,start_tid,entry_type,kilde,entry_status,medarbejder_id,aktiv_timer,round_block_min,ikke_placeret,work_type) SELECT id,customer_id,%s,0.01,CURRENT_DATE,%s,'pending',(customer_id IS NOT NULL),'draft',CURRENT_TIMESTAMP,'manuel','sag_v5','kladde',%s,true,30,false,'support' FROM sag_sager WHERE id=%s RETURNING id",(c['description'],author,actor['id'],cid));item['id']=cursor.fetchone()['id']
elifkind=='estimate':cursor.execute('UPDATE sag_sager SET estimated_minutes=%s WHERE id=%s',(c['minutes'],cid))
cursor.execute('SELECT id,deleted_at FROM sag_solutions WHERE sag_id=%s FOR UPDATE',(cid,));existing=cursor.fetchone()
ifexisting:raiseHTTPException(409,detail='Sagen har allerede en løsning. Ret den eksisterende løsning i løsningsmodulet.')
cursor.execute("INSERT INTO sag_solutions (sag_id,title,description,solution_type,result,approval_status,visibility,is_final,created_by_user_id,updated_by_user_id) VALUES (%s,%s,%s,'Support','Løst','draft','internal',true,%s,%s) RETURNING *",(cid,'Løsning',c['description'],actor['id'],actor['id']));solution=dict(cursor.fetchone());item['id']=solution['id']
cursor.execute('INSERT INTO sag_solution_versions (solution_id,version_number,snapshot,changed_by_user_id,change_note) VALUES (%s,1,%s::jsonb,%s,%s)',(solution['id'],json.dumps(jsonable_encoder(solution)),actor['id'],'Løsning oprettet via kommando'))
elifkind=='relation':
cursor.execute("INSERT INTO sag_relationer (kilde_sag_id,målsag_id,relationstype) SELECT %s,%s,'Relateret til' WHERE NOT EXISTS (SELECT 1 FROM sag_relationer WHERE kilde_sag_id=%s AND målsag_id=%s AND relationstype='Relateret til' AND deleted_at IS NULL)",(cid,c['case_id'],cid,c['case_id']))
elifkind=='time':
cursor.execute('SELECT customer_id FROM sag_sager WHERE id=%s',(cid,));customer=cursor.fetchone()['customer_id'];minutes=c['minutes'];rounded=((minutes+29)//30)*30
cursor.execute("""INSERT INTO tmodule_times (sag_id,customer_id,description,original_hours,worked_date,user_name,status,billable,billing_method,faktisk_tid_min,fakturerbar_tid_min,entry_type,kilde,entry_status,medarbejder_id,aktiv_timer,round_block_min,ikke_placeret,work_type,prepaid_card_id,fixed_price_agreement_id)
VALUES(%s,%s,%s,%s,CURRENT_DATE,%s,'pending',%s,%s,%s,%s,'manuel','sag_v5',%s,%s,false,30,false,'other',%s,%s)RETURNINGid""",(cid,customer,f"{c.get('category') or 'Arbejde'}: {c['description']}",minutes/60,author,customer is not None,c['billing']['method'],minutes,rounded,c['billing']['status'],actor['id'],c['billing']['card_id'],c['billing']['agreement_id']))
cursor.execute('SELECT * FROM sag_command_batches WHERE request_id=%s',(rid,));previous=cursor.fetchone()
ifprevious:
ifprevious['sag_id']!=sag_idorprevious['actor_id']!=actor['id']orprevious['payload_hash']!=digest:raiseHTTPException(409,detail='Denne request_id er allerede brugt til andre handlinger')