From 2aa67e02718ed33083b8128fce85da5e1c945734 Mon Sep 17 00:00:00 2001 From: "watcha.h" Date: Mon, 8 Dec 2014 21:54:25 +0700 Subject: [PATCH] labor cost --- .../layouts/clinic_labor_cost_form.xml | 11 +- netforce_clinic/models/cycle_item.py | 132 +-------------- netforce_clinic/models/labor_cost.py | 158 +++++++++++++++++- netforce_clinic/models/labor_cost_line.py | 6 + netforce_clinic/models/staff.py | 21 +++ 5 files changed, 194 insertions(+), 134 deletions(-) diff --git a/netforce_clinic/layouts/clinic_labor_cost_form.xml b/netforce_clinic/layouts/clinic_labor_cost_form.xml index 9fc3ff8..866b00e 100644 --- a/netforce_clinic/layouts/clinic_labor_cost_form.xml +++ b/netforce_clinic/layouts/clinic_labor_cost_form.xml @@ -3,6 +3,9 @@ + + + @@ -10,7 +13,6 @@ - @@ -34,18 +36,23 @@ + - + +
+ + +
diff --git a/netforce_clinic/models/cycle_item.py b/netforce_clinic/models/cycle_item.py index 638d94c..c9022cd 100644 --- a/netforce_clinic/models/cycle_item.py +++ b/netforce_clinic/models/cycle_item.py @@ -103,140 +103,16 @@ class CycleItem(Model): if lc: lc.compute() obj.write({ - 'state': 'validate', - }) - - return - - levels={} - for line in obj.lines: - level=line.level_id - levels[level.id]={ - 'amount': line.amount or 0, - 'qty': line.qty, - 'level_id': level.id, - } - - lines=[] - # cost's nurses - for nr in obj.nurses: - nurse=nr.nurse_id - level=nr.level_id - vals=levels.get(level.id) - rate,amt,qty=0.0,0.0,0 - level_id=level.id - if vals: - level_id=vals['level_id'] - amt=vals['amount'] - qty=vals['qty'] - if qty: - rate=amt/qty - lines.append(('create',{ - 'cycle_id': obj.cycle_id.id, - 'staff_id': nurse.id, - 'level_id': level_id, - 'rate': rate, - 'type': 'nurse', - 'qty': 1, - })) - - # cost's doctor - st=get_model('clinic.setting').browse(1) - cost_per_case=st.cost_per_case or 0 - staff_total={} - for hd_case in obj.hd_cases: - staffs=hd_case.staffs - for ps in staffs: - staff=ps.staff_id - if not staff: - continue - base=staff.base - if not base: - base=cost_per_case - if not staff_total.get(staff.id): - staff_total[staff.id]={ - 'base': 0, - 'level_id': staff.level_id.id, - 'type': ps.type, - 'qty': 0, - } - staff_total[staff.id]['base']=base - staff_total[staff.id]['qty']+=1 - - for doctor_id, value in staff_total.items(): - base=value['base'] - type=value['type'] - qty=value['qty'] - level_id=value['level_id'] - lines.append(('create',{ - 'cycle_id': obj.cycle_id.id, - 'staff_id': doctor_id, - 'level_id': level_id, - 'rate': base, - 'qty': qty, - 'type': type, - })) - - cycle_daily=obj.cycle_daily_id - # clear cost line - for line in cycle_daily.lines: - cycle=line.cycle_id - if obj.cycle_id.id==cycle.id: # only own cycle - line.delete() - - # group staff and cycle date - glines={} - for line in lines: - mode,vals=line - cycle_id=vals['cycle_id'] - staff_id=vals['staff_id'] - #amount=vals['amount'] or 0 - rate=vals['rate'] or 0 - qty=vals['qty'] or 0 - amount=qty*rate - key=(cycle_id,staff_id) - if not key in glines.keys(): - glines[key]={ - 'amount': amount, - 'type': vals['type'], - 'level_id': vals['level_id'], - 'rate': rate, - 'qty': qty, - } - continue - glines[key]['amount']+=amount - glines[key]['qty']+=qty - - lines=[] - for key,vals in glines.items(): - cycle_id,staff_id=key - line={ - 'cycle_id': cycle_id, - 'staff_id': staff_id, - 'date': obj.date, - } - line.update(vals) - lines.append(('create',line)) - - # call from outside - if context.get('called'): - return lines - - cycle_daily.write({ - 'lines': lines, - }) - - obj.write({ - 'state': 'done', + 'state': 'validated', }) return { 'next': { - 'name': 'clinic_cycle_daily', + 'name': 'clinic_cycle_item', 'mode': 'form', - 'active_id': cycle_daily.id, + 'active_id': obj.id, }, - 'flash': 'Cycle Item has been validated, please see the detail of cost below.', + 'flash': 'Cycle Item has been validated.', } def to_draft(self,ids,context={}): diff --git a/netforce_clinic/models/labor_cost.py b/netforce_clinic/models/labor_cost.py index f7b14da..e77ddec 100644 --- a/netforce_clinic/models/labor_cost.py +++ b/netforce_clinic/models/labor_cost.py @@ -1,4 +1,5 @@ from netforce.model import Model, fields, get_model +from netforce.utils import get_data_path class LaborCost(Model): _name="clinic.labor.cost" @@ -13,16 +14,21 @@ class LaborCost(Model): total_case=len(hd_cases) total_a,total_b=0,0 total=0.0 - for line in obj.lines: - total+=line.amount or 0 - total_a+=line.var_a or 0 - total_b+=line.var_b or 0 + for fline in obj.formulars: + total+=fline.amount or 0 + total_a+=fline.var_a or 0 + total_b+=fline.var_b or 0 var_ptx=total_case*(obj.var_k or 0) var_fml1='PTxK=%sX%s'%(total_a,total_b) total_bstr=total_b < 0 and "+%s"%(abs(total_b)) or "-%s"%total_b var_x=0.0 if total_a: var_x=eval('(%s%s)/%s'%(var_ptx,total_bstr,total_a)) + + total_cost=0.0 + for line in obj.lines: + total_cost+=line.amount or 0.0 + res[obj.id]={ 'var_pt': total_case, 'var_ptx': total_case*(obj.var_k or 0), @@ -31,7 +37,9 @@ class LaborCost(Model): 'var_fml3': '(%s%s)/%s'%(var_ptx,total_bstr,total_a), 'var_x': round(var_x,2), 'total': total, + 'total_cost': total_cost, } + return res _fields={ @@ -44,6 +52,7 @@ class LaborCost(Model): 'var_fml3': fields.Char("X:",function="_get_all",function_multi=True), 'var_x': fields.Char("X:",function="_get_all",function_multi=True), 'total': fields.Float("Total",function="_get_all",function_multi=True), + 'total_cost': fields.Float("Total",function="_get_all",function_multi=True), 'manual': fields.Boolean("Manual"), "formulars": fields.One2Many("clinic.labor.cost.formular", "labor_cost_id", "Formulars"), "staffs": fields.One2Many("clinic.labor.cost.staff", "labor_cost_id", "Staffs"), @@ -174,6 +183,7 @@ class LaborCost(Model): 'formulars': formulars, }) + levels={} if obj.manual: for fline in obj.formulars: fml=(fline.formular or "").replace("X","*%s") @@ -185,6 +195,125 @@ class LaborCost(Model): 'amount': amt, }) + level=fline.level_id + levels[level.id]={ + 'amount': amt or 0.0, + 'qty': fline.qty or 0, + 'level_id': level.id, + } + else: + for fline in formulars: + vals=fline[1] + level_id=vals['level_id'] + levels[level_id]={ + 'amount': vals['amount'] or 0.0, + 'qty': vals['qty'] or 0, + 'level_id': level_id, + } + + #TODO UPDATE COST : like cycle daily + item=obj.cycle_item_id + lines=[] + # cost's nurses + for nr in item.nurses: + nurse=nr.nurse_id + level=nr.level_id + vals=levels.get(level.id) + rate,amt,qty=0.0,0.0,0 + level_id=level.id + if vals: + level_id=vals['level_id'] + amt=vals['amount'] + qty=vals['qty'] + if qty: + rate=amt/qty + lines.append(('create',{ + 'cycle_id': item.cycle_id.id, + 'staff_id': nurse.id, + 'level_id': level_id, + 'rate': rate, + 'type': 'nurse', + 'qty': 1, + })) + + # cost's doctor + st=get_model('clinic.setting').browse(1) + cost_per_case=st.cost_per_case or 0 + staff_total={} + for hd_case in item.hd_cases: + staffs=hd_case.staffs + for ps in staffs: + staff=ps.staff_id + if not staff: + continue + base=staff.base + if not base: + base=cost_per_case + if not staff_total.get(staff.id): + staff_total[staff.id]={ + 'base': 0, + 'level_id': staff.level_id.id, + 'type': ps.type, + 'qty': 0, + } + staff_total[staff.id]['base']=base + staff_total[staff.id]['qty']+=1 + + for doctor_id, value in staff_total.items(): + base=value['base'] + type=value['type'] + qty=value['qty'] + level_id=value['level_id'] + lines.append(('create',{ + 'cycle_id': item.cycle_id.id, + 'staff_id': doctor_id, + 'level_id': level_id, + 'rate': base, + 'qty': qty, + 'type': type, + })) + + # clear cost line + for line in obj.lines: + line.delete() + + # group staff and cycle date + glines={} + for line in lines: + mode,vals=line + cycle_id=vals['cycle_id'] + staff_id=vals['staff_id'] + rate=vals['rate'] or 0 + qty=vals['qty'] or 0 + amount=qty*rate + key=(cycle_id,staff_id) + if not key in glines.keys(): + glines[key]={ + 'amount': amount, + 'type': vals['type'], + 'level_id': vals['level_id'], + 'rate': rate, + 'qty': qty, + } + continue + glines[key]['amount']+=amount + glines[key]['qty']+=qty + + lines=[] + for key,vals in glines.items(): + cycle_id,staff_id=key + line={ + 'cycle_id': cycle_id, + 'staff_id': staff_id, + 'date': item.date, + } + line.update(vals) + lines.append(('create',line)) + + obj.write({ + 'lines': lines, + }) + return { 'next': { 'name': 'clinic_labor_cost', @@ -194,5 +323,26 @@ class LaborCost(Model): 'flash':'Compute successfully', } + def onchange_cost_line(self,context={}): + data=context['data'] + path=context['path'] + line=get_data_path(data,path,parent=True) + qty=line.get("qty",0) + rate=line.get("rate",0.0) + amt=qty*rate + line['amount']=amt + data=self.update_amt(context) + return data + + def update_amt(self,context): + total=0.0 + data=context['data'] + for line in data['lines']: + qty=line['qty'] or 0 + rate=line['rate'] or 0.0 + amt=qty*rate + total+=amt + data['total_cost']=total + return data LaborCost.register() diff --git a/netforce_clinic/models/labor_cost_line.py b/netforce_clinic/models/labor_cost_line.py index b2d2aa9..a0b440d 100644 --- a/netforce_clinic/models/labor_cost_line.py +++ b/netforce_clinic/models/labor_cost_line.py @@ -10,13 +10,19 @@ class LaborCostLine(Model): "labor_cost_id": fields.Many2One("clinic.labor.cost","Cycle Item",required=True), 'staff_id': fields.Many2One("clinic.staff", "Staff"), 'level_id': fields.Many2One("clinic.staff.level", "Level"), + 'cycle_id': fields.Many2One("clinic.cycle", "Cycle"), 'qty': fields.Integer("Qty"), + 'rate': fields.Float("Rate",scale=2), 'amount': fields.Float("Amount",scale=2), + 'date': fields.Date("Date"), + "type": fields.Selection([('staff','Staff'),("doctor","Doctor"),('nurse','Nurse')],"Type",required=True), 'company_id': fields.Many2One('company','Company'), } _defaults={ "company_id": lambda *a: get_active_company(), } + + _order="cycle_id,level_id" LaborCostLine.register() diff --git a/netforce_clinic/models/staff.py b/netforce_clinic/models/staff.py index cadd2e2..f399a84 100644 --- a/netforce_clinic/models/staff.py +++ b/netforce_clinic/models/staff.py @@ -171,4 +171,25 @@ class Staff(Model): vals['employee_id']=emp_id super().write(ids,vals,**kw) + def name_get(self,ids,context={}): + vals=[] + for obj in self.browse(ids): + level=obj.level_id + name="%s (%s)"%(obj.name,level.name) + vals.append((obj.id,name)) + return vals + + def name_search(self,name,domain=None,context={},**kw): + dom=[["name","ilike","%"+name+"%"]] + if domain: + dom=[dom,domain] + ids1=self.search(dom) + # XXX need to store db + dom=[["level_id.name","ilike","%"+name+"%"]] + if domain: + dom=[dom,domain] + ids2=self.search_read(dom) + ids=list(set(ids1+ids2)) + return self.name_get(ids,context=context) + Staff.register()