import time from datetime import datetime, timedelta from calendar import monthrange from netforce.model import Model, fields, get_model from netforce.utils import get_file_path from . import utils class ImportPayment(Model): _name="import.clinic.payment" _string="Clinic Payment" def _get_name(self,ids,context={}): res={} for obj in self.browse(ids): res[obj.id]=obj.type_id.name return res _fields={ 'name': fields.Char("Name",function="_get_name"), 'type_id': fields.Many2One("clinic.patient.type","Patient Type",required=True), 'hcode_id': fields.Many2One("clinic.hospital", "Hospital",required=True), 'date': fields.Date("Date"), 'date_from': fields.Date("From"), 'date_to': fields.Date("To"), 'file': fields.File("File"), 'max_row': fields.Integer("Max Row"), 'remain_row': fields.Integer("Pending"), 'total_row': fields.Integer("Total Record"), 'est_time': fields.Float("Estimate Time",scale=4), 'msg': fields.Text("Message"), 'done_qty': fields.Integer("Success"), 'fail_qty': fields.Integer("Fail"), 'match_qty': fields.Integer("Match"), 'unmatch_qty': fields.Integer("UnMatch"), 'state': fields.Selection([['draft','Draft'],['confirmed','Confirmed'],['fail','Fail'],['success','Success']],'State'), 'match_lines': fields.One2Many("import.clinic.payment.line","import_payment_id","Match",domain=[["state","=","match"]]), 'unmatch_lines': fields.One2Many("import.clinic.payment.line","import_payment_id","UnMatch",domain=[["state","=","unmatch"]]), 'payment_id': fields.Many2One("account.payment","Payment"), } def get_hcode_id(self,context={}): hp_ids=get_model("clinic.hospital").search([]) hp_id=None if hp_ids: hp_id=hp_ids[0] return hp_id def _get_date_from(self,context={}): datenow=time.strftime("%Y-%m-%d") year,month,day=datenow.split("-") return '%s-%s-01'%(year,month) def _get_date_to(self,context={}): datenow=datetime.now().strftime("%Y-%m-%d") year,month,day=datenow.split("-") weekday, total_day=monthrange(int(year), int(month)) return '%s-%s-%s'%(year,month,total_day) _defaults={ 'date': lambda *a: time.strftime("%Y-%m-%d"), 'date_from': _get_date_from, 'date_to': _get_date_to, 'hcode_id': get_hcode_id, 'max_row': 50, 'state': 'draft', } def import_payment(self,ids,context={}): fmt='%Y-%m-%d %H:%M:%S' start_time=time.strftime(fmt) obj=self.browse(ids)[0] fname=obj.file fpath=get_file_path(fname) patient_type=obj.type_id if patient_type.code in ('PKS'): lines=utils.read_excel(fpath,show_datetime=False) else: lines=utils.read_xml(fpath,show_datetime=False) if not lines: raise Exception("Wrong File") msg="" count=0 nofound=0 did=0 blank=0 fail_qty=0 done_qty=0 match_qty=0 unmatch_qty=0 msg+=""*10; msg+="hcode,hn,name\n" print("getting invoice") dom=[] dom.append(['state','=','waiting_payment']) invoices={} for inv in get_model("account.invoice").search_browse(dom): hd_case=inv.related_id patient=hd_case.patient_id key=(inv.date,patient.id) invoices[key]={ 'id': inv.id, 'amount_due': inv.amount_due, 'hd_case_id': hd_case.id, } print("getting patient") patients={} for pt in get_model("clinic.patient").search_read([[]],['hn','hn_num']): key=pt['hn_num'] patients[key]={ 'id': pt['id'], } print("getting hd case") # need to optimize -> from, to hd_cases={} for hd_case in get_model("clinic.hd.case").search_read([[]],['patient_id','date']): patient_id=hd_case['patient_id'][0] date=hd_case['date'] key=(date,patient_id) hd_cases[key]={ 'id': hd_case['id'], } def get_hn_num(hn=""): return ''.join(h for h in hn if h.isdigit()) mlines=[] umlines=[] for line in lines: name=line.get("name14") hn=line.get('hn',"") hn_num=get_hn_num(hn) hct=line.get("hct","") inv_date=line.get("dttran") amount=line.get('amount23') hcode=line.get('hcode18','0') if not hcode: hcode='0' hcode=int(hcode) hcode=str(hcode) if not obj.hcode_id.code==hcode: if hcode: nofound+=1 if hcode!='0': msg+="not found %s, %s, %s \n"%(hcode,hn,name) fail_qty+=1 else: blank+=1 continue if patients.get(hn_num): patient_id=patients[hn_num]['id'] key=(inv_date,patient_id) if invoices.get(key): inv=invoices[key] mlines.append(('create',{ 'date': inv_date, 'invoice_id': inv['id'], 'hd_case_id': inv['hd_case_id'], 'patient_id': patient_id, 'amount': inv['amount_due'] or 0.0, 'state': 'match', })) match_qty+=1 else: hd_case=hd_cases.get(key) vals={ 'date': inv_date, 'patient_id': patient_id, 'amount': amount, } if hd_case: vals['hd_case_id']=hd_case['id'] umlines.append(('create',vals)) unmatch_qty+=1 for mline in obj.match_lines: mline.delete() for umline in obj.unmatch_lines: umline.delete() stop_time=time.strftime(fmt) est_time=datetime.strptime(stop_time,fmt)-datetime.strptime(start_time,fmt) remain_row=len(lines)-blank-did-count if remain_row <= 0: msg="Nothing to import" obj.write({ 'total_row': len(lines), 'remain_row': remain_row-match_qty, 'msg': msg, 'done_qty': match_qty+unmatch_qty, 'fail_qty': fail_qty, 'match_qty': match_qty, 'unmatch_qty': unmatch_qty, 'est_time': est_time.seconds/3600, 'match_lines': mlines, 'unmatch_lines': umlines, }) print("Done!") ImportPayment.register()