diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml
index 2122c879fbb..1db17ed16cf 100644
--- a/addons/account/account_invoice_view.xml
+++ b/addons/account/account_invoice_view.xml
@@ -512,15 +512,15 @@
src_model="account.journal"/>
diff --git a/addons/account/report/account_report.py b/addons/account/report/account_report.py
index 362d0adb414..b7d3441913f 100644
--- a/addons/account/report/account_report.py
+++ b/addons/account/report/account_report.py
@@ -20,9 +20,8 @@
##############################################################################
import time
-import datetime
-import mx.DateTime
-
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
import pooler
import tools
from osv import fields,osv
@@ -128,13 +127,13 @@ class report_aged_receivable(osv.osv):
LIST_RANGES = []
if fy_id:
fy_start_date = pool_obj_fy.read(cr, uid, fy_id, ['date_start'])['date_start']
- fy_start_date = mx.DateTime.strptime(fy_start_date, '%Y-%m-%d')
- last_month_date = mx.DateTime.strptime(today, '%Y-%m-%d') - mx.DateTime.RelativeDateTime(months=1)
+ fy_start_date = datetime.strptime(fy_start_date, '%Y-%m-%d')
+ last_month_date = datetime.strptime(today, '%Y-%m-%d') - relativedelta(months=1)
while (last_month_date > fy_start_date):
LIST_RANGES.append(today + " to " + last_month_date.strftime('%Y-%m-%d'))
today = (last_month_date- 1).strftime('%Y-%m-%d')
- last_month_date = mx.DateTime.strptime(today, '%Y-%m-%d') - mx.DateTime.RelativeDateTime(months=1)
+ last_month_date = datetime.strptime(today, '%Y-%m-%d') - relativedelta(months=1)
LIST_RANGES.append(today +" to " + fy_start_date.strftime('%Y-%m-%d'))
cr.execute('delete from temp_range')
diff --git a/addons/account/wizard/account_report_aged_partner_balance.py b/addons/account/wizard/account_report_aged_partner_balance.py
index 99983654c82..10548095131 100644
--- a/addons/account/wizard/account_report_aged_partner_balance.py
+++ b/addons/account/wizard/account_report_aged_partner_balance.py
@@ -20,8 +20,8 @@
##############################################################################
import time
-import datetime
-from mx.DateTime import *
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
from lxml import etree
from osv import osv, fields
@@ -69,26 +69,26 @@ class account_aged_trial_balance(osv.osv_memory):
if not data['form']['date_from']:
raise osv.except_osv(_('UserError'), _('Enter a Start date !'))
- start = datetime.date.fromtimestamp(time.mktime(time.strptime(data['form']['date_from'], "%Y-%m-%d")))
- start = DateTime(int(start.year), int(start.month), int(start.day))
+ start = datetime.strptime(data['form']['date_from'], "%Y-%m-%d")
+
if data['form']['direction_selection'] == 'past':
for i in range(5)[::-1]:
- stop = start - RelativeDateTime(days=period_length)
+ stop = start - relativedelta(days=period_length)
res[str(i)] = {
'name': (i!=0 and (str((5-(i+1)) * period_length) + '-' + str((5-i) * period_length)) or ('+'+str(4 * period_length))),
'stop': start.strftime('%Y-%m-%d'),
'start': (i!=0 and stop.strftime('%Y-%m-%d') or False),
}
- start = stop - RelativeDateTime(days=1)
+ start = stop - relativedelta(days=1)
else:
for i in range(5):
- stop = start + RelativeDateTime(days=period_length)
+ stop = start + relativedelta(days=period_length)
res[str(5-(i+1))] = {
'name' : (i!=4 and str((i) * period_length)+'-' + str((i+1) * period_length) or ('+'+str(4 * period_length))),
'start': start.strftime('%Y-%m-%d'),
'stop': (i!=4 and stop.strftime('%Y-%m-%d') or False),
}
- start = stop + RelativeDateTime(days=1)
+ start = stop + relativedelta(days=1)
data['form'].update(res)
return {
diff --git a/addons/account_analytic_default/account_analytic_default_view.xml b/addons/account_analytic_default/account_analytic_default_view.xml
index 2513d1229b6..95a39eb11e6 100644
--- a/addons/account_analytic_default/account_analytic_default_view.xml
+++ b/addons/account_analytic_default/account_analytic_default_view.xml
@@ -66,14 +66,16 @@
id="act_account_acount_move_line_open"
res_model="account.move.line"
src_model="account.account"
- domain="[('account_id', '=', active_id)]"/>
+ context="{'search_default_account_id': [active_id]}"
+ />
+
diff --git a/addons/account_budget/crossovered_budget_view.xml b/addons/account_budget/crossovered_budget_view.xml
index 7a4883ec61d..99083d097b6 100644
--- a/addons/account_budget/crossovered_budget_view.xml
+++ b/addons/account_budget/crossovered_budget_view.xml
@@ -260,7 +260,7 @@
diff --git a/addons/account_report/account.py b/addons/account_report/account.py
index 5dffc0c6a78..6e5fbc94026 100644
--- a/addons/account_report/account.py
+++ b/addons/account_report/account.py
@@ -26,9 +26,6 @@ import pooler
from tools.misc import currency
from tools.translate import _
-import mx.DateTime
-from mx.DateTime import RelativeDateTime, now, DateTime, localtime
-
class account_report(osv.osv):
_name = "account.report.report"
diff --git a/addons/account_report/wizard/account_report_print_indicators_with_pdf.py b/addons/account_report/wizard/account_report_print_indicators_with_pdf.py
index 9e71d3e88c9..2ae373e58f0 100644
--- a/addons/account_report/wizard/account_report_print_indicators_with_pdf.py
+++ b/addons/account_report/wizard/account_report_print_indicators_with_pdf.py
@@ -19,7 +19,6 @@
#
##############################################################################
import time
-from mx.DateTime import *
import os
import base64
import StringIO
diff --git a/addons/account_reporting/account.py b/addons/account_reporting/account.py
index c1c68f04d9b..7fc08401496 100644
--- a/addons/account_reporting/account.py
+++ b/addons/account_reporting/account.py
@@ -24,9 +24,6 @@ from osv import fields, osv
from tools.misc import currency
-import mx.DateTime
-from mx.DateTime import RelativeDateTime, now, DateTime, localtime
-
class color_rml(osv.osv):
_name = "color.rml"
diff --git a/addons/account_voucher/voucher_view.xml b/addons/account_voucher/voucher_view.xml
index d007d20acab..972850e0114 100644
--- a/addons/account_voucher/voucher_view.xml
+++ b/addons/account_voucher/voucher_view.xml
@@ -161,10 +161,10 @@
diff --git a/addons/auction/auction_view.xml b/addons/auction/auction_view.xml
index d149fc89f1c..c3068753a6e 100644
--- a/addons/auction/auction_view.xml
+++ b/addons/auction/auction_view.xml
@@ -765,7 +765,7 @@
diff --git a/addons/base_calendar/wizard/base_calendar_set_exrule.py b/addons/base_calendar/wizard/base_calendar_set_exrule.py
index ab458c8f7f5..995d2a98dcc 100644
--- a/addons/base_calendar/wizard/base_calendar_set_exrule.py
+++ b/addons/base_calendar/wizard/base_calendar_set_exrule.py
@@ -23,7 +23,6 @@ from base_calendar import base_calendar
from osv import fields, osv
from tools.translate import _
import tools
-import mx.DateTime
import re
diff --git a/addons/base_contact/base_contact.py b/addons/base_contact/base_contact.py
index 8e3a4ded7eb..13ee62bf768 100644
--- a/addons/base_contact/base_contact.py
+++ b/addons/base_contact/base_contact.py
@@ -26,7 +26,7 @@ class res_partner_contact(osv.osv):
_name = "res.partner.contact"
_description = "Contact"
-
+
def _main_job(self, cr, uid, ids, fields, arg, context=None):
"""
@param self: The object pointer
@@ -36,12 +36,16 @@ class res_partner_contact(osv.osv):
@fields: Get Fields
@param context: A standard dictionary for contextual values
@param arg: list of tuples of form [(‘name_of_the_field’, ‘operator’, value), ...]. """
-
-
res = dict.fromkeys(ids, False)
+
+ res_partner_job_obj = self.pool.get('res.partner.job')
+ all_job_ids = res_partner_job_obj.search(cr, uid, [])
+ all_job_names = dict(zip(all_job_ids, res_partner_job_obj.name_get(cr, uid, all_job_ids, context=context)))
+
for contact in self.browse(cr, uid, ids, context):
if contact.job_ids:
- res[contact.id] = contact.job_ids[0].name_get()[0]
+ res[contact.id] = all_job_names.get(contact.job_ids[0].id, False)
+
return res
_columns = {
@@ -61,7 +65,7 @@ class res_partner_contact(osv.osv):
'function': fields.related('job_ids', 'function', type='char', \
string='Main Function'),
'job_id': fields.function(_main_job, method=True, type='many2one',\
- relation='res.partner.job', string='Main Job', store=True),
+ relation='res.partner.job', string='Main Job'),
'email': fields.char('E-Mail', size=240),
'comment': fields.text('Notes', translate=True),
'photo': fields.binary('Image'),
@@ -138,8 +142,7 @@ class res_partner_address(osv.osv):
res_partner_address()
class res_partner_job(osv.osv):
-
- def name_get(self, cr, uid, ids, context={}):
+ def name_get(self, cr, uid, ids, context=None):
"""
@param self: The object pointer
@param cr: the current row, from the database cursor,
@@ -147,12 +150,15 @@ class res_partner_job(osv.osv):
@param ids: List of partner address’s IDs
@param context: A standard dictionary for contextual values
"""
+ if context is None:
+ context = {}
- if not len(ids):
+ if not ids:
return []
res = []
jobs = self.browse(cr, uid, ids)
+
contact_ids = [rec.contact_id.id for rec in jobs]
contact_names = dict(self.pool.get('res.partner.contact').name_get(cr, uid, contact_ids, context=context))
@@ -160,6 +166,7 @@ class res_partner_job(osv.osv):
function_name = r.function
funct = function_name and (", " + function_name) or ""
res.append((r.id, contact_names.get(r.contact_id.id, '') + funct))
+
return res
def search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False):
diff --git a/addons/base_contact/base_contact_view.xml b/addons/base_contact/base_contact_view.xml
index 1f22b550bdc..59894ab55d0 100644
--- a/addons/base_contact/base_contact_view.xml
+++ b/addons/base_contact/base_contact_view.xml
@@ -408,8 +408,9 @@
diff --git a/addons/crm/crm_lead.py b/addons/crm/crm_lead.py
index ee778401e4a..cdc3553dc0e 100644
--- a/addons/crm/crm_lead.py
+++ b/addons/crm/crm_lead.py
@@ -23,7 +23,6 @@ from osv import fields, osv
from datetime import datetime
import crm
import time
-import mx.DateTime
from tools.translate import _
from crm import crm_case
import binascii
@@ -84,12 +83,12 @@ class crm_lead(crm_case, osv.osv):
new_dates = cal_obj.interval_get(cr,
uid,
lead.section_id.resource_calendar_id and lead.section_id.resource_calendar_id.id or False,
- mx.DateTime.strptime(lead.create_date, '%Y-%m-%d %H:%M:%S'),
+ datetime.strptime(lead.create_date, '%Y-%m-%d %H:%M:%S'),
duration,
resource=resource_id
)
no_days = []
- date_until = mx.DateTime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
+ date_until = datetime.strptime(date_until, '%Y-%m-%d %H:%M:%S')
for in_time, out_time in new_dates:
if in_time.date not in no_days:
no_days.append(in_time.date)
diff --git a/addons/crm/crm_meeting_menu.xml b/addons/crm/crm_meeting_menu.xml
index 53eabcf0136..7601fcdab43 100644
--- a/addons/crm/crm_meeting_menu.xml
+++ b/addons/crm/crm_meeting_menu.xml
@@ -8,8 +8,7 @@
res_model="crm.meeting"
src_model="res.partner"
view_mode="calendar,tree,form,gantt"
- context="{'default_partner_id': active_id, 'default_duration': 4.0}"
- domain="[('partner_id', '=', active_id)]"
+ context="{'search_default_partner_id': active_id, 'default_duration': 4.0}"
/>
diff --git a/addons/crm/crm_opportunity.py b/addons/crm/crm_opportunity.py
index 84e1392168f..771212a171d 100644
--- a/addons/crm/crm_opportunity.py
+++ b/addons/crm/crm_opportunity.py
@@ -24,7 +24,6 @@ from osv import fields,osv,orm
from tools.translate import _
import crm
import time
-import mx.DateTime
AVAILABLE_STATES = [
('draft','Draft'),
diff --git a/addons/crm/crm_phonecall_menu.xml b/addons/crm/crm_phonecall_menu.xml
index 44f1bcb219f..141a6add970 100644
--- a/addons/crm/crm_phonecall_menu.xml
+++ b/addons/crm/crm_phonecall_menu.xml
@@ -8,8 +8,7 @@
res_model="crm.phonecall"
src_model="res.partner"
view_mode="calendar,tree,form"
- context="{'default_partner_id': active_id, 'default_duration': 1.0}"
- domain="[('partner_id', '=', active_id)]"
+ context="{'search_default_partner_id': [active_id], 'default_duration': 1.0}"
groups="base.group_extended"
/>
diff --git a/addons/crm_claim/crm_claim_view.xml b/addons/crm_claim/crm_claim_view.xml
index 64c917ffe4b..da73f879eab 100644
--- a/addons/crm_claim/crm_claim_view.xml
+++ b/addons/crm_claim/crm_claim_view.xml
@@ -310,8 +310,7 @@
-
diff --git a/addons/document_ics/document_ics_config_wizard.py b/addons/document_ics/document_ics_config_wizard.py
index 611c804a62c..51ccab59204 100644
--- a/addons/document_ics/document_ics_config_wizard.py
+++ b/addons/document_ics/document_ics_config_wizard.py
@@ -23,7 +23,6 @@ import time
import tools
from osv import fields, osv, orm
import os
-import mx.DateTime
import base64
import pooler
diff --git a/addons/event/event_view.xml b/addons/event/event_view.xml
index c791b0baefd..f58a948fad2 100644
--- a/addons/event/event_view.xml
+++ b/addons/event/event_view.xml
@@ -264,7 +264,7 @@
res_model="event.registration"
src_model="event.event"
view_mode="tree,form,calendar,graph"
- domain="[('event_id', '=', active_id)]"
+ context="{'search_default_event_id': [active_id]}"
view_type="form"/>
diff --git a/addons/event_project/event_view.xml b/addons/event_project/event_view.xml
index 5060ed2cb3f..7793d4fbcf7 100644
--- a/addons/event_project/event_view.xml
+++ b/addons/event_project/event_view.xml
@@ -36,7 +36,7 @@
res_model="project.task"
src_model="event.event"
view_mode="tree,form,calendar,graph"
- domain="[('project_id', '=', project_id)]"
+ context="{'search_default_project_id': project_id}"
view_type="form"/>
diff --git a/addons/hr_attendance/report/attendance_by_month.py b/addons/hr_attendance/report/attendance_by_month.py
index 650df0048bf..a4a50f61320 100644
--- a/addons/hr_attendance/report/attendance_by_month.py
+++ b/addons/hr_attendance/report/attendance_by_month.py
@@ -19,9 +19,9 @@
#
##############################################################################
-from mx import DateTime
-from mx.DateTime import now
import time
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
import datetime
import netsvc
import pooler
@@ -31,7 +31,7 @@ from report.interface import toxml
from report import report_sxw
-one_day = DateTime.RelativeDateTime(days=1)
+one_day = relativedelta(days=1)
month2name = [0, 'January', 'February', 'March', 'April', 'May', 'Jun', 'July', 'August', 'September', 'October', 'November', 'December']
#def hour2str(h):
@@ -57,7 +57,7 @@ class report_custom(report_rml):
obj_emp = pooler.get_pool(cr.dbname).get('hr.employee')
if context is None:
context = {}
- month = DateTime.DateTime(datas['form']['year'], datas['form']['month'], 1)
+ month = datetime(datas['form']['year'], datas['form']['month'], 1)
emp_ids = context.get('active_ids', [])
user_xml = ['%s' % month2name[month.month], '%s' % month.year]
if emp_ids:
@@ -89,7 +89,7 @@ class report_custom(report_rml):
attendences.append({'name': tomor.strftime('%Y-%m-%d %H:%M:%S'), 'action':'sign_out'})
# sum up the attendances' durations
for att in attendences:
- dt = DateTime.strptime(att['name'], '%Y-%m-%d %H:%M:%S')
+ dt = datetime.strptime(att['name'], '%Y-%m-%d %H:%M:%S')
if att['action'] == 'sign_out':
wh += (dt - ldt).hours
ldt = dt
diff --git a/addons/hr_attendance/report/timesheet.py b/addons/hr_attendance/report/timesheet.py
index 94dc1edcbbd..1465be81bc8 100644
--- a/addons/hr_attendance/report/timesheet.py
+++ b/addons/hr_attendance/report/timesheet.py
@@ -19,16 +19,16 @@
#
##############################################################################
-from mx import DateTime
-from mx.DateTime import now
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
import pooler
from report.interface import report_rml
from report.interface import toxml
-one_week = DateTime.RelativeDateTime(days=7)
+one_week = relativedelta(days=7)
num2day = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
def to_hour(h):
@@ -38,10 +38,12 @@ class report_custom(report_rml):
def create_xml(self, cr, uid, ids, datas, context=None):
obj_emp = pooler.get_pool(cr.dbname).get('hr.employee')
- start_date = DateTime.strptime(datas['form']['init_date'], '%Y-%m-%d')
- end_date = DateTime.strptime(datas['form']['end_date'], '%Y-%m-%d')
- first_monday = start_date - DateTime.RelativeDateTime(days=start_date.day_of_week)
- last_monday = end_date + DateTime.RelativeDateTime(days=7 - end_date.day_of_week)
+
+ start_date = datetime.strptime(datas['form']['init_date'], '%Y-%m-%d')
+ end_date = datetime.strptime(datas['form']['end_date'], '%Y-%m-%d')
+ first_monday = start_date - relativedelta(days=start_date.day_of_week)
+ last_monday = end_date + relativedelta(days=7 - end_date.day_of_week)
+
if last_monday < first_monday:
first_monday, last_monday = last_monday, first_monday
@@ -67,7 +69,7 @@ class report_custom(report_rml):
order by att.name
'''
for idx in range(7):
- cr.execute(sql, (monday.strftime('%Y-%m-%d %H:%M:%S'), (monday + DateTime.RelativeDateTime(days=idx+1)).strftime('%Y-%m-%d %H:%M:%S'), employee_id))
+ cr.execute(sql, (monday.strftime('%Y-%m-%d %H:%M:%S'), (monday + relativedelta(days=idx+1)).strftime('%Y-%m-%d %H:%M:%S'), employee_id))
attendances = cr.dictfetchall()
week_wh = {}
# Fake sign ins/outs at week ends, to take attendances across week ends into account
@@ -78,7 +80,7 @@ class report_custom(report_rml):
attendances.append({'name': n_monday.strftime('%Y-%m-%d %H:%M:%S'), 'action': 'sign_out'})
# sum up the attendances' durations
for att in attendances:
- dt = DateTime.strptime(att['name'], '%Y-%m-%d %H:%M:%S')
+ dt = datetime.strptime(att['name'], '%Y-%m-%d %H:%M:%S')
if att['action'] == 'sign_out':
week_wh[ldt.day_of_week] = week_wh.get(ldt.day_of_week, 0) + (dt - ldt).hours
ldt = dt
diff --git a/addons/hr_contract/hr_contract_view.xml b/addons/hr_contract/hr_contract_view.xml
index cb486df91b1..c8f84ce55cc 100644
--- a/addons/hr_contract/hr_contract_view.xml
+++ b/addons/hr_contract/hr_contract_view.xml
@@ -279,7 +279,12 @@
-
+
diff --git a/addons/hr_evaluation/hr_evaluation_view.xml b/addons/hr_evaluation/hr_evaluation_view.xml
index 9ec02b4ad0b..5dcc7b6f346 100644
--- a/addons/hr_evaluation/hr_evaluation_view.xml
+++ b/addons/hr_evaluation/hr_evaluation_view.xml
@@ -385,7 +385,12 @@
action="action_hr_evaluation_send_mail" sequence="45"/>
-
+
diff --git a/addons/hr_payroll/report/report_emp_salary_structure.py b/addons/hr_payroll/report/report_emp_salary_structure.py
index d4365a8423b..7deafcf63e4 100644
--- a/addons/hr_payroll/report/report_emp_salary_structure.py
+++ b/addons/hr_payroll/report/report_emp_salary_structure.py
@@ -23,7 +23,6 @@
##############################################################################
import time
-import mx.DateTime
from report import report_sxw
from tools import amount_to_text_en
diff --git a/addons/hr_payroll/report/report_employees_detail.py b/addons/hr_payroll/report/report_employees_detail.py
index 004dae84531..d36df160ad2 100644
--- a/addons/hr_payroll/report/report_employees_detail.py
+++ b/addons/hr_payroll/report/report_employees_detail.py
@@ -5,8 +5,6 @@ from report import report_sxw
import time
import pooler
import rml_parse
-import mx.DateTime
-from mx.DateTime import RelativeDateTime, now, DateTime, localtime
class employees_salary_report(rml_parse.rml_parse):
diff --git a/addons/hr_payroll/report/report_payroll_advice.py b/addons/hr_payroll/report/report_payroll_advice.py
index 2f4d82c263b..1c7fbd91357 100644
--- a/addons/hr_payroll/report/report_payroll_advice.py
+++ b/addons/hr_payroll/report/report_payroll_advice.py
@@ -1,5 +1,5 @@
import time
-import mx.DateTime
+from datetime import datetime
from report import report_sxw
from tools import amount_to_text_en
@@ -22,7 +22,7 @@ class payroll_advice_report(report_sxw.rml_parse):
res = {
'mname':''
}
- date = mx.DateTime.strptime(input_date, '%Y-%m-%d')
+ date = datetime.strptime(input_date, '%Y-%m-%d')
res['mname']= date.strftime('%B')+'-'+date.strftime('%Y')
return res
diff --git a/addons/hr_payroll/report/report_payroll_register.py b/addons/hr_payroll/report/report_payroll_register.py
index 6ab5b0c35c9..b146e2900af 100644
--- a/addons/hr_payroll/report/report_payroll_register.py
+++ b/addons/hr_payroll/report/report_payroll_register.py
@@ -1,5 +1,5 @@
import time
-import mx.DateTime
+from datetime import datetime
from report import report_sxw
from tools import amount_to_text_en
@@ -56,7 +56,7 @@ class report_payroll_register(report_sxw.rml_parse):
return self.net
def get_month(self, indate):
- new_date = mx.DateTime.strptime(indate, '%Y-%m-%d')
+ new_date = datetime.strptime(indate, '%Y-%m-%d')
out_date = new_date.strftime('%B')+'-'+new_date.strftime('%Y')
return out_date
diff --git a/addons/hr_payroll/report/report_payslip.py b/addons/hr_payroll/report/report_payslip.py
index 4fc9410861d..e818e0f3727 100755
--- a/addons/hr_payroll/report/report_payslip.py
+++ b/addons/hr_payroll/report/report_payslip.py
@@ -23,7 +23,7 @@
##############################################################################
import time
-import mx.DateTime
+from datetime import datetime
from report import report_sxw
from tools import amount_to_text_en
@@ -93,7 +93,7 @@ class payslip_report(report_sxw.rml_parse):
res = {
'mname':''
}
- date = mx.DateTime.strptime(obj.date, '%Y-%m-%d')
+ date = datetime.strptime(obj.date, '%Y-%m-%d')
res['mname']= date.strftime('%B')+"-"+date.strftime('%Y')
return res['mname']
diff --git a/addons/hr_payroll/report/report_year_salary.py b/addons/hr_payroll/report/report_year_salary.py
index b0f02bc077e..a85d7328973 100755
--- a/addons/hr_payroll/report/report_year_salary.py
+++ b/addons/hr_payroll/report/report_year_salary.py
@@ -5,8 +5,6 @@ from report import report_sxw
import time
import pooler
import rml_parse
-import mx.DateTime
-from mx.DateTime import RelativeDateTime, now, DateTime, localtime
class year_salary_report(rml_parse.rml_parse):
diff --git a/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml b/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml
index ba155d3590a..c0f82b0475b 100644
--- a/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml
+++ b/addons/hr_timesheet_invoice/report/hr_timesheet_invoice_report_view.xml
@@ -395,13 +395,34 @@
-
+
+
-
+
-
+
-
+
diff --git a/addons/hr_timesheet_invoice/report/report_analytic_view.xml b/addons/hr_timesheet_invoice/report/report_analytic_view.xml
index 32129287470..f5573a394ef 100644
--- a/addons/hr_timesheet_invoice/report/report_analytic_view.xml
+++ b/addons/hr_timesheet_invoice/report/report_analytic_view.xml
@@ -134,7 +134,13 @@
-
+
diff --git a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
index 19a9af3c33d..f078be2dbe1 100644
--- a/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
+++ b/addons/hr_timesheet_sheet/hr_timesheet_sheet_view.xml
@@ -290,11 +290,27 @@
-
+
-
+
+
-
+
hr.timesheet.sheet.tree.simplified
diff --git a/addons/l10n_ch/__openerp__.py b/addons/l10n_ch/__openerp__.py
index a9315abdf55..bca3c7ebcd6 100644
--- a/addons/l10n_ch/__openerp__.py
+++ b/addons/l10n_ch/__openerp__.py
@@ -66,7 +66,7 @@ TODO :
""",
- "version" : "5.0",
+ "version" : "5.1",
"author" : "Camptocamp SA",
"category" : "Localisation/Europe",
"website": "http://www.camptocamp.com",
diff --git a/addons/l10n_ch/report/bvr_invoice_report.rml b/addons/l10n_ch/report/bvr_invoice_report.rml
index e00c061522a..46798ae7da4 100755
--- a/addons/l10n_ch/report/bvr_invoice_report.rml
+++ b/addons/l10n_ch/report/bvr_invoice_report.rml
@@ -1,8 +1,6 @@
-
-
diff --git a/addons/l10n_ch/report/bvr_report.py b/addons/l10n_ch/report/bvr_report.py
index 646806b202f..d90d4db91de 100644
--- a/addons/l10n_ch/report/bvr_report.py
+++ b/addons/l10n_ch/report/bvr_report.py
@@ -35,16 +35,32 @@ import os
import sys
import shutil
import time
-from mx.DateTime import *
+from datetime import datetime
from report import report_sxw
from tools import mod10r
+import logging
+log = logging.getLogger('init')
+
+try:
+ this_module = 'l10n_ch'
+ from report.render.rml2pdf import customfonts
+ from addons import get_module_resource
+ ocrb_fname = get_module_resource(this_module, 'report', 'ocrbb.ttf')
+ if not ocrb_fname:
+ raise OSError("Cannot find ocrbb.ttf in %s resources", this_module)
+ customfonts.CustomTTFonts.append( ('ocrb', 'ocrb', ocrb_fname , None ) )
+ log.debug("module: %s registered custom OCR-B font at %s", this_module, ocrb_fname)
+except ImportError:
+ log.debug("Import error", exc_info=True)
+ pass
+except Exception, e:
+ log.exception("Cannot register custom font")
class account_invoice_bvr(report_sxw.rml_parse):
"""Report class that Allows to print BVR payement vector"""
def __init__(self, cr, uid, name, context):
super(account_invoice_bvr, self).__init__(cr, uid, name, context)
- self.copyocrbfile('addons/l10n_ch/report/ocrbb.ttf')
self.localcontext.update({
'time': time,
'user':self.pool.get("res.users").browse(cr,uid,uid),
@@ -53,8 +69,6 @@ class account_invoice_bvr(report_sxw.rml_parse):
'_get_ref': self._get_ref,
'comma_me': self.comma_me,
'format_date': self._get_and_change_date_format_for_swiss,
- 'police_absolute_path' : self.police_absolute_path,
- 'copyocrbfile': self.copyocrbfile
})
def _get_and_change_date_format_for_swiss (self,date_to_format):
date_formatted=''
@@ -63,23 +77,6 @@ class account_invoice_bvr(report_sxw.rml_parse):
date_formatted = strptime(date_to_format,'%Y-%m-%d').strftime('%d.%m.%Y')
return date_formatted
- def police_absolute_path(self, inner_path) :
- path = os.path.join(os.path.dirname(sys.argv[0]), inner_path)
- return path
-
- def copyocrbfile(self,file):
- src = self.police_absolute_path(file)
- file = os.path.basename(src)
- dest = os.path.join('/tmp/',file)
- if not os.path.isfile(dest):
- try:
- shutil.copyfile(src,dest)
- except:
- """print ocrbfile was not copy in /tmp/ please
- copy it manually from l10_ch/report"""
-
-
-
def comma_me(self,amount):
if type(amount) is float :
amount = str('%.2f'%amount)
diff --git a/addons/l10n_ch/report/bvr_report.rml b/addons/l10n_ch/report/bvr_report.rml
index 838f29523b3..c20e3371a41 100755
--- a/addons/l10n_ch/report/bvr_report.rml
+++ b/addons/l10n_ch/report/bvr_report.rml
@@ -1,7 +1,6 @@
-
diff --git a/addons/l10n_ch/wizard/create_dta.py b/addons/l10n_ch/wizard/create_dta.py
index 8bde159013a..d3e2856387d 100644
--- a/addons/l10n_ch/wizard/create_dta.py
+++ b/addons/l10n_ch/wizard/create_dta.py
@@ -31,7 +31,7 @@
##############################################################################
import time
-import mx.DateTime
+from datetime import datetime
import base64
from osv import osv, fields
@@ -469,11 +469,11 @@ def _create_dta(obj, cr, uid, data, context=None):
'on line: ' + pline.name)
if pline.order_id.date_scheduled:
- date_value = mx.DateTime.strptime(pline.order_id.date_scheduled, '%Y-%m-%d')
+ date_value = datetime.strptime(pline.order_id.date_scheduled, '%Y-%m-%d')
elif pline.date:
- date_value = mx.DateTime.strptime(pline.date, '%Y-%m-%d')
+ date_value = datetime.strptime(pline.date, '%Y-%m-%d')
else:
- date_value = mx.DateTime.now()
+ date_value = datetime.now()
v['date_value'] = date_value.strftime("%y%m%d")
# si compte iban -> iban (836)
diff --git a/addons/l10n_lu/wizard/print_vat.py b/addons/l10n_lu/wizard/print_vat.py
index 0e16c5ccf4c..3f356d31cf6 100644
--- a/addons/l10n_lu/wizard/print_vat.py
+++ b/addons/l10n_lu/wizard/print_vat.py
@@ -10,7 +10,7 @@ import tools
from tools.translate import _
from report.render import render
from report.interface import report_int
-
+import addons
class external_pdf(render):
def __init__(self, pdf):
@@ -46,7 +46,7 @@ class report_custom(report_int):
result['info_address'] = partner.address[0].street
result['info_address2'] = (partner.address[0].zip or '') + ' ' + (partner.address[0].city or '')
try:
- tools.pdf_utils.fill_pdf(tools.config['addons_path']+'/l10n_lu/wizard/2008_DECL_F_M10.pdf', '/tmp/output.pdf', result)
+ tools.pdf_utils.fill_pdf(addons.get_module_resource('l10n_lu','wizard', '2008_DECL_F_M10.pdf'), '/tmp/output.pdf', result)
self.obj = external_pdf(file('/tmp/output.pdf').read())
self.obj.render()
return (self.obj.pdf, 'pdf')
@@ -75,4 +75,4 @@ class vat_declaration_report(osv.osv_memory):
vat_declaration_report()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/marketing_campaign/marketing_campaign_view.xml b/addons/marketing_campaign/marketing_campaign_view.xml
index 7d1c8d3d2bf..614055dddcd 100644
--- a/addons/marketing_campaign/marketing_campaign_view.xml
+++ b/addons/marketing_campaign/marketing_campaign_view.xml
@@ -446,18 +446,20 @@
view_type="form"
view_mode="tree,form"
id="act_marketing_campaing_segment_opened"
- domain="[('campaign_id','=',active_id)]"
+ context="{'search_default_campaign_id': [active_id]}"
/>
-
-
mx.DateTime.strptime(guarantee_limit, '%Y-%m-%d'):
+ if guarantee_limit and date.today() > datetime.strptime(guarantee_limit, '%Y-%m-%d'):
to_invoice=True
return {'value': {
'to_invoice': to_invoice,
diff --git a/addons/mrp_subproduct/test/mrp_subproduct.yml b/addons/mrp_subproduct/test/mrp_subproduct.yml
index 520a4e98163..56c62b94d09 100644
--- a/addons/mrp_subproduct/test/mrp_subproduct.yml
+++ b/addons/mrp_subproduct/test/mrp_subproduct.yml
@@ -164,6 +164,6 @@
I see that stock moves of Wood and Nails including Wooden Table are done now.
-
!python {model: stock.move}: |
- move_ids = self.search(cr, uid, [('product_id','in',[ref("product_product_woodenchair0"),ref("product_product_woodentable0"),ref("product_product_wood0"),ref("product_product_nails0")])])
+ move_ids = self.search(cr, uid, [('product_id','in',[ref("product_product_woodentable0"),ref("product_product_wood0"),ref("product_product_nails0")])])
moves = self.browse(cr, uid, move_ids)
assert all(move.state == 'done' for move in moves), 'Moves are not done!'
diff --git a/addons/point_of_sale/account_bank_statement.py b/addons/point_of_sale/account_bank_statement.py
index 395319eeb64..c24dc221596 100644
--- a/addons/point_of_sale/account_bank_statement.py
+++ b/addons/point_of_sale/account_bank_statement.py
@@ -20,12 +20,8 @@
#
##############################################################################
-import time
from osv import osv
from osv import fields
-from mx import DateTime
-from decimal import Decimal
-from tools.translate import _
class account_journal(osv.osv):
@@ -46,8 +42,8 @@ class account_cash_statement(osv.osv):
_inherit = 'account.bank.statement'
- def _equal_balance(self, cr, uid, ids, statement, context={}):
-
+ def _equal_balance(self, cr, uid, cash_id, context={}):
+ statement = self.browse(cr, uid, cash_id, context=context)
if not statement.journal_id.check_dtls:
return True
diff --git a/addons/point_of_sale/pos.py b/addons/point_of_sale/pos.py
index 769d3a0460e..0d6ab5f2b33 100644
--- a/addons/point_of_sale/pos.py
+++ b/addons/point_of_sale/pos.py
@@ -1022,15 +1022,16 @@ class pos_order_line(osv.osv):
def _amount_line_ttc(self, cr, uid, ids, field_name, arg, context):
res = dict.fromkeys(ids, 0.0)
account_tax_obj = self.pool.get('account.tax')
+ prices = self.price_by_product_multi(cr, uid, ids)
for line in self.browse(cr, uid, ids):
tax_amount = 0.0
taxes = [t for t in line.product_id.taxes_id]
- if line.qty == 0.0:
- continue
+ if line.qty == 0.0:
+ continue
computed_taxes = account_tax_obj.compute_all(cr, uid, taxes, line.price_unit, line.qty)['taxes']
for tax in computed_taxes:
tax_amount += tax['amount']
- price = self.price_by_product(cr, uid, ids, line.order_id.pricelist_id.id, line.product_id.id, line.qty, line.order_id.partner_id.id)
+ price = prices[line.id]
if line.discount!=0.0:
res[line.id] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0)
else:
@@ -1041,14 +1042,91 @@ class pos_order_line(osv.osv):
def _amount_line(self, cr, uid, ids, field_name, arg, context):
res = {}
+ prices = self.price_by_product_multi(cr, uid, ids)
for line in self.browse(cr, uid, ids):
- price = self.price_by_product(cr, uid, ids, line.order_id.pricelist_id.id, line.product_id.id, line.qty, line.order_id.partner_id.id)
+ price = prices[line.id]
if line.discount!=0.0:
res[line.id] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0)
else:
res[line.id]=line.price_unit*line.qty
return res
+ def _amount_line_all(self, cr, uid, ids, field_names, arg, context):
+ res = dict([(i, {}) for i in ids])
+
+ account_tax_obj = self.pool.get('account.tax')
+
+ prices = self.price_by_product_multi(cr, uid, ids)
+ for line in self.browse(cr, uid, ids):
+ for f in field_names:
+ if f == 'price_subtotal':
+ price = prices[line.id]
+ if line.discount != 0.0:
+ res[line.id][f] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0)
+ else:
+ res[line.id][f] = line.price_unit * line.qty
+ elif f == 'price_subtotal_incl':
+ tax_amount = 0.0
+ taxes = [t for t in line.product_id.taxes_id]
+ if line.qty == 0.0:
+ continue
+ computed_taxes = account_tax_obj.compute_all(cr, uid, taxes, line.price_unit, line.qty)['taxes']
+ for tax in computed_taxes:
+ tax_amount += tax['amount']
+ price = prices[line.id]
+ if line.discount!=0.0:
+ res[line.id][f] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0)
+ else:
+ res[line.id][f] = line.price_unit * line.qty
+ res[line.id][f] += tax_amount
+ return res
+
+ def price_by_product_multi(self, cr, uid, ids, context=None):
+ if context is None:
+ context = {}
+
+ res = {}.fromkeys(ids, 0.0)
+
+ lines = self.browse(cr, uid, ids, context=context)
+
+ pricelist_ids = [line.order_id.pricelist_id.id for line in lines]
+ products_by_qty_by_partner = [(line.product_id.id, line.qty, line.order_id.partner_id.id) for line in lines]
+
+ price_get_multi_res = self.pool.get('product.pricelist').price_get_multi(cr, uid, pricelist_ids, products_by_qty_by_partner, context=context)
+
+ for line in lines:
+ pricelist = line.order_id.pricelist_id.id
+ product_id = line.product_id
+ qty = line.qty or 0
+ partner_id = line.order_id.partner_id.id or False
+
+ if not product_id:
+ res[line.id] = 0.0
+ continue
+ if not pricelist:
+ raise osv.except_osv(_('No Pricelist !'),
+ _('You have to select a pricelist in the sale form !\n' \
+ 'Please set one before choosing a product.'))
+
+ uom_id = product_id.uom_po_id.id
+
+ #old_price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist], product_id.id, qty or 1.0, partner_id, {'uom': uom_id})[pricelist]
+ #print "prod_id: %s, pricelist: %s, price: %s" % (product_id.id, pricelist, price)
+ price = price_get_multi_res[line.product_id.id][pricelist]
+ #print "prod_id: %s, pricelist: %s, price2: %s" % (product_id.id, pricelist, price2)
+
+ #if old_price != price:
+ # raise Exception('old_price != price')
+
+ unit_price = price or product_id.list_price
+ res[line.id] = unit_price
+ if unit_price is False:
+ raise osv.except_osv(_('No valid pricelist line found !'),
+ _("Couldn't find a pricelist line matching this product" \
+ " and quantity.\nYou have to change either the product," \
+ " the quantity or the pricelist."))
+ return res
+
def price_by_product(self, cr, uid, ids, pricelist, product_id, qty=0, partner_id=False):
if not product_id:
return 0.0
@@ -1057,7 +1135,7 @@ class pos_order_line(osv.osv):
_('You have to select a pricelist in the sale form !\n' \
'Please set one before choosing a product.'))
p_obj = self.pool.get('product.product').browse(cr,uid,[product_id])[0]
- uom_id=p_obj.uom_po_id.id
+ uom_id = p_obj.uom_po_id.id
price = self.pool.get('product.pricelist').price_get(cr, uid,
[pricelist], product_id, qty or 1.0, partner_id,{'uom': uom_id})[pricelist]
unit_price=price or p_obj.list_price
@@ -1120,13 +1198,13 @@ class pos_order_line(osv.osv):
return {'value': {'notice':'Minimum Discount','price_ded':price*discount*0.01 or 0.0 }}
else :
return {'value': {'notice':'No Discount', 'price_ded':price*discount*0.01 or 0.0}}
-
+
def onchange_qty(self, cr, uid, ids, discount, qty, price, context=None):
subtotal = qty * price
if discount:
subtotal = subtotal - (subtotal * discount / 100)
return {'value': {'price_subtotal_incl': subtotal}}
-
+
_columns = {
'name': fields.char('Line Description', size=512),
'company_id':fields.many2one('res.company', 'Company', required=True),
@@ -1137,8 +1215,8 @@ class pos_order_line(osv.osv):
'price_ded': fields.float('Discount(Amount)',digits_compute=dp.get_precision('Point Of Sale')),
'qty': fields.float('Quantity'),
'qty_rfd': fields.float('Refunded Quantity'),
- 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal w/o Tax'),
- 'price_subtotal_incl': fields.function(_amount_line_ttc, method=True, string='Subtotal'),
+ 'price_subtotal': fields.function(_amount_line_all, method=True, multi='pos_order_line_amount', string='Subtotal w/o Tax'),
+ 'price_subtotal_incl': fields.function(_amount_line_all, method=True, multi='pos_order_line_amount', string='Subtotal'),
'discount': fields.float('Discount (%)', digits=(16, 2)),
'order_id': fields.many2one('pos.order', 'Order Ref', ondelete='cascade'),
'create_date': fields.datetime('Creation Date', readonly=True),
diff --git a/addons/point_of_sale/pos_demo.xml b/addons/point_of_sale/pos_demo.xml
index 18029826008..80ba3d24397 100644
--- a/addons/point_of_sale/pos_demo.xml
+++ b/addons/point_of_sale/pos_demo.xml
@@ -61,14 +61,5 @@
Discount Applied
-
- St. 05/19
- 0.0
- 2010-05-19
-
-
- draft
-
-
diff --git a/addons/point_of_sale/test/pos_report.yml b/addons/point_of_sale/test/pos_report.yml
index aeb99e4df57..d17e487794e 100644
--- a/addons/point_of_sale/test/pos_report.yml
+++ b/addons/point_of_sale/test/pos_report.yml
@@ -67,6 +67,16 @@
(data, format) = netsvc.LocalService('report.pos.details').create(cr, uid, [], {'model':'ir.ui.menu', 'form':{'date_start': time.strftime('%Y-%m-%d'), 'date_end': time.strftime('%Y-%m-%d') }}, {})
if tools.config['test_report_directory']:
file(os.path.join(tools.config['test_report_directory'], 'point_of_sale- pos details report'+format), 'wb+').write(data)
+-
+ I create a record for Bank Statement.
+-
+ !record {model: account.bank.statement, id: account_bank_statement_st0}:
+ name: St.05/19
+ balance_end_real: 0.0
+ date: '2010-05-19'
+ journal_id: account.bank_journal
+ period_id: account.period_5
+ state: 'draft'
-
In order to test the PDF reports defined on a Point Of Sale, we will print a Account Statement Report
-
diff --git a/addons/procurement/procurement_view.xml b/addons/procurement/procurement_view.xml
index 01c50d67e64..1e6395c660e 100644
--- a/addons/procurement/procurement_view.xml
+++ b/addons/procurement/procurement_view.xml
@@ -240,12 +240,16 @@
-
+
=', date),
+ ]
+
+ plversion_ids = product_pricelist_version_obj.search(cr, uid, plversions_search_args)
+ if len(pricelist_version_ids) != len(plversion_ids):
+ msg = "At least one pricelist has no active version !\nPlease create or activate one."
+ raise osv.except_osv(_('Warning !'), _(msg))
+
+ # product.product:
+ product_ids = list(set([k[0] for k in product_map.keys()]))
+ products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])])
+
+ # product.category:
+ product_category_ids = product_category_obj.search(cr, uid, [])
+ product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id'])
+ product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']])
+
+ results = {}
+ for (product_id, pricelist_id), line in product_map.items():
+ price = False
+
+ partner = line['partner_id']
+ qty = line['qty']
+ tmpl_id = products[product_id]['product_tmpl_id'] and products[product_id]['product_tmpl_id'][0] or False
+
+ categ_id = products[product_id]['categ_id'] and products[product_id]['categ_id'][0] or False
+ categ_ids = _create_parent_category_list(categ_id, [categ_id])
+ if categ_ids:
+ categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))'
+ else:
+ categ_where = '(categ_id IS NULL)'
+
+ cr.execute(
+ 'SELECT i.*, pl.currency_id '
+ 'FROM product_pricelist_item AS i, '
+ 'product_pricelist_version AS v, product_pricelist AS pl '
+ 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) '
+ 'AND (product_id IS NULL OR product_id = %s) '
+ 'AND (' + categ_where + ' OR (categ_id IS NULL)) '
+ 'AND price_version_id = %s '
+ 'AND (min_quantity IS NULL OR min_quantity <= %s) '
+ 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id '
+ 'ORDER BY sequence',
+ (tmpl_id, product_id, pricelist_id, qty))
+ res1 = cr.dictfetchall()
+
+ for res in res1:
+ if res:
+ if res['base'] == -1:
+ if not res['base_pricelist_id']:
+ price = 0.0
+ else:
+ price_tmp = self.price_get(cr, uid,
+ [res['base_pricelist_id']], prod_id,
+ qty)[res['base_pricelist_id']]
+ ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id
+ price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False)
+ break
+ elif res['base'] == -2:
+ # this section could be improved by moving the queries outside the loop:
+ where = []
+ if partner:
+ where = [('name', '=', partner) ]
+ sinfo = supplierinfo_obj.search(cr, uid,
+ [('product_id', '=', tmpl_id)] + where)
+ price = 0.0
+ if sinfo:
+ cr.execute('SELECT * ' \
+ 'FROM pricelist_partnerinfo ' \
+ 'WHERE suppinfo_id IN %s' \
+ 'AND min_quantity <= %s ' \
+ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty,))
+ res2 = cr.dictfetchone()
+ if res2:
+ price = res2['price']
+ break
+ else:
+ price_type = price_type_obj.browse(cr, uid, int(res['base']))
+ price = currency_obj.compute(cr, uid,
+ price_type.currency_id.id, res['currency_id'],
+ product_obj.price_get(cr, uid, [product_id],
+ price_type.field)[product_id], round=False, context=context)
+
+ if price:
+ price_limit = price
+
+ price = price * (1.0+(res['price_discount'] or 0.0))
+ price = rounding(price, res['price_round'])
+ price += (res['price_surcharge'] or 0.0)
+ if res['price_min_margin']:
+ price = max(price, price_limit+res['price_min_margin'])
+ if res['price_max_margin']:
+ price = min(price, price_limit+res['price_max_margin'])
+ break
+
+ else:
+ # False means no valid line found ! But we may not raise an
+ # exception here because it breaks the search
+ price = False
+
+ if price:
+ p_uom_id = products[product_id]['uos_id'] and products[product_id]['uos_id'][0] or products[product_id]['uom_id'] and products[product_id]['uom_id'][0] or False
+ if p_uom_id:
+ price = product_uom_obj._compute_price(cr, uid, p_uom_id, price, context.get('uom', False))
+
+ if results.get(product_id):
+ results[product_id][pricelist_id] = price
+ else:
+ results[product_id] = {pricelist_id: price}
+
+ return results
+
+ #def price_get_multi(self, cr, uid, product_ids, context=None):
+ def price_get_multi(self, cr, uid, pricelist_ids, products_by_qty_by_partner, context=None):
+ """multi products 'price_get'.
+ @param pricelist_ids:
+ @param products_by_qty:
+ @param partner:
+ @param context: {
+ 'date': Date of the pricelist (%Y-%m-%d),}
+ @return: a dict of dict with product_id as key and a dict 'price by pricelist' as value
+ """
+
+ def _create_parent_category_list(id, lst):
+ if not id:
+ return []
+ parent = product_category_tree.get(id)
+ if parent:
+ lst.append(parent)
+ return _create_parent_category_list(parent, lst)
+ else:
+ return lst
+ # _create_parent_category_list
+
+ if context is None:
+ context = {}
+
+ date = time.strftime('%Y-%m-%d')
+ if 'date' in context:
+ date = context['date']
+
+ currency_obj = self.pool.get('res.currency')
+ product_obj = self.pool.get('product.product')
+ product_category_obj = self.pool.get('product.category')
+ product_uom_obj = self.pool.get('product.uom')
+ supplierinfo_obj = self.pool.get('product.supplierinfo')
+ price_type_obj = self.pool.get('product.price.type')
+ product_pricelist_version_obj = self.pool.get('product.pricelist.version')
+
+ # product.pricelist.version:
+ if pricelist_ids:
+ pricelist_version_ids = pricelist_ids
+ else:
+ # all pricelists:
+ pricelist_version_ids = product_pricelist_version_obj.search(cr, uid, [])
+
+ pricelist_version_ids = list(set(pricelist_version_ids))
+
+ plversions_search_args = [
+ ('pricelist_id', 'in', pricelist_version_ids),
+ '|',
+ ('date_start', '=', False),
+ ('date_start', '<=', date),
+ '|',
+ ('date_end', '=', False),
+ ('date_end', '>=', date),
+ ]
+
+ plversion_ids = product_pricelist_version_obj.search(cr, uid, plversions_search_args)
+ if len(pricelist_version_ids) != len(plversion_ids):
+ msg = "At least one pricelist has no active version !\nPlease create or activate one."
+ raise osv.except_osv(_('Warning !'), _(msg))
+
+ # product.product:
+ product_ids = [i[0] for i in products_by_qty_by_partner]
+ #products = dict([(item['id'], item) for item in product_obj.read(cr, uid, product_ids, ['categ_id', 'product_tmpl_id', 'uos_id', 'uom_id'])])
+ products = product_obj.browse(cr, uid, product_ids, context=context)
+ products_dict = dict([(item.id, item) for item in products])
+
+ # product.category:
+ product_category_ids = product_category_obj.search(cr, uid, [])
+ product_categories = product_category_obj.read(cr, uid, product_category_ids, ['parent_id'])
+ product_category_tree = dict([(item['id'], item['parent_id'][0]) for item in product_categories if item['parent_id']])
+
+ results = {}
+ for product_id, qty, partner in products_by_qty_by_partner:
+ for pricelist_id in pricelist_version_ids:
+ price = False
+
+ tmpl_id = products_dict[product_id].product_tmpl_id and products_dict[product_id].product_tmpl_id.id or False
+
+ categ_id = products_dict[product_id].categ_id and products_dict[product_id].categ_id.id or False
+ categ_ids = _create_parent_category_list(categ_id, [categ_id])
+ if categ_ids:
+ categ_where = '(categ_id IN (' + ','.join(map(str, categ_ids)) + '))'
+ else:
+ categ_where = '(categ_id IS NULL)'
+
+ cr.execute(
+ 'SELECT i.*, pl.currency_id '
+ 'FROM product_pricelist_item AS i, '
+ 'product_pricelist_version AS v, product_pricelist AS pl '
+ 'WHERE (product_tmpl_id IS NULL OR product_tmpl_id = %s) '
+ 'AND (product_id IS NULL OR product_id = %s) '
+ 'AND (' + categ_where + ' OR (categ_id IS NULL)) '
+ 'AND price_version_id = %s '
+ 'AND (min_quantity IS NULL OR min_quantity <= %s) '
+ 'AND i.price_version_id = v.id AND v.pricelist_id = pl.id '
+ 'ORDER BY sequence',
+ (tmpl_id, product_id, pricelist_id, qty))
+ res1 = cr.dictfetchall()
+
+ for res in res1:
+ if res:
+ if res['base'] == -1:
+ if not res['base_pricelist_id']:
+ price = 0.0
+ else:
+ price_tmp = self.price_get(cr, uid,
+ [res['base_pricelist_id']], prod_id,
+ qty)[res['base_pricelist_id']]
+ ptype_src = self.browse(cr, uid, res['base_pricelist_id']).currency_id.id
+ price = currency_obj.compute(cr, uid, ptype_src, res['currency_id'], price_tmp, round=False)
+ break
+ elif res['base'] == -2:
+ # this section could be improved by moving the queries outside the loop:
+ where = []
+ if partner:
+ where = [('name', '=', partner) ]
+ sinfo = supplierinfo_obj.search(cr, uid,
+ [('product_id', '=', tmpl_id)] + where)
+ price = 0.0
+ if sinfo:
+ cr.execute('SELECT * ' \
+ 'FROM pricelist_partnerinfo ' \
+ 'WHERE suppinfo_id IN %s' \
+ 'AND min_quantity <= %s ' \
+ 'ORDER BY min_quantity DESC LIMIT 1', (tuple(sinfo),qty,))
+ res2 = cr.dictfetchone()
+ if res2:
+ price = res2['price']
+ break
+ else:
+ price_type = price_type_obj.browse(cr, uid, int(res['base']))
+ price = currency_obj.compute(cr, uid,
+ price_type.currency_id.id, res['currency_id'],
+ product_obj.price_get(cr, uid, [product_id],
+ price_type.field)[product_id], round=False, context=context)
+
+ if price:
+ price_limit = price
+
+ price = price * (1.0+(res['price_discount'] or 0.0))
+ price = rounding(price, res['price_round'])
+ price += (res['price_surcharge'] or 0.0)
+ if res['price_min_margin']:
+ price = max(price, price_limit+res['price_min_margin'])
+ if res['price_max_margin']:
+ price = min(price, price_limit+res['price_max_margin'])
+ break
+
+ else:
+ # False means no valid line found ! But we may not raise an
+ # exception here because it breaks the search
+ price = False
+
+ if price:
+ if 'uom' in context:
+ product = products_dict[product_id]
+ uom = product.uos_id or product.uom_id
+ price = self.pool.get('product.uom')._compute_price(cr, uid, uom.id, price, context['uom'])
+
+ if results.get(product_id):
+ results[product_id][pricelist_id] = price
+ else:
+ results[product_id] = {pricelist_id: price}
+
+ return results
+
def price_get(self, cr, uid, ids, prod_id, qty, partner=None, context=None):
+ res_multi = self.price_get_multi(cr, uid, pricelist_ids=ids, products_by_qty_by_partner=[(prod_id, qty, partner)], context=context)
+ res = res_multi[prod_id]
+ res.update({'item_id': {ids[-1]: ids[-1]}})
+ return res
+
+ def price_get_old(self, cr, uid, ids, prod_id, qty, partner=None, context=None):
'''
context = {
'uom': Unit of Measure (int),
@@ -134,8 +462,8 @@ class product_pricelist(osv.osv):
'date': Date of the pricelist (%Y-%m-%d),
}
'''
- price=False
- item_id=0
+ price = False
+ item_id = 0
context = context or {}
currency_obj = self.pool.get('res.currency')
product_obj = self.pool.get('product.product')
@@ -219,7 +547,7 @@ class product_pricelist(osv.osv):
elif res['base'] == -2:
where = []
if partner:
- where = [('name', '=', partner) ]
+ where = [('name', '=', partner) ]
sinfo = supplierinfo_obj.search(cr, uid,
[('product_id', '=', tmpl_id)] + where)
price = 0.0
@@ -264,6 +592,7 @@ class product_pricelist(osv.osv):
uom = product.uos_id or product.uom_id
result[id] = self.pool.get('product.uom')._compute_price(cr,
uid, uom.id, result[id], context['uom'])
+
return result
product_pricelist()
diff --git a/addons/product/product.py b/addons/product/product.py
index 1b74bef87f9..6c1125268a9 100644
--- a/addons/product/product.py
+++ b/addons/product/product.py
@@ -503,7 +503,15 @@ class product_product(osv.osv):
#
# Could be overrided for variants matrices prices
#
- def price_get(self, cr, uid, ids, ptype='list_price', context={}):
+ def price_get(self, cr, uid, ids, ptype='list_price', context=None):
+ if context is None:
+ context = {}
+
+ if 'currency_id' in context:
+ pricetype_obj = self.pool.get('product.price.type')
+ price_type_id = pricetype_obj.search(cr, uid, [('field','=',ptype)])[0]
+ price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id
+
res = {}
product_uom_obj = self.pool.get('product.uom')
for product in self.browse(cr, uid, ids, context=context):
@@ -517,11 +525,8 @@ class product_product(osv.osv):
uom.id, res[product.id], context['uom'])
# Convert from price_type currency to asked one
if 'currency_id' in context:
- pricetype_obj = self.pool.get('product.price.type')
# Take the price_type currency from the product field
# This is right cause a field cannot be in more than one currency
- price_type_id = pricetype_obj.search(cr, uid, [('field','=',ptype)])[0]
- price_type_currency_id = pricetype_obj.browse(cr,uid,price_type_id).currency_id.id
res[product.id] = self.pool.get('res.currency').compute(cr, uid, price_type_currency_id,
context['currency_id'], res[product.id],context=context)
diff --git a/addons/product_margin/product_margin.py b/addons/product_margin/product_margin.py
index d8d6d7a1702..132f6e27d55 100644
--- a/addons/product_margin/product_margin.py
+++ b/addons/product_margin/product_margin.py
@@ -23,6 +23,7 @@ import time
from osv import fields, osv
+
class product_product(osv.osv):
_inherit = "product.product"
@@ -30,30 +31,31 @@ class product_product(osv.osv):
res = {}
if context is None:
context = {}
- for val in self.browse(cr, uid, ids,context=context):
+
+ for val in self.browse(cr, uid, ids, context=context):
res[val.id] = {}
date_from = context.get('date_from', time.strftime('%Y-01-01'))
date_to = context.get('date_to', time.strftime('%Y-12-31'))
invoice_state = context.get('invoice_state', 'open_paid')
if 'date_from' in field_names:
- res[val.id]['date_from']=date_from
+ res[val.id]['date_from'] = date_from
if 'date_to' in field_names:
- res[val.id]['date_to']=date_to
+ res[val.id]['date_to'] = date_to
if 'invoice_state' in field_names:
- res[val.id]['invoice_state']=invoice_state
+ res[val.id]['invoice_state'] = invoice_state
invoice_types = ()
states = ()
- if invoice_state=='paid':
- states=('paid',)
- elif invoice_state=='open_paid':
- states=('open','paid')
- elif invoice_state=='draft_open_paid':
- states=('draft','open','paid')
+ if invoice_state == 'paid':
+ states = ('paid',)
+ elif invoice_state == 'open_paid':
+ states = ('open', 'paid')
+ elif invoice_state == 'draft_open_paid':
+ states = ('draft', 'open', 'paid')
if 'sale_avg_price' in field_names or 'sale_num_invoiced' in field_names or 'turnover' in field_names or 'sale_expected' in field_names:
- invoice_types=('out_invoice','in_refund')
+ invoice_types = ('out_invoice', 'in_refund')
if 'purchase_avg_price' in field_names or 'purchase_num_invoiced' in field_names or 'total_cost' in field_names or 'normal_cost' in field_names:
- invoice_types=('in_invoice','out_refund')
+ invoice_types = ('in_invoice', 'out_refund')
if len(invoice_types):
cr.execute("""select
avg(l.price_unit) as avg_unit_price,
@@ -65,51 +67,65 @@ class product_product(osv.osv):
left join account_invoice i on (l.invoice_id = i.id)
left join product_template product on (product.id=l.product_id)
where l.product_id = %s and i.state in %s and i.type IN %s and i.date_invoice>=%s and i.date_invoice<=%s
- """,(val.id,states,invoice_types,date_from,date_to))
- result=cr.fetchall()[0]
+ """, (val.id, states, invoice_types, date_from, date_to))
+ result = cr.fetchall()[0]
if 'sale_avg_price' in field_names or 'sale_num_invoiced' in field_names or 'turnover' in field_names or 'sale_expected' in field_names:
- res[val.id]['sale_avg_price']=result[0] and result[0] or 0.0
- res[val.id]['sale_num_invoiced']=result[1] and result[1] or 0.0
- res[val.id]['turnover']=result[2] and result[2] or 0.0
- res[val.id]['sale_expected']=result[3] and result[3] or 0.0
- res[val.id]['sales_gap']=res[val.id]['sale_expected']-res[val.id]['turnover']
+ res[val.id]['sale_avg_price'] = result[0] and result[0] or 0.0
+ res[val.id]['sale_num_invoiced'] = result[1] and result[1] or 0.0
+ res[val.id]['turnover'] = result[2] and result[2] or 0.0
+ res[val.id]['sale_expected'] = result[3] and result[3] or 0.0
+ res[val.id]['sales_gap'] = res[val.id]['sale_expected']-res[val.id]['turnover']
if 'purchase_avg_price' in field_names or 'purchase_num_invoiced' in field_names or 'total_cost' in field_names or 'normal_cost' in field_names:
- res[val.id]['purchase_avg_price']=result[0] and result[0] or 0.0
- res[val.id]['purchase_num_invoiced']=result[1] and result[1] or 0.0
- res[val.id]['total_cost']=result[2] and result[2] or 0.0
- res[val.id]['normal_cost']=result[4] and result[4] or 0.0
- res[val.id]['purchase_gap']=res[val.id]['normal_cost']-res[val.id]['total_cost']
+ res[val.id]['purchase_avg_price'] = result[0] and result[0] or 0.0
+ res[val.id]['purchase_num_invoiced'] = result[1] and result[1] or 0.0
+ res[val.id]['total_cost'] = result[2] and result[2] or 0.0
+ res[val.id]['normal_cost'] = result[4] and result[4] or 0.0
+ res[val.id]['purchase_gap'] = res[val.id]['normal_cost']-res[val.id]['total_cost']
if 'total_margin' in field_names:
- res[val.id]['total_margin']=val.turnover-val.standard_price
+ res[val.id]['total_margin'] = val.turnover - val.standard_price
if 'expected_margin' in field_names:
- res[val.id]['expected_margin']=val.sale_expected-val.normal_cost
+ res[val.id]['expected_margin'] = val.sale_expected - val.normal_cost
if 'total_margin_rate' in field_names:
- res[val.id]['total_margin_rate']=val.turnover and val.total_margin * 100 / val.turnover or 0.0
+ res[val.id]['total_margin_rate'] = val.turnover and val.total_margin * 100 / val.turnover or 0.0
if 'expected_margin_rate' in field_names:
- res[val.id]['expected_margin_rate']=val.sale_expected and val.expected_margin * 100 / val.sale_expected or 0.0
+ res[val.id]['expected_margin_rate'] = val.sale_expected and val.expected_margin * 100 / val.sale_expected or 0.0
return res
_columns = {
- 'date_from': fields.function(_product_margin, method=True, type='date', string='From Date', multi=True),
- 'date_to': fields.function(_product_margin, method=True, type='date', string='To Date', multi=True),
+ 'date_from': fields.function(_product_margin, method=True, type='date', string='From Date', multi='product_margin'),
+ 'date_to': fields.function(_product_margin, method=True, type='date', string='To Date', multi='product_margin'),
'invoice_state': fields.function(_product_margin, method=True, type='selection', selection=[
- ('paid','Paid'),('open_paid','Open and Paid'),('draft_open_paid','Draft, Open and Paid')
- ], string='Invoice State',multi=True, readonly=True),
- 'sale_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='sale',help="Avg. Price in Customer Invoices)"),
- 'purchase_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='purchase',help="Avg. Price in Supplier Invoices "),
- 'sale_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='sale',help="Sum of Quantity in Customer Invoices"),
- 'purchase_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='purchase',help="Sum of Quantity in Supplier Invoices"),
- 'sales_gap' : fields.function(_product_margin, method=True, type='float', string='Sales Gap', multi='sale',help="Expected Sale - Turn Over"),
- 'purchase_gap' : fields.function(_product_margin, method=True, type='float', string='Purchase Gap', multi='purchase',help="Normal Cost - Total Cost"),
- 'turnover' : fields.function(_product_margin, method=True, type='float', string='Turnover' ,multi='sale',help="Sum of Multification of Invoice price and quantity of Customer Invoices"),
- 'total_cost' : fields.function(_product_margin, method=True, type='float', string='Total Cost', multi='purchase',help="Sum of Multification of Invoice price and quantity of Supplier Invoices "),
- 'sale_expected' : fields.function(_product_margin, method=True, type='float', string='Expected Sale', multi='sale',help="Sum of Multification of Sale Catalog price and quantity of Customer Invoices"),
- 'normal_cost' : fields.function(_product_margin, method=True, type='float', string='Normal Cost', multi='purchase',help="Sum of Multification of Cost price and quantity of Supplier Invoices"),
- 'total_margin' : fields.function(_product_margin, method=True, type='float', string='Total Margin', multi='total',help="Turnorder - Standard price"),
- 'expected_margin' : fields.function(_product_margin, method=True, type='float', string='Expected Margin', multi='total',help="Expected Sale - Normal Cost"),
- 'total_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Total Margin (%)', multi='margin',help="Total margin * 100 / Turnover"),
- 'expected_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Expected Margin (%)', multi='margin',help="Expected margin * 100 / Expected Sale"),
+ ('paid','Paid'),('open_paid','Open and Paid'),('draft_open_paid','Draft, Open and Paid')
+ ], string='Invoice State',multi='product_margin', readonly=True),
+ 'sale_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='product_margin',
+ help="Avg. Price in Customer Invoices)"),
+ 'purchase_avg_price' : fields.function(_product_margin, method=True, type='float', string='Avg. Unit Price', multi='product_margin',
+ help="Avg. Price in Supplier Invoices "),
+ 'sale_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='product_margin',
+ help="Sum of Quantity in Customer Invoices"),
+ 'purchase_num_invoiced' : fields.function(_product_margin, method=True, type='float', string='# Invoiced', multi='product_margin',
+ help="Sum of Quantity in Supplier Invoices"),
+ 'sales_gap' : fields.function(_product_margin, method=True, type='float', string='Sales Gap', multi='product_margin',
+ help="Expected Sale - Turn Over"),
+ 'purchase_gap' : fields.function(_product_margin, method=True, type='float', string='Purchase Gap', multi='product_margin',
+ help="Normal Cost - Total Cost"),
+ 'turnover' : fields.function(_product_margin, method=True, type='float', string='Turnover' ,multi='product_margin',
+ help="Sum of Multification of Invoice price and quantity of Customer Invoices"),
+ 'total_cost' : fields.function(_product_margin, method=True, type='float', string='Total Cost', multi='product_margin',
+ help="Sum of Multification of Invoice price and quantity of Supplier Invoices "),
+ 'sale_expected' : fields.function(_product_margin, method=True, type='float', string='Expected Sale', multi='product_margin',
+ help="Sum of Multification of Sale Catalog price and quantity of Customer Invoices"),
+ 'normal_cost' : fields.function(_product_margin, method=True, type='float', string='Normal Cost', multi='product_margin',
+ help="Sum of Multification of Cost price and quantity of Supplier Invoices"),
+ 'total_margin' : fields.function(_product_margin, method=True, type='float', string='Total Margin', multi='product_margin',
+ help="Turnorder - Standard price"),
+ 'expected_margin' : fields.function(_product_margin, method=True, type='float', string='Expected Margin', multi='product_margin',
+ help="Expected Sale - Normal Cost"),
+ 'total_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Total Margin (%)', multi='product_margin',
+ help="Total margin * 100 / Turnover"),
+ 'expected_margin_rate' : fields.function(_product_margin, method=True, type='float', string='Expected Margin (%)', multi='product_margin',
+ help="Expected margin * 100 / Expected Sale"),
}
product_product()
diff --git a/addons/project/board_project_manager_view.xml b/addons/project/board_project_manager_view.xml
index 76c40324d31..12559b0629b 100644
--- a/addons/project/board_project_manager_view.xml
+++ b/addons/project/board_project_manager_view.xml
@@ -9,7 +9,11 @@
-
+
diff --git a/addons/project/project.py b/addons/project/project.py
index f4574e90d37..a6a7f837efe 100644
--- a/addons/project/project.py
+++ b/addons/project/project.py
@@ -389,6 +389,7 @@ class task(osv.osv):
if not default.get('remaining_hours', False):
default['remaining_hours'] = float(self.read(cr, uid, id, ['planned_hours'])['planned_hours'])
default['active'] = True
+ default['type_id'] = False
if not default.get('name', False):
default['name'] = self.browse(cr, uid, id, context=context).name + _(' (copy)')
return super(task, self).copy_data(cr, uid, id, default, context)
diff --git a/addons/project/project_view.xml b/addons/project/project_view.xml
index d91a52f5af1..656c5c724a8 100644
--- a/addons/project/project_view.xml
+++ b/addons/project/project_view.xml
@@ -107,11 +107,12 @@
-
-
+
+
+
diff --git a/addons/project_planning/project_planning.py b/addons/project_planning/project_planning.py
index 2044772e6cc..729a8ee6bbb 100644
--- a/addons/project_planning/project_planning.py
+++ b/addons/project_planning/project_planning.py
@@ -21,7 +21,8 @@
##############################################################################
import time
-import mx.DateTime
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
from osv import fields, osv
from tools.translate import _
@@ -139,7 +140,7 @@ class report_account_analytic_planning(osv.osv):
}
_defaults = {
'date_from': time.strftime('%Y-%m-01'),
- 'date_to': (mx.DateTime.now()+mx.DateTime.RelativeDateTime(months=1, day=1, days=-1)).strftime('%Y-%m-%d'),
+ 'date_to': (datetime.now()+relativedelta(months=1, day=1, days=-1)).strftime('%Y-%m-%d'),
'user_id': lambda self, cr, uid, c: uid,
'state': 'draft',
'business_days': 20,
diff --git a/addons/project_timesheet/report/task_report.py b/addons/project_timesheet/report/task_report.py
index ea454519394..261f4e17c64 100644
--- a/addons/project_timesheet/report/task_report.py
+++ b/addons/project_timesheet/report/task_report.py
@@ -18,7 +18,8 @@
# along with this program. If not, see .
#
##############################################################################
-import mx.DateTime
+from datetime import datetime
+from dateutil.relativedelta import relativedelta
from osv import fields,osv
import tools
@@ -31,7 +32,7 @@ class report_timesheet_task_user(osv.osv):
def _get_task_hours(self, cr, uid, ids, name,args,context):
result = {}
for record in self.browse(cr, uid, ids,context):
- last_date = mx.DateTime.strptime(record.name, '%Y-%m-%d') + mx.DateTime.RelativeDateTime(months=1) - 1
+ last_date = datetime(record.name, '%Y-%m-%d') + relativedelta(months=1) - 1
task_obj=self.pool.get('project.task.work')
task_ids = task_obj.search(cr, uid, [('user_id','=',record.user_id.id),('date','>=',record.name),('date','<=',last_date.strftime('%Y-%m-%d'))])
tsk_hrs = task_obj.read(cr, uid, task_ids, ['hours','date','user_id'])
@@ -45,7 +46,7 @@ class report_timesheet_task_user(osv.osv):
result = {}
sum = 0.0
for record in self.browse(cr, uid, ids, context):
- last_date = mx.DateTime.strptime(record.name, '%Y-%m-%d') + mx.DateTime.RelativeDateTime(months=1) - 1
+ last_date = datetime.strptime(record.name, '%Y-%m-%d') + relativedelta(months=1) - 1
obj=self.pool.get('hr_timesheet_sheet.sheet.day')
sheet_ids = obj.search(cr, uid, [('sheet_id.user_id','=',record.user_id.id),('name','>=',record.name),('name','<=',last_date.strftime('%Y-%m-%d'))])
data_days = obj.read(cr, uid, sheet_ids, ['name','sheet_id.user_id','total_attendance'])
diff --git a/addons/purchase/purchase_view.xml b/addons/purchase/purchase_view.xml
index cbe75dd56d3..e151cdc56f9 100644
--- a/addons/purchase/purchase_view.xml
+++ b/addons/purchase/purchase_view.xml
@@ -365,15 +365,14 @@
0) and maxrecur:
+ for (hour_from,hour_to) in [(item['hour_from'], item['hour_to']) for item in hours_by_cal[id] if item['dayofweek'] == str(dt_from.weekday())]:
+ leave_flag = False
+ if (hour_to>current_hour) and (todo>0):
+ m = max(hour_from, current_hour)
+ if (hour_to-m)>todo:
+ hour_to = m+todo
+ dt_check = dt_from.strftime('%Y-%m-%d')
+ for leave in dt_leave:
+ if dt_check == leave:
+ dt_check = datetime.strptime(dt_check, '%Y-%m-%d') + timedelta(days=1)
+ leave_flag = True
+ if leave_flag:
+ break
+ else:
+ d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
+ d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60))
+ result.append((d1, d2))
+ current_hour = hour_to
+ todo -= (hour_to - m)
+ dt_from += timedelta(days=1)
+ current_hour = 0
+ maxrecur -= 1
+ results[(d, hours, id)] = result
+ return results
+
def interval_get(self, cr, uid, id, dt_from, hours, resource=False, byday=True):
- if not id:
- td = int(hours)*3
- return [(dt_from, dt_from + timedelta(hours=td))]
- dt_leave = self._get_leaves(cr, uid, id, resource)
- todo = hours
- result = []
- maxrecur = 100
- current_hour = dt_from.hour
- while (todo>0) and maxrecur:
- cr.execute("select hour_from,hour_to from resource_calendar_attendance where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.weekday(),id))
- for (hour_from,hour_to) in cr.fetchall():
- leave_flag = False
- if (hour_to>current_hour) and (todo>0):
- m = max(hour_from, current_hour)
- if (hour_to-m)>todo:
- hour_to = m+todo
- dt_check = dt_from.strftime('%Y-%m-%d')
- for leave in dt_leave:
- if dt_check == leave:
- dt_check = datetime.strptime(dt_check, '%Y-%m-%d') + timedelta(days=1)
- leave_flag = True
- if leave_flag:
- break
- else:
- d1 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(m)), int((m%1) * 60))
- d2 = datetime(dt_from.year, dt_from.month, dt_from.day, int(math.floor(hour_to)), int((hour_to%1) * 60))
- result.append((d1, d2))
- current_hour = hour_to
- todo -= (hour_to - m)
- dt_from += timedelta(days=1)
- current_hour = 0
- maxrecur -= 1
- return result
+ res = self.interval_get_multi(cr, uid, [(dt_from.strftime('%Y-%m-%d %H:%M:%S'), hours, id)], resource, byday)[(dt_from.strftime('%Y-%m-%d %H:%M:%S'), hours, id)]
+ return res
def interval_hours_get(self, cr, uid, id, dt_from, dt_to, resource=False):
if not id:
diff --git a/addons/sale/sale_view.xml b/addons/sale/sale_view.xml
index b8a8b64e7ce..eec5847ed92 100644
--- a/addons/sale/sale_view.xml
+++ b/addons/sale/sale_view.xml
@@ -515,9 +515,20 @@ to your configuration: from the sales order, from the pickings, etc.
-
+
-
+
diff --git a/addons/sale_journal/sale_journal_view.xml b/addons/sale_journal/sale_journal_view.xml
index fd09f362000..f4305329d0d 100644
--- a/addons/sale_journal/sale_journal_view.xml
+++ b/addons/sale_journal/sale_journal_view.xml
@@ -303,7 +303,7 @@
@@ -311,7 +311,8 @@
@@ -319,7 +320,8 @@
@@ -327,7 +329,8 @@
@@ -335,7 +338,8 @@
diff --git a/addons/sale_mrp/sale_mrp.py b/addons/sale_mrp/sale_mrp.py
index e8cb0c61f91..c278ef98db1 100644
--- a/addons/sale_mrp/sale_mrp.py
+++ b/addons/sale_mrp/sale_mrp.py
@@ -58,17 +58,17 @@ class mrp_production(osv.osv):
return move_id
res = {}
- productions = self.read(cr, uid, ids, ['id','move_prod_id'])
+ productions = self.browse(cr, uid, ids)
for production in productions:
- res[production['id']] = False
- if production.get('move_prod_id',False):
- parent_move_line = get_parent_move(production['move_prod_id'][0])
+ res[production.id] = False
+ if production.move_prod_id:
+ parent_move_line = get_parent_move(production.move_prod_id)
if parent_move_line:
move = move_obj.browse(cr,uid,parent_move_line)
if field_name == 'name':
- res[production['id']] = move.sale_line_id and move.sale_line_id.order_id.name or False
+ res[production.id] = move.sale_line_id and move.sale_line_id.order_id.name or False
if field_name == 'client_order_ref':
- res[production['id']] = move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False
+ res[production.id] = move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False
return res
_columns = {
@@ -78,4 +78,4 @@ class mrp_production(osv.osv):
mrp_production()
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/stock/stock.py b/addons/stock/stock.py
index d14f891e016..d73a842bedd 100644
--- a/addons/stock/stock.py
+++ b/addons/stock/stock.py
@@ -21,6 +21,8 @@
from datetime import datetime
from dateutil.relativedelta import relativedelta
import time
+from operator import itemgetter
+from itertools import groupby
from osv import fields, osv
from tools.translate import _
@@ -103,66 +105,42 @@ class stock_location(osv.osv):
res[m.id] = _get_one_full_name(m)
return res
- def _product_qty_available(self, cr, uid, ids, field_names, arg, context=None):
- """ Finds real and virtual quantity for product available at particular location.
- @return: Dictionary of values
- """
- res = {}
- for id in ids:
- res[id] = {}.fromkeys(field_names, 0.0)
- if ('product_id' not in context) or not ids:
- return res
- for loc in ids:
- context['location'] = [loc]
- prod = self.pool.get('product.product').browse(cr, uid, context['product_id'], context)
- if 'stock_real' in field_names:
- res[loc]['stock_real'] = prod.qty_available
- if 'stock_virtual' in field_names:
- res[loc]['stock_virtual'] = prod.virtual_available
- return res
-
- def product_detail(self, cr, uid, id, field, context=None):
- """ Finds detail of product like price type, currency and then calculates its price.
- @param field: Field name
- @return: Calculated price
- """
- res = {}
- res[id] = {}
- final_value = 0.0
- field_to_read = 'virtual_available'
- if context is None:
- context = {}
- if field == 'stock_real_value':
- field_to_read = 'qty_available'
- cr.execute('select distinct product_id from stock_move where (location_id=%s) or (location_dest_id=%s)', (id, id))
- result = cr.dictfetchall()
- if result:
- # Choose the right filed standard_price to read
- # Take the user company
- price_type_id = self.pool.get('res.users').browse(cr,uid,uid).company_id.property_valuation_price_type.id
- pricetype = self.pool.get('product.price.type').browse(cr, uid, price_type_id, context=context)
- for r in result:
- c = (context or {}).copy()
- c['location'] = id
- product = self.pool.get('product.product').read(cr, uid, r['product_id'], [field_to_read], context=c)
- # Compute the amount_unit in right currency
- context['currency_id'] = self.pool.get('res.users').browse(cr,uid,uid).company_id.currency_id.id
- amount_unit = self.pool.get('product.product').browse(cr,uid,r['product_id']).price_get(pricetype.field, context)[r['product_id']]
- final_value += (product[field_to_read] * amount_unit)
- return final_value
-
def _product_value(self, cr, uid, ids, field_names, arg, context=None):
- """ Calculates real and virtual stock value of a product.
+ """Computes stock value (real and virtual) for a product, as well as stock qty (real and virtual).
@param field_names: Name of field
@return: Dictionary of values
"""
- result = {}
- for id in ids:
- result[id] = {}.fromkeys(field_names, 0.0)
- for field_name in field_names:
- for loc in ids:
- ret_dict = self.product_detail(cr, uid, loc, field=field_name)
- result[loc][field_name] = ret_dict
+ result = dict([(i, {}.fromkeys(field_names, 0.0)) for i in ids])
+
+ product_product_obj = self.pool.get('product.product')
+
+ cr.execute('select distinct product_id, location_id from stock_move where location_id in %s or location_dest_id in %s', (tuple(ids), tuple(ids)))
+ res_products_by_location = sorted(cr.dictfetchall(), key=itemgetter('location_id'))
+ products_by_location = dict((k, [v['product_id'] for v in itr]) for k, itr in groupby(res_products_by_location, itemgetter('location_id')))
+
+ currency_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.currency_id.id
+ currency_obj = self.pool.get('res.currency')
+ currency = self.pool.get('res.currency').browse(cr, uid, currency_id)
+ currency_obj.round(cr, uid, currency, 300)
+
+ for loc_id, product_ids in products_by_location.items():
+ c = (context or {}).copy()
+ c['location'] = loc_id
+ for prod in product_product_obj.browse(cr, uid, product_ids, context=c):
+ for f in field_names:
+ if f == 'stock_real':
+ result[loc_id][f] += prod.qty_available
+ elif f == 'stock_virtual':
+ result[loc_id][f] += prod.virtual_available
+ elif f == 'stock_real_value':
+ amount = prod.qty_available * prod.standard_price
+ amount = currency_obj.round(cr, uid, currency, amount)
+ result[loc_id][f] += amount
+ elif f == 'stock_virtual_value':
+ amount = prod.virtual_available * prod.standard_price
+ amount = currency_obj.round(cr, uid, currency, amount)
+ result[loc_id][f] += amount
+
return result
_columns = {
@@ -180,8 +158,8 @@ class stock_location(osv.osv):
# temporarily removed, as it's unused: 'allocation_method': fields.selection([('fifo', 'FIFO'), ('lifo', 'LIFO'), ('nearest', 'Nearest')], 'Allocation Method', required=True),
'complete_name': fields.function(_complete_name, method=True, type='char', size=100, string="Location Name"),
- 'stock_real': fields.function(_product_qty_available, method=True, type='float', string='Real Stock', multi="stock"),
- 'stock_virtual': fields.function(_product_qty_available, method=True, type='float', string='Virtual Stock', multi="stock"),
+ 'stock_real': fields.function(_product_value, method=True, type='float', string='Real Stock', multi="stock"),
+ 'stock_virtual': fields.function(_product_value, method=True, type='float', string='Virtual Stock', multi="stock"),
'location_id': fields.many2one('stock.location', 'Parent Location', select=True, ondelete='cascade'),
'child_ids': fields.one2many('stock.location', 'location_id', 'Contains'),
diff --git a/addons/stock/stock_view.xml b/addons/stock/stock_view.xml
index 0f284b7cf45..a7ef71c9acd 100644
--- a/addons/stock/stock_view.xml
+++ b/addons/stock/stock_view.xml
@@ -1851,8 +1851,7 @@
src_model="stock.location"/>
-
-
- tree,form
-
-