[Merge] Merge with main addons

bzr revid: mdi@tinyerp.com-20111221065640-ekqu516ob7fspdbt
This commit is contained in:
Divyesh Makwana (Open ERP)
2011-12-21 12:26:40 +05:30
28 changed files with 227 additions and 199 deletions
@@ -1,4 +1,5 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_audittrail_rule_all_users,audittrail rule all,model_audittrail_rule,base.group_user,1,0,0,0
access_audittrail_rule_all_users,audittrail rule all,model_audittrail_rule,base.group_system,1,1,1,0
access_audittrail_rule_all_access,audittrail rule all,model_audittrail_rule,base.group_erp_manager,1,1,1,0
access_audittrail_log_all_users,audittrail log all,model_audittrail_log,base.group_user,1,0,1,0
access_audittrail_log_line_all_users,audittrail log line all,model_audittrail_log_line,base.group_user,1,0,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_audittrail_rule_all_users audittrail rule all model_audittrail_rule base.group_user base.group_system 1 0 1 0 1 0
3 access_audittrail_rule_all_access audittrail rule all model_audittrail_rule base.group_erp_manager 1 1 1 0
4 access_audittrail_log_all_users audittrail log all model_audittrail_log base.group_user 1 0 1 0
5 access_audittrail_log_line_all_users audittrail log line all model_audittrail_log_line base.group_user 1 0 1 0
+2 -2
View File
@@ -38,7 +38,7 @@
<page string="General">
<group colspan="4" col="4">
<group colspan="2" col="4">
<separator string="Communication" colspan="4"/>
<separator string="Personal Information" colspan="4"/>
<field name="mobile"/>
<field name="email" widget="email"/>
<field name="website"/>
@@ -52,7 +52,7 @@
<form string="Functions and Addresses">
<field name="location_id"/>
<field name="function" />
<separator string="Communication" colspan="4"/>
<separator string="Professional Info" colspan="4"/>
<field name="phone"/>
<field name="fax"/>
<field name="email" widget="email"/>
-2
View File
@@ -468,12 +468,10 @@ class crm_case(crm_base):
self._action(cr, uid, cases, state)
return True
#DEAD Code
def remind_partner(self, cr, uid, ids, context=None, attach=False):
return self.remind_user(cr, uid, ids, context, attach,
destination=False)
#DEAD Code
def remind_user(self, cr, uid, ids, context=None, attach=False, destination=True):
mail_message = self.pool.get('mail.message')
for case in self.browse(cr, uid, ids, context=context):
+1 -1
View File
@@ -125,7 +125,7 @@ class base_action_rule(osv.osv):
"""Gets available states for crm"""
res = super(base_action_rule, self).state_get(cr, uid, context=context)
return res + crm.AVAILABLE_STATES
# Dead Code
def priority_get(self, cr, uid, context=None):
res = super(base_action_rule, self).priority_get(cr, uid, context=context)
return res + crm.AVAILABLE_PRIORITIES
+2 -1
View File
@@ -601,7 +601,8 @@ class EDIMixin(object):
self._name, external_id, value)
# also need_new_ext_id here, but already been set above
model = self.pool.get(model)
res_id, name = model.name_create(cr, uid, value, context=context)
# should use name_create() but e.g. res.partner won't allow it at the moment
res_id = model.create(cr, uid, {model._rec_name: value}, context=context)
target = model.browse(cr, uid, res_id, context=context)
if need_new_ext_id:
ext_id_members = split_external_id(external_id)
+1 -1
View File
@@ -37,7 +37,7 @@ This is the module to manage the accounting chart for France in OpenERP.
Credits: Sistheo Zeekom CrysaLEAD
""",
"depends" : ['base', 'account', 'account_chart', 'base_vat', 'l10n_fr_rib'],
"depends" : ['base_iban', 'account', 'account_chart', 'base_vat', 'l10n_fr_rib'],
"init_xml" : [],
"update_xml" : [
"fr_report_demo.xml",
+12 -11
View File
@@ -41,6 +41,7 @@ class report_custom(report_rml):
rml_obj=report_sxw.rml_parse(cr, uid, product_pool._name,context)
rml_obj.localcontext.update({'lang':context.get('lang',False)})
company_currency = user_pool.browse(cr, uid, uid).company_id.currency_id
company_currency_symbol = company_currency.symbol or company_currency.name
def process_bom(bom, currency_id, factor=1):
xml = '<row>'
sum = 0
@@ -62,7 +63,7 @@ class report_custom(report_rml):
'uom': prod.uom_po_id.id,
'date': time.strftime('%Y-%m-%d'),
})[pricelist.id]
main_sp_price = """<b>"""+rml_obj.formatLang(price)+' '+ company_currency.symbol+"""</b>\r\n"""
main_sp_price = """<b>"""+rml_obj.formatLang(price)+' '+ (company_currency_symbol)+"""</b>\r\n"""
sum += prod_qtty*price
std_price = product_uom_pool._compute_price(cr, uid, prod.uom_id.id, prod.standard_price, to_uom_id=product_uom.id)
main_strd_price = str(std_price) + '\r\n'
@@ -75,11 +76,11 @@ class report_custom(report_rml):
'uom': prod.uom_po_id.id,
'date': time.strftime('%Y-%m-%d'),
})[pricelist.id]
sellers_price += """<i>"""+rml_obj.formatLang(price) +' '+ company_currency.symbol +"""</i>\r\n"""
sellers_price += """<i>"""+rml_obj.formatLang(price) +' '+ (company_currency_symbol) +"""</i>\r\n"""
xml += """<col para='yes'> """+ prod_name +""" </col>
<col para='yes'> """+ main_sp_name + sellers + """ </col>
<col f='yes'>"""+ rml_obj.formatLang(prod_qtty) +' '+ product_uom_name +"""</col>
<col f='yes'>"""+ rml_obj.formatLang(float(main_strd_price)) +' '+ company_currency.symbol +"""</col>
<col f='yes'>"""+ rml_obj.formatLang(float(main_strd_price)) +' '+ (company_currency_symbol) +"""</col>
<col f='yes'>""" + main_sp_price + sellers_price + """</col>'"""
xml += '</row>'
@@ -93,9 +94,9 @@ class report_custom(report_rml):
xml = '<row>'
xml += "<col para='yes'>" + to_xml(workcenter.name) + '</col>'
xml += "<col/>"
xml += """<col f='yes'>"""+rml_obj.formatLang(cost_cycle)+' '+ company_currency.symbol + """</col>"""
xml += """<col f='yes'>"""+rml_obj.formatLang(cost_hour)+' '+ company_currency.symbol + """</col>"""
xml += """<col f='yes'>"""+rml_obj.formatLang(cost_hour + cost_cycle)+' '+ company_currency.symbol + """</col>"""
xml += """<col f='yes'>"""+rml_obj.formatLang(cost_cycle)+' '+ (company_currency_symbol) + """</col>"""
xml += """<col f='yes'>"""+rml_obj.formatLang(cost_hour)+' '+ (company_currency_symbol) + """</col>"""
xml += """<col f='yes'>"""+rml_obj.formatLang(cost_hour + cost_cycle)+' '+ (company_currency_symbol) + """</col>"""
xml += '</row>'
return xml, total
@@ -159,8 +160,8 @@ class report_custom(report_rml):
<col> """ + _('Total Cost of %s %s') % (str(number), product_uom_name) + """: </col>
<col/>
<col f='yes'/>
<col t='yes'>"""+ rml_obj.formatLang(total_strd, digits=purchase_price_digits) +' '+ company_currency.symbol + """</col>
<col t='yes'>"""+ rml_obj.formatLang(total, digits=purchase_price_digits) +' '+ company_currency.symbol + """</col>
<col t='yes'>"""+ rml_obj.formatLang(total_strd, digits=purchase_price_digits) +' '+ (company_currency_symbol) + """</col>
<col t='yes'>"""+ rml_obj.formatLang(total, digits=purchase_price_digits) +' '+ (company_currency_symbol) + """</col>
</row></lines>'"""
else:
bom = bom_pool.browse(cr, uid, bom_id, context=context)
@@ -186,7 +187,7 @@ class report_custom(report_rml):
<col> """ + _('Components Cost of %s %s') % (str(number), product_uom_name) + """: </col>
<col/>
<col t='yes'/>
<col t='yes'>"""+ rml_obj.formatLang(total_strd, digits=purchase_price_digits) +' '+ company_currency.symbol + """</col>
<col t='yes'>"""+ rml_obj.formatLang(total_strd, digits=purchase_price_digits) +' '+ (company_currency_symbol) + """</col>
<col t='yes'></col>
</row></lines>'"""
@@ -204,13 +205,13 @@ class report_custom(report_rml):
<col/>
<col/>
<col/>
<col t='yes'>"""+ rml_obj.formatLang(total2, digits=purchase_price_digits) +' '+ company_currency.symbol +"""</col>
<col t='yes'>"""+ rml_obj.formatLang(total2, digits=purchase_price_digits) +' '+ (company_currency_symbol) +"""</col>
</row></lines>'"""
xml += """<lines style='total'> <row>
<col> """ + _('Total Cost of %s %s') % (str(number), product_uom_name) + """: </col>
<col/>
<col t='yes'/>
<col t='yes'>"""+ rml_obj.formatLang(total_strd+total2, digits=purchase_price_digits) +' '+ company_currency.symbol + """</col>
<col t='yes'>"""+ rml_obj.formatLang(total_strd+total2, digits=purchase_price_digits) +' '+ (company_currency_symbol) + """</col>
<col t='yes'></col>
</row></lines>'"""
+3 -2
View File
@@ -12,13 +12,14 @@ class plugin_handler(osv.osv_memory):
def _make_url(self, cr, uid, res_id, model, context=None):
"""
@param id: on which document the message is pushed
@param res_id: on which document the message is pushed
@param model: name of the document linked with the mail
@return url
"""
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='http://localhost:8069', context=context)
if base_url:
base_url += '/?id=%s&model=%s'%(res_id,model)
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
base_url += '/web/webclient/login?db=%s&login=%s&key=%s#id=%s&model=%s' % (cr.dbname, user.login, user.password, res_id, model)
return base_url
def is_installed(self, cr, uid):
-1
View File
@@ -737,7 +737,6 @@ class product_product(osv.osv):
'expense_pdt': fields.boolean('PoS Cash Output', help="This is a product you can use to take cash from a statement for the point of sale backend, exemple: money lost, transfer to bank, etc."),
'img': fields.binary('Product Image, must be 50x50', help="Use an image size of 50x50."),
'pos_categ_id': fields.many2one('pos.category','PoS Category',
domain="[('type','=','normal')]",
help="If you want to sell this product through the point of sale, select the category it belongs to.")
}
product_product()
+1 -1
View File
@@ -82,7 +82,7 @@ class pos_box_out(osv.osv_memory):
stat_done = statement_obj.browse(cr, uid, done_statmt, context=context)
am = 0.0
product = product_obj.browse(cr, uid, data['product_id'], context=context)
acc_id = product.property_account_income
acc_id = product.property_account_income or product.categ_id.property_account_income_categ
if not acc_id:
raise osv.except_osv(_('Error !'), _('please check that account is set to %s')%(product.name))
if not statement_ids:
-7
View File
@@ -114,13 +114,6 @@ class project(osv.osv):
if task.project_id: result[task.project_id.id] = True
return result.keys()
#dead code
def _get_project_work(self, cr, uid, ids, context=None):
result = {}
for work in self.pool.get('project.task.work').browse(cr, uid, ids, context=context):
if work.task_id and work.task_id.project_id: result[work.task_id.project_id.id] = True
return result.keys()
def unlink(self, cr, uid, ids, *args, **kwargs):
for proj in self.browse(cr, uid, ids):
if proj.tasks:
@@ -72,13 +72,7 @@ class project_phase(osv.osv):
if phase['date_start'] and phase['date_end'] and phase['date_start'] > phase['date_end']:
return False
return True
#dead code
def _get_default_uom_id(self, cr, uid):
model_data_obj = self.pool.get('ir.model.data')
model_data_id = model_data_obj._get_id(cr, uid, 'product', 'uom_hour')
return model_data_obj.read(cr, uid, [model_data_id], ['res_id'])[0]['res_id']
#dead code
def _compute_progress(self, cr, uid, ids, field_name, arg, context=None):
res = {}
if not ids:
+2 -45
View File
@@ -254,6 +254,7 @@ class project_scrum_task(osv.osv):
for task in line.tasks_id:
result[task.id] = True
return result.keys()
_columns = {
'product_backlog_id': fields.many2one('project.scrum.product.backlog', 'Product Backlog',help="Related product backlog that contains this task. Used in SCRUM methodology"),
'sprint_id': fields.related('product_backlog_id','sprint_id', type='many2one', relation='project.scrum.sprint', string='Sprint',
@@ -262,12 +263,7 @@ class project_scrum_task(osv.osv):
'project.scrum.product.backlog': (_get_task, ['sprint_id'], 10)
}),
}
#dead code
def onchange_backlog_id(self, cr, uid, backlog_id=False):
if not backlog_id:
return {}
project_id = self.pool.get('project.scrum.product.backlog').browse(cr, uid, backlog_id).project_id.id
return {'value': {'project_id': project_id}}
project_scrum_task()
class project_scrum_meeting(osv.osv):
@@ -292,45 +288,6 @@ class project_scrum_meeting(osv.osv):
_defaults = {
'date' : lambda *a: time.strftime('%Y-%m-%d'),
}
# dead code
def button_send_to_master(self, cr, uid, ids, context=None):
meeting_id = self.browse(cr, uid, ids, context=context)[0]
if meeting_id and meeting_id.sprint_id.scrum_master_id.user_email:
res = self.email_send(cr, uid, ids, meeting_id.sprint_id.scrum_master_id.user_email)
if not res:
raise osv.except_osv(_('Error !'), _('Email notification could not be sent to the scrum master %s') % meeting_id.sprint_id.scrum_master_id.name)
else:
raise osv.except_osv(_('Error !'), _('Please provide email address for scrum master defined on sprint.'))
return True
#dead code
def button_send_product_owner(self, cr, uid, ids, context=None):
if context is None:
context = {}
context.update({'button_send_product_owner': True})
meeting_id = self.browse(cr, uid, ids, context=context)[0]
if meeting_id.sprint_id.product_owner_id.user_email:
res = self.email_send(cr,uid,ids,meeting_id.sprint_id.product_owner_id.user_email)
if not res:
raise osv.except_osv(_('Error !'), _('Email notification could not be sent to the product owner %s') % meeting_id.sprint_id.product_owner_id.name)
else:
raise osv.except_osv(_('Error !'), _('Please provide email address for product owner defined on sprint.'))
return True
#dead code
def email_send(self, cr, uid, ids, email, context=None):
mail_message_obj = self.pool.get('mail.message')
meeting_id = self.browse(cr, uid, ids, context=context)[0]
user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
user_email = user.user_email or tools.config.get('email_from', False)
body = _("Hello %s,\n \nI am sending you Daily Meeting Details of date %s for the Sprint %s\n") %(meeting_id.sprint_id.scrum_master_id.name, meeting_id.date, meeting_id.sprint_id.name)
body += _('\n* Tasks since yesterday:\n_______________________\n%s\n\n* Task for Today:\n_______________________ \n%s\n\n* Blocks encountered:\n_______________________ \n\n%s') %(meeting_id.question_yesterday,meeting_id.question_today, meeting_id.question_blocks or _('No Blocks'))
body += _("\n\nThank you,\n%s") % user.name
sub_name = meeting_id.name or _('Scrum Meeting of %s') % meeting_id.date
flag = mail_message_obj.schedule_with_attach(cr, uid, user_email , [email], sub_name, body, model='project.scrum.meeting', res_id=meeting_id.id, context=context)
if not flag:
return False
return True
project_scrum_meeting()
-27
View File
@@ -35,14 +35,6 @@ from osv.orm import browse_record, browse_null
#
class purchase_order(osv.osv):
def _calc_amount(self, cr, uid, ids, prop, unknow_none, unknow_dict):
res = {}
for order in self.browse(cr, uid, ids):
res[order.id] = 0
for oline in order.order_line:
res[order.id] += oline.price_unit * oline.product_qty
return res
def _amount_all(self, cr, uid, ids, field_name, arg, context=None):
res = {}
cur_obj=self.pool.get('res.currency')
@@ -300,25 +292,6 @@ class purchase_order(osv.osv):
for id in ids:
self.write(cr, uid, [id], {'state' : 'confirmed', 'validator' : uid})
return True
# Dead code:
def wkf_warn_buyer(self, cr, uid, ids):
self.write(cr, uid, ids, {'state' : 'wait', 'validator' : uid})
request = pooler.get_pool(cr.dbname).get('res.request')
for po in self.browse(cr, uid, ids):
managers = []
for oline in po.order_line:
manager = oline.product_id.product_manager
if manager and not (manager.id in managers):
managers.append(manager.id)
for manager_id in managers:
request.create(cr, uid,{
'name' : _("Purchase amount over the limit"),
'act_from' : uid,
'act_to' : manager_id,
'body': _('Somebody has just confirmed a purchase with an amount over the defined limit'),
'ref_partner_id': po.partner_id.id,
'ref_doc1': 'purchase.order,%d' % (po.id,),
})
def _prepare_inv_line(self, cr, uid, account_id, order_line, context=None):
"""Collects require data from purchase order line that is used to create invoice line
+1 -54
View File
@@ -27,60 +27,7 @@ import pooler
class order(report_sxw.rml_parse):
def __init__(self, cr, uid, name, context):
super(order, self).__init__(cr, uid, name, context=context)
self.localcontext.update({
'time': time,
'get_line_tax': self._get_line_tax,
'get_tax': self._get_tax,
'get_product_code': self._get_product_code,
})
#dead code
def _get_line_tax(self, line_obj):
self.cr.execute("SELECT tax_id FROM purchase_order_taxe WHERE order_line_id=%s", (line_obj.id))
res = self.cr.fetchall() or None
if not res:
return ""
if isinstance(res, list):
tax_ids = [t[0] for t in res]
else:
tax_ids = res[0]
res = [tax.name for tax in pooler.get_pool(self.cr.dbname).get('account.tax').browse(self.cr, self.uid, tax_ids)]
return ",\n ".join(res)
#dead code
def _get_tax(self, order_obj):
self.cr.execute("SELECT DISTINCT tax_id FROM purchase_order_taxe, purchase_order_line, purchase_order \
WHERE (purchase_order_line.order_id=purchase_order.id) AND (purchase_order.id=%s)", (order_obj.id))
res = self.cr.fetchall() or None
if not res:
return []
if isinstance(res, list):
tax_ids = [t[0] for t in res]
else:
tax_ids = res[0]
tax_obj = pooler.get_pool(self.cr.dbname).get('account.tax')
res = []
for tax in tax_obj.browse(self.cr, self.uid, tax_ids):
self.cr.execute("SELECT DISTINCT order_line_id FROM purchase_order_line, purchase_order_taxe \
WHERE (purchase_order_taxe.tax_id=%s) AND (purchase_order_line.order_id=%s)", (tax.id, order_obj.id))
lines = self.cr.fetchall() or None
if lines:
if isinstance(lines, list):
line_ids = [l[0] for l in lines]
else:
line_ids = lines[0]
base = 0
for line in pooler.get_pool(self.cr.dbname).get('purchase.order.line').browse(self.cr, self.uid, line_ids):
base += line.price_subtotal
res.append({'code':tax.name,
'base':base,
'amount':base*tax.amount})
return res
#dead code
def _get_product_code(self, product_id, partner_id):
product_obj=pooler.get_pool(self.cr.dbname).get('product.product')
return product_obj._product_code(self.cr, self.uid, [product_id], name=None, arg=None, context={'partner_id': partner_id})[product_id]
self.localcontext.update({'time': time})
report_sxw.report_sxw('report.purchase.order','purchase.order','addons/purchase/report/order.rml',parser=order)
+4
View File
@@ -45,6 +45,10 @@ It also manages the leaves of every resource.
],
'demo_xml': ['resource_demo.xml'
],
'test': [
'test/resource.yml',
'test/duplicate_resource.yml',
],
'installable': True,
'active': False,
'certificate': '00746371192190459469',
+50 -10
View File
@@ -22,7 +22,6 @@
from datetime import datetime, timedelta
import math
from faces import *
from new import classobj
from osv import fields, osv
from tools.translate import _
@@ -44,9 +43,12 @@ class resource_calendar(osv.osv):
}
def working_hours_on_day(self, cr, uid, resource_calendar_id, day, context=None):
"""
"""Calculates the Working Total Hours based on Resource Calendar and
given working day (datetime object).
@param resource_calendar_id: resource.calendar browse record
@param day: datetime object
@return: returns the working hours (as float) men should work on the given day if is in the attendance_ids of the resource_calendar_id (i.e if that day is a working day), returns 0.0 otherwise
"""
res = 0.0
@@ -56,9 +58,16 @@ class resource_calendar(osv.osv):
return res
def _get_leaves(self, cr, uid, id, resource):
"""Private Method to Calculate resource Leaves days
@param id: resource calendar id
@param resource: resource id for which leaves will ew calculated
@return : returns the list of dates, where resource on leave in
resource.calendar.leaves object (e.g.['%Y-%m-%d', '%Y-%m-%d'])
"""
resource_cal_leaves = self.pool.get('resource.calendar.leaves')
dt_leave = []
resource_leave_ids = resource_cal_leaves.search(cr, uid, [('calendar_id','=',id), '|', ('resource_id','=',False), ('resource_id','=',resource)])
#res_leaves = resource_cal_leaves.read(cr, uid, resource_leave_ids, ['date_from', 'date_to'])
res_leaves = resource_cal_leaves.browse(cr, uid, resource_leave_ids)
@@ -73,6 +82,21 @@ class resource_calendar(osv.osv):
return dt_leave
def interval_min_get(self, cr, uid, id, dt_from, hours, resource=False):
"""
Calculates the working Schedule from supplied from date to till hours
will be satisfied based or resource calendar id. If resource is also
given then it will consider the resource leave also and than will
calculates resource working schedule
@param dt_from: datetime object, start of working scheduled
@param hours: float, total number working hours needed scheduled from
start date
@param resource : Optional Resource id, if supplied than resource leaves
will also taken into consideration for calculating working
schedule.
@return : List datetime object of working schedule based on supplies
params
"""
if not id:
td = int(hours)*3
return [(dt_from - timedelta(hours=td), dt_from)]
@@ -162,10 +186,32 @@ class resource_calendar(osv.osv):
return results
def interval_get(self, cr, uid, id, dt_from, hours, resource=False, byday=True):
"""Calculates Resource Working Internal Timing Based on Resource Calendar.
@param dt_from: start resource schedule calculation.
@param hours : total number of working hours to be scheduled.
@param resource: optional resource id, If supplied it will take care of
resource leave while scheduling.
@param byday: boolean flag bit enforce day wise scheduling
@return : list of scheduled working timing based on resource calendar.
"""
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):
""" Calculates the Total Working hours based on given start_date to
end_date, If resource id is supplied that it will consider the source
leaves also in calculating the hours.
@param dt_from : date start to calculate hours
@param dt_end : date end to calculate hours
@param resource: optional resource id, If given resource leave will be
considered.
@return : Total number of working hours based dt_from and dt_end and
resource if supplied.
"""
if not id:
return 0.0
dt_leave = self._get_leaves(cr, uid, id, resource)
@@ -290,6 +336,7 @@ class resource_resource(osv.osv):
def compute_vacation(self, cr, uid, calendar_id, resource_id=False, resource_calendar=False, context=None):
"""
Compute the vacation from the working calendar of the resource.
@param calendar_id : working calendar of the project
@param resource_id : resource working on phase/task
@param resource_calendar : working calendar of the resource
@@ -366,13 +413,6 @@ class resource_resource(osv.osv):
wktime_cal.append((non_working[:-1], time_range))
return wktime_cal
#TODO: Write optimized alogrothem for resource availability. : Method Yet not implemented
def check_availability(self, cr, uid, ids, start, end, context=None):
if context == None:
contex = {}
allocation = {}
return allocation
resource_resource()
class resource_calendar_leaves(osv.osv):
+53 -11
View File
@@ -5,73 +5,73 @@
<!-- Example employee -->
<record id="timesheet_group1" model="resource.calendar">
<field name="name">38 Hours/Week</field>
<field name="name">45 Hours/Week</field>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_mon1">
<field name="name">Monday morning</field>
<field name="dayofweek">0</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_mon2">
<field name="name">Monday evening</field>
<field name="dayofweek">0</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_tue1">
<field name="name">Tuesday morning</field>
<field name="dayofweek">1</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_tue2">
<field name="name">Tuesday evening</field>
<field name="dayofweek">1</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_wed1">
<field name="name">Wednesday morning</field>
<field name="dayofweek">2</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_wed2">
<field name="name">Wednesday evening</field>
<field name="dayofweek">2</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_thu1">
<field name="name">Thursday morning</field>
<field name="dayofweek">3</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_thu2">
<field name="name">Thursday evening</field>
<field name="hour_from">13</field>
<field name="hour_to">18</field>
<field name="dayofweek">3</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_fri1">
<field name="name">Friday morning</field>
<field name="dayofweek">4</field>
<field name="hour_from">08</field>
<field name="hour_to">12</field>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record model="resource.calendar.attendance">
<record model="resource.calendar.attendance" id="calendar_attendance_fri2">
<field name="name">Friday evening</field>
<field name="dayofweek">4</field>
<field name="hour_from">13</field>
@@ -79,5 +79,47 @@
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record id="resource_analyst" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="base.user_root"/>
<field name="name">Analyst</field>
<field eval="1" name="active"/>
<field name="calendar_id" ref="timesheet_group1"/>
<field name="resource_type">user</field>
</record>
<record id="resource_designer" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="base.user_demo"/>
<field name="name">Designer</field>
<field eval="1" name="active"/>
<field name="calendar_id" ref="timesheet_group1"/>
<field name="resource_type">user</field>
</record>
<record id="resource_developer" model="resource.resource">
<field eval="1.0" name="time_efficiency"/>
<field name="user_id" ref="base.user_demo"/>
<field name="name">Developer</field>
<field eval="1" name="active"/>
<field name="calendar_id" ref="timesheet_group1"/>
<field name="resource_type">user</field>
</record>
<record id="resource_analyst_leaves_demoleave1" model="resource.calendar.leaves">
<field name="name">2 Hours On Leave</field>
<field name="resource_id" ref="resource_analyst"/>
<field name="date_from" eval="time.strftime('%Y-%m-%d 08:00:00')"/>
<field name="date_to" eval="time.strftime('%Y-%m-%d 11:00:00')"/>
<field name="calendar_id" ref="timesheet_group1"/>
</record>
<record id="resource_dummyleave" model="resource.calendar.leaves">
<field name="name">Dummy Resource Leave</field>
<field name="resource_id" ref="resource_analyst"/>
<field name="date_from" eval="time.strftime('%Y-%m-%d 08:00:00')"/>
<field name="date_to" eval="time.strftime('%Y-%m-%d 11:00:00')"/>
</record>
</data>
</openerp>
@@ -0,0 +1,6 @@
-
I duplicate the resource "Analyst"
-
!python {model: resource.resource}: |
copied_id = self.copy(cr, uid, ref("resource_analyst"))
assert copied_id, "Unable to Duplicate Resource"
+59
View File
@@ -0,0 +1,59 @@
-
In order to test resource.
-
I assign working calendar '45 Hours/Week' to human resource.
-
!python {model: resource.resource}: |
self.write(cr, uid, [ref('resource_analyst'), ref('resource_designer'), ref('resource_developer')], {'calendar_id' : ref('timesheet_group1'), 'resource_type': 'user'})
-
I had Project of OpenERP Integration of 50 Hours with three human resource assigned on it. I have started project from this week start.
-
First, I generate the resource detail and check the resource Efficiency assigned.
-
!python {model: resource.resource}: |
resources = self.generate_resources(cr, uid, [ref('base.user_root'),ref('base.user_demo')], ref('timesheet_group1'), context)
for resource in resources.values():
assert resource.get('efficiency', 0.0) == 1.0, 'Invalid resource generated.'
-
I check per day work hour availability of the Resource based on Working Calendar Assigned to each resource, for first day of the week.
-
!python {model: resource.resource}: |
calendar_pool = self.pool.get('resource.calendar')
resources = self.browse(cr, uid, [ref('resource_analyst'), ref('resource_designer'), ref('resource_developer')], context)
from datetime import datetime, timedelta
now = datetime.now()
dt = now - timedelta(days=now.weekday())
for resource in resources:
result = calendar_pool.working_hours_on_day(cr, uid, resource.calendar_id, dt, context)
assert result == 9.0, 'Wrong calculation of day work hour availability of the Resource.'
-
Now, resource "Developer" drafted leave on Thursday in this week.
-
!python {model: resource.calendar.leaves}: |
from datetime import datetime,timedelta
now = datetime.now()
dt = (now - timedelta(days=now.weekday()) ) + timedelta(days=3)
self.write(cr, uid, [ref('resource_dummyleave')], {'resource_id': ref('resource_developer'), 'calendar_id': ref('timesheet_group1'), 'date_from': dt.strftime("%Y-%m-%d 09:00:00"), 'date_to': dt.strftime("%Y-%m-%d 18:00:00")})
-
I check Actual working hours on resource 'Developer' from this week
-
!python {model: resource.calendar}: |
from datetime import datetime, timedelta
now = datetime.now()
dt_from = now - timedelta(days=now.weekday())
dt_to = dt_from+ timedelta(days=6)
hours = self.interval_hours_get(cr, uid, ref('timesheet_group1'), dt_from, dt_to, resource=ref('resource_developer'))
assert hours > 27 , 'Invalid Total Week working hour calculated'
-
Project Analysis work is of 20 hours which will start from Week start so i will calculate working schedule for resource Analyst for the same.
-
!python {model: resource.calendar}: |
from datetime import datetime, timedelta
now = datetime.now()
work_intreval = self.interval_min_get(cr, uid, ref('timesheet_group1'), now, 20.0, resource=ref('resource_designer'))
assert len(work_intreval) >= 5, 'Wrong Schedule Calculated'
+6 -2
View File
@@ -771,6 +771,11 @@ class sale_order(osv.osv):
self.pool.get('procurement.order').write(cr, uid, [proc_id], {'product_qty': mov.product_qty, 'product_uos_qty': mov.product_uos_qty})
return True
def _get_date_planned(self, cr, uid, order, line, start_date, *args):
date_planned = datetime.strptime(start_date, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=line.delay or 0.0)
date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
return date_planned
def _create_pickings_and_procurements(self, cr, uid, order, order_lines, picking_id=False, *args):
"""Create the required procurements to supply sale order lines, also connecting
the procurements to appropriate stock moves in order to bring the goods to the
@@ -799,8 +804,7 @@ class sale_order(osv.osv):
if line.state == 'done':
continue
date_planned = datetime.strptime(order.date_order, DEFAULT_SERVER_DATE_FORMAT) + relativedelta(days=line.delay or 0.0)
date_planned = (date_planned - timedelta(days=order.company_id.security_lead)).strftime(DEFAULT_SERVER_DATETIME_FORMAT)
date_planned = self._get_date_planned(cr, uid, order, line, order.date_order, *args)
if line.product_id:
if line.product_id.product_tmpl_id.type in ('product', 'consu'):
+1
View File
@@ -58,3 +58,4 @@ access_product_pricelist_type_sale_manager,product.pricelist.type salemanager,pr
access_product_pricelist_sale_manager,product.pricelist salemanager,product.model_product_pricelist,base.group_sale_manager,1,1,1,1
access_product_group_res_partner_sale_manager,res_partner group_sale_manager,base.model_res_partner,base.group_sale_manager,1,1,1,0
access_product_pricelist_version_sale_manager,product.pricelist.version sale_manager,product.model_product_pricelist_version,base.group_sale_manager,1,1,1,1
access_account_invoice_report_salesman,account.invoice.report salesman,account.model_account_invoice_report,base.group_sale_salesman,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
58 access_product_pricelist_sale_manager product.pricelist salemanager product.model_product_pricelist base.group_sale_manager 1 1 1 1
59 access_product_group_res_partner_sale_manager res_partner group_sale_manager base.model_res_partner base.group_sale_manager 1 1 1 0
60 access_product_pricelist_version_sale_manager product.pricelist.version sale_manager product.model_product_pricelist_version base.group_sale_manager 1 1 1 1
61 access_account_invoice_report_salesman account.invoice.report salesman account.model_account_invoice_report base.group_sale_salesman 1 0 0 0
+1 -1
View File
@@ -1,2 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_account_invoice_report_salesman,account.invoice.report salesman,account.model_account_invoice_report,base.group_sale_salesman,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2
+1 -1
View File
@@ -9,7 +9,7 @@
<field name="name">sale.order.form.inherit_1</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="priority">30</field>
<field name="priority">1000</field>
<field name="type">form</field>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='order_line']" position="replace">
+7 -3
View File
@@ -95,10 +95,13 @@ class share_wizard(osv.osv_memory):
# NOTE: take _ids in parameter to allow usage through browse_record objects
base_url = self.pool.get('ir.config_parameter').get_param(cr, uid, 'web.base.url', default='', context=context)
if base_url:
base_url += '/?db=%(dbname)s&login=%(login)s'
base_url += '/web/webclient/login?db=%(dbname)s&login=%(login)s'
extra = context and context.get('share_url_template_extra_arguments')
if extra:
base_url += '&' + '&'.join('%s=%%(%s)s' % (x,x) for x in extra)
hash_ = context and context.get('share_url_template_hash_arguments')
if hash_:
base_url += '#' + '&'.join('%s=%%(%s)s' % (x,x) for x in hash_)
return base_url
def _share_root_url(self, cr, uid, ids, _fieldname, _args, context=None):
@@ -156,9 +159,10 @@ class share_wizard(osv.osv_memory):
result = dict.fromkeys(ids, '')
for this in self.browse(cr, uid, ids, context=context):
if this.result_line_ids:
ctx = dict(context, share_url_template_extra_arguments=['key'])
ctx = dict(context, share_url_template_extra_arguments=['key'],
share_url_template_hash_arguments=['action_id'])
user = this.result_line_ids[0]
data = dict(dbname=cr.dbname, login=user.login, key=user.password)
data = dict(dbname=cr.dbname, login=user.login, key=user.password, action_id=this.action_id.id)
result[this.id] = this.share_url_template(context=ctx) % data
return result
Binary file not shown.
@@ -169,6 +169,16 @@ function searchmail()
}
function url_for(model, id) {
var base = getWebServerURL(),
db = getDbName(),
login = getusername(),
password = getPassword();
return base + '/web/webclient/login?db='+db+'&login='+login+'&key='+password+'#model='+model+'&id='+id;
}
var openPartnerHandler = {
onResult: function(client, context, result) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserAccess');
@@ -186,15 +196,11 @@ var openPartnerHandler = {
}
if(strlSearchResult=="partner_id"){
partner_id = strlSearchResultValue;
weburl = getWebServerURL();
if (parseInt(partner_id) > 0){
//Encode the url and form an url to have menu in webclient
var encoded = encodeURIComponent("/openerp/form/view?model=res.partner&id="+partner_id)
var t = weburl + "?next=" + encoded
var messenger = Components.classes["@mozilla.org/messenger;1"].createInstance();
messenger = messenger.QueryInterface(Components.interfaces.nsIMessenger);
messenger.launchExternalURL(t);
messenger.launchExternalURL(url_for('res.partner', partner_id));
}
else{
alert("Partner is not Available.");
@@ -298,7 +304,6 @@ var listDocumentHandler = {
var res = result.QueryInterface(Components.interfaces.nsISupportsArray);
res_id = res.QueryElementAt(1, Components.interfaces.nsISupportsPRInt32);
model = res.QueryElementAt(0, Components.interfaces.nsISupportsCString);
weburl = getWebServerURL();
if(res_id==0)
{
alert("Document is not available.");
@@ -307,11 +312,9 @@ var listDocumentHandler = {
else
{
var encoded = encodeURIComponent("/openerp/form/view?model=" + model +"&id=" + res_id)
var t = weburl + "?next=" + encoded
var messenger = Components.classes["@mozilla.org/messenger;1"].createInstance();
messenger = messenger.QueryInterface(Components.interfaces.nsIMessenger);
messenger.launchExternalURL(t);
messenger.launchExternalURL(url_for(model, res_id));
}
},