-
-
-
-
The , the latest payment follow-up
was:
diff --git a/addons/account_payment/account_payment_view.xml b/addons/account_payment/account_payment_view.xml
index e49d6dfe93b..d62a7969754 100644
--- a/addons/account_payment/account_payment_view.xml
+++ b/addons/account_payment/account_payment_view.xml
@@ -69,14 +69,14 @@
-
-
-
+
+
+
@@ -292,7 +292,7 @@
-
+
diff --git a/addons/account_voucher/account_voucher_view.xml b/addons/account_voucher/account_voucher_view.xml
index 3e4f1635914..a5885156442 100644
--- a/addons/account_voucher/account_voucher_view.xml
+++ b/addons/account_voucher/account_voucher_view.xml
@@ -200,9 +200,9 @@
-
+
diff --git a/addons/claim_from_delivery/claim_delivery_view.xml b/addons/claim_from_delivery/claim_delivery_view.xml
index 9187b1d11ca..852d602c269 100644
--- a/addons/claim_from_delivery/claim_delivery_view.xml
+++ b/addons/claim_from_delivery/claim_delivery_view.xml
@@ -9,7 +9,6 @@
{'default_ref': 'stock.picking.out,'+str(context.get('active_id', False))}
[('ref','=','stock.picking.out,'+str(context.get('active_id',False)))]
-
crm.claim.from_delivery.form
stock.picking.out
@@ -17,11 +16,13 @@
-
+
-
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index 9dfe22202ec..f3ce3ace549 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -214,7 +214,14 @@ class crm_lead(format_address, osv.osv):
duration = len(no_days)
res[lead.id][field] = abs(int(duration))
return res
-
+ def _meeting_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for meeting in self.browse(cr, uid, ids, context=context):
+ res[meeting.id] = len(meeting.opportunity_ids)
+ except:
+ pass
+ return res
_columns = {
'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange',
select=True, help="Linked partner (optional). Usually created when converting the lead."),
@@ -289,6 +296,8 @@ class crm_lead(format_address, osv.osv):
'payment_mode': fields.many2one('crm.payment.mode', 'Payment Mode', \
domain="[('section_id','=',section_id)]"),
'planned_cost': fields.float('Planned Costs'),
+ 'opportunity_ids': fields.one2many('calendar.event', 'opportunity_id', 'Opportunities'),
+ 'meeting_count': fields.function(_meeting_count, string='# Meetings', type='integer'),
}
_defaults = {
diff --git a/addons/crm/crm_lead_view.xml b/addons/crm/crm_lead_view.xml
index a33b215fb8f..beed7ba5c97 100644
--- a/addons/crm/crm_lead_view.xml
+++ b/addons/crm/crm_lead_view.xml
@@ -103,9 +103,8 @@
-
+
@@ -389,11 +388,13 @@
-
-
+
+
diff --git a/addons/crm/crm_phonecall.py b/addons/crm/crm_phonecall.py
index 19bc98c585a..be92fcad2bf 100644
--- a/addons/crm/crm_phonecall.py
+++ b/addons/crm/crm_phonecall.py
@@ -31,6 +31,15 @@ class crm_phonecall(osv.osv):
_description = "Phonecall"
_order = "id desc"
_inherit = ['mail.thread']
+
+ def _meeting_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for meeting in self.browse(cr, uid, ids, context=context):
+ res[meeting.id] = len(meeting.meeting_ids)
+ except:
+ pass
+ return res
_columns = {
'date_action_last': fields.datetime('Last Action', readonly=1),
'date_action_next': fields.datetime('Next Action', readonly=1),
@@ -65,6 +74,8 @@ class crm_phonecall(osv.osv):
'date_closed': fields.datetime('Closed', readonly=True),
'date': fields.datetime('Date'),
'opportunity_id': fields.many2one ('crm.lead', 'Lead/Opportunity'),
+ 'meeting_ids': fields.one2many('calendar.event', 'phonecall_id', 'Phonecalls'),
+ 'meeting_count': fields.function(_meeting_count, string='# Meetings', type='integer'),
}
def _get_default_state(self, cr, uid, context=None):
diff --git a/addons/crm/crm_phonecall_view.xml b/addons/crm/crm_phonecall_view.xml
index 60b5934ac53..25cddce10b6 100644
--- a/addons/crm/crm_phonecall_view.xml
+++ b/addons/crm/crm_phonecall_view.xml
@@ -64,15 +64,16 @@
-
-
-
-
+
+
+
+
diff --git a/addons/crm_claim/crm_claim.py b/addons/crm_claim/crm_claim.py
index 50cbe4a6c44..d55036193c4 100644
--- a/addons/crm_claim/crm_claim.py
+++ b/addons/crm_claim/crm_claim.py
@@ -190,8 +190,17 @@ class crm_claim(osv.osv):
class res_partner(osv.osv):
_inherit = 'res.partner'
+ def _claim_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for partner in self.browse(cr, uid, ids, context=context):
+ res[partner.id] = len(partner.claims_ids)
+ except:
+ pass
+ return res
_columns = {
'claims_ids': fields.one2many('crm.claim', 'partner_id', 'Claims'),
+ 'claim_count': fields.function(_claim_count, string='# Claims', type='integer'),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/crm_claim/res_partner_view.xml b/addons/crm_claim/res_partner_view.xml
index 4a5db879311..6d5d54498ee 100644
--- a/addons/crm_claim/res_partner_view.xml
+++ b/addons/crm_claim/res_partner_view.xml
@@ -9,11 +9,11 @@
-
+ name="%(crm_case_categ_claim0)d" icon="fa-comments" groups="base.group_sale_salesman">
+
+
diff --git a/addons/crm_project_issue/project_issue_view.xml b/addons/crm_project_issue/project_issue_view.xml
index b62e5f74880..65ca274f086 100644
--- a/addons/crm_project_issue/project_issue_view.xml
+++ b/addons/crm_project_issue/project_issue_view.xml
@@ -36,7 +36,8 @@
-
+
diff --git a/addons/email_template/email_template_view.xml b/addons/email_template/email_template_view.xml
index 4f7828cb531..52fb270eb12 100644
--- a/addons/email_template/email_template_view.xml
+++ b/addons/email_template/email_template_view.xml
@@ -14,15 +14,16 @@
-
-
+
-
+
+ context="{'template_id':active_id}" widget="statinfo"/>
diff --git a/addons/event/event.py b/addons/event/event.py
index 7ee99402158..497d75f9be0 100644
--- a/addons/event/event.py
+++ b/addons/event/event.py
@@ -149,6 +149,17 @@ class event_event(osv.osv):
res[event.id]= True
continue
return res
+
+ def _count_all(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,{'count_regitrations': 0, 'count_tracks': 0,}), ids))
+ try:
+ for data in self.browse(cr, uid, ids, context=context):
+ res[data.id] = {'count_regitrations': len(data.registration_ids),
+ 'count_tracks': len(data.track_ids),
+ }
+ except:
+ pass
+ return res
_columns = {
'name': fields.char('Event Name', size=64, required=True, translate=True, readonly=False, states={'done': [('readonly', True)]}),
@@ -169,6 +180,7 @@ class event_event(osv.osv):
store={'event.registration': (_get_events_from_registrations, ['state'], 10),
'event.event': (lambda self, cr, uid, ids, c = {}: ids, ['seats_max', 'registration_ids'], 20)}),
'registration_ids': fields.one2many('event.registration', 'event_id', 'Registrations', readonly=False, states={'done': [('readonly', True)]}),
+ 'track_ids': fields.one2many('event.track', 'event_id', 'Tracks', readonly=False),
'date_begin': fields.datetime('Start Date', required=True, readonly=True, states={'draft': [('readonly', False)]}),
'date_end': fields.datetime('End Date', required=True, readonly=True, states={'draft': [('readonly', False)]}),
'state': fields.selection([
@@ -191,6 +203,8 @@ class event_event(osv.osv):
'company_id': fields.many2one('res.company', 'Company', required=False, change_default=True, readonly=False, states={'done': [('readonly', True)]}),
'is_subscribed' : fields.function(_subscribe_fnc, type="boolean", string='Subscribed'),
'organizer_id': fields.many2one('res.partner', "Organizer"),
+ 'count_regitrations': fields.function(_count_all, type="integer", string="Registrations", multi=True),
+ 'count_tracks': fields.function(_count_all, type='integer', string='Tracks', multi=True),
}
_defaults = {
'state': 'draft',
diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml
index 07a36ea3a6b..6f41646d156 100644
--- a/addons/event/event_view.xml
+++ b/addons/event/event_view.xml
@@ -65,13 +65,19 @@
-
-
-
+
+
+
diff --git a/addons/fleet/fleet.py b/addons/fleet/fleet.py
index 8aea73ba405..0e964cafc80 100644
--- a/addons/fleet/fleet.py
+++ b/addons/fleet/fleet.py
@@ -313,6 +313,20 @@ class fleet_vehicle(osv.Model):
except ValueError:
model_id = False
return model_id
+
+ def _count_all(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,{'odometer_count': 0, 'fuel_logs_count': 0, 'service_count': 0, 'contract_count': 0, 'cost_count': 0,}), ids))
+ try:
+ for costs in self.browse(cr, uid, ids, context=context):
+ res[costs.id] = {'odometer_count': len(costs.odometer_ids),
+ 'fuel_logs_count': len(costs.log_fuel),
+ 'service_count': len(costs.log_services),
+ 'contract_count': len(costs.log_contracts),
+ 'cost_count': len(costs.costs_ids)
+ }
+ except:
+ pass
+ return res
_name = 'fleet.vehicle'
_description = 'Information on a vehicle'
@@ -327,6 +341,13 @@ class fleet_vehicle(osv.Model):
'log_fuel': fields.one2many('fleet.vehicle.log.fuel', 'vehicle_id', 'Fuel Logs'),
'log_services': fields.one2many('fleet.vehicle.log.services', 'vehicle_id', 'Services Logs'),
'log_contracts': fields.one2many('fleet.vehicle.log.contract', 'vehicle_id', 'Contracts'),
+ 'costs_ids': fields.one2many('fleet.vehicle.cost', 'vehicle_id', 'Costs'),
+ 'odometer_ids': fields.one2many('fleet.vehicle.odometer', 'vehicle_id', 'Odometer'),
+ 'cost_count': fields.function(_count_all, type='integer', string="Costs" , multi=True),
+ 'contract_count': fields.function(_count_all, type='integer', string='Contracts', multi=True),
+ 'service_count': fields.function(_count_all, type='integer', string='Services', multi=True),
+ 'fuel_logs_count': fields.function(_count_all, type='integer', string='Fuel Logs', multi=True),
+ 'odometer_count': fields.function(_count_all, type='integer', string='Odometer', multi=True),
'acquisition_date': fields.date('Acquisition Date', required=False, help='Date when the vehicle has been bought'),
'color': fields.char('Color', size=32, help='Color of the vehicle'),
'state_id': fields.many2one('fleet.vehicle.state', 'State', help='Current state of the vehicle', ondelete="set null"),
diff --git a/addons/fleet/fleet_view.xml b/addons/fleet/fleet_view.xml
index d8c47e43b9d..e4cdbe886f7 100644
--- a/addons/fleet/fleet_view.xml
+++ b/addons/fleet/fleet_view.xml
@@ -211,11 +211,46 @@
-
-
-
-
-
+
+
+
+
+
diff --git a/addons/gamification/models/challenge.py b/addons/gamification/models/challenge.py
index 06d0c44baac..11b5f787bdd 100644
--- a/addons/gamification/models/challenge.py
+++ b/addons/gamification/models/challenge.py
@@ -114,6 +114,15 @@ class gamification_challenge(osv.Model):
return self.pool.get('ir.model.data').get_object_reference(cr, uid, 'gamification', 'simple_report_template')[1]
except ValueError:
return False
+
+ def _count_goals(self, cr, uid, ids, field_name, arg, context=None):
+ res = {}
+ try:
+ for goals in self.browse(cr, uid, ids, context=context):
+ res[goals.id] = len(goals.goals_ids)
+ except:
+ pass
+ return res
_order = 'end_date, start_date, name, id'
_columns = {
@@ -191,6 +200,8 @@ class gamification_challenge(osv.Model):
'category': fields.selection(lambda s, *a, **k: s._get_categories(*a, **k),
string="Appears in", help="Define the visibility of the challenge through menus", required=True),
+ 'goals_ids': fields.one2many('gamification.goal', 'challenge_id', 'Related Goals'),
+ 'goals_count': fields.function(_count_goals, type='integer', string='Related Goals')
}
_defaults = {
diff --git a/addons/gamification/views/challenge.xml b/addons/gamification/views/challenge.xml
index 075afcaccfa..9683557a14c 100644
--- a/addons/gamification/views/challenge.xml
+++ b/addons/gamification/views/challenge.xml
@@ -53,7 +53,13 @@
-
+
diff --git a/addons/hr/hr.py b/addons/hr/hr.py
index a13a1866493..4efa72e8f5e 100644
--- a/addons/hr/hr.py
+++ b/addons/hr/hr.py
@@ -92,6 +92,17 @@ class hr_job(osv.Model):
res.append(employee.job_id.id)
return res
+ def _count_all(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,{'documents_count': 0, 'application_count': 0,}), ids))
+ try:
+ for data in self.browse(cr, uid, ids, context=context):
+ res[data.id] = {'documents_count': len(data.document_ids),
+ 'application_count': len(data.applicant_ids),
+ }
+ except:
+ pass
+ return res
+
_name = "hr.job"
_description = "Job Position"
_inherit = ['mail.thread', 'ir.needaction_mixin']
@@ -122,6 +133,10 @@ class hr_job(osv.Model):
track_visibility='always',
help="By default 'Closed', set it to 'In Recruitment' if recruitment process is going on for this job position."),
'write_date': fields.datetime('Update Date', readonly=True),
+ 'applicant_ids':fields.one2many('hr.applicant', 'job_id', 'Applications'),
+ 'application_count': fields.function(_count_all, type='integer', string='Applications', multi=True),
+ 'document_ids': fields.one2many('ir.attachment', 'company_id', 'Documents'),
+ 'documents_count': fields.function(_count_all, type='integer', string='Documents', multi=True),
}
_defaults = {
@@ -186,6 +201,20 @@ class hr_employee(osv.osv):
def _set_image(self, cr, uid, id, name, value, args, context=None):
return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context)
+
+ def _count_all(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,{'appraisal_count': 0, 'leaves_count': 0, 'contracts_count': 0, 'timesheet_count': 0, 'payslip_count': 0,}), ids))
+ try:
+ for datas in self.browse(cr, uid, ids, context=context):
+ res[datas.id] = {'appraisal_count': len(datas.appraisal_ids),
+ 'leaves_count': len(datas.leave_ids),
+ 'contracts_count': len(datas.contract_ids),
+ 'timesheet_count': len(datas.timsheet_ids),
+ 'payslip_count': len(datas.payslip_ids)
+ }
+ except:
+ pass
+ return res
_columns = {
#we need a related field in order to be able to sort the employee by name
@@ -237,6 +266,16 @@ class hr_employee(osv.osv):
'city': fields.related('address_id', 'city', type='char', string='City'),
'login': fields.related('user_id', 'login', type='char', string='Login', readonly=1),
'last_login': fields.related('user_id', 'date', type='datetime', string='Latest Connection', readonly=1),
+ 'appraisal_ids': fields.one2many('hr.evaluation.interview', 'user_to_review_id', 'Appraisal Interviews'),
+ 'leave_ids': fields.one2many('hr.holidays', 'employee_id', 'Leaves'),
+ 'contracts_ids': fields.one2many('hr.contract', 'employee_id', 'Contracts'),
+ 'timsheet_ids': fields.one2many('hr_timesheet_sheet.sheet', 'employee_id', 'Timesheets'),
+ 'payslip_ids': fields.one2many('hr.payslip', 'employee_id', 'Payslips'),
+ 'appraisal_count': fields.function(_count_all, type='integer', string='Appraisal Interviews', multi=True),
+ 'leaves_count': fields.function(_count_all, type='integer', string='Leaves', multi=True),
+ 'contracts_count': fields.function(_count_all, type='integer', string='Contracts', multi=True),
+ 'timesheet_count': fields.function(_count_all, type='integer', string='Timsheets', multi=True),
+ 'payslip_count': fields.function(_count_all, type='integer', string='Payslips', multi=True),
}
def _get_default_image(self, cr, uid, context=None):
diff --git a/addons/hr_contract/hr_contract_view.xml b/addons/hr_contract/hr_contract_view.xml
index c21690401f2..f97aefd70ed 100644
--- a/addons/hr_contract/hr_contract_view.xml
+++ b/addons/hr_contract/hr_contract_view.xml
@@ -21,7 +21,13 @@
-
+
diff --git a/addons/hr_evaluation/hr_evaluation_view.xml b/addons/hr_evaluation/hr_evaluation_view.xml
index 28bc4a6c96e..ab8363049c1 100644
--- a/addons/hr_evaluation/hr_evaluation_view.xml
+++ b/addons/hr_evaluation/hr_evaluation_view.xml
@@ -145,7 +145,12 @@
-
+
diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml
index d4b84bab012..a15a18d20aa 100644
--- a/addons/hr_holidays/hr_holidays_view.xml
+++ b/addons/hr_holidays/hr_holidays_view.xml
@@ -483,7 +483,13 @@
-
+
diff --git a/addons/hr_payroll/hr_payroll.py b/addons/hr_payroll/hr_payroll.py
index 3c01847f812..8a8353ad5a0 100644
--- a/addons/hr_payroll/hr_payroll.py
+++ b/addons/hr_payroll/hr_payroll.py
@@ -258,6 +258,15 @@ class hr_payslip(osv.osv):
for r in res:
result[r[0]].append(r[1])
return result
+
+ def _count_detail_payslip(self, cr, uid, ids, field_name, arg, context=None):
+ res = {}
+ try:
+ for details in self.browse(cr, uid, ids, context=context):
+ res[details.id] = len(details.line_ids)
+ except:
+ pass
+ return res
_columns = {
'struct_id': fields.many2one('hr.payroll.structure', 'Structure', readonly=True, states={'draft': [('readonly', False)]}, help='Defines the rules that have to be applied to this payslip, accordingly to the contract chosen. If you let empty the field contract, this field isn\'t mandatory anymore and thus the rules applied will be all the rules set on the structure of all contracts of the employee valid for the chosen period'),
@@ -287,6 +296,7 @@ class hr_payslip(osv.osv):
'details_by_salary_rule_category': fields.function(_get_lines_salary_rule_category, method=True, type='one2many', relation='hr.payslip.line', string='Details by Salary Rule Category'),
'credit_note': fields.boolean('Credit Note', help="Indicates this payslip has a refund of another", readonly=True, states={'draft': [('readonly', False)]}),
'payslip_run_id': fields.many2one('hr.payslip.run', 'Payslip Batches', readonly=True, states={'draft': [('readonly', False)]}),
+ 'payslip_count': fields.function(_count_detail_payslip, type='integer', string="Payslip Computation Details"),
}
_defaults = {
'date_from': lambda *a: time.strftime('%Y-%m-01'),
diff --git a/addons/hr_payroll/hr_payroll_view.xml b/addons/hr_payroll/hr_payroll_view.xml
index 4410784c63c..4cf7597d87e 100644
--- a/addons/hr_payroll/hr_payroll_view.xml
+++ b/addons/hr_payroll/hr_payroll_view.xml
@@ -222,7 +222,12 @@
-
+
@@ -387,7 +392,13 @@
-
+
diff --git a/addons/hr_recruitment/hr_recruitment_view.xml b/addons/hr_recruitment/hr_recruitment_view.xml
index c9dc0d04ffb..6221d0d83f1 100644
--- a/addons/hr_recruitment/hr_recruitment_view.xml
+++ b/addons/hr_recruitment/hr_recruitment_view.xml
@@ -74,16 +74,27 @@
-
-
+
-
-
+
@@ -367,10 +378,23 @@
-
-
-
-
+
+
+
+
+
+
diff --git a/addons/hr_timesheet/hr_timesheet_view.xml b/addons/hr_timesheet/hr_timesheet_view.xml
index 0cd8a880a68..a9de1bb19c9 100644
--- a/addons/hr_timesheet/hr_timesheet_view.xml
+++ b/addons/hr_timesheet/hr_timesheet_view.xml
@@ -118,10 +118,8 @@
-
-
+
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
index 9226787e908..d71d083fbcd 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet.py
@@ -103,6 +103,17 @@ class hr_timesheet_sheet(osv.osv):
for sheet in self.browse(cr, uid, ids, context=context):
if sheet.employee_id.id not in employee_ids: employee_ids.append(sheet.employee_id.id)
return hr_employee.attendance_action_change(cr, uid, employee_ids, context=context)
+
+ def _count_all(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,{'timesheet_activity_count': 0, 'attendance_count': 0,}), ids))
+ try:
+ for datas in self.browse(cr, uid, ids, context=context):
+ res[datas.id] = {'timesheet_activity_count': len(datas.timesheet_activity_ids),
+ 'attendance_count': len(datas.attendances_ids),
+ }
+ except:
+ pass
+ return res
_columns = {
'name': fields.char('Note', size=64, select=1,
@@ -134,6 +145,9 @@ class hr_timesheet_sheet(osv.osv):
'account_ids': fields.one2many('hr_timesheet_sheet.sheet.account', 'sheet_id', 'Analytic accounts', readonly=True),
'company_id': fields.many2one('res.company', 'Company'),
'department_id':fields.many2one('hr.department','Department'),
+ 'timesheet_activity_ids': fields.one2many('hr.analytic.timesheet', 'sheet_id', 'Timesheet Activities'),
+ 'timesheet_activity_count': fields.function(_count_all, type='integer', string='Timesheet Activities', multi=True),
+ 'attendance_count': fields.function(_count_all, type='integer', string="Attendances", multi=True),
}
def _default_date_from(self, cr, uid, context=None):
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
index 644586ec502..a60afda8531 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
@@ -73,10 +73,15 @@
+ class="oe_stat_button"
+ icon="fa-clock-o">
+
+
+ class="oe_stat_button" icon="fa-users"
+ name="%(act_hr_timesheet_sheet_sheet_2_hr_attendance)d">
+
+
@@ -365,7 +370,13 @@
-
+
diff --git a/addons/marketing_campaign/marketing_campaign.py b/addons/marketing_campaign/marketing_campaign.py
index e434090ad76..142d059e1f9 100644
--- a/addons/marketing_campaign/marketing_campaign.py
+++ b/addons/marketing_campaign/marketing_campaign.py
@@ -85,6 +85,15 @@ translate_selections = {
class marketing_campaign(osv.osv):
_name = "marketing.campaign"
_description = "Marketing Campaign"
+
+ def _count_segments(self, cr, uid, ids, field_name, arg, context=None):
+ res = {}
+ try:
+ for segments in self.browse(cr, uid, ids, context=context):
+ res[segments.id] = len(segments.segment_ids)
+ except:
+ pass
+ return res
_columns = {
'name': fields.char('Name', size=64, required=True),
@@ -121,6 +130,8 @@ Normal - the campaign runs normally and automatically sends all emails and repor
'activity_ids': fields.one2many('marketing.campaign.activity',
'campaign_id', 'Activities'),
'fixed_cost': fields.float('Fixed Cost', help="Fixed cost for running this campaign. You may also specify variable cost and revenue on each campaign activity. Cost and Revenue statistics are included in Campaign Reporting.", digits_compute=dp.get_precision('Product Price')),
+ 'segment_ids': fields.one2many('marketing.campaign.segment', 'campaign_id', 'Segments', readonly=False),
+ 'segments_count': fields.function(_count_segments, type='integer', string='Segments')
}
_defaults = {
diff --git a/addons/marketing_campaign/marketing_campaign_view.xml b/addons/marketing_campaign/marketing_campaign_view.xml
index 6503cc482ab..20c3a1bb6e7 100644
--- a/addons/marketing_campaign/marketing_campaign_view.xml
+++ b/addons/marketing_campaign/marketing_campaign_view.xml
@@ -64,12 +64,19 @@
+ class="oe_stat_button"
+ icon="fa-keyboard-o"
+ string="Statistics" help="Marketing Campaign Statistics"/>
+ class="oe_stat_button"
+ icon="fa-table">
+
+
diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py
index 91d50e93236..537e3f5bfda 100644
--- a/addons/mrp/mrp.py
+++ b/addons/mrp/mrp.py
@@ -1111,8 +1111,24 @@ class mrp_production_product_line(osv.osv):
class product_product(osv.osv):
_inherit = "product.product"
+ def _bom_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,{'bom_count': 0, 'mo_count': 0, 'bom_strct':0}), ids))
+ try:
+ for bom in self.browse(cr, uid, ids, context=context):
+ res[bom.id] = {
+ 'bom_count': len(bom.bom_ids),
+ 'mo_count': len(bom.mo_ids),
+ 'bom_strct':len(bom.bom_ids),
+ }
+ except:
+ pass
+ return res
_columns = {
'bom_ids': fields.one2many('mrp.bom', 'product_id', 'Bill of Materials'),
+ 'mo_ids': fields.one2many('mrp.production', 'product_id', 'Manufacturing Orders'),
+ 'bom_count': fields.function(_bom_count, string='# Bill of Material', type='integer', multi="bom_count"),
+ 'bom_strct': fields.function(_bom_count, string='# Bill of Material Structure', type='integer', multi="bom_count"),
+ 'mo_count': fields.function(_bom_count, string='# Manufacturing Orders', type='integer', multi="bom_count"),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/mrp/mrp_view.xml b/addons/mrp/mrp_view.xml
index 6073d02fcc0..eb42b970add 100644
--- a/addons/mrp/mrp_view.xml
+++ b/addons/mrp/mrp_view.xml
@@ -1040,9 +1040,18 @@
-
-
-
+
+
+
diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml
index 7740020e37f..1d1bd73703f 100644
--- a/addons/point_of_sale/point_of_sale_view.xml
+++ b/addons/point_of_sale/point_of_sale_view.xml
@@ -843,8 +843,10 @@
-
-
+
+
Session:
diff --git a/addons/procurement/procurement.py b/addons/procurement/procurement.py
index 1e7076d9c8f..8e1a83ed65c 100644
--- a/addons/procurement/procurement.py
+++ b/addons/procurement/procurement.py
@@ -614,8 +614,17 @@ class product_template(osv.osv):
class product_product(osv.osv):
_inherit="product.product"
+ def _orderpoint_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for orderpoint in self.browse(cr, uid, ids, context=context):
+ res[orderpoint.id] = len(orderpoint.orderpoint_ids)
+ except:
+ pass
+ return res
_columns = {
'orderpoint_ids': fields.one2many('stock.warehouse.orderpoint', 'product_id', 'Minimum Stock Rules'),
+ 'orderpoint_count': fields.function(_orderpoint_count, string='# Orderpoints', type='integer'),
}
diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml
index faec656cf20..596ce2f0ba0 100644
--- a/addons/procurement/procurement_view.xml
+++ b/addons/procurement/procurement_view.xml
@@ -357,7 +357,10 @@
-
+
-
-
+
+
-
+
+
-
+
To invoice or setup invoicing and renewal options, go to the related contract:
.
-
diff --git a/addons/project/res_partner.py b/addons/project/res_partner.py
index e49cacf4f89..79af0413385 100644
--- a/addons/project/res_partner.py
+++ b/addons/project/res_partner.py
@@ -22,11 +22,20 @@
from openerp.osv import fields,osv
class res_partner(osv.osv):
-
+ def _task_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for partner in self.browse(cr, uid, ids, context):
+ res[partner.id] = len(partner.task_ids)
+ except:
+ pass
+ return res
+
""" Inherits partner and adds Tasks information in the partner form """
_inherit = 'res.partner'
_columns = {
'task_ids': fields.one2many('project.task', 'partner_id', 'Tasks'),
+ 'task_count': fields.function(_task_count, string='# Tasks', type='integer'),
}
def copy(self, cr, uid, record_id, default=None, context=None):
diff --git a/addons/project/res_partner_view.xml b/addons/project/res_partner_view.xml
index f12189b5163..a77ea467dcb 100644
--- a/addons/project/res_partner_view.xml
+++ b/addons/project/res_partner_view.xml
@@ -10,11 +10,13 @@
-
+ icon="fa-tasks" groups="project.group_project_user">
+
+
+
+
diff --git a/addons/project_issue/project_issue.py b/addons/project_issue/project_issue.py
index bfc65ca7d88..098826c0a06 100644
--- a/addons/project_issue/project_issue.py
+++ b/addons/project_issue/project_issue.py
@@ -229,7 +229,6 @@ class project_issue(osv.Model):
if work.task_id:
issues += issue_pool.search(cr, uid, [('task_id','=',work.task_id.id)])
return issues
-
_columns = {
'id': fields.integer('ID', readonly=True),
'name': fields.char('Issue', size=128, required=True),
@@ -491,21 +490,15 @@ class project(osv.Model):
return [('project.task', "Tasks"), ("project.issue", "Issues")]
def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
- """ :deprecated: this method will be removed with OpenERP v8. Use issue_ids
- fields instead. """
- res = dict.fromkeys(ids, 0)
- issue_ids = self.pool.get('project.issue').search(cr, uid, [('project_id', 'in', ids)])
- for issue in self.pool.get('project.issue').browse(cr, uid, issue_ids, context):
- if issue.stage_id and not issue.stage_id.fold:
- res[issue.project_id.id] += 1
+ res={}
+ for issues in self.browse(cr, uid, ids, context):
+ res[issues.id] = len(issues.issue_ids)
return res
-
_columns = {
'project_escalation_id': fields.many2one('project.project', 'Project Escalation',
help='If any issue is escalated from the current Project, it will be listed under the project selected here.',
states={'close': [('readonly', True)], 'cancelled': [('readonly', True)]}),
- 'issue_count': fields.function(_issue_count, type='integer', string="Unclosed Issues",
- deprecated="This field will be removed in OpenERP v8. Use issue_ids one2many field instead."),
+ 'issue_count': fields.function(_issue_count, type='integer', string="Issues",),
'issue_ids': fields.one2many('project.issue', 'project_id',
domain=[('stage_id.fold', '=', False)])
}
@@ -575,5 +568,20 @@ class project_project(osv.Model):
self._check_create_write_values(cr, uid, vals, context=context)
return super(project_project, self).write(cr, uid, ids, vals, context=context)
-
+class res_partner(osv.osv):
+ def _issue_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for partner in self.browse(cr, uid, ids, context=context):
+ res[partner.id] = len(partner.issue_ids)
+ except:
+ pass
+ return res
+
+ """ Inherits partner and adds Issue information in the partner form """
+ _inherit = 'res.partner'
+ _columns = {
+ 'issue_ids': fields.one2many('project.issue', 'partner_id', 'Issues'),
+ 'issue_count': fields.function(_issue_count, string='# Issues', type='integer'),
+ }
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/project_issue/project_issue_view.xml b/addons/project_issue/project_issue_view.xml
index 3af9ee608d6..a312b8e78d8 100644
--- a/addons/project_issue/project_issue_view.xml
+++ b/addons/project_issue/project_issue_view.xml
@@ -306,7 +306,10 @@
-
+
{'invisible': [('use_tasks', '=', False),('use_issues','=',False)]}
@@ -375,11 +378,14 @@
-
+ attrs="{'invisible': [('customer', '=', False)]}"
+ icon="fa-bug" groups="project.group_project_user">
+
+
+
+
diff --git a/addons/project_long_term/project_long_term.py b/addons/project_long_term/project_long_term.py
index 29e94591094..3bb78892994 100644
--- a/addons/project_long_term/project_long_term.py
+++ b/addons/project_long_term/project_long_term.py
@@ -98,7 +98,14 @@ class project_phase(osv.osv):
else:
res[phase.id] = round(100.0 * done / tot, 2)
return res
-
+ def _tasks_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for task in self.browse(cr, uid, ids, context=context):
+ res[task.id] = len(task.task_ids)
+ except:
+ pass
+ return res
_columns = {
'name': fields.char("Name", size=64, required=True),
'date_start': fields.datetime('Start Date', select=True, help="It's computed by the scheduler according the project date or the end date of the previous phase.", states={'done':[('readonly',True)], 'cancelled':[('readonly',True)]}),
@@ -119,6 +126,7 @@ class project_phase(osv.osv):
help='If the phase is created the status \'Draft\'.\n If the phase is started, the status becomes \'In Progress\'.\n If review is needed the phase is in \'Pending\' status.\
\n If the phase is over, the status is set to \'Done\'.'),
'progress': fields.function(_compute_progress, string='Progress', help="Computed based on related tasks"),
+ 'tasks_count': fields.function(_tasks_count, string='# Related Tasks', type='integer'),
}
_defaults = {
'state': 'draft',
diff --git a/addons/project_long_term/project_long_term_view.xml b/addons/project_long_term/project_long_term_view.xml
index 36fb83000ce..4af0a7aed0a 100644
--- a/addons/project_long_term/project_long_term_view.xml
+++ b/addons/project_long_term/project_long_term_view.xml
@@ -102,9 +102,10 @@
-
+
@@ -151,7 +152,11 @@
-
+
+
+
diff --git a/addons/project_timesheet/project_timesheet_view.xml b/addons/project_timesheet/project_timesheet_view.xml
index 548264eb07b..a51c7976602 100644
--- a/addons/project_timesheet/project_timesheet_view.xml
+++ b/addons/project_timesheet/project_timesheet_view.xml
@@ -30,7 +30,10 @@
-
+
diff --git a/addons/purchase/partner.py b/addons/purchase/partner.py
index d8cda9b20b9..b7757c2f91f 100644
--- a/addons/purchase/partner.py
+++ b/addons/purchase/partner.py
@@ -26,15 +26,14 @@ class res_partner(osv.osv):
_inherit = 'res.partner'
def _purchase_order_count(self, cr, uid, ids, field_name, arg, context=None):
- res = dict(map(lambda x: (x,0), ids))
- # this user may not have access to user rights
- try:
- for partner in self.browse(cr, uid, ids, context=context):
- res[partner.id] = len(partner.purchase_order_ids)
- except:
- pass
+ res = dict(map(lambda x: (x,{'purchase_order_count': 0, 'supplier_invoice_count': 0}), ids))
+ invoice_ids = self.pool.get('account.invoice').search(cr,uid, [('type', '=', 'in_invoice'), ('partner_id', '=', ids[0])])
+ for partner in self.browse(cr, uid, ids, context=context):
+ res[partner.id] = {
+ 'purchase_order_count': len(partner.purchase_order_ids),
+ 'supplier_invoice_count': len(invoice_ids),
+ }
return res
-
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
@@ -53,8 +52,10 @@ class res_partner(osv.osv):
domain=[('type','=','purchase')],
string="Purchase Pricelist",
help="This pricelist will be used, instead of the default one, for purchases from the current partner"),
- 'purchase_order_count': fields.function(_purchase_order_count, string='# of Purchase Order', type='integer'),
- 'purchase_order_ids': fields.one2many('purchase.order','partner_id','Purchase Order')
+ 'purchase_order_count': fields.function(_purchase_order_count, string='# of Purchase Order', type='integer', multi="count"),
+ 'purchase_order_ids': fields.one2many('purchase.order','partner_id','Purchase Order'),
+ 'invoice_ids': fields.one2many('account.invoice','partner_id','Supplier Invoices'),
+ 'supplier_invoice_count': fields.function(_purchase_order_count, string='# Supplier Invoices', type='integer', multi="count"),
}
diff --git a/addons/purchase/partner_view.xml b/addons/purchase/partner_view.xml
index 25aeb3d8119..6d1916f9cc3 100644
--- a/addons/purchase/partner_view.xml
+++ b/addons/purchase/partner_view.xml
@@ -74,13 +74,15 @@
-
-
+ groups="purchase.group_purchase_user" icon="fa-shopping-cart">
+
+
+
diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py
index ed131670737..a27dfce1985 100644
--- a/addons/purchase/purchase.py
+++ b/addons/purchase/purchase.py
@@ -150,6 +150,17 @@ class purchase_order(osv.osv):
limit=1)
return res and res[0] or False
+ def _count_all(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,{'shipment_count': 0, 'invoice_count': 0,}), ids))
+ try:
+ for data in self.browse(cr, uid, ids, context=context):
+ res[data.id] = {'shipment_count': len(data.picking_ids),
+ 'invoice_count': len(data.invoice_ids),
+ }
+ except:
+ pass
+ return res
+
STATE_SELECTION = [
('draft', 'Draft PO'),
('sent', 'RFQ Sent'),
@@ -226,6 +237,8 @@ class purchase_order(osv.osv):
'create_uid': fields.many2one('res.users', 'Responsible'),
'company_id': fields.many2one('res.company','Company',required=True,select=1, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}),
'journal_id': fields.many2one('account.journal', 'Journal'),
+ 'shipment_count': fields.function(_count_all, type='integer', string='Incoming Shipments', multi=True),
+ 'invoice_count': fields.function(_count_all, type='integer', string='Invoices', multi=True)
}
_defaults = {
'date_order': fields.date.context_today,
@@ -1257,8 +1270,19 @@ class mail_mail(osv.Model):
class product_template(osv.Model):
_name = 'product.template'
_inherit = 'product.template'
+
+ def _purchase_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for purchase in self.browse(cr, uid, ids, context=context):
+ res[purchase.id] = len(purchase.purchase_ids)
+ except:
+ pass
+ return res
_columns = {
'purchase_ok': fields.boolean('Can be Purchased', help="Specify if the product can be selected in a purchase order line."),
+ 'purchase_ids': fields.one2many('purchase.order', 'product_id', 'Purchases'),
+ 'purchase_count': fields.function(_purchase_count, string='# Purchases', type='integer'),
}
_defaults = {
'purchase_ok': 1,
diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml
index 209bad47495..1b603092028 100644
--- a/addons/purchase/purchase_view.xml
+++ b/addons/purchase/purchase_view.xml
@@ -631,7 +631,10 @@
-
+
diff --git a/addons/purchase/stock_view.xml b/addons/purchase/stock_view.xml
index 0ba48a63512..33972c90fb6 100644
--- a/addons/purchase/stock_view.xml
+++ b/addons/purchase/stock_view.xml
@@ -47,9 +47,17 @@
+ class="oe_stat_button"
+ icon="fa-truck"
+ states="approved">
+
+
+ class="oe_stat_button"
+ icon="fa-pencil-square-o"
+ attrs="{'invisible': [('state', 'in', ['draft','sent'])]}">
+
+
diff --git a/addons/sale/res_partner_view.xml b/addons/sale/res_partner_view.xml
index 5107f0c17af..e689cac1476 100644
--- a/addons/sale/res_partner_view.xml
+++ b/addons/sale/res_partner_view.xml
@@ -48,10 +48,11 @@
-
+ icon="fa-strikethrough" groups="base.group_sale_salesman">
+
+
diff --git a/addons/sale/sale.py b/addons/sale/sale.py
index 48b09ec7493..20a806f4d7f 100644
--- a/addons/sale/sale.py
+++ b/addons/sale/sale.py
@@ -1024,4 +1024,18 @@ class account_invoice(osv.Model):
workflow.trg_validate(uid, 'account.invoice', id, 'invoice_cancel', cr)
return super(account_invoice, self).unlink(cr, uid, ids, context=context)
+class product_product(osv.Model):
+ _inherit = 'product.product'
+ def _sales_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for sale in self.browse(cr, uid, ids, context=context):
+ res[sale.id] = len(sale.sales_ids)
+ except:
+ pass
+ return res
+ _columns = {
+ 'sales_ids': fields.one2many('sale.order.line', 'product_id', 'Sales '),
+ 'sales_count': fields.function(_sales_count, string='# Sales', type='integer'),
+ }
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index c9ffb94b985..7ea9d441c5c 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -499,7 +499,10 @@
-
+
diff --git a/addons/stock/product.py b/addons/stock/product.py
index 3eddf0a1c72..863b7111bb0 100644
--- a/addons/stock/product.py
+++ b/addons/stock/product.py
@@ -352,7 +352,14 @@ class product_product(osv.osv):
for id in ids:
res[id][f] = stock.get(id, 0.0)
return res
-
+ def _move_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = dict(map(lambda x: (x,0), ids))
+ try:
+ for move in self.browse(cr, uid, ids, context=context):
+ res[move.id] = len(move.move_ids)
+ except:
+ pass
+ return res
_columns = {
'reception_count': fields.function(_stock_move_count, string="Reception", type='integer', multi='pickings'),
'delivery_count': fields.function(_stock_move_count, string="Delivery", type='integer', multi='pickings'),
@@ -413,6 +420,8 @@ class product_product(osv.osv):
help="If real-time valuation is enabled for a product, the system will automatically write journal entries corresponding to stock moves." \
"The inventory variation account set on the product category will represent the current inventory value, and the stock input and stock output account will hold the counterpart moves for incoming and outgoing products."
, required=True),
+ 'move_ids': fields.one2many('stock.move', 'product_id', 'Moves'),
+ 'move_count': fields.function(_move_count, string='# Moves', type='integer'),
}
_defaults = {
diff --git a/addons/stock/product_view.xml b/addons/stock/product_view.xml
index 11f970d6ddb..a3fa9224bbe 100644
--- a/addons/stock/product_view.xml
+++ b/addons/stock/product_view.xml
@@ -73,8 +73,14 @@
-
-
+
+
+
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index 7e73d7fcd53..bd0254a81d3 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -636,7 +636,11 @@ class stock_picking(osv.osv):
vals['name'] = self.pool.get('ir.sequence').get(cr, user, seq_obj_name)
new_id = super(stock_picking, self).create(cr, user, vals, context)
return new_id
-
+ def _claim_count(self, cr, uid, ids, field_name, arg, context=None):
+ res = {}
+ claim = self.pool.get('crm.claim').search(cr, uid, [('ref', '=',('stock.picking.out,' + str(ids[0])))], context=context)
+ res[ids[0]] = len(claim)
+ return res
_columns = {
'name': fields.char('Reference', size=64, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
'origin': fields.char('Source Document', size=64, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="Reference of the document", select=True),
@@ -680,6 +684,7 @@ class stock_picking(osv.osv):
("none", "Not Applicable")], "Invoice Control",
select=True, required=True, readonly=True, track_visibility='onchange', states={'draft': [('readonly', False)]}),
'company_id': fields.many2one('res.company', 'Company', required=True, select=True, states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}),
+ 'claim_count': fields.function(_claim_count, string='Claims', type='integer'),
}
_defaults = {
'name': lambda self, cr, uid, context: '/',
@@ -3122,7 +3127,9 @@ class stock_picking_out(osv.osv):
out_defaults = super(stock_picking_out, self).default_get(cr, uid, fields_list, context=context)
defaults.update(out_defaults)
return defaults
-
+ def _claim_count(self, cr, uid, ids, field_name, arg, context=None):
+ return super(stock_picking_out, self)._claim_count(cr, uid, ids, field_name, arg, context=context)
+
_columns = {
'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
'state': fields.selection(
@@ -3139,6 +3146,7 @@ class stock_picking_out(osv.osv):
* Ready to Deliver: products reserved, simply waiting for confirmation.\n
* Delivered: has been processed, can't be modified or cancelled anymore\n
* Cancelled: has been cancelled, can't be confirmed anymore"""),
+ 'claim_count': fields.function(_claim_count, string='Claims', type='integer'),
}
_defaults = {
'type': 'out',
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index e96652c11aa..b9518cc03c3 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -239,12 +239,23 @@
-
-
-
-
+
+
+
+
+
+
@@ -344,8 +355,16 @@