From 17b58758b3c2ea4ed82503482ec91b8a3805b0c1 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Wed, 26 Aug 2015 16:20:16 +0700 Subject: [PATCH 01/36] xxx --- netforce_clinic/models/payment_matching.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/netforce_clinic/models/payment_matching.py b/netforce_clinic/models/payment_matching.py index 69d10a1..531764d 100644 --- a/netforce_clinic/models/payment_matching.py +++ b/netforce_clinic/models/payment_matching.py @@ -301,10 +301,10 @@ class PaymentMatching(Model): pc=0 if total_invoice: pc=(total_match_invoice/total_invoice)*100 - if inv_match_ids and obj: - obj.write({ - 'inv_ids': str(inv_match_ids), - }) + #if inv_match_ids and obj: + #obj.write({ + #'inv_ids': str(inv_match_ids), + #}) data={ 'lines': lines, 'date_from': date_from, From 5e680d983bf20f5f408154471a68a769284b79a3 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Thu, 27 Aug 2015 10:01:57 +0700 Subject: [PATCH 02/36] import tb #1 --- netforce_clinic/migrations/__init__.py | 2 +- netforce_clinic/migrations/repost_invoice.py | 1 - netforce_clinic/models/conv_bal.py | 54 ++++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/netforce_clinic/migrations/__init__.py b/netforce_clinic/migrations/__init__.py index 4647e40..1c3d47f 100644 --- a/netforce_clinic/migrations/__init__.py +++ b/netforce_clinic/migrations/__init__.py @@ -1,3 +1,3 @@ #from . import clinic_setting +from . import repost_invoice from . import conv_bal -#from . import repost_invoice diff --git a/netforce_clinic/migrations/repost_invoice.py b/netforce_clinic/migrations/repost_invoice.py index 94fd6d9..ac0f8ba 100644 --- a/netforce_clinic/migrations/repost_invoice.py +++ b/netforce_clinic/migrations/repost_invoice.py @@ -39,7 +39,6 @@ class Migration(migration.Migration): 'state': 'draft', }) ids=list(hdcase_ids) - for seq in get_model("sequence").search_browse([['type','in',['cust_invoice','clinic_invoice_noclaim']]]): for run in seq.running: run.delete() diff --git a/netforce_clinic/models/conv_bal.py b/netforce_clinic/models/conv_bal.py index 0f12683..1a3b528 100644 --- a/netforce_clinic/models/conv_bal.py +++ b/netforce_clinic/models/conv_bal.py @@ -181,4 +181,58 @@ class ConvBal(Model): } } + def import_sale_file(self,ids,context): + obj=self.browse(ids)[0] + path=get_file_path(obj.file) + data=open(path).read() + rd=csv.reader(StringIO(data)) + headers=next(rd) + headers=[h.strip() for h in headers] + if not context.get('is_append'): + del_ids=get_model("conv.sale.invoice").search([["conv_id","=",obj.id]]) + get_model("conv.sale.invoice").delete(del_ids) + for row in rd: + print("row",row) + line=dict(zip(headers,row)) + print("line",line) + if not line.get("Number"): + continue + number=line["Number"].strip() + if not number: + continue + ref=line["Reference"].strip() + contact_name=line["Contact"].strip() + res=get_model("partner").search([["name","=",contact_name]]) + if not res: + raise Exception("Contact not found: '%s'"%contact_name) + contact_id=res[0] + date=datetime.datetime.strptime(line["Date"].strip(),obj.date_fmt).strftime("%Y-%m-%d") + due_date=datetime.datetime.strptime(line["Due Date"].strip(),obj.date_fmt).strftime("%Y-%m-%d") + amount_due=float(line["Amount Due"].strip().replace(",","") or 0) + acc_code=line["Account"].strip() + res=get_model("account.account").search([["code","=",acc_code]]) + if not res: + raise Exception("Account code not found: %s"%acc_code) + acc_id=res[0] + amount_cur=float(line["Amount Cur"].strip().replace(",","") or 0) + vals={ + "conv_id": obj.id, + "number": number, + "ref": ref, + "contact_id": contact_id, + "date": date, + "due_date": due_date, + "amount_due": amount_due, + "account_id": acc_id, + "amount_cur": amount_cur, + } + get_model("conv.sale.invoice").create(vals) + return { + "next": { + "name": "conv_bal", + "active_id": obj.id, + "view_xml": "conv_bal2", + } + } + ConvBal.register() From 2fabd1355d683a3477cc162f2fea184460d8e441 Mon Sep 17 00:00:00 2001 From: "watcha.h@almacom.co.th" Date: Fri, 28 Aug 2015 08:10:25 +0700 Subject: [PATCH 03/36] multi print customer invoice --- netforce_clinic/reports/cust_invoice.odt | Bin 40891 -> 50702 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/netforce_clinic/reports/cust_invoice.odt b/netforce_clinic/reports/cust_invoice.odt index 17429e7855d0918708ad8560fc1f5f676758cb49..a9036b62d838126de5eaf44973d56819440131b5 100644 GIT binary patch delta 36410 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 N&_2&IQ0njA{{z7~t%v{s From 535daf39673319ddc46455e99202750e4acf9141 Mon Sep 17 00:00:00 2001 From: "watcha.h@almacom.co.th" Date: Fri, 28 Aug 2015 08:14:30 +0700 Subject: [PATCH 04/36] todo --- netforce_clinic/todo.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/netforce_clinic/todo.txt b/netforce_clinic/todo.txt index aff5c34..43a2aa6 100644 --- a/netforce_clinic/todo.txt +++ b/netforce_clinic/todo.txt @@ -1 +1,4 @@ -- move patient to antother location +redesign print payment & invoice from hdcase + - print payment + - direct payment + - invoice payment From 5c9591f18781fc853ef89e466d1676c2cad4b40f Mon Sep 17 00:00:00 2001 From: "watcha.h@almacom.co.th" Date: Fri, 28 Aug 2015 08:15:55 +0700 Subject: [PATCH 05/36] todo migrate --- netforce_clinic/todo.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/netforce_clinic/todo.txt b/netforce_clinic/todo.txt index 43a2aa6..5dd8b32 100644 --- a/netforce_clinic/todo.txt +++ b/netforce_clinic/todo.txt @@ -2,3 +2,6 @@ redesign print payment & invoice from hdcase - print payment - direct payment - invoice payment + +migration: + match invoice less than 2015-06-30 to hdcase From ccb1b4590348f5b82fdb3968f96672b0b55db2aa Mon Sep 17 00:00:00 2001 From: "watcha.h@almacom.co.th" Date: Sun, 30 Aug 2015 22:47:58 +0700 Subject: [PATCH 06/36] if nurse more that number of cycle item should show name of nurse --- netforce_clinic/models/report_cycle_item.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/netforce_clinic/models/report_cycle_item.py b/netforce_clinic/models/report_cycle_item.py index 9d01d74..3e030d1 100644 --- a/netforce_clinic/models/report_cycle_item.py +++ b/netforce_clinic/models/report_cycle_item.py @@ -98,17 +98,20 @@ class ReportCycleItem(Model): ptypes={} for ptype in get_model("clinic.patient.type").search_read([],['name']): ptypes[ptype['name'] or ""]=0 + cycle_check={} for citem in get_model('clinic.cycle.item').search_browse(dom,order="date"): cycle=citem.cycle_id date=citem.date key='%s-%s'%(date,cycle.id) if key not in cycles.keys(): cycles[key]=[] + cycle_check[key]=0 for line in citem.lines: nurse=line.nurse_id cycles[key].append({ 'name': nurse.name, 'first_name': nurse.first_name or "", + 'cycle_item_id': citem.id, }) for hdcase in citem.hd_cases: if hdcase.state not in ('paid', 'waiting_payment'): @@ -120,6 +123,8 @@ class ReportCycleItem(Model): ptype=patient.type_id if ptype_id and ptype_id!=ptype.id: continue + key='%s-%s'%(hdcase.date,hdcase.cycle_id.id) + cycle_check[key]+=1 ptypes[ptype.name or ""]+=1 doctor=hdcase.doctor_id cycle=hdcase.cycle_id @@ -221,7 +226,6 @@ class ReportCycleItem(Model): sub_mdc+=x['mdc'] or 0 if not epos.get(x['mdc_name']): epos[x['mdc_name']]=0 - #XXX if not epos.get(x['iron_name']): epos[x['iron_name']]=0 epos[x['iron_name']]+=x['total_ivr'] or 0 #XXX @@ -245,10 +249,20 @@ class ReportCycleItem(Model): key='%s-%s'%(date,cid) cres=cycles[key] line['nurse']='' + more_lines=[] if index < len(cres): line['nurse']=cres[index]['name'] line['nfirst_name']=cres[index]['first_name'] + if index+1==cycle_check[key]: + for i in range(index+1,len(cres)): + more_lines.append({ + 'nurse': cres[i]['name'], + 'nfirst_name': cres[i]['first_name'], + 'ctid': cres[i]['cycle_item_id'], + }) nlines.append(line) + # if nurse more that cres, should show name of nurses + nlines+=more_lines if no==count: epo_items=[{'name': k, 'qty': v} for k,v in epos.items() if k ] nlines.append({ From 8d52a9a91882811ac173361d3cc43396a9b469fa Mon Sep 17 00:00:00 2001 From: "watcha.h@almacom.co.th" Date: Wed, 2 Sep 2015 07:44:03 +0700 Subject: [PATCH 07/36] reimport tb --- netforce_clinic/migrations/__init__.py | 3 +- netforce_clinic/migrations/conv_bal.py | 35 +++++- netforce_clinic/migrations/tb_ap_import.py | 75 ++++++++++++ netforce_clinic/models/conv_bal.py | 127 --------------------- 4 files changed, 111 insertions(+), 129 deletions(-) create mode 100644 netforce_clinic/migrations/tb_ap_import.py diff --git a/netforce_clinic/migrations/__init__.py b/netforce_clinic/migrations/__init__.py index 1c3d47f..ed43705 100644 --- a/netforce_clinic/migrations/__init__.py +++ b/netforce_clinic/migrations/__init__.py @@ -1,3 +1,4 @@ #from . import clinic_setting -from . import repost_invoice +#from . import repost_invoice from . import conv_bal +#from . import tb_ap_import diff --git a/netforce_clinic/migrations/conv_bal.py b/netforce_clinic/migrations/conv_bal.py index 869303e..fd67a2f 100644 --- a/netforce_clinic/migrations/conv_bal.py +++ b/netforce_clinic/migrations/conv_bal.py @@ -12,11 +12,43 @@ class Migration(migration.Migration): #for mv in get_model("account.move").search_browse([['number','ilike', 'OPEN']]): #mv.to_draft() #mv.delete() + + # delete old account payable + dom=[ + ['memo','=','Conversion balance 2015-06-30'], + ['type','=','in'], + ['state','=','waiting_payment'], + ] + for inv in get_model('account.invoice').search_browse(dom): + print('delete invoice... ', inv.number) + inv.to_draft() + inv.delete() + + # delete old account rereivable + dom=[ + ['memo','=','Conversion balance 2015-06-30'], + ['type','=','out'], + ['state','=','waiting_payment'], + ] + for inv in get_model('account.invoice').search_browse(dom): + print('delete invoice... ', inv.number) + inv.to_draft() + inv.delete() + # remove journal entry + dom=[ + ['number','=','OPENING ENTRY'], + ] + for move in get_model('account.move').search_browse(dom): + print('delete accout.move... ', move.number) + move.to_draft() + move.delete() + cbv_id=24 cbv=get_model("conv.bal").browse(cbv_id) cbv.write({ 'date_fmt': '%Y-%m-%d', 'file': 'tb.csv', + 'date': '2015-06-30', }) print("import acc file (step 1) running ...") get_model("conv.bal").import_acc_file([cbv.id],context={}) @@ -39,7 +71,8 @@ class Migration(migration.Migration): print("import purch file (step 3) running ...") cbv.write({ 'file': 'ap.csv', - 'date_fmt': '%d/%m/%Y', + #'date_fmt': '%d/%m/%Y', + 'date_fmt': '%Y-%m-%d', }) get_model("conv.bal").import_purch_file([cbv.id],context={}) get_model("conv.bal").import_purch([cbv.id],context={}) diff --git a/netforce_clinic/migrations/tb_ap_import.py b/netforce_clinic/migrations/tb_ap_import.py new file mode 100644 index 0000000..207e573 --- /dev/null +++ b/netforce_clinic/migrations/tb_ap_import.py @@ -0,0 +1,75 @@ +from netforce.model import get_model +from netforce import migration +from netforce.access import set_active_user, set_active_company + +class Migration(migration.Migration): + _name="clinic.tb.ap.import" + _version="2.10.0" + + def migrate(self): + set_active_user(1) + set_active_company(1) + #for mv in get_model("account.move").search_browse([['number','ilike', 'OPEN']]): + #mv.to_draft() + #mv.delete() + cbv_id=24 + cbv=get_model("conv.bal").browse(cbv_id) + cbv.write({ + 'date_fmt': '%Y-%m-%d', + 'file': 'tb.csv', + 'date': '2015-06-30', + }) + print("import acc file (step 1) running ...") + get_model("conv.bal").import_acc_file([cbv.id],context={}) + get_model("conv.bal").import_acc([cbv.id],context={}) + + #print("import sale file (step 2)running ...") + #del_ids=get_model("conv.sale.invoice").search([["conv_id","=",cbv.id]]) + #get_model('conv.sale.invoice').delete(del_ids) + #for ar_file in ['ar_fee','ar_epo','ar_srv','ar_other']: + #cbv.write({ + #'date_fmt': '%d/%m/%Y', + #'file': '%s.csv'%(ar_file), + #}) + #ctx={ + #'is_append': True, + #} + #get_model("conv.bal").import_sale_file([cbv.id],context=ctx) + #get_model("conv.bal").import_sale([cbv.id],context={}) + + print("import purch file (step 3) running ...") + cbv.write({ + 'file': 'ap.csv', + #'date_fmt': '%d/%m/%Y', + 'date_fmt': '%Y-%m-%d', + }) + get_model("conv.bal").import_purch_file([cbv.id],context={}) + get_model("conv.bal").import_purch([cbv.id],context={}) + + cbv.write({ + 'date_fmt': '%Y-%m-%d', + }) + # delete old account payable + dom=[ + ['memo','=','Conversion balance 2015-06-30'], + ['type','=','in'], + ['state','=','waiting_payment'], + ] + for inv in get_model('account.invoice').search_browse(dom): + print('delete invoice... ', inv.number) + inv.to_draft() + inv.delete() + print(">> next 3") + print("create_open_entry...") + ctx={ + 'tb_ap_only': True, + } + cbv.create_open_entry(context=ctx) + #print("create_sale_invoices...") + #cbv.create_sale_invoices() + print("create_purch_invoices...") + cbv.create_purch_invoices() + print("Done!") + return True + +Migration.register() diff --git a/netforce_clinic/models/conv_bal.py b/netforce_clinic/models/conv_bal.py index 1a3b528..11a6fe2 100644 --- a/netforce_clinic/models/conv_bal.py +++ b/netforce_clinic/models/conv_bal.py @@ -54,133 +54,6 @@ class ConvBal(Model): else: get_model("account.invoice").create(vals) - def _import_sale_file(self,ids,context): - obj=self.browse(ids)[0] - path=get_file_path(obj.file) - data=open(path).read() - rd=csv.reader(StringIO(data)) - headers=next(rd) - headers=[h.strip() for h in headers] - del_ids=get_model("conv.sale.invoice").search([["conv_id","=",obj.id]]) - get_model("conv.sale.invoice").delete(del_ids) - for row in rd: - #print("row",row) - row+="," #XXX append blank column for Amount Cur - line=dict(zip(headers,row)) - #print("line",line) - track_id=None - department_id=None - department_name=line.get("Department") - if department_name: - for dpt in get_model("clinic.department").search_browse([['name','=',department_name]]): - department_id=dpt.id - track_id=dpt.branch_id.track_id.id - if not line.get("Number"): - continue - number=line["Number"].strip() - if not number: - continue - - ##XXX remove invoice - #for inv in get_model('account.invoice').search_browse([['number','=', number]]): - #print('number --> ', number) - #inv.to_draft() - #inv.delete() - #continue - - ref=line["Reference"].strip() - contact_name=line["Contact"].strip() - res=get_model("partner").search([["name","=",contact_name]]) - if not res: - raise Exception("Contact not found: '%s'"%contact_name) - contact_id=res[0] - date=datetime.datetime.strptime(line["Date"].strip(),obj.date_fmt).strftime("%Y-%m-%d") - due_date=datetime.datetime.strptime(line["Due Date"].strip(),obj.date_fmt).strftime("%Y-%m-%d") - amount_due=float(line["Amount Due"].strip().replace(",","") or 0) - acc_code=line["Account"].strip() - amount_cur=float(line["Amount Cur"].strip().replace(",","") or 0) - acc_codes=acc_code.split(",") - amts=[] #XXX - for m in line['Memo'].split(","): - amt=m.split(":")[1] - amt=amt.strip() - if amt: - amt=float(amt) - amts.append(amt) - if len(acc_codes) > 1: - count=0 - print("*"*80) - for acc_code in acc_codes: - acc_code=acc_code.strip() - res=get_model("account.account").search([["code","=",acc_code]]) - if not res: - raise Exception("Account code not found: %s"%acc_code) - acc_id=res[0] - amount_due=amts[count] - vals={ - "conv_id": obj.id, - "number": number, - "ref": ref, - "contact_id": contact_id, - "date": date, - "due_date": due_date, - "amount_due": amount_due, - "account_id": acc_id, - "amount_cur": amount_due, #XXX - 'track_id': track_id, - 'department_id': department_id, - } - get_model("conv.sale.invoice").create(vals) - count+=1 - elif len(amts) >= 1 and len(acc_codes)<=1: - acc_code=acc_codes[0].strip() - res=get_model("account.account").search([["code","=",acc_code]]) - if not res: - raise Exception("Account code not found: %s"%acc_code) - acc_id=res[0] - for amt in amts: - amount_due=amt - vals={ - "conv_id": obj.id, - "number": number, - "ref": ref, - "contact_id": contact_id, - "date": date, - "due_date": due_date, - "amount_due": amount_due, - "account_id": acc_id, - "amount_cur": amount_due, #XXX - 'track_id': track_id, - 'department_id': department_id, - } - get_model("conv.sale.invoice").create(vals) - else: - res=get_model("account.account").search([["code","=",acc_code]]) - if not res: - raise Exception("Account code not found: %s"%acc_code) - acc_id=res[0] - vals={ - "conv_id": obj.id, - "number": number, - "ref": ref, - "contact_id": contact_id, - "date": date, - "due_date": due_date, - "amount_due": amount_due, - "account_id": acc_id, - "amount_cur": amount_cur, - 'track_id': track_id, - 'department_id': department_id, - } - get_model("conv.sale.invoice").create(vals) - return { - "next": { - "name": "conv_bal", - "active_id": obj.id, - "view_xml": "conv_bal2", - } - } - def import_sale_file(self,ids,context): obj=self.browse(ids)[0] path=get_file_path(obj.file) From 798cdd7149c1b4418bbe1f82a95a8bb13436d959 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Wed, 2 Sep 2015 13:54:25 +0700 Subject: [PATCH 08/36] import tb --- netforce_clinic/migrations/conv_bal.py | 3 --- netforce_clinic/models/conv_bal.py | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/netforce_clinic/migrations/conv_bal.py b/netforce_clinic/migrations/conv_bal.py index fd67a2f..3311db6 100644 --- a/netforce_clinic/migrations/conv_bal.py +++ b/netforce_clinic/migrations/conv_bal.py @@ -9,9 +9,6 @@ class Migration(migration.Migration): def migrate(self): set_active_user(1) set_active_company(1) - #for mv in get_model("account.move").search_browse([['number','ilike', 'OPEN']]): - #mv.to_draft() - #mv.delete() # delete old account payable dom=[ diff --git a/netforce_clinic/models/conv_bal.py b/netforce_clinic/models/conv_bal.py index 11a6fe2..730b6f2 100644 --- a/netforce_clinic/models/conv_bal.py +++ b/netforce_clinic/models/conv_bal.py @@ -7,6 +7,10 @@ from netforce.utils import get_file_path class ConvBal(Model): _inherit="conv.bal" + _fields={ + 'track_id': fields.Many2One("account.track.categ","Track-1"), + 'department_id': fields.Many2One("clinic.department","Department"), + } def create_sale_invoices(self,ids,context={}): obj=self.browse(ids)[0] @@ -99,6 +103,17 @@ class ConvBal(Model): "account_id": acc_id, "amount_cur": amount_cur, } + department_name=line['Department'] + track_name=line['Track-1'] + if department_name: + for department in get_model("clinic.department").search_browse([['name','=',department_name]]): + vals['department_id']=department.id + branch=department.branch_id + track=branch.track_id + vals['track_id']=track.id + elif track_name: + for track_id in get_model("account.track.categ").search([['name','=',track_name]]): + vals['track_id']=track_id get_model("conv.sale.invoice").create(vals) return { "next": { From dd87e8eea1fdc322cb52877d7ebdefe39fe5ad87 Mon Sep 17 00:00:00 2001 From: "watcha.h@almacom.co.th" Date: Fri, 11 Sep 2015 07:12:37 +0700 Subject: [PATCH 09/36] [report hd case summary] get and del patient in the same month --- netforce_clinic/models/report_hd_case_detail.py | 2 +- netforce_clinic/models/report_recent_patient.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/netforce_clinic/models/report_hd_case_detail.py b/netforce_clinic/models/report_hd_case_detail.py index 692b514..64de81c 100644 --- a/netforce_clinic/models/report_hd_case_detail.py +++ b/netforce_clinic/models/report_hd_case_detail.py @@ -201,7 +201,7 @@ class ReportHDCaseDetail(Model): dom.append(['reg_date','>=',time_start]) dom.append(['reg_date','<=',time_stop]) dom.append(['walkin','=',"no"]) - dom.append(['dispose','=',False]) + #dom.append(['dispose','=',False]) if branch_id: dom.append(['branch_id','=',branch_id]) if department_id: diff --git a/netforce_clinic/models/report_recent_patient.py b/netforce_clinic/models/report_recent_patient.py index 23917a6..c423d33 100644 --- a/netforce_clinic/models/report_recent_patient.py +++ b/netforce_clinic/models/report_recent_patient.py @@ -72,7 +72,7 @@ class ReportRecentPatient(Model): dom.append(['reg_date','>=',time_start]) dom.append(['reg_date','<=',time_stop]) dom.append(['walkin','=',"no"]) - dom.append(['dispose','=',False]) + #dom.append(['dispose','=',False]) if branch_id: dom.append(['branch_id','=',branch_id]) if department_id: From a5afa558e033fc837aaa6015346aff1ce890b0e6 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Thu, 15 Oct 2015 11:31:59 +0700 Subject: [PATCH 10/36] fix get_sequence --- netforce_clinic/models/hd_case.py | 6 +++--- netforce_clinic/models/sequence.py | 8 +++++--- netforce_clinic/models/visit.py | 8 ++++---- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index 9546245..00ae99c 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -288,7 +288,7 @@ class HDCase(Model): def _get_number(self,context={}): while 1: - seq_id=get_model("sequence").find_sequence(type="clinic_hdcase") + seq_id=get_model("sequence").find_sequence(type="clinic_hdcase",context=context) num=get_model("sequence").get_next_number(seq_id,context=context) if not num: return None @@ -1500,7 +1500,7 @@ class HDCase(Model): #break return vals - def create(self,vals,**kw): + def create(self,vals,context): patient_id=vals['patient_id'] if 'vascular_acc' in vals.keys(): patient=get_model("clinic.patient").browse(patient_id) @@ -1509,7 +1509,7 @@ class HDCase(Model): }) vals=self.get_staff_line(vals,patient_id) vals=self.get_hct(vals,patient_id) - new_id=super().create(vals,**kw) + new_id=super().create(vals,context) self.function_store([new_id]) return new_id diff --git a/netforce_clinic/models/sequence.py b/netforce_clinic/models/sequence.py index cdb61ae..61da104 100644 --- a/netforce_clinic/models/sequence.py +++ b/netforce_clinic/models/sequence.py @@ -69,14 +69,16 @@ class Sequence(Model): user=get_model('base.user').browse(user_id) dpt=user.department_id branch=user.branch_id - if dpt: + if context.get('branch_id'): + comp_dom=comp_dom+[["branch_id","=",context['branch_id']]] + elif dpt: branch_id=dpt.branch_id.id comp_dom=comp_dom+[["branch_id","=",branch_id]] elif branch: branch_id=branch.id comp_dom=comp_dom+[["branch_id","=",branch_id]] - elif context.get('branch_id'): - comp_dom=comp_dom+[["branch_id","=",context['branch_id']]] + #elif context.get('branch_id'): + #comp_dom=comp_dom+[["branch_id","=",context['branch_id']]] print('com_dom ', comp_dom) res=self.search(comp_dom,order="id") if res: diff --git a/netforce_clinic/models/visit.py b/netforce_clinic/models/visit.py index eda35cb..44851c2 100644 --- a/netforce_clinic/models/visit.py +++ b/netforce_clinic/models/visit.py @@ -58,7 +58,7 @@ class Visit(Model): def _get_number(self,context={}): while 1: seq_type='clinic_visit' - seq_id=get_model("sequence").find_sequence(type=seq_type) + seq_id=get_model("sequence").find_sequence(type=seq_type,context=context) if not seq_id: raise Exception("Can not found sequence %s"%seq_type) num=get_model("sequence").get_next_number(seq_id,context=context) @@ -206,7 +206,7 @@ class Visit(Model): hd_case.write(vals) hd_case_id=hd_case.id else: - hd_case_id=hd_case_obj.create(vals) + hd_case_id=hd_case_obj.create(vals,context) if context.get("called"): #XXX call outside return hd_case_id @@ -476,8 +476,8 @@ class Visit(Model): 'flash': 'Visit\'s %s has been cancelled'%obj.patient_id.name } - def create(self, vals,**kw): - new_id=super().create(vals,**kw) + def create(self, vals,context): + new_id=super().create(vals,context) self.function_store([new_id]) return new_id From b9436c5990acd522a38dcb97eff191c971dd1c0e Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Thu, 15 Oct 2015 12:09:42 +0700 Subject: [PATCH 11/36] migrate/update sequence --- netforce_clinic/migrations/__init__.py | 3 +- netforce_clinic/migrations/check_seq.py | 37 +++++++++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 netforce_clinic/migrations/check_seq.py diff --git a/netforce_clinic/migrations/__init__.py b/netforce_clinic/migrations/__init__.py index ed43705..eb3aead 100644 --- a/netforce_clinic/migrations/__init__.py +++ b/netforce_clinic/migrations/__init__.py @@ -1,4 +1,5 @@ #from . import clinic_setting #from . import repost_invoice -from . import conv_bal +#from . import conv_bal #from . import tb_ap_import +from . import check_seq diff --git a/netforce_clinic/migrations/check_seq.py b/netforce_clinic/migrations/check_seq.py new file mode 100644 index 0000000..95b7559 --- /dev/null +++ b/netforce_clinic/migrations/check_seq.py @@ -0,0 +1,37 @@ +from netforce.model import get_model +from netforce import migration +from netforce.access import set_active_user, set_active_company + +class Migration(migration.Migration): + _name="clinic.check.seq" + _version="2.11.0" + + def migrate(self): + set_active_user(1) + set_active_company(1) + fnames=['branch_id','prefix'] + seqs=dict([(x['branch_id'][0],x['prefix']) for x in get_model("sequence").search_read([['type','=','clinic_hdcase']],fnames)]) + print('seqs ',seqs) + count=0 + for hdcase in get_model('clinic.hd.case').search_browse([]): + seq=seqs[hdcase.branch_id.id] + rp=seq.split("/")[-1].replace("-","") + if '/' in hdcase.number and hdcase.number!='/': + if seq not in hdcase.number: + pf=hdcase.number.split('-')[0].split("/")[-1] + new_hdcase_number=hdcase.number.replace(pf,rp) + new_visit_number=hdcase.visit_id.number.replace(pf,rp) + print(hdcase.number, new_hdcase_number,hdcase.department_id.name) + print(hdcase.visit_id.number, new_visit_number, hdcase.visit_id.department_id.name) + hdcase.write({ + 'number': new_hdcase_number, + }) + hdcase.visit_id.write({ + 'number': new_visit_number, + }) + print('-'*100) + #print(seq, ' : ', hdcase.number, hdcase.visit_id.number, hdcase.date, hdcase.patient_id.name) + count+=1 + print('total unmatch', count) + +Migration.register() From e78208db1d3da7b18449cb41d82692614a711caf Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Thu, 15 Oct 2015 12:42:27 +0700 Subject: [PATCH 12/36] can not create visit / hdcase --- netforce_clinic/models/hd_case.py | 2 +- netforce_clinic/models/visit.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index 00ae99c..54c046f 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -1509,7 +1509,7 @@ class HDCase(Model): }) vals=self.get_staff_line(vals,patient_id) vals=self.get_hct(vals,patient_id) - new_id=super().create(vals,context) + new_id=super().create(vals,context=context) self.function_store([new_id]) return new_id diff --git a/netforce_clinic/models/visit.py b/netforce_clinic/models/visit.py index 44851c2..9c14006 100644 --- a/netforce_clinic/models/visit.py +++ b/netforce_clinic/models/visit.py @@ -477,7 +477,7 @@ class Visit(Model): } def create(self, vals,context): - new_id=super().create(vals,context) + new_id=super().create(vals,context=context) self.function_store([new_id]) return new_id From 03770dc2c805cc1b8a21093cba7f355f5fcb42c5 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Thu, 15 Oct 2015 12:42:27 +0700 Subject: [PATCH 13/36] can not create visit / hdcase --- netforce_clinic/models/hd_case.py | 2 +- netforce_clinic/models/visit.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index 00ae99c..54c046f 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -1509,7 +1509,7 @@ class HDCase(Model): }) vals=self.get_staff_line(vals,patient_id) vals=self.get_hct(vals,patient_id) - new_id=super().create(vals,context) + new_id=super().create(vals,context=context) self.function_store([new_id]) return new_id diff --git a/netforce_clinic/models/visit.py b/netforce_clinic/models/visit.py index 44851c2..fc9a2b3 100644 --- a/netforce_clinic/models/visit.py +++ b/netforce_clinic/models/visit.py @@ -206,7 +206,7 @@ class Visit(Model): hd_case.write(vals) hd_case_id=hd_case.id else: - hd_case_id=hd_case_obj.create(vals,context) + hd_case_id=hd_case_obj.create(vals,context=context) if context.get("called"): #XXX call outside return hd_case_id @@ -477,7 +477,7 @@ class Visit(Model): } def create(self, vals,context): - new_id=super().create(vals,context) + new_id=super().create(vals,context=context) self.function_store([new_id]) return new_id From 4326614a0420f88a6bfb3ca29a132e34d9cdf593 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Fri, 16 Oct 2015 12:23:14 +0700 Subject: [PATCH 14/36] prevent do gen picking from hdcase and dlz --- netforce_clinic/layouts/clinic_setting.xml | 1 + netforce_clinic/migrations/__init__.py | 3 +- netforce_clinic/migrations/del_gi.py | 50 ++++++++++ netforce_clinic/models/dialyzer.py | 107 +++++++++++---------- netforce_clinic/models/hd_case.py | 4 + netforce_clinic/models/setting.py | 1 + netforce_clinic/models/visit_board.py | 4 +- 7 files changed, 115 insertions(+), 55 deletions(-) create mode 100644 netforce_clinic/migrations/del_gi.py diff --git a/netforce_clinic/layouts/clinic_setting.xml b/netforce_clinic/layouts/clinic_setting.xml index 75a0875..cd4bf92 100644 --- a/netforce_clinic/layouts/clinic_setting.xml +++ b/netforce_clinic/layouts/clinic_setting.xml @@ -10,6 +10,7 @@ + diff --git a/netforce_clinic/migrations/__init__.py b/netforce_clinic/migrations/__init__.py index eb3aead..24348b7 100644 --- a/netforce_clinic/migrations/__init__.py +++ b/netforce_clinic/migrations/__init__.py @@ -2,4 +2,5 @@ #from . import repost_invoice #from . import conv_bal #from . import tb_ap_import -from . import check_seq +#from . import check_seq +from . import del_gi diff --git a/netforce_clinic/migrations/del_gi.py b/netforce_clinic/migrations/del_gi.py new file mode 100644 index 0000000..3d6d2b5 --- /dev/null +++ b/netforce_clinic/migrations/del_gi.py @@ -0,0 +1,50 @@ +import time + +from netforce.model import get_model +from netforce import migration +from netforce.access import set_active_user, set_active_company + +class Migration(migration.Migration): + _name="clinic.del.gi" + _version="2.12.0" + + def migrate(self): + set_active_user(1) + set_active_company(1) + #fmt='%Y-%m-%d %H:%M:%S' + #datenow=time.strftime(fmt) + dom=[ + ['date','>=','2015-01-01 00:00:00'], + ['date','<=','2015-06-30 23:59:59'], + ['type','=','out'], + ] + count=0 + for pick in get_model('stock.picking').search_browse(dom): + print('del ', pick.date, pick.id, pick.number) + pick.delete() + count+=1 + + print("Delete From 2015-01-01 to 2015-06-30 Total is: ", count) + + rows=open("/tmp/del_gi.csv","r").read() + ids=[] + for row in rows.split("\n"): + try: + r=row.split(",") + idtxt=r[1] + if idtxt.isnumeric(): + ids.append(int(idtxt)) + except Exception as e: + print("ERROR ", e) + count=0 + for id in ids: + pick=get_model('stock.picking').browse(id) + try: + print('del ', pick.date, pick.id, pick.number) + pick.delete() + except Exception as e: + print("ERROR ",e) + count+=1 + print("Delete from file Total: ",count) + +Migration.register() diff --git a/netforce_clinic/models/dialyzer.py b/netforce_clinic/models/dialyzer.py index 6dca684..a70dad1 100644 --- a/netforce_clinic/models/dialyzer.py +++ b/netforce_clinic/models/dialyzer.py @@ -117,63 +117,64 @@ class Dialyzer(Model): st=get_model("clinic.setting").browse(1) stock_journal=st.stock_journal_id - wh_loc_id=None - cust_loc_id=None - department=obj.department_id - if department: - stock_journal=department.pick_out_journal_id - if stock_journal: - wh_loc_id=stock_journal.location_from_id.id - cust_loc_id=stock_journal.location_to_id.id - print("get location from stock journal %s "%(stock_journal.name)) + if st.picking_auto: + wh_loc_id=None + cust_loc_id=None + department=obj.department_id + if department: + stock_journal=department.pick_out_journal_id + if stock_journal: + wh_loc_id=stock_journal.location_from_id.id + cust_loc_id=stock_journal.location_to_id.id + print("get location from stock journal %s "%(stock_journal.name)) - if not stock_journal: - raise Exception("Not found stock journal") + if not stock_journal: + raise Exception("Not found stock journal") + pick_vals={ + "type": "out", + 'journal_id': stock_journal.id, + 'date': obj.date, + "ref": obj.number, + "related_id": "clinic.dialyzer,%s"%obj.id, + "partner_id": obj.patient_id.partner_id.id, + "ship_address_id": ship_address_id, + "lines": [], + "state": "draft", + } - pick_vals={ - "type": "out", - 'journal_id': stock_journal.id, - 'date': obj.date, - "ref": obj.number, - "related_id": "clinic.dialyzer,%s"%obj.id, - "partner_id": obj.patient_id.partner_id.id, - "ship_address_id": ship_address_id, - "lines": [], - "state": "draft", - } - - if not cust_loc_id: - res=get_model("stock.location").search([["type","=","customer"]]) - if not res: - raise Exception("Customer location not found") - cust_loc_id=res[0] - - prod=obj.product_id - if not wh_loc_id: - wh_loc_id=prod.location_id.id # product -> tab inventory -> warehouse filed - if not wh_loc_id: - res=get_model("stock.location").search([["type","=","internal"]]) + if not cust_loc_id: + res=get_model("stock.location").search([["type","=","customer"]]) if not res: - raise Exception("Warehouse not found") - wh_loc_id=res[0] + raise Exception("Customer location not found") + cust_loc_id=res[0] + + prod=obj.product_id + if not wh_loc_id: + wh_loc_id=prod.location_id.id # product -> tab inventory -> warehouse filed + if not wh_loc_id: + res=get_model("stock.location").search([["type","=","internal"]]) + if not res: + raise Exception("Warehouse not found") + wh_loc_id=res[0] + + if prod.type=='stock': + line_vals={ + "product_id": prod.id, + "qty": 1, + "uom_id": prod.uom_id.id, + "location_from_id": wh_loc_id, + "location_to_id": cust_loc_id, + } + pick_vals["lines"].append(("create",line_vals)) + picking_obj=get_model("stock.picking") + context={ + 'pick_type': 'out', + 'journal_id': pick_vals['journal_id'], + } + pick_id=picking_obj.create(pick_vals,context=context) + pick=picking_obj.browse(pick_id) + pick.set_done([pick_id]) - if prod.type=='stock': - line_vals={ - "product_id": prod.id, - "qty": 1, - "uom_id": prod.uom_id.id, - "location_from_id": wh_loc_id, - "location_to_id": cust_loc_id, - } - pick_vals["lines"].append(("create",line_vals)) - picking_obj=get_model("stock.picking") - context={ - 'pick_type': 'out', - 'journal_id': pick_vals['journal_id'], - } - pick_id=picking_obj.create(pick_vals,context=context) - pick=picking_obj.browse(pick_id) - pick.set_done([pick_id]) number=obj.number.replace("/","") if not number: department=obj.department_id diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index 54c046f..d428623 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -757,6 +757,10 @@ class HDCase(Model): }) def make_pickings(self,ids,context={}): + st=get_model('clinic.setting').browse(1) + if not st.picking_auto: + return + obj=self.browse(ids[0]) # no picking if not obj.lines: diff --git a/netforce_clinic/models/setting.py b/netforce_clinic/models/setting.py index 907a73f..9236b17 100644 --- a/netforce_clinic/models/setting.py +++ b/netforce_clinic/models/setting.py @@ -64,6 +64,7 @@ class ClinicSetting(Model): 'staff_from_id': fields.Many2One("clinic.staff","Staff From"), 'staff_to_id': fields.Many2One("clinic.staff","Staff To"), 'product_categ_view': fields.Many2Many("product.categ","Product Category View"), + 'picking_auto': fields.Boolean("Picking Auto"), } _defaults={ diff --git a/netforce_clinic/models/visit_board.py b/netforce_clinic/models/visit_board.py index fafea9f..b7f556e 100644 --- a/netforce_clinic/models/visit_board.py +++ b/netforce_clinic/models/visit_board.py @@ -86,6 +86,7 @@ class VisitBoard(Model): defaults=self.default_get(context=context) department_id=defaults.get("department_id",None) branch_id=defaults.get("branch_id",None) + context['branch_id']=branch_id state=defaults.get("state",'pending') if ids: obj=self.browse(ids)[0] @@ -96,6 +97,7 @@ class VisitBoard(Model): doctor_id=obj.doctor_id.id department_id=obj.department_id.id branch_id=obj.branch_id.id + context['branch_id']=branch_id state=obj.state # auto generate visit day to day def auto_gen_visit(dom=[]): @@ -147,7 +149,7 @@ class VisitBoard(Model): 'visit_date': date_txt, 'state': 'pending', } - visit_id=get_model("clinic.visit").create(vals) + visit_id=get_model("clinic.visit").create(vals,context=context) print('create new visit %s for %s'%(visit_id,pt.name)) time_start='%s 00:00:00'%(date_from) time_stop='%s 23:59:59'%(date_to) From dbf0d685c3a9bd2c64925f2236c34168e1594ab2 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Sat, 17 Oct 2015 18:45:06 +0700 Subject: [PATCH 15/36] change visit --- netforce_clinic/models/change_visit.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/netforce_clinic/models/change_visit.py b/netforce_clinic/models/change_visit.py index d4e6e55..3f52e6d 100644 --- a/netforce_clinic/models/change_visit.py +++ b/netforce_clinic/models/change_visit.py @@ -41,6 +41,7 @@ class ChangeVisit(Model): def do_change(self,ids,context): obj=self.browse(ids)[0] + context['branch_id']=obj.department_id.branch_id.id dom=[ ['visit_date','=',obj.visit_date], ['patient_id','=',obj.patient_id.id], @@ -60,7 +61,7 @@ class ChangeVisit(Model): 'time_stop': obj.time_stop, 'visit_date': obj.visit_date, 'state': 'pending', - }) + },context=context) obj.visit_id.to_draft() obj.visit_id.cancel() visit=get_model("clinic.visit").browse(new_id) From 210ddcc5a85941e5c7ed527b997df5bba42f41c0 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Wed, 21 Oct 2015 11:28:27 +0700 Subject: [PATCH 16/36] migrate picking --- netforce_clinic/layouts/clinic_setting.xml | 5 +-- netforce_clinic/migrations/__init__.py | 3 +- netforce_clinic/migrations/restore_picking.py | 33 +++++++++++++++++++ netforce_clinic/models/dialyzer.py | 2 +- netforce_clinic/models/hd_case.py | 12 +------ netforce_clinic/models/setting.py | 3 +- 6 files changed, 42 insertions(+), 16 deletions(-) create mode 100644 netforce_clinic/migrations/restore_picking.py diff --git a/netforce_clinic/layouts/clinic_setting.xml b/netforce_clinic/layouts/clinic_setting.xml index cd4bf92..b683086 100644 --- a/netforce_clinic/layouts/clinic_setting.xml +++ b/netforce_clinic/layouts/clinic_setting.xml @@ -9,8 +9,9 @@ - - + + + diff --git a/netforce_clinic/migrations/__init__.py b/netforce_clinic/migrations/__init__.py index 24348b7..8bbdb6c 100644 --- a/netforce_clinic/migrations/__init__.py +++ b/netforce_clinic/migrations/__init__.py @@ -3,4 +3,5 @@ #from . import conv_bal #from . import tb_ap_import #from . import check_seq -from . import del_gi +#from . import del_gi +from . import restore_picking diff --git a/netforce_clinic/migrations/restore_picking.py b/netforce_clinic/migrations/restore_picking.py new file mode 100644 index 0000000..e1852a8 --- /dev/null +++ b/netforce_clinic/migrations/restore_picking.py @@ -0,0 +1,33 @@ +import time + +from netforce.model import get_model +from netforce import migration +from netforce.access import set_active_user, set_active_company + +class Migration(migration.Migration): + _name="clinic.restore.picking" + _version="2.12.1" + + def migrate(self): + set_active_user(1) + set_active_company(1) + #remove all good issued from dlz + total_del=0 + for dlz in get_model('clinic.dialyzer').search_browse([]): + for pick in dlz.pickings: + print('del pick ',pick.number) + pick.delete() + total_del+=1 + print('total delete ', total_del) + fmt='%Y-%m-%d %H:%M:%S' + datenow=time.strftime(fmt) + dom=[ + ['date','>=','2015-01-01'], + ['date','<=',datenow], + ] + for hdcase in get_model("clinic.hd.case").search_browse(dom): + if not hdcase.pickings: + print('gen picking for %s in %s'%(hdcase.number, hdcase.date)) + hdcase.make_pickings() + +Migration.register() diff --git a/netforce_clinic/models/dialyzer.py b/netforce_clinic/models/dialyzer.py index a70dad1..ac97b11 100644 --- a/netforce_clinic/models/dialyzer.py +++ b/netforce_clinic/models/dialyzer.py @@ -117,7 +117,7 @@ class Dialyzer(Model): st=get_model("clinic.setting").browse(1) stock_journal=st.stock_journal_id - if st.picking_auto: + if st.dlz_picking_auto: wh_loc_id=None cust_loc_id=None department=obj.department_id diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index d428623..954f2dc 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -758,14 +758,11 @@ class HDCase(Model): def make_pickings(self,ids,context={}): st=get_model('clinic.setting').browse(1) - if not st.picking_auto: + if not st.hdcase_picking_auto: return - obj=self.browse(ids[0]) - # no picking if not obj.lines: return - patient=obj.patient_id partner=patient.partner_id if not partner: @@ -777,7 +774,6 @@ class HDCase(Model): break if not ship_address_id: patient.simple_address() - #raise Exception("contact %s dont'have address with type shipping"%partner.name) # default journal cust_loc_id=None wh_loc_id=None @@ -789,7 +785,6 @@ class HDCase(Model): if stock_journal: wh_loc_id=stock_journal.location_from_id.id cust_loc_id=stock_journal.location_to_id.id - print("get location from stock journal %s "%(stock_journal.name)) pick_vals={ "type": "out", 'journal_id': stock_journal.id, @@ -806,8 +801,6 @@ class HDCase(Model): if not res: raise Exception("Customer location not found") cust_loc_id=res[0] - - #XXX no_lines=context.get('no_line') or False if no_lines: return @@ -832,13 +825,10 @@ class HDCase(Model): if prod_ids and prod.id not in prod_ids or prod.id in prod_exist_ids: continue prod_exist_ids.append(prod.id) - #XXX dpt_prods=get_model('clinic.department.product').get_location(obj.department_id.id,prod.id) if dpt_prods: - print("get location from menu department products") wh_loc_id=dpt_prods.get('wh_loc_id') cust_loc_id=dpt_prods.get('cust_loc_id') - #pick_vals['journal_id']=dpt_prods.get('journal_id') if not wh_loc_id: wh_loc_id=prod.location_id.id if wh_loc_id: diff --git a/netforce_clinic/models/setting.py b/netforce_clinic/models/setting.py index 9236b17..9a542d0 100644 --- a/netforce_clinic/models/setting.py +++ b/netforce_clinic/models/setting.py @@ -64,7 +64,8 @@ class ClinicSetting(Model): 'staff_from_id': fields.Many2One("clinic.staff","Staff From"), 'staff_to_id': fields.Many2One("clinic.staff","Staff To"), 'product_categ_view': fields.Many2Many("product.categ","Product Category View"), - 'picking_auto': fields.Boolean("Picking Auto"), + 'hdcase_picking_auto': fields.Boolean("HDCase Auto Picking"), + 'dlz_picking_auto': fields.Boolean("DLZ Auto Picking"), } _defaults={ From e3a75860ea19ad4e5b396c6255b469085bba3217 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Sun, 25 Oct 2015 15:14:50 +0700 Subject: [PATCH 17/36] prevent duplicat staff --- netforce_clinic/migrations/restore_picking.py | 5 ++++- netforce_clinic/models/hd_case.py | 9 ++++++--- netforce_clinic/models/visit.py | 3 +++ 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/netforce_clinic/migrations/restore_picking.py b/netforce_clinic/migrations/restore_picking.py index e1852a8..8c06148 100644 --- a/netforce_clinic/migrations/restore_picking.py +++ b/netforce_clinic/migrations/restore_picking.py @@ -28,6 +28,9 @@ class Migration(migration.Migration): for hdcase in get_model("clinic.hd.case").search_browse(dom): if not hdcase.pickings: print('gen picking for %s in %s'%(hdcase.number, hdcase.date)) - hdcase.make_pickings() + ctx={ + 'migrate':True, + } + hdcase.make_pickings(context=ctx) Migration.register() diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index 954f2dc..5a05eb8 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -819,9 +819,12 @@ class HDCase(Model): if patient.type_id.main_product: if len(prod_code)>1: prods=get_model('product').search_browse(['code','=',prod_code]) - if not prods: - raise Exception("Can not create good issue: product code %s is not found!"%prod_code) - prod=prods[0] + if not context.get('migrate'): + if not prods: + raise Exception("Can not create goods issue: product code %s is not found!"%prod_code) + prod=prods[0] + else: + continue if prod_ids and prod.id not in prod_ids or prod.id in prod_exist_ids: continue prod_exist_ids.append(prod.id) diff --git a/netforce_clinic/models/visit.py b/netforce_clinic/models/visit.py index fc9a2b3..c075edf 100644 --- a/netforce_clinic/models/visit.py +++ b/netforce_clinic/models/visit.py @@ -203,6 +203,9 @@ class Visit(Model): hd_case_id=None if obj.hd_cases: hd_case=obj.hd_cases[0] + # prevent duplicate staff: del old staff + for staff in hd_case.staffs: + staff.delete() hd_case.write(vals) hd_case_id=hd_case.id else: From 1a408090c361f984f3596d3e79043c9084cb8753 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Mon, 26 Oct 2015 10:51:57 +0700 Subject: [PATCH 18/36] prevent to generate dlz on hdcase (accountant required) --- netforce_clinic/models/hd_case.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index 5a05eb8..16c7a99 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -814,6 +814,8 @@ class HDCase(Model): prod=line.product_id if prod.type != 'stock': continue + if not st.dlz_picking_auto and prod.categ_id.code=='DLZ': + continue # check orginal product prod_code=prod.code.split("-")[0] if patient.type_id.main_product: From d8fcfdb126a7880c14c4f454d28b9832311a2a0c Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Thu, 5 Nov 2015 11:36:02 +0700 Subject: [PATCH 19/36] new & drop dlz on hd case option --- netforce_clinic/layouts/clinic_hd_case_dlz_form.xml | 1 + netforce_clinic/layouts/clinic_hd_case_form.xml | 1 + netforce_clinic/models/hd_case.py | 13 +++++++++++++ netforce_clinic/models/hd_case_dialyzer.py | 8 ++++++++ netforce_clinic/models/hd_case_popup_dlz.py | 3 +++ 5 files changed, 26 insertions(+) diff --git a/netforce_clinic/layouts/clinic_hd_case_dlz_form.xml b/netforce_clinic/layouts/clinic_hd_case_dlz_form.xml index 83203c1..810ae6a 100644 --- a/netforce_clinic/layouts/clinic_hd_case_dlz_form.xml +++ b/netforce_clinic/layouts/clinic_hd_case_dlz_form.xml @@ -6,6 +6,7 @@ + diff --git a/netforce_clinic/models/hd_case.py b/netforce_clinic/models/hd_case.py index 6ffdfe8..41dbcba 100644 --- a/netforce_clinic/models/hd_case.py +++ b/netforce_clinic/models/hd_case.py @@ -914,9 +914,6 @@ class HDCase(Model): use_time=dlz_line.use_time or 0 max_use_time=dlz_line.max_use_time or 0 desc=dlz_line.description or '' - #TODO when we to draft after approve hdcase it will update the wrong use time - #if use_time > (dlz.use_time or 0): - #continue if is_decrease: use_time-=1 vals={ @@ -957,7 +954,7 @@ class HDCase(Model): cycle_item_ids=cycle_item.search(dom) cycle_item_id=None if cycle_item_ids: - cycle_item_id=cycle_item_ids[0] + cycle_item_id=cycle_item_ids[-1] else: cycle_item_id=cycle_item.create({ 'date': obj.date, @@ -1013,7 +1010,6 @@ class HDCase(Model): obj.make_invoices(context=context) obj.post_invoices(context=context) obj.create_cycle_item() - #obj.do_expense(context=context) vals={ "state":"waiting_payment", # for government } @@ -1023,6 +1019,7 @@ class HDCase(Model): date=obj.date vals['time_stop']='%s %s'%(date,timenow) obj.write(vals) + obj.recompute_labor_cost() if context.get("called"): return obj.id return { @@ -1058,13 +1055,11 @@ class HDCase(Model): def undo(self,ids,context={}): obj=self.browse(ids)[0] - # recompute labor cost - lc=get_model("clinic.labor.cost").search_browse([['cycle_item_id','=',obj.cycle_item_id.id]]) - if lc: - lc.compute() context['is_decrease']=True - # in case to draft - obj.update_usetime(context=context) + # should not reset use time if not the day of treatment is not today + datenow=time.strftime("%Y-%m-%d") + if obj.date==datenow: + obj.update_usetime(context=context) for line in obj.lines: line.write({ 'state': 'draft', @@ -1087,7 +1082,7 @@ class HDCase(Model): payment.delete() for pm_line in obj.payment_lines: pm_line.delete() - + #XXX remove for exp in obj.expenes: exp.delete() @@ -1100,7 +1095,7 @@ class HDCase(Model): obj.sickbed_id.write({ 'available': False, }) - + obj.recompute_labor_cost() return { 'next': { 'name': 'clinic_hd_case', @@ -1109,7 +1104,16 @@ class HDCase(Model): }, 'flash': '%s has been undo'%obj.number, } - + + def recompute_labor_cost(self,ids,context={}): + for obj in self.browse(ids): + cit=obj.cycle_item_id + # recompute labor cost + if cit.state=='validated': + for lc in get_model("clinic.labor.cost").search_browse([['cycle_item_id','=',cit.id]]): + lc.compute() + + def view_payment(self,ids,context={}): print("clinic_view_payment") return { diff --git a/netforce_clinic/models/hd_case_dialyzer.py b/netforce_clinic/models/hd_case_dialyzer.py index e58fcf5..030bb32 100644 --- a/netforce_clinic/models/hd_case_dialyzer.py +++ b/netforce_clinic/models/hd_case_dialyzer.py @@ -31,7 +31,7 @@ class HDCaseDialyzerLine(Model): "membrane_type": fields.Selection([("unsub","Unsub cellul"),("sub","Sub cellul"),("synthetic","Synthetic")],"Membrane Type"), 'hdcase_date': fields.Date('Date', function="_get_all",function_multi=True), "hdcase_state": fields.Selection([("draft","Draft"),('waiting_treatment','Waiting Treatment'),("in_progress","In Progress"),("completed","Finish Treatment"),('paid','Paid'),("waiting_payment","Waiting Payment"),("discountinued","Discountinued"),("cancelled","Cancelled")],"Status",required=True,function="_get_all",function_multi=True), - 'nurse_id': fields.Many2One('clinic.staff', 'Nurse',function="_get_all",function_multi=True), + 'nurse_id': fields.Many2One('clinic.staff', 'Use by',function="_get_all",function_multi=True), "state": fields.Selection([("new","New"),("active","Active"),("drop","Drop"),("expire","Expire"),('cancelled','Cancelled')],"Status",function="_get_dlz_state"), } diff --git a/netforce_clinic/models/hd_case_payment.py b/netforce_clinic/models/hd_case_payment.py index ce18120..1856c3b 100644 --- a/netforce_clinic/models/hd_case_payment.py +++ b/netforce_clinic/models/hd_case_payment.py @@ -65,6 +65,7 @@ class HDCasePayment(Model): obj.write({ 'pay_amount': hd_case.amount, }) + hd_case.recompute_labor_cost() return { 'next': { 'name': 'clinic_hd_case', @@ -85,6 +86,7 @@ class HDCasePayment(Model): 'state': 'waiting_payment', 'req_fee': 0, # force to hide button pay! }) + hd_case.recompute_labor_cost() inv_number=[] for inv in hd_case.invoices: inv_number.append(inv.number or "") From 5d1a7ba4f17c5c5d1c736e5566a0f7076e77d682 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Fri, 11 Dec 2015 13:44:03 +0700 Subject: [PATCH 28/36] show owner of dlz --- netforce_clinic/layouts/clinic_dialyzer_form.xml | 2 ++ netforce_clinic/models/dialyzer.py | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/netforce_clinic/layouts/clinic_dialyzer_form.xml b/netforce_clinic/layouts/clinic_dialyzer_form.xml index 583ad80..63b996f 100644 --- a/netforce_clinic/layouts/clinic_dialyzer_form.xml +++ b/netforce_clinic/layouts/clinic_dialyzer_form.xml @@ -24,6 +24,8 @@ + +