labor cost

conv_bal
watcha.h 2014-12-08 21:54:25 +07:00
parent c02a2b4a98
commit 2aa67e0271
5 changed files with 194 additions and 134 deletions

View File

@ -3,6 +3,9 @@
<button string="Options" dropdown="1"> <button string="Options" dropdown="1">
</button> </button>
</head> </head>
<group form_layout="stacked">
<field name="cycle_item_id" span="3"/>
</group>
<tabs> <tabs>
<tab string="Computation"> <tab string="Computation">
<group form_layout="stacked"> <group form_layout="stacked">
@ -10,7 +13,6 @@
<field name="var_pt" span="3"/> <field name="var_pt" span="3"/>
<field name="var_ptx" span="3"/> <field name="var_ptx" span="3"/>
<field name="manual" span="3" help="Help"/> <field name="manual" span="3" help="Help"/>
<field name="cycle_item_id" span="3"/>
<field name="formulars" nolabel="1"> <field name="formulars" nolabel="1">
<list colors='{"red":[["state","=","fail"]]}'> <list colors='{"red":[["state","=","fail"]]}'>
<field name="level_id"/> <field name="level_id"/>
@ -34,18 +36,23 @@
<tab string="Cost"> <tab string="Cost">
<field name="lines" nolabel="1"> <field name="lines" nolabel="1">
<list> <list>
<field name="cycle_id"/>
<field name="staff_id"/> <field name="staff_id"/>
<field name="level_id"/> <field name="level_id"/>
<field name="qty"/> <field name="qty" onchange="onchange_cost_line"/>
<field name="rate" onchange="onchange_cost_line"/>
<field name="amount"/> <field name="amount"/>
</list> </list>
<form> <form>
<field name="cycle_id"/>
<field name="staff_id"/> <field name="staff_id"/>
<field name="level_id"/> <field name="level_id"/>
<field name="qty"/> <field name="qty"/>
<field name="rate"/>
<field name="amount"/> <field name="amount"/>
</form> </form>
</field> </field>
<field name="total_cost" span="3" offset="9"/>
</tab> </tab>
</tabs> </tabs>
<foot> <foot>

View File

@ -103,140 +103,16 @@ class CycleItem(Model):
if lc: if lc:
lc.compute() lc.compute()
obj.write({ obj.write({
'state': 'validate', 'state': 'validated',
})
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',
}) })
return { return {
'next': { 'next': {
'name': 'clinic_cycle_daily', 'name': 'clinic_cycle_item',
'mode': 'form', '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={}): def to_draft(self,ids,context={}):

View File

@ -1,4 +1,5 @@
from netforce.model import Model, fields, get_model from netforce.model import Model, fields, get_model
from netforce.utils import get_data_path
class LaborCost(Model): class LaborCost(Model):
_name="clinic.labor.cost" _name="clinic.labor.cost"
@ -13,16 +14,21 @@ class LaborCost(Model):
total_case=len(hd_cases) total_case=len(hd_cases)
total_a,total_b=0,0 total_a,total_b=0,0
total=0.0 total=0.0
for line in obj.lines: for fline in obj.formulars:
total+=line.amount or 0 total+=fline.amount or 0
total_a+=line.var_a or 0 total_a+=fline.var_a or 0
total_b+=line.var_b or 0 total_b+=fline.var_b or 0
var_ptx=total_case*(obj.var_k or 0) var_ptx=total_case*(obj.var_k or 0)
var_fml1='PTxK=%sX%s'%(total_a,total_b) var_fml1='PTxK=%sX%s'%(total_a,total_b)
total_bstr=total_b < 0 and "+%s"%(abs(total_b)) or "-%s"%total_b total_bstr=total_b < 0 and "+%s"%(abs(total_b)) or "-%s"%total_b
var_x=0.0 var_x=0.0
if total_a: if total_a:
var_x=eval('(%s%s)/%s'%(var_ptx,total_bstr,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]={ res[obj.id]={
'var_pt': total_case, 'var_pt': total_case,
'var_ptx': total_case*(obj.var_k or 0), '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_fml3': '(%s%s)/%s'%(var_ptx,total_bstr,total_a),
'var_x': round(var_x,2), 'var_x': round(var_x,2),
'total': total, 'total': total,
'total_cost': total_cost,
} }
return res return res
_fields={ _fields={
@ -44,6 +52,7 @@ class LaborCost(Model):
'var_fml3': fields.Char("X:",function="_get_all",function_multi=True), 'var_fml3': fields.Char("X:",function="_get_all",function_multi=True),
'var_x': 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': fields.Float("Total",function="_get_all",function_multi=True),
'total_cost': fields.Float("Total",function="_get_all",function_multi=True),
'manual': fields.Boolean("Manual"), 'manual': fields.Boolean("Manual"),
"formulars": fields.One2Many("clinic.labor.cost.formular", "labor_cost_id", "Formulars"), "formulars": fields.One2Many("clinic.labor.cost.formular", "labor_cost_id", "Formulars"),
"staffs": fields.One2Many("clinic.labor.cost.staff", "labor_cost_id", "Staffs"), "staffs": fields.One2Many("clinic.labor.cost.staff", "labor_cost_id", "Staffs"),
@ -174,6 +183,7 @@ class LaborCost(Model):
'formulars': formulars, 'formulars': formulars,
}) })
levels={}
if obj.manual: if obj.manual:
for fline in obj.formulars: for fline in obj.formulars:
fml=(fline.formular or "").replace("X","*%s") fml=(fline.formular or "").replace("X","*%s")
@ -185,6 +195,125 @@ class LaborCost(Model):
'amount': amt, '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 { return {
'next': { 'next': {
'name': 'clinic_labor_cost', 'name': 'clinic_labor_cost',
@ -194,5 +323,26 @@ class LaborCost(Model):
'flash':'Compute successfully', '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() LaborCost.register()

View File

@ -10,13 +10,19 @@ class LaborCostLine(Model):
"labor_cost_id": fields.Many2One("clinic.labor.cost","Cycle Item",required=True), "labor_cost_id": fields.Many2One("clinic.labor.cost","Cycle Item",required=True),
'staff_id': fields.Many2One("clinic.staff", "Staff"), 'staff_id': fields.Many2One("clinic.staff", "Staff"),
'level_id': fields.Many2One("clinic.staff.level", "Level"), 'level_id': fields.Many2One("clinic.staff.level", "Level"),
'cycle_id': fields.Many2One("clinic.cycle", "Cycle"),
'qty': fields.Integer("Qty"), 'qty': fields.Integer("Qty"),
'rate': fields.Float("Rate",scale=2),
'amount': fields.Float("Amount",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'), 'company_id': fields.Many2One('company','Company'),
} }
_defaults={ _defaults={
"company_id": lambda *a: get_active_company(), "company_id": lambda *a: get_active_company(),
} }
_order="cycle_id,level_id"
LaborCostLine.register() LaborCostLine.register()

View File

@ -171,4 +171,25 @@ class Staff(Model):
vals['employee_id']=emp_id vals['employee_id']=emp_id
super().write(ids,vals,**kw) 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() Staff.register()