from datetime import datetime, timedelta from netforce.access import get_active_user, set_active_user from netforce.model import Model, fields, get_model from netforce.utils import get_data_path FMT_DATE="%Y-%m-%d" FMT_DATETIME="%Y-%m-%d %H:%M:%S" class GenVisit(Model): _name="clinic.gen.visit" _transient=True _fields={ 'date_from': fields.Date("From", required=True), 'date_to': fields.Date("To", required=True), 'patient_lines': fields.One2Many("clinic.gen.visit.line","gen_id","Patient Lines"), 'patient_type_id': fields.Many2One("clinic.patient.type","Patient Type"), 'patient_categ_id': fields.Many2One("clinic.patient.categ", "Patient Category"), 'time_lines': fields.One2Many("clinic.gen.visit.time","gen_id","Time Lines"), 'department_id': fields.Many2One("clinic.department","Department"), 'doctor_id': fields.Many2One("clinic.staff","Doctor",domain=[['type','=','doctor']]), } def _get_patient_lines(self,context={}): ids=context.get("ids") if not ids: ids=[context.get("refer_id")] lines=[] if any(ids): lines=[{'patient_id': id} for id in ids if type(id)==type(1)] return lines def _get_time_lines(self,context={}): return [ {'day': 'mon',}, {'day': 'tue',}, {'day': 'wed',}, {'day': 'thu',}, {'day': 'fri',}, {'day': 'sat',}, {'day': 'sun',}, ] _defaults={ 'date_from': lambda *a: datetime.now().strftime(FMT_DATE), 'date_to': lambda *a: (datetime.now()+timedelta(days=7)).strftime(FMT_DATE), 'patient_lines': _get_patient_lines, 'time_lines': _get_time_lines, } def onchange_cycle(self,context={}): data=context['data'] cycle_id=data['cycle_id'] if cycle_id: cycle=get_model('clinic.cycle').browse(cycle_id) data['time_start']=cycle.time_start data['time_stop']=cycle.time_stop else: data['time_start']='' data['time_stop']='' return data def gen_visit(self,ids,context): obj=self.browse(ids)[0] visit_obj=get_model('clinic.visit') b_ids=get_model('clinic.branch').search([]) branch_id=None if b_ids: branch_id=b_ids[0] days={} for tline in obj.time_lines: if tline.day and tline.cycle_id and tline.time_start and tline.time_stop: day=tline.day cycle_id=tline.cycle_id.id time_start=tline.time_start time_stop=tline.time_stop d=0 if day=='mon': d=1 elif day=='tue': d=2 elif day=='wed': d=3 elif day=='thu': d=4 elif day=='fri': d=5 elif day=='sat': d=6 elif day=='sun': d=7 days.update({ d:{ 'cycle_id': cycle_id, 'time_start': time_start, 'time_stop': time_stop, }}) if not days: raise Exception("Please select Days") visit_vals=[] date_from=datetime.strptime(obj.date_from,FMT_DATE) date_to=datetime.strptime(obj.date_to,FMT_DATE) patients=[p.patient_id.id for p in obj.patient_lines if p.patient_id] if not patients and obj.patient_type_id: patients=get_model("clinic.patient").search([['type_id','=',obj.patient_type_id.id]]) if not patients: raise Exception("No patient for type %s"%obj.patient_type_id.name) elif not patients and obj.patient_categ_id: patients=get_model("clinic.patient").search([['categ_id','=',obj.patient_categ_id.id]]) if not patients: raise Exception("No patient for category %s"%obj.patient_categ_id.name) elif patients: # continue to generate with condition pass else: raise Exception("Please select some patient or patient type") day_choices=days.keys() for patient_id in patients: patient=get_model("clinic.patient").browse(patient_id) ntoday=1 day_total=(date_to-date_from).days+ntoday for weekday in day_choices: wd=date_from.weekday() start_date=date_from while wd != weekday-1: start_date+=timedelta(days=1) wd=start_date.weekday() #XXX should gen only in scope if start_date.strftime(FMT_DATE) > date_to.strftime(FMT_DATE): continue count=0 tmp=start_date cstart=days[weekday]['time_start'] cstop=days[weekday]['time_stop'] while count < day_total: tmp=start_date+timedelta(days=count) visit_date="%s"%(tmp.strftime(FMT_DATE)) ttime_start="%s %s" % (visit_date,cstart) ttime_stop="%s %s" % (visit_date,cstop) vals={ 'patient_id': patient_id, 'doctor_id': obj.doctor_id.id or patient.doctor_id.id, 'department_id': patient.department_id.id, 'branch_id': patient.branch_id.id or branch_id, 'cycle_id': days[weekday]['cycle_id'], 'time_start': ttime_start, 'time_stop': ttime_stop, 'visit_date': visit_date, 'state': 'pending', } visit_vals.append(vals) count+=7 dom=[] dom.append(['time_start','>=','%s %s'%(tmp.strftime(FMT_DATE)[0:10],' 00:00:00')]) dom.append(['time_stop','<=','%s %s'%(tmp.strftime(FMT_DATE)[0:10],' 23:59:59')]) dom.append(['patient_id', '=', patient_id]) dom.append(['cycle_id', '=', days[weekday]['cycle_id']]) dom.append(['state','=','pending']) vids=visit_obj.search(dom) visit_obj.delete(vids) start_date=tmp user_id=get_active_user() staff_ids=get_model("clinic.staff").search([['type','=','type'],['user_id','=',user_id]]) confirm_id=None if staff_ids: confirm_id=staff_ids[0] for vals in visit_vals: print("vals ", vals) vals['nurse_id']=confirm_id visit_obj.create(vals) return { 'next': { 'name': 'clinic_visit', 'mode': 'list', }, 'flash': 'Generate OK', } def clear_visit(self,ids,context={}): obj=self.browse(ids)[0] days={} for tline in obj.time_lines: if tline.day and tline.cycle_id and tline.time_start and tline.time_stop: day=tline.day cycle_id=tline.cycle_id.id time_start=tline.time_start time_stop=tline.time_stop d=0 if day=='mon': d=1 elif day=='tue': d=2 elif day=='wed': d=3 elif day=='thu': d=4 elif day=='fri': d=5 elif day=='sat': d=6 elif day=='sun': d=7 days.update({ d:{ 'cycle_id': cycle_id, 'time_start': time_start, 'time_stop': time_stop, }}) if not days: raise Exception("Please select Days") visit_ids=[] date_from=datetime.strptime(obj.date_from,FMT_DATE) date_to=datetime.strptime(obj.date_to,FMT_DATE) # FIXME add more 1 week for make sure date_to2=(date_to+timedelta(days=7)).strftime(FMT_DATETIME) visit_obj=get_model("clinic.visit") patients=[p.patient_id.id for p in obj.patient_lines if p.patient_id] if not patients and obj.patient_type: patients=get_model("clinic.patient").search([['type','=',obj.patient_type]]) elif not patients and obj.patient_categ_id: patients=get_model("clinic.patient").search([['categ_id','=',obj.patient_categ_id.id]]) elif patients: pass else: dom=[] dom.append(['time_start','>=','%s %s'%(obj.date_from[0:10],' 00:00:00')]) dom.append(['time_stop','<=','%s %s'%(date_to2[0:10],' 23:59:59')]) dom.append(['state','=','pending']) vids=visit_obj.search(dom) visit_obj.delete(vids) return { 'next': { 'name': 'clinic_gen_visit_form', 'mode': 'form', }, 'flash': 'Clear %s visits'%len(vids), } day_choices=days.keys() if day_choices: for patient_id in patients: # loop days in weekend ntoday=1 day_total=(date_to-date_from).days+ntoday for weekday in day_choices: wd=date_from.weekday() start_date=date_from while wd != weekday-1: start_date+=timedelta(days=1) wd=start_date.weekday() #XXX should gen only in scop if start_date.strftime(FMT_DATE) > date_to.strftime(FMT_DATE): continue count=0 tmp=start_date while count < day_total: tmp=start_date+timedelta(days=count) time_start="%s 00:00:00" % (tmp.strftime(FMT_DATE)) time_stop="%s 23:59:59" % (tmp.strftime(FMT_DATE)) dom=[] dom.append(['time_start','>=','%s'%time_start]) dom.append(['time_stop','<=','%s'%time_stop]) dom.append(['patient_id','=','%s'%patient_id]) dom.append(['cycle_id','=','%s'%days[weekday]['cycle_id']]) dom.append(['state','=','pending']) count+=7 vids=visit_obj.search(dom) print('x dom ', vids) if vids: visit_ids.append(vids[0]) start_date=tmp else: # discard time_start=obj.date_from time_stop=obj.date_to for patient_id in patients: dom=[] dom.append(['time_start','>=','%s'%time_start]) dom.append(['time_stop','<=','%s'%time_stop]) dom.append(['patient_id','=','%s'%patient_id]) dom.append(['state','=','pending']) print('dom ', dom) vids=visit_obj.search(dom) if vids: visit_ids.append(vids[0]) if visit_ids: get_model("clinic.visit").delete(visit_ids) return { 'next': { 'name': 'clinic_visit', 'mode': 'list', }, 'flash': 'Clear %s visits'%len(visit_ids), } def onchange_cycle_line(self,context={}): data=context['data'] path=context['path'] line=get_data_path(data,path,parent=True) cycle_id=line['cycle_id'] if cycle_id: cycle=get_model('clinic.cycle').browse(cycle_id) line['time_start']=cycle.time_start line['time_stop']=cycle.time_stop return data GenVisit.register()