from datetime import datetime, timedelta from netforce.access import get_active_user from netforce.model import Model, fields, get_model 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), 'time_start': fields.Char("Time start"), 'time_stop': fields.Char("Time Stop"), 'cycle_id': fields.Many2One("clinic.cycle","Cycle", required=True), 'patient_lines': fields.One2Many("clinic.gen.visit.line","gen_id","Patient Lines"), 'nurse_lines': fields.One2Many("clinic.gen.visit.line","gen_id","Nurse Lines"), 'monday': fields.Boolean("Monday"), 'tuesday': fields.Boolean("Tuesdays"), 'wednesday': fields.Boolean("Wednesdays"), 'thursday': fields.Boolean("Thursdays"), 'friday': fields.Boolean("Fridays"), 'sathurday': fields.Boolean("Sathurday"), 'sunday': fields.Boolean("Sunday"), 'doctor_id': fields.Many2One("clinic.staff","Doctor",domain=[['type','=','doctor']]), 'department_id': fields.Many2One("clinic.department","Department"), "patient_type": fields.Selection([("s","Social Security"),("u","UC."),("others","Others")],"Patient Type"), 'patient_categ_id': fields.Many2One("clinic.patient.categ", "Patient Category"), 'nurse_categ_id': fields.Many2One("clinic.staff.categ", "Nurse Category", domain=[['type','=','nurse']]), } def _get_patient_lines(self,context={}): ids=context.get("ids") if not ids: ids=[context.get("refer_id")] lines=[] # XXX [None] if any(ids): lines=[{'patient_id': id} for id in ids] return lines def _get_nurse(self,context={}): user_id=get_active_user() print("user_id ",user_id) nurse_ids=get_model("clinic.nurse").search([['user_id','=',user_id]]) if nurse_ids: return nurse_ids[0] return None def _get_cycle(self,context={}): cycle_ids=get_model('clinic.cycle').search([],order="sequence") if cycle_ids: cycle_id=cycle_ids[0] return cycle_id or None def _get_start(self,context={}): cycle_ids=get_model('clinic.cycle').search([],order="sequence") time_start="00:00" if cycle_ids: cycle_id=cycle_ids[0] cycle=get_model('clinic.cycle').browse(cycle_id) time_start=cycle.time_start return time_start def _get_stop(self,context={}): cycle_ids=get_model('clinic.cycle').search([],order="sequence") time_stop="00:00" if cycle_ids: cycle_id=cycle_ids[0] cycle=get_model('clinic.cycle').browse(cycle_id) time_stop=cycle.time_stop return time_stop _defaults={ 'patient_lines': _get_patient_lines, 'date_from': lambda *a: datetime.now().strftime(FMT_DATE), 'date_to': lambda *a: (datetime.now()+timedelta(days=7)).strftime(FMT_DATE), 'time_start': _get_start, 'time_stop': _get_stop, 'nurse_id': _get_nurse, 'duration': 2, 'cycle_id': _get_cycle, #'monday': True, # dynamic select weekday, use default_get } def default_get(self,field_names=None,context=None,**kw): vals=super().default_get(field_names,context,**kw) wd=datetime.now().weekday() wds={ 0: 'monday', 1: 'tuesday', 2: 'wednesday', 3: 'thursday', 4: 'friday', 5: 'sathurday', 6: 'sunday', } vals[wds[wd]]=True return vals 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 return data def gen_visit(self,ids,context): obj=self.browse(ids)[0] visit_obj=get_model('clinic.visit') days=[ obj.monday and 1 or 0, obj.tuesday and 2 or 0, obj.wednesday and 3 or 0, obj.thursday and 4 or 0, obj.friday and 5 or 0, obj.sathurday and 6 or 0, obj.sunday and 7 or 0, ] days=[day for day in days if day] if not days: raise Exception("Please select Day") 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: patients=get_model("clinic.patient").search([['type','=',obj.patient_type]]) if not patients: raise Exception("No patient for type %s"%obj.patient_type) 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") nurse_vals=[] for nurse_line in obj.nurse_lines: nurse=nurse_line.nurse_id # None if nurse: nurse_vals.append({ 'id': nurse.id, 'level_id': nurse.level_id.id, }) #XXX if not nurse_vals: for nurse in get_model("clinic.staff").search_browse([['type','=','nurse'],['categ_id','=',obj.nurse_categ_id.id]]): nurse_vals.append({ 'id': nurse.id, 'level_id': nurse.level_id.id, }) schedules={} cycle=obj.cycle_id cstart='%s:00'%cycle.time_start cstop='%s:00'%cycle.time_stop 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 days: 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 while count < day_total: tmp=start_date+timedelta(days=count) ttime_start="%s %s" % (tmp.strftime(FMT_DATE),cstart) ttime_stop="%s %s" % (tmp.strftime(FMT_DATE),cstop) vals={ 'patient_id': patient_id, 'doctor_id': obj.doctor_id.id or patient.doctor_id.id, 'department_id': obj.department_id.id, 'cycle_id': cycle.id, 'time_start': ttime_start, 'time_stop': ttime_stop, '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', '=', obj.cycle_id.id]) #XXX dom.append(['state','=','pending']) vids=visit_obj.search(dom) visit_obj.delete(vids) key='%s/%s'%(vals['cycle_id'], vals['time_start']) if not schedules.get(key): schedules[key]={ 'cycle_id': obj.cycle_id.id, 'time_start': ttime_start, 'time_stop': ttime_stop, 'state':'pending', } 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: vals['nurse_id']=confirm_id visit_obj.create(vals) print("create schedule") print("="*50) for k, v in schedules.items(): cycle_id,time_start=k.split("/") schedule_date=time_start[0:10] dom=[] dom.append(['date','=',schedule_date]) schedules=get_model("clinic.schedule").search_browse(dom) if schedules: schedule=schedules[0] if schedule.state=='draft': for line in schedule.lines: line.delete() else: vals={ 'date': time_start[0:10], 'time_start': time_start, 'time_stop': time_start, } schedule_id=get_model("clinic.schedule").create(vals) schedule=get_model("clinic.schedule").browse(schedule_id) lines=[] for nv in nurse_vals: nurse_id=nv['id'] lines.append(('create',{ 'nurse_id': nurse_id, 'cycle_id': cycle_id, })) schedule.write({'lines': lines}) print("="*50) return { 'next': { 'name': 'clinic_visit', 'mode': 'list', }, 'flash': 'Generate OK', } def clear_visit(self,ids,context={}): obj=self.browse(ids)[0] days=[ obj.monday and 1 or 0, obj.tuesday and 2 or 0, obj.wednesday and 3 or 0, obj.thursday and 4 or 0, obj.friday and 5 or 0, ] days=[day for day in days if day] 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") schedule_obj=get_model("clinic.schedule") 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: # continue to create with critiria 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) schedule_obj=get_model("clinic.schedule") dom[-1][2]='draft' #XXX schedules=schedule_obj.search_browse(dom) schedule_ids=[] for sch in schedules: for line in sch.lines: if obj.cycle_id.id==line.cycle_id.id: schedule_ids.append(sch.id) schedule_obj.delete(schedule_ids) return { 'next': { 'name': 'clinic_gen_visit_form', 'mode': 'form', }, 'flash': 'Clear %s visits'%len(vids), } if days: for patient_id in patients: # loop days in weekend ntoday=1 day_total=(date_to-date_from).days+ntoday for weekday in days: 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(['state','=','pending']) count+=7 vids=visit_obj.search(dom) if vids: visit_ids.append(vids[0]) start_date=tmp else: 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']) vids=visit_obj.search(dom) if vids: visit_ids.append(vids[0]) if visit_ids: get_model("clinic.visit").delete(visit_ids) 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(['cycle_id','=',obj.cycle_id.id]) schedule_ids=schedule_obj.search(dom) schedule_obj.delete(schedule_ids) return { 'next': { 'name': 'clinic_visit', 'mode': 'list', }, 'flash': 'Clear %s visits'%len(visit_ids), } GenVisit.register()