report labor cost

conv_bal
watcha.h 2015-02-18 15:50:35 +07:00
parent 6e8d3806f0
commit 08bb9f9c98
27 changed files with 312 additions and 23 deletions

View File

@ -0,0 +1,8 @@
<action>
<field name="string">Report Labor Cost Overtime</field>
<field name="view_cls">report</field>
<field name="model">clinic.report.labor.cost.overtime</field>
<field name="report_template">report_labor_cost_overtime</field>
<field name="report_template_xls">report_labor_cost_overtime</field>
<field name="menu">account_menu</field>
</action>

View File

@ -11,6 +11,7 @@
<item string="Labor Cost Summary" action="clinic_report_labor_cost_summary"/>
<item string="Labor Cost Detail" action="clinic_report_labor_cost_detail"/>
<item string="Labor Cost Daily" action="clinic_report_labor_cost_daily"/>
<item string="Labor Cost Overtime" action="clinic_report_labor_cost_overtime"/>
<!--<item string="Staff" action="clinic_report_staff"/>-->
<!--<item string="Staff Fee" action="clinic_report_staff_fee"/>-->
<!--<item string="Staff Fee Detail" action="clinic_report_staff_fee_detail"/>-->

View File

@ -43,5 +43,11 @@
<field name="income_account_id" string="Account Receivable"/>
<field name="import_account_id"/>
</tab>
<tab string="Reporting">
<field name="helper_categ_id"/>
</tab>
<tab string="Other">
<field name="base_salary_day"/>
</tab>
</tabs>
</form>

View File

@ -47,6 +47,7 @@
<field name="total_ncost" string="Total" span="3" offset="9"/>
</tab>
<tab string="Doctor Cost">
<field name="cost_per_case"/>
<field name="doctor_lines" nolabel="1">
<list>
<field name="cycle_id"/>

View File

@ -1,7 +1,7 @@
<menu string="Clinic" perm="clinic">
<item string="Dashboard" action="clinic_board"/>
<item string="Staffs" perm="clinic_staff">
<item string="Staffs" action="clinic_staff" action_options="tab_no=1"/>
<item string="Staffs" action="clinic_staff" action_options="tab_no=2"/>
<item string="Doctors" action="clinic_staff" action_options="tab_no=3"/>
<item string="Nurses" action="clinic_staff" action_options="tab_no=4"/>
<divider/>

View File

@ -1,6 +1,6 @@
<form model="clinic.report.labor.cost.daily">
<field name="date" required="1" span="2"/>
<field name="type" onchange="onchange_type" span="2"/>
<field name="staff_type" onchange="onchange_type" span="2"/>
<field name="staff_id" domain='[["type","=",type]]' span="2"/>
<field name="department_id" span="2"/>
</form>

View File

@ -0,0 +1,9 @@
<form model="clinic.report.labor.cost.overtime">
<field name="date" mode="month" onchange="onchange_date" span="2"/>
<field name="date_from" required="1" span="2"/>
<field name="date_to" required="1" span="2"/>
<field name="type" onchange="onchange_type" span="2"/>
<field name="staff_id" domain='[["type","=",type]]' span="2"/>
<field name="categ_id" span="2"/>
<field name="level_id" span="2"/>
</form>

View File

@ -2,8 +2,9 @@
<field name="date" mode="month" onchange="onchange_date" span="2"/>
<field name="date_from" required="1" span="2"/>
<field name="date_to" required="1" span="2"/>
<field name="type" onchange="onchange_type" span="2"/>
<field name="staff_type" onchange="onchange_type" span="2"/>
<field name="staff_id" domain='[["type","=",type]]' span="2"/>
<field name="categ_id" span="2"/>
<field name="level_id" span="2"/>
<field name="only_value" span="2"/>
</form>

View File

@ -42,7 +42,8 @@
<field name="cycle_id"/>
<field name="wage"/>
<field name="max_cycle"/>
<field name="check_max_cycle"/>
<field name="ot_per_cycle"/>
<!--<field name="check_max_cycle"/>-->
</tab>
<tab string="Note">
<field name="note" nolabel="1"/>

View File

@ -7,6 +7,7 @@
<field name="resign_date"/>
<field name="wage"/>
<field name="max_cycle"/>
<field name="ot_per_cycle"/>
<field name="note"/>
<field name="company_id" invisible="1"/>
</form>

View File

@ -78,6 +78,7 @@ from . import report_payment_matching
from . import report_labor_cost_summary
from . import report_labor_cost_detail
from . import report_labor_cost_daily
from . import report_labor_cost_overtime
from . import branch
from . import period
from . import period_line

View File

@ -1020,7 +1020,7 @@ class HDCase(Model):
"membrane_type": pop.membrane_type,
}
else:
dlz_vals=get_model("clinic.dialyzer").default_get()
dlz_vals=get_model("clinic.dialyzer").default_get(context=context)
dlz_vals['patient_id']=obj.patient_id.id
dlz_vals['company_id']=dlz_vals['company_id'][0]
product_name=dlz_vals['product_id'][1]

View File

@ -90,10 +90,16 @@ class LaborCost(Model):
'cycle_id': fields.Many2One('clinic.cycle',"Cycle", function="_get_store",function_multi=True,store=True,search=True),
'department_id': fields.Many2One('clinic.department',"Department", function="_get_store",function_multi=True,store=True,search=True),
'branch_id': fields.Many2One('clinic.branch',"Branch", function="_get_store",function_multi=True,store=True,search=True),
'cost_per_case': fields.Float("Cost Per Case"), # for doctor
}
def _get_cost_per_case(self,context={}):
st=get_model("clinic.setting").browse(1)
return st.cost_per_case or 0
_defaults={
'company_id': lambda *a: get_active_company(),
'cost_per_case': _get_cost_per_case,
}
def compute(self,ids,context={}):
@ -279,7 +285,7 @@ class LaborCost(Model):
# cost's doctor
st=get_model('clinic.setting').browse(1)
cost_per_case=st.cost_per_case or 0
cost_per_case=obj.cost_per_case or st.cost_per_case or 0
staff_total={}
for hd_case in item.hd_cases:
staffs=hd_case.staffs

View File

@ -312,7 +312,7 @@ class Patient(Model):
def new_dialyzer(self,ids,context={}):
dlz_id=None
for obj in self.browse(ids):
dlz_vals=get_model("clinic.dialyzer").default_get()
dlz_vals=get_model("clinic.dialyzer").default_get(context=context)
dlz_vals['patient_id']=obj.id
dlz_vals['company_id']=dlz_vals['company_id'][0]
dlz_vals['product_id']=dlz_vals['product_id'][0]

View File

@ -11,7 +11,7 @@ class ReportLaborCostDaily(Model):
_fields={
"date": fields.Date("Date"),
"type": fields.Selection([["doctor","Doctor"],["nurse","Nurse"],["staff","Staff"]],"Type"),
"staff_type": fields.Selection([["doctor","Doctor"],["nurse","Nurse"],["staff","Staff"]],"Type"),
'staff_id': fields.Many2One("clinic.staff","Staff"),
'department_id': fields.Many2One("clinic.department",'Department'),
}
@ -26,7 +26,7 @@ class ReportLaborCostDaily(Model):
department_id=int(defaults.get('department_id', "0"))
res={
'date': date,
'type': staff_type,
'staff_type': staff_type,
'staff_id': staff_id and staff_id or None,
'department_id': department_id and department_id or None,
}
@ -36,7 +36,7 @@ class ReportLaborCostDaily(Model):
def get_report_data(self,ids,context={}):
company_id=get_active_company()
comp=get_model("company").browse(company_id)
defaults=context.get("defaults")
defaults=self.default_get(context=context)
date=defaults.get("date")
staff_id=defaults.get("staff_id")
staff_type=defaults.get("staff_type")
@ -52,6 +52,7 @@ class ReportLaborCostDaily(Model):
dom.append(['date','<=',date])
# prevent to load more
if not staff_id:
print("not staff_id")
return {}
if staff_id:
dom.append(['staff_id','=',staff_id])
@ -59,6 +60,7 @@ class ReportLaborCostDaily(Model):
dom.append(['type','=',staff_type])
if dpt_id:
dom.append(['labor_cost_id.cycle_item_id.department_id','=',dpt_id])
print('dom ', dom)
lines=[]
no=1
for line in get_model("clinic.labor.cost.line").search_browse(dom):
@ -90,6 +92,7 @@ class ReportLaborCostDaily(Model):
})
no+=1
elif staff_type=='nurse':
print("nurse ")
for hdcase in citem.hd_cases:
doctor=hdcase.doctor_id
pt_type=hdcase.patient_type_id

View File

@ -179,7 +179,12 @@ class ReportLaborCostDetail(Model):
'amt_text': 'จำนวนเงิน',
})
comp_span=(len(dpts)*2)+1
staff_name=''
if staff_id:
staff=get_model("clinic.staff").browse(staff_id)
staff_name=staff.name or ''
data={
'staff_name': staff_name,
'date_from': date_from,
'date_to': date_to,
'dpts': dpts,

View File

@ -0,0 +1,171 @@
import time
from calendar import monthrange
from netforce.model import Model,fields,get_model
from netforce.access import get_active_company
class ReportLaborCostOverTime(Model):
_name="clinic.report.labor.cost.overtime"
_string="Report Labor Cost Overtime"
_transient=True
_fields={
"date": fields.Date("Month"),
"date_from": fields.Date("From", required=True),
"date_to": fields.Date("To", required=True),
'staff_id': fields.Many2One("clinic.staff","Staff"),
"type": fields.Selection([["nurse","Nurse"]],"Type"),
'department_id': fields.Many2One("clinic.department","Department"),
'level_id': fields.Many2One("clinic.staff.level","Level"),
'categ_id': fields.Many2One("clinic.staff.categ","Category"),
}
def _get_date_from(self,context={}):
year,month=time.strftime("%Y-%m").split("-")
return '%s-%s-01'%(year,month)
def _get_date_to(self,context={}):
year,month,day=time.strftime("%Y-%m-%d").split("-")
weekday, total_day=monthrange(int(year), int(month))
return "%s-%s-%s"%(year,month,total_day)
def _get_helper_categ(self,ids,context={}):
st=get_model("clinic.setting").browse(1)
return st.helper_categ_id.id
_defaults={
'date': lambda *a: time.strftime("%Y-%m-%d"),
'date_from': _get_date_from,
'date_to': _get_date_to,
'type': 'nurse',
'categ_id': _get_helper_categ,
}
def get_report_data(self,ids,context={}):
setting=get_model("clinic.setting").browse(1)
base_salary_day=setting.base_salary_day or 1
res=get_model("clinic.report.labor.cost.overtime").default_get(context=context)
date_from=res['date_from']
date_to=res['date_to']
if res.get("categ_id"):
categ_id=res['categ_id'][0]
staff_id=None
level_id=None
dom=[]
if ids:
obj=self.browse(ids)[0]
date_from=obj.date_from
date_to=obj.date_to
staff_id=obj.staff_id.id
level_id=obj.level_id.id
categ_id=obj.categ_id.id
dom.append(['date','>=',date_from])
dom.append(['date','<=',date_to])
dom.append(['staff_id.type','=','nurse'])
if staff_id:
dom.append(['staff_id','=',staff_id])
if categ_id:
dom.append(['staff_id.categ_id','=',categ_id])
print("dom ", dom)
staffs={}
for line in get_model("clinic.labor.cost.line").search_browse(dom):
#lcost=line.labor_cost_id
#citem=lcost.cycle_item_id
amt=line.amount or 0
staff=line.staff_id
categ_name=''
categ_id=None
categ=staff.categ_id
if level_id and staff.level_id.id!=level_id:
continue
if categ:
categ_id=categ.id
categ_name=categ.name or ""
wage=staff.wage or 0
#wage_per_day=wage/base_salary_day
if not staffs.get(staff.name):
staffs[staff.name]={
'number': staff.number or '',
'staff_id': staff.id,
'staff_type': staff.type,
'staff_name': staff.name or '',
'staff_level': staff.level_id.name,
'staff_wage': wage or 0,
'categ_name': categ_name,
'categ_id': categ_id,
'max_cycle': staff.max_cycle or 0,
'ot_per_cycle': staff.ot_per_cycle or 0,
'cycle_qty':0,
'amount': 0,
}
staffs[staff.name]['amount']+=amt # amount from formular
staffs[staff.name]['cycle_qty']+=1 # number of cycle
lines=[]
snames=sorted(staffs.keys()) #sort by staff name
no=1
for sname in snames:
vals=staffs[sname]
cycle_qty=vals.get("cycle_qty",0)
max_cycle=vals.get("max_cycle",0)
ot_qty=cycle_qty-max_cycle
#prevent to show
if ot_qty < 1:
ot_qty=0
ot_per_cycle=vals.get("ot_per_cycle",0)
ot_amount=ot_per_cycle*ot_qty
net_pay=(vals['staff_wage'] or 0)+ot_amount
net_diff=(vals['amount'] or 0)-net_pay
vals.update({
'no': no,
'ot_qty': ot_qty,
'ot_amount': ot_amount,
'net_pay': net_pay,
'net_diff': net_diff,
})
lines.append(vals)
no+=1
company_id=get_active_company()
comp=get_model("company").browse(company_id)
data={
'date_from': date_from,
'date_to': date_to,
'comp_name': comp.name or 0,
'lines': lines,
'total_amount':0,
'total_max_cycle':0,
'total_cycle_qty':0,
'total_ot_qty':0,
'total_ot_per_cycle':0,
'total_ot_amount':0,
'total_wage': 0,
'total_net_pay': 0,
'total_net_diff': 0,
}
for line in lines:
data['total_amount']+=line['amount'] or 0
data['total_max_cycle']+=line['max_cycle'] or 0
data['total_cycle_qty']+=line['cycle_qty'] or 0
data['total_ot_qty']+=line['ot_qty'] or 0
data['total_ot_per_cycle']+=line['ot_per_cycle'] or 0
data['total_ot_amount']+=line['ot_amount'] or 0
data['total_wage']+=line['staff_wage'] or 0
data['total_net_pay']+=line['net_pay'] or 0
data['total_net_diff']+=line['net_diff'] or 0
return data
def onchange_date(self,context={}):
data=context['data']
date=data['date']
year,month,day=date.split("-")
weekday, total_day=monthrange(int(year), int(month))
data['date_from']="%s-%s-01"%(year,month)
data['date_to']="%s-%s-%s"%(year,month,total_day)
return data
def onchange_type(self,context={}):
data=context['data']
data['staff_id']=None
return data
ReportLaborCostOverTime.register()

View File

@ -14,11 +14,10 @@ class ReportLaborCostSummary(Model):
"date_from": fields.Date("From", required=True),
"date_to": fields.Date("To", required=True),
'staff_id': fields.Many2One("clinic.staff","Staff"),
"type": fields.Selection([["doctor","Doctor"],["nurse","Nurse"],["staff","Staff"]],"Type"),
"staff_type": fields.Selection([["doctor","Doctor"],["nurse","Nurse"],["staff","Staff"]],"Type"),
'department_id': fields.Many2One("clinic.department","Department"),
'level_id': fields.Many2One("clinic.staff.level","Level"),
'categ_id': fields.Many2One("clinic.staff.categ","Category"),
'branch_id': fields.Many2One("clinic.branch","Branch"),
'only_value': fields.Boolean("Only Amount"),
}
@ -31,20 +30,29 @@ class ReportLaborCostSummary(Model):
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,
'only_value': True,
'type': 'nurse',
}
def default_get(self,field_names=None,context={},**kw):
defaults=context.get("defaults",{})
date_from=defaults.get("date", self._get_date_from())
date_to=defaults.get("date", self._get_date_to())
staff_type=defaults.get("staff_type","doctor")
staff_id=int(defaults.get('staff_id', "0"))
print('defaults ', defaults)
res={
'date': time.strftime("%Y-%m-%d"),
'date_from': date_from,
'date_to': date_to,
'staff_type': staff_type,
'staff_id': staff_id and staff_id or None,
'only_value': True,
}
return res
def get_report_data(self,ids,context={}):
res=get_model("clinic.report.labor.cost.summary").default_get()
res=get_model("clinic.report.labor.cost.summary").default_get(context=context)
date_from=res['date_from']
date_to=res['date_to']
staff_id=None
staff_type=res['type']
staff_id=res['staff_id']
staff_type=res['staff_type']
only_value=res['only_value']
level_id=None
categ_id=None
@ -78,6 +86,8 @@ class ReportLaborCostSummary(Model):
categ_name=''
categ_id=None
categ=staff.categ_id
if level_id and staff.level_id.id!=level_id:
continue
if categ:
categ_id=categ.id
categ_name=categ.name or ""

View File

@ -72,7 +72,7 @@ class ReportMedicalSummary(Model):
prod_categ_id=None
branch_id=None
department_id=None
res=get_model("clinic.report.medical.summary").default_get()
res=get_model("clinic.report.medical.summary").default_get(context=context)
if res:
if res.get("prod_categ_id"):
prod_categ_id=res.get("prod_categ_id")[0]

View File

@ -34,6 +34,8 @@ class ClinicSetting(Model):
"cash_account_id": fields.Many2One("account.account","Cash Account",multi_company=True),
"income_account_id": fields.Many2One("account.account","Income Account",multi_company=True),
"import_account_id": fields.Many2One("account.account","Import Account",multi_company=True),
'helper_categ_id': fields.Many2One("clinic.staff.categ","Helper Category"),
'base_salary_day': fields.Float("Base Salary Day"),
}
_defaults={

View File

@ -47,9 +47,11 @@ class Staff(Model):
for rotate in obj.rotations:
wage=rotate.wage
max_cycle=rotate.max_cycle
ot_per_cycle=rotate.ot_per_cycle or 0
res[obj.id]={
'wage': wage,
'max_cycle': max_cycle,
'ot_per_cycle': ot_per_cycle,
}
return res
@ -113,6 +115,7 @@ class Staff(Model):
'date': fields.Date("Register Date"),
'wage': fields.Float("Wage", function="_get_base",function_multi=True),
'max_cycle': fields.Integer("Max Cycle", function="_get_base",function_multi=True),
'ot_per_cycle': fields.Integer("OT Per Cycle", function="_get_base",function_multi=True),
'check_max_cycle': fields.Boolean("Check Max Cycle"),
'hire_date': fields.Date("Hire Date"),
'resign_date': fields.Date("Resign Date"),

View File

@ -15,6 +15,7 @@ class StaffRotation(Model):
"resign_date": fields.Date("Resign Date", search=True),
"wage": fields.Float("Wage"),
"max_cycle": fields.Integer("Max Cycle"),
"ot_per_cycle": fields.Float("OT Per Cycle"),
"note": fields.Text("Note"),
'company_id': fields.Many2One("company","Company"),
}

View File

@ -0,0 +1,59 @@
<p></p>
<table class="table table-condensed table-striped">
<thead>
<tr>
<th>ลำดับ</th>
<th>รหัส</th>
<th>ชื่อ-สกุล</th>
<th>ระดับ</th>
<th style="text-align:right;">รวมยอด</th>
<th style="text-align:right;">ฐานวันที่ทำงาน (รอบ)</th>
<th style="text-align:right;">ทำงานจริง (รอบ)</th>
<th style="text-align:right;">OT ทั้งหมด</th>
<th style="text-align:right;">OT ต่อรอบ</th>
<th style="text-align:right;">รวม OT</th>
<th style="text-align:right;">เงินเดือน</th>
<th style="text-align:right;">จ่ายจริง</th>
<th style="text-align:right;">ผลต่าง</th>
</tr>
</thead>
<tbody>
{{#each lines }}
<tr>
<td>{{no}}</th>
<td style="width:10%">{{number}}</th>
<td>
{{view "link" string=staff_name action="clinic_staff" action_options="mode=form" active_id=staff_id}}
</td>
<td>{{staff_level}}</td>
<td style="text-align:right;">
<a href="#name=clinic_report_labor_cost_summary&defaults.date_from={{../date_from}}&defaults.date_to={{../date_to}}&defaults.staff_type={{staff_type}}&defaults.staff_id={{staff_id}}">{{currency amount zero=""}}</a>
</td>
<td style="text-align:right;">{{max_cycle}}</th>
<td style="text-align:right;">{{cycle_qty}}</th>
<td style="text-align:right;">{{ot_qty}}</th>
<td style="text-align:right;">{{currency ot_per_cycle zero=""}}</th>
<td style="text-align:right;color:orange">{{currency ot_amount zero=""}}</th>
<td style="text-align:right;color:blue">{{currency staff_wage zero=""}}</th>
<td style="text-align:right;color:green">{{currency net_pay zero=""}}</th>
<td style="text-align:right;color:red">{{currency net_diff zero=""}}</th>
</tr>
{{/each}}
</tbody>
<tfoot>
<th></th>
<th></th>
<th></th>
<th>รวม</th>
<th style="text-align:right">{{currency total_amount zero=""}}</th>
<th style="text-align:right">{{total_max_cycle}}</th>
<th style="text-align:right">{{total_cycle_qty}}</th>
<th style="text-align:right">{{total_ot_qty}}</th>
<th style="text-align:right">{{currency total_ot_per_cycle zero=""}}</th>
<th style="text-align:right">{{currency total_ot_amount zero=""}}</th>
<th style="text-align:right">{{currency total_wage zero=""}}</th>
<th style="text-align:right">{{currency total_net_pay zero=""}}</th>
<th style="text-align:right">{{currency total_net_diff zero=""}}</th>
<th></th>
</tfoot>
</table>