[MERGE] forward port of branch saas-1 up to revid 8772 chs@openerp.com-20130910122113-171osvcukxffxcry

bzr revid: chs@openerp.com-20130910124803-wxkb8gkz1tub5qjf
This commit is contained in:
Christophe Simonis 2013-09-10 14:48:03 +02:00
commit 3fa90321e1
36 changed files with 207 additions and 93 deletions

View File

@ -137,16 +137,27 @@ class account_account_type(osv.osv):
_name = "account.account.type"
_description = "Account Type"
def _get_current_report_type(self, cr, uid, ids, name, arg, context=None):
def _get_financial_report_ref(self, cr, uid, context=None):
obj_data = self.pool.get('ir.model.data')
obj_financial_report = self.pool.get('account.financial.report')
financial_report_ref = {}
for key, financial_report in [
('asset','account_financial_report_assets0'),
('liability','account_financial_report_liability0'),
('income','account_financial_report_income0'),
('expense','account_financial_report_expense0'),
]:
try:
financial_report_ref[key] = obj_financial_report.browse(cr, uid,
obj_data.get_object_reference(cr, uid, 'account', financial_report)[1],
context=context)
except ValueError:
pass
return financial_report_ref
def _get_current_report_type(self, cr, uid, ids, name, arg, context=None):
res = {}
financial_report_ref = {
'asset': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_assets0')[1], context=context),
'liability': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_liability0')[1], context=context),
'income': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_income0')[1], context=context),
'expense': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_expense0')[1], context=context),
}
financial_report_ref = self._get_financial_report_ref(cr, uid, context=context)
for record in self.browse(cr, uid, ids, context=context):
res[record.id] = 'none'
for key, financial_report in financial_report_ref.items():
@ -157,15 +168,9 @@ class account_account_type(osv.osv):
def _save_report_type(self, cr, uid, account_type_id, field_name, field_value, arg, context=None):
field_value = field_value or 'none'
obj_data = self.pool.get('ir.model.data')
obj_financial_report = self.pool.get('account.financial.report')
#unlink if it exists somewhere in the financial reports related to BS or PL
financial_report_ref = {
'asset': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_assets0')[1], context=context),
'liability': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_liability0')[1], context=context),
'income': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_income0')[1], context=context),
'expense': obj_financial_report.browse(cr, uid, obj_data.get_object_reference(cr, uid, 'account','account_financial_report_expense0')[1], context=context),
}
financial_report_ref = self._get_financial_report_ref(cr, uid, context=context)
for key, financial_report in financial_report_ref.items():
list_ids = [x.id for x in financial_report.account_type_ids]
if account_type_id in list_ids:
@ -1258,6 +1263,10 @@ class account_move(osv.osv):
return [('id', 'in', tuple(ids))]
return [('id', '=', '0')]
def _get_move_from_lines(self, cr, uid, ids, context=None):
line_obj = self.pool.get('account.move.line')
return [line.move_id.id for line in line_obj.browse(cr, uid, ids, context=context)]
_columns = {
'name': fields.char('Number', size=64, required=True),
'ref': fields.char('Reference', size=64),
@ -1267,7 +1276,10 @@ class account_move(osv.osv):
help='All manually created new journal entries are usually in the status \'Unposted\', but you can set the option to skip that status on the related journal. In that case, they will behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' status.'),
'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store={
_name: (lambda self, cr,uid,ids,c: ids, ['line_id'], 10),
'account.move.line': (_get_move_from_lines, ['partner_id'],10)
}),
'amount': fields.function(_amount_compute, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount),
'date': fields.date('Date', required=True, states={'posted':[('readonly',True)]}, select=True),
'narration':fields.text('Internal Note'),
@ -1633,9 +1645,11 @@ class account_move(osv.osv):
else:
# We can't validate it (it's unbalanced)
# Setting the lines as draft
obj_move_line.write(cr, uid, line_ids, {
'state': 'draft'
}, context, check=False)
not_draft_line_ids = list(set(line_ids) - set(line_draft_ids))
if not_draft_line_ids:
obj_move_line.write(cr, uid, not_draft_line_ids, {
'state': 'draft'
}, context, check=False)
# Create analytic lines for the valid moves
for record in valid_moves:
obj_move_line.create_analytic_lines(cr, uid, [line.id for line in record.line_id], context)

View File

@ -1431,6 +1431,7 @@ class account_invoice_line(osv.osv):
_name = "account.invoice.line"
_description = "Invoice Line"
_order = "invoice_id,sequence,id"
_columns = {
'name': fields.text('Description', required=True),
'origin': fields.char('Source Document', size=256, help="Reference of the document that produced this invoice."),
@ -1467,6 +1468,7 @@ class account_invoice_line(osv.osv):
'discount': 0.0,
'price_unit': _price_unit_default,
'account_id': _default_account_id,
'sequence': 10,
}
def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False):

View File

@ -192,6 +192,7 @@
<page string="Invoice">
<field context="{'partner_id': partner_id, 'price_type': context.get('price_type') or False, 'type': type}" name="invoice_line">
<tree string="Invoice lines" editable="bottom">
<field name="sequence" widget="handle" />
<field name="product_id"
on_change="product_id_change(product_id, uos_id, quantity, name, parent.type, parent.partner_id, parent.fiscal_position, price_unit, parent.currency_id, context, parent.company_id)"/>
<field name="name"/>

View File

@ -7,16 +7,16 @@
<field name="model">account.analytic.chart</field>
<field name="arch" type="xml">
<form string="Analytic Account Charts" version="7.0">
<header>
<button name="analytic_account_chart_open_window" string="Open Charts" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</header>
<group string="Select the Period for Analysis" col="4">
<field name="from_date"/>
<field name="to_date"/>
<label string="(Keep empty to open the current situation)" colspan="4"/>
</group>
<footer>
<button name="analytic_account_chart_open_window" string="Open Charts" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>

View File

@ -38,6 +38,7 @@ class report_account_common(report_sxw.rml_parse, common_report_header):
'get_filter': self._get_filter,
'get_start_date':self._get_start_date,
'get_end_date':self._get_end_date,
'get_target_move': self._get_target_move,
})
self.context = context

View File

@ -166,11 +166,12 @@
<para style="Standard">
<font color="white"> </font>
</para>
<blockTable colWidths="163.0,163.0,163.0" style="Table2_header">
<blockTable colWidths="122.0,122.0,122.0,122.0" style="Table2_header">
<tr>
<td><para style="terp_tblheader_General_Centre">Chart of Accounts</para></td>
<td><para style="terp_tblheader_General_Centre">Fiscal Year</para></td>
<td><para style="terp_tblheader_General_Centre">Filter By [[ get_filter(data)!='No Filters' and get_filter(data) ]]</para></td>
<td><para style="terp_tblheader_General_Centre">Target Moves</para></td>
</tr>
<tr>
<td><para style="terp_default_Centre_8">[[ get_account(data) or removeParentNode('para') ]]</para></td>
@ -197,6 +198,10 @@
</tr>
</blockTable>
</td>
<td>
<para style="terp_default_Centre_8">[[ get_target_move(data) ]]</para>
</td>
</tr>
</blockTable>
<para style="Standard">

View File

@ -54,7 +54,7 @@ class accounting_report(osv.osv_memory):
'target_move': 'posted',
'account_report_id': _get_account_report,
}
def _build_comparison_context(self, cr, uid, ids, data, context=None):
if context is None:
context = {}
@ -62,6 +62,7 @@ class accounting_report(osv.osv_memory):
result['fiscalyear'] = 'fiscalyear_id_cmp' in data['form'] and data['form']['fiscalyear_id_cmp'] or False
result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
result['chart_account_id'] = 'chart_account_id' in data['form'] and data['form']['chart_account_id'] or False
result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
if data['form']['filter_cmp'] == 'filter_date':
result['date_from'] = data['form']['date_from_cmp']
result['date_to'] = data['form']['date_to_cmp']
@ -86,7 +87,7 @@ class accounting_report(osv.osv_memory):
return res
def _print_report(self, cr, uid, ids, data, context=None):
data['form'].update(self.read(cr, uid, ids, ['date_from_cmp', 'debit_credit', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter'], context=context)[0])
data['form'].update(self.read(cr, uid, ids, ['date_from_cmp', 'debit_credit', 'date_to_cmp', 'fiscalyear_id_cmp', 'period_from_cmp', 'period_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter','target_move'], context=context)[0])
return {
'type': 'ir.actions.report.xml',
'report_name': 'account.financial.report',

View File

@ -157,8 +157,8 @@ class account_invoice_refund(osv.osv_memory):
for line in movelines:
if line.account_id.id == inv.account_id.id:
to_reconcile_ids[line.account_id.id] = [line.id]
if type(line.reconcile_id) != osv.orm.browse_null:
reconcile_obj.unlink(cr, uid, line.reconcile_id.id)
if line.reconcile_id:
line.reconcile_id.unlink()
inv_obj.signal_invoice_open(cr, uid, [refund.id])
refund = inv_obj.browse(cr, uid, refund_id[0], context=context)
for tmpline in refund.move_id.line_id:

View File

@ -154,6 +154,7 @@ class account_common_report(osv.osv_memory):
result['fiscalyear'] = 'fiscalyear_id' in data['form'] and data['form']['fiscalyear_id'] or False
result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
result['chart_account_id'] = 'chart_account_id' in data['form'] and data['form']['chart_account_id'] or False
result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
if data['form']['filter'] == 'filter_date':
result['date_from'] = data['form']['date_from']
result['date_to'] = data['form']['date_to']

View File

@ -295,10 +295,6 @@ class account_analytic_account(osv.osv):
args=[]
if context is None:
context={}
if context.get('current_model') == 'project.project':
project_obj = self.pool.get("account.analytic.account")
project_ids = project_obj.search(cr, uid, args)
return self.name_get(cr, uid, project_ids, context=context)
if name:
account_ids = self.search(cr, uid, [('code', '=', name)] + args, limit=limit, context=context)
if not account_ids:

View File

@ -578,8 +578,7 @@ property or property parameter."),
def do_accept(self, cr, uid, ids, context=None, *args):
"""
Update state of invitation as Accepted and if the invited user is other
then event user it will make a copy of this event for invited user.
Marks event invitation as Accepted.
@param cr: the current row, from the database cursor
@param uid: the current user's ID for security checks
@param ids: list of calendar attendee's IDs
@ -589,15 +588,7 @@ property or property parameter."),
if context is None:
context = {}
for vals in self.browse(cr, uid, ids, context=context):
if vals.ref and vals.ref.user_id:
mod_obj = self.pool[vals.ref._name]
res=mod_obj.read(cr,uid,[vals.ref.id],['duration','class'],context)
defaults = {'user_id': vals.user_id.id, 'organizer_id': vals.ref.user_id.id,'duration':res[0]['duration'],'class':res[0]['class']}
mod_obj.copy(cr, uid, vals.ref.id, default=defaults, context=context)
self.write(cr, uid, vals.id, {'state': 'accepted'}, context)
return True
return self.write(cr, uid, ids, {'state': 'accepted'}, context)
def do_decline(self, cr, uid, ids, context=None, *args):
"""
@ -1126,12 +1117,14 @@ rule or repeating pattern of time to exclude from the recurring rule."),
for partner in event.partner_ids:
if partner.id in attendees:
continue
local_context = context.copy()
local_context.pop('default_state', None)
att_id = self.pool.get('calendar.attendee').create(cr, uid, {
'partner_id': partner.id,
'user_id': partner.user_ids and partner.user_ids[0].id or False,
'ref': self._name+','+str(event.id),
'email': partner.email
}, context=context)
}, context=local_context)
if partner.email:
mail_to = mail_to + " " + partner.email
self.write(cr, uid, [event.id], {

View File

@ -160,7 +160,7 @@ class crm_case_section(osv.osv):
'note': fields.text('Description'),
'working_hours': fields.float('Working Hours', digits=(16, 2)),
'stage_ids': fields.many2many('crm.case.stage', 'section_stage_rel', 'section_id', 'stage_id', 'Stages'),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="The email address associated with this team. New emails received will automatically "
"create new leads assigned to the team."),
'color': fields.integer('Color Index'),

View File

@ -634,7 +634,7 @@ class crm_lead(format_address, osv.osv):
# Merge notifications about loss of information
opportunities = [highest]
opportunities.extend(opportunities_rest)
self._merge_notify(cr, uid, highest, opportunities, context=context)
self._merge_notify(cr, uid, highest.id, opportunities, context=context)
# Check if the stage is in the stages of the sales team. If not, assign the stage with the lowest sequence
if merged_data.get('section_id'):
section_stage_ids = self.pool.get('crm.case.stage').search(cr, uid, [('section_ids', 'in', merged_data['section_id']), ('type', '=', merged_data.get('type'))], order='sequence', context=context)

View File

@ -21,6 +21,8 @@
##############################################################################
import base64
import datetime
import dateutil.relativedelta as relativedelta
import logging
import openerp
@ -57,6 +59,12 @@ try:
'str': str,
'quote': quote,
'urlencode': urlencode,
'datetime': datetime,
# dateutil.relativedelta is an old-style class and cannot be directly
# instanciated wihtin a jinja2 expression, so a lambda "proxy" is
# is needed, apparently.
'relativedelta': lambda *a, **kw : relativedelta.relativedelta(*a, **kw),
})
except ImportError:
_logger.warning("jinja2 not available, templating features will not work!")

View File

@ -36,13 +36,6 @@ def _employee_get(obj, cr, uid, context=None):
class hr_expense_expense(osv.osv):
def copy(self, cr, uid, id, default=None, context=None):
if context is None:
context = {}
if not default: default = {}
default.update({'date_confirm': False, 'date_valid': False, 'user_valid': False})
return super(hr_expense_expense, self).copy(cr, uid, id, default, context=context)
def _amount(self, cr, uid, ids, field_name, arg, context=None):
res= {}
for expense in self.browse(cr, uid, ids, context=context):
@ -116,7 +109,11 @@ class hr_expense_expense(osv.osv):
def copy(self, cr, uid, id, default=None, context=None):
if default is None:
default = {}
default.update(account_move_id=False)
default.update(
account_move_id=False,
date_confirm=False,
date_valid=False,
user_valid=False)
return super(hr_expense_expense, self).copy(cr, uid, id, default=default, context=context)
def unlink(self, cr, uid, ids, context=None):

View File

@ -463,7 +463,7 @@ class hr_job(osv.osv):
_inherits = {'mail.alias': 'alias_id'}
_columns = {
'survey_id': fields.many2one('survey', 'Interview Form', help="Choose an interview form for this job position and you will be able to print/answer this interview from all applicants who apply for this job"),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Email alias for this job position. New emails will automatically "
"create new applicants for this job position."),
}

View File

@ -247,9 +247,9 @@ class partner_vat_intra(osv.osv_memory):
for client in xml_data['clientlist']:
if not client['vatnum']:
raise osv.except_osv(_('Insufficient Data!'),_('No vat number defined for %s.') % client['partner_name'])
data_clientinfo +='\n\t\t<ns2:IntraClient SequenceNumber="%(seq)s">\n\t\t\t<ns2:CompanyVATNumber issuedBy="%(country)s">%(vatnum)s</ns2:CompanyVATNumber>\n\t\t\t<ns2:Code>%(code)s</ns2:Code>\n\t\t\t<ns2:Amount>%(amount)s</ns2:Amount>\n\t\t</ns2:IntraClient>' % (client)
data_clientinfo +='\n\t\t<ns2:IntraClient SequenceNumber="%(seq)s">\n\t\t\t<ns2:CompanyVATNumber issuedBy="%(country)s">%(vatnum)s</ns2:CompanyVATNumber>\n\t\t\t<ns2:Code>%(code)s</ns2:Code>\n\t\t\t<ns2:Amount>%(amount).2f</ns2:Amount>\n\t\t</ns2:IntraClient>' % (client)
data_decl = '\n\t<ns2:IntraListing SequenceNumber="1" ClientsNbr="%(clientnbr)s" DeclarantReference="%(dnum)s" AmountSum="%(amountsum)s">' % (xml_data)
data_decl = '\n\t<ns2:IntraListing SequenceNumber="1" ClientsNbr="%(clientnbr)s" DeclarantReference="%(dnum)s" AmountSum="%(amountsum).2f">' % (xml_data)
data_file += data_head + data_decl + data_comp_period + data_clientinfo + '\n\t\t<ns2:Comment>%(comments)s</ns2:Comment>\n\t</ns2:IntraListing>\n</ns2:IntraConsignment>' % (xml_data)
context['file_save'] = data_file

View File

@ -241,11 +241,11 @@ class account_coda_import(osv.osv_memory):
if statement['debit'] == '1': # 1=Debit
statement['balance_end_real'] = - statement['balance_end_real']
if statement['balance_end_realDate']:
period_id = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', statement['balance_end_realDate']), ('date_stop', '>=', statement['balance_end_realDate'])])
period_id = self.pool.get('account.period').search(cr, uid, [('company_id', '=', statement['journal_id'].company_id.id), ('date_start', '<=', statement['balance_end_realDate']), ('date_stop', '>=', statement['balance_end_realDate'])])
else:
period_id = self.pool.get('account.period').search(cr, uid, [('date_start', '<=', statement['date']), ('date_stop', '>=', statement['date'])])
period_id = self.pool.get('account.period').search(cr, uid, [('company_id', '=', statement['journal_id'].company_id.id), ('date_start', '<=', statement['date']), ('date_stop', '>=', statement['date'])])
if not period_id and len(period_id) == 0:
raise osv.except_osv(_('Error') + 'R0002', _("The CODA Statement New Balance date doesn't fall within a defined Accounting Period! Please create the Accounting Period for date %s.") % statement['balance_end_realDate'])
raise osv.except_osv(_('Error') + 'R0002', _("The CODA Statement New Balance date doesn't fall within a defined Accounting Period! Please create the Accounting Period for date %s for the company %s.") % (statement['balance_end_realDate'], statement['journal_id'].company_id.name))
statement['period_id'] = period_id[0]
elif line[0] == '9':
statement['balanceMin'] = float(rmspaces(line[22:37])) / 1000

View File

@ -76,7 +76,7 @@ class mail_group(osv.Model):
help="Small-sized photo of the group. It is automatically "\
"resized as a 64x64px image, with aspect ratio preserved. "\
"Use this field anywhere a small image is required."),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="The email address associated with this group. New emails received will automatically "
"create new topics."),
}

View File

@ -36,7 +36,7 @@ class res_users(osv.Model):
_inherits = {'mail.alias': 'alias_id'}
_columns = {
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Email address internally associated with this user. Incoming "\
"emails will appear in the user's notifications."),
'display_groups_suggestions': fields.boolean("Display Groups Suggestions"),

View File

@ -158,6 +158,7 @@
<record id="view_res_partner_member_filter" model="ir.ui.view">
<field name="name">res.partner.select</field>
<field name="model">res.partner</field>
<field name="priority">50</field>
<field name="arch" type="xml">
<search string="Membership Partners">
<field name="membership_start" invisible="1"/>

View File

@ -318,9 +318,10 @@ class mrp_bom(osv.osv):
"""
routing_obj = self.pool.get('mrp.routing')
factor = factor / (bom.product_efficiency or 1.0)
factor = rounding(factor, bom.product_rounding)
if factor < bom.product_rounding:
factor = bom.product_rounding
max_rounding = max(bom.product_rounding, bom.product_uom.rounding)
factor = rounding(factor, max_rounding)
if factor < max_rounding:
factor = max_rounding
result = []
result2 = []
phantom = False

View File

@ -1027,7 +1027,7 @@
<field name="name">Bill of Materials</field>
<field name="domain">[('bom_id','=',False)]</field>
<field name="res_model">mrp.bom</field>
<field name="view_type">tree</field>
<field name="view_type">form</field>
</record>
<record id="act_product_mrp_production" model="ir.actions.act_window">
<field name="context">{'search_default_product_id': [active_id]}</field>

View File

@ -33,7 +33,13 @@ class TestMrpMulticompany(common.TransactionCase):
self.res_users = self.registry('res.users')
self.stock_location = self.registry('stock.location')
model, self.multicompany_user_id = self.ir_model_data.get_object_reference(cr, uid, 'stock', 'multicompany_user')
model, group_user_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
model, group_stock_manager_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'group_stock_manager')
model, company_2_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'res_company_2')
self.multicompany_user_id = self.res_users.create(cr, uid,
{'name': 'multicomp', 'login': 'multicomp',
'groups_id': [(6, 0, [group_user_id, group_stock_manager_id])],
'company_id': company_2_id, 'company_ids': [(6,0,[company_2_id])]})
def test_00_multicompany_user(self):

View File

@ -478,6 +478,11 @@ class pos_session(osv.osv):
context = {}
if not ids:
return {}
for session in self.browse(cr, uid, ids, context=context):
if session.user_id.id != uid:
raise osv.except_osv(
_('Error!'),
_("You cannot use the session of another users. This session is owned by %s. Please first close this one to use this point of sale." % session.user_id.name))
context.update({'active_id': ids[0]})
return {
'type' : 'ir.actions.client',
@ -507,7 +512,6 @@ class pos_order(osv.osv):
'pos_reference':order['name'],
'partner_id': order['partner_id'] or False
}, context)
for payments in order['statement_ids']:
payment = payments[2]
self.add_payment(cr, uid, order_id, {
@ -809,9 +813,18 @@ class pos_order(osv.osv):
"""Create a copy of order for refund order"""
clone_list = []
line_obj = self.pool.get('pos.order.line')
for order in self.browse(cr, uid, ids, context=context):
current_session_ids = self.pool.get('pos.session').search(cr, uid, [
('state', '!=', 'closed'),
('user_id', '=', uid)], context=context)
if not current_session_ids:
raise osv.except_osv(_('Error!'), _('To return product(s), you need to open a session that will be used to register the refund.'))
clone_id = self.copy(cr, uid, order.id, {
'name': order.name + ' REFUND',
'name': order.name + ' REFUND', # not used, name forced by create
'session_id': current_session_ids[0],
'date_order': time.strftime('%Y-%m-%d %H:%M:%S'),
}, context=context)
clone_list.append(clone_id)

View File

@ -26,7 +26,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
this.custom_payment_status = this.default_payment_status;
this.connection = new instance.web.Session(undefined,url);
this.connection.session_id = _.uniqueId('posproxy');
this.bypass_proxy = false;
this.notifications = {};
@ -439,7 +439,7 @@ function openerp_pos_devices(instance,module){ //module is instance.point_of_sal
// The barcode readers acts as a keyboard, we catch all keyup events and try to find a
// barcode sequence in the typed keys, then act accordingly.
$('body').delegate('','keyup', function (e){
$('body').delegate('','keypress', function (e){
//console.log('keyup:'+String.fromCharCode(e.keyCode)+' '+e.keyCode,e);
//We only care about numbers
if (e.keyCode >= 48 && e.keyCode < 58){

View File

@ -93,6 +93,7 @@ class product_pricelist(osv.osv):
_name = "product.pricelist"
_description = "Pricelist"
_order = 'name'
_columns = {
'name': fields.char('Pricelist Name',size=64, required=True, translate=True),
'active': fields.boolean('Active', help="If unchecked, it will allow you to hide the pricelist without removing it."),
@ -111,6 +112,27 @@ class product_pricelist(osv.osv):
result.append((pl.id,name))
return result
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
if name and operator == '=' and not args:
# search on the name of the pricelist and its currency, opposite of name_get(),
# Used by the magic context filter in the product search view.
query_args = {'name': name, 'limit': limit}
query = """SELECT p.id
FROM product_pricelist p JOIN
res_currency c ON (p.currency_id = c.id)
WHERE p.name || ' (' || c.name || ')' = %(name)s
ORDER BY p.name"""
if limit:
query += " LIMIT %(limit)s"
cr.execute(query, query_args)
ids = [r[0] for r in cr.fetchall()]
# regular search() to apply ACLs - may limit results below limit in some cases
ids = self.search(cr, uid, [('id', 'in', ids)], limit=limit, context=context)
if ids:
return self.name_get(cr, uid, ids, context)
return super(product_pricelist, self).name_search(
cr, uid, name, args, operator=operator, context=context, limit=limit)
def _get_currency(self, cr, uid, ctx):
comp = self.pool.get('res.users').browse(cr, uid, uid).company_id

View File

@ -420,6 +420,11 @@ class product_product(osv.osv):
pricelist = context.get('pricelist', False)
partner = context.get('partner', False)
if pricelist:
# Support context pricelists specified as display_name or ID for compatibility
if isinstance(pricelist, basestring):
pricelist_ids = self.pool.get('product.pricelist').name_search(
cr, uid, pricelist, operator='=', context=context, limit=1)
pricelist = pricelist_ids[0][0] if pricelist_ids else pricelist
for id in ids:
try:
price = self.pool.get('product.pricelist').price_get(cr,uid,[pricelist], id, quantity, partner=partner, context=context)[pricelist]
@ -762,7 +767,7 @@ class product_product(osv.osv):
context = {}
if context and context.get('search_default_categ_id', False):
args.append((('categ_id', 'child_of', context['search_default_categ_id'])))
return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=False)
return super(product_product, self).search(cr, uid, args, offset=offset, limit=limit, order=order, context=context, count=count)
class product_packaging(osv.osv):

View File

@ -15,7 +15,7 @@
<filter string="Can be Sold" name="filter_to_sell" icon="terp-accessories-archiver-minus" domain="[('sale_ok','=',1)]"/>
<field name="categ_id"/>
<group expand="0" string="Context...">
<field name="pricelist_id" context="{'pricelist': self}" groups="product.group_sale_pricelist"/>
<field name="pricelist_id" context="{'pricelist': self}" filter_domain="[]" groups="product.group_sale_pricelist"/>
<field name="company_id" groups="base.group_multi_company"/>
</group>
<group expand='0' string='Group by...'>

View File

@ -265,7 +265,7 @@ class project(osv.osv):
'type_ids': fields.many2many('project.task.type', 'project_task_type_rel', 'project_id', 'type_id', 'Tasks Stages', states={'close':[('readonly',True)], 'cancelled':[('readonly',True)]}),
'task_count': fields.function(_task_count, type='integer', string="Open Tasks"),
'color': fields.integer('Color Index'),
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="cascade", required=True,
'alias_id': fields.many2one('mail.alias', 'Alias', ondelete="restrict", required=True,
help="Internal email associated with this project. Incoming emails are automatically synchronized"
"with Tasks (or optionally Issues if the Issue Tracker module is installed)."),
'alias_model': fields.selection(_alias_models, "Alias Model", select=True, required=True,
@ -717,6 +717,16 @@ class task(osv.osv):
new_name = _("%s (copy)") % (default.get('name', ''))
default.update({'name':new_name})
return super(task, self).copy_data(cr, uid, id, default, context)
def copy(self, cr, uid, id, default=None, context=None):
if context is None:
context = {}
if default is None:
default = {}
stage = self._get_default_stage_id(cr, uid, context=context)
if stage:
default['stage_id'] = stage
return super(task, self).copy(cr, uid, id, default, context)
def _is_template(self, cr, uid, ids, field_name, arg, context=None):
res = {}
@ -1248,6 +1258,18 @@ class account_analytic_account(osv.osv):
raise osv.except_osv(_('Warning!'), _('Please delete the project linked with this account first.'))
return super(account_analytic_account, self).unlink(cr, uid, ids, *args, **kwargs)
def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100):
if args is None:
args = []
if context is None:
context={}
if context.get('current_model') == 'project.project':
project_ids = self.search(cr, uid, args + [('name', operator, name)], limit=limit, context=context)
return self.name_get(cr, uid, project_ids, context=context)
return super(account_analytic_account, self).name_search(cr, uid, name, args=args, operator=operator, context=context, limit=limit)
class project_project(osv.osv):
_inherit = 'project.project'
_defaults = {

View File

@ -51,7 +51,7 @@
<field eval="&quot;&quot;&quot;Procurement Task&quot;&quot;&quot;" name="name"/>
<field eval="&quot;&quot;&quot;if product type is 'service' then it creates the task.&quot;&quot;&quot;" name="note"/>
<field name="target_node_id" ref="process_node_procuretasktask0"/>
<field name="source_node_id" ref="sale_stock.process_node_saleprocurement0"/>
<field name="source_node_id" ref="mrp.process_node_productionorder0"/>
</record>
<record id="process_transition_createtask0" model="process.transition">

View File

@ -41,7 +41,7 @@ class res_partner(osv.osv):
default.update({'purchase_order_ids': []})
super(res_partner, self).copy(cr, uid, id, default=default, context=context)
return super(res_partner, self).copy(cr, uid, id, default=default, context=context)
def _commercial_fields(self, cr, uid, context=None):
return super(res_partner, self)._commercial_fields(cr, uid, context=context) + ['property_product_pricelist_purchase']

View File

@ -2053,7 +2053,10 @@ class stock_move(osv.osv):
ptype = todo[0][1][5] and todo[0][1][5] or location_obj.picking_type_get(cr, uid, todo[0][0].location_dest_id, todo[0][1][0])
if picking:
# name of new picking according to its type
new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
if ptype == 'internal':
new_pick_name = seq_obj.get(cr, uid,'stock.picking')
else :
new_pick_name = seq_obj.get(cr, uid, 'stock.picking.' + ptype)
pickid = self._create_chained_picking(cr, uid, new_pick_name, picking, ptype, todo, context=context)
# Need to check name of old picking because it always considers picking as "OUT" when created from Sales Order
old_ptype = location_obj.picking_type_get(cr, uid, picking.move_lines[0].location_id, picking.move_lines[0].location_dest_id)
@ -2940,8 +2943,8 @@ class stock_warehouse(osv.osv):
def _default_lot_output_id(self, cr, uid, context=None):
try:
lot_input_stock_model, lot_input_stock_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_output')
self.pool.get('stock.location').check_access_rule(cr, uid, [lot_input_stock_id], 'read', context=context)
lot_output_model, lot_output_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'stock', 'stock_location_output')
self.pool.get('stock.location').check_access_rule(cr, uid, [lot_output_id], 'read', context=context)
except (ValueError, orm.except_orm):
# the user does not have read access on the location or it does not exists
lot_output_id = False
@ -2999,6 +3002,18 @@ class stock_picking_in(osv.osv):
# instead of its own workflow (which is not existing)
return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context)
def message_post(self, *args, **kwargs):
"""Post the message on stock.picking to be able to see it in the form view when using the chatter"""
return self.pool.get('stock.picking').message_post(*args, **kwargs)
def message_subscribe(self, *args, **kwargs):
"""Send the subscribe action on stock.picking model as it uses _name in request"""
return self.pool.get('stock.picking').message_subscribe(*args, **kwargs)
def message_unsubscribe(self, *args, **kwargs):
"""Send the unsubscribe action on stock.picking model to match with subscribe"""
return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
_columns = {
'backorder_id': fields.many2one('stock.picking.in', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
'state': fields.selection(
@ -3060,6 +3075,18 @@ class stock_picking_out(osv.osv):
# instead of its own workflow (which is not existing)
return self.pool.get('stock.picking').signal_workflow(cr, uid, ids, signal, context=context)
def message_post(self, *args, **kwargs):
"""Post the message on stock.picking to be able to see it in the form view when using the chatter"""
return self.pool.get('stock.picking').message_post(*args, **kwargs)
def message_subscribe(self, *args, **kwargs):
"""Send the subscribe action on stock.picking model as it uses _name in request"""
return self.pool.get('stock.picking').message_subscribe(*args, **kwargs)
def message_unsubscribe(self, *args, **kwargs):
"""Send the unsubscribe action on stock.picking model to match with subscribe"""
return self.pool.get('stock.picking').message_unsubscribe(*args, **kwargs)
_columns = {
'backorder_id': fields.many2one('stock.picking.out', 'Back Order of', states={'done':[('readonly', True)], 'cancel':[('readonly',True)]}, help="If this shipment was split, then this field links to the shipment which contains the already processed part.", select=True),
'state': fields.selection(

View File

@ -287,16 +287,6 @@
<field name="company_id" ref="base.main_company"/>
</record>
<record id="multicompany_user" model="res.users">
<field name="name">multicomp</field>
<field name="login">multicomp</field>
<field name="password">multicomp</field>
<field name="company_id" ref="res_company_2"/>
<field name="company_ids" eval="[(6,0,[ref('res_company_2')])]"/>
<field name="groups_id" eval="[(6,0,[ref('base.group_user'), ref('stock.group_stock_manager')])]"/>
</record>
</data>
</openerp>

View File

@ -36,7 +36,13 @@ class TestStockMulticompany(common.TransactionCase):
self.stock_fill_inventory = self.registry('stock.fill.inventory')
self.stock_warehouse = self.registry('stock.warehouse')
model, self.multicompany_user_id = self.ir_model_data.get_object_reference(cr, uid, 'stock', 'multicompany_user')
model, group_user_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'base', 'group_user')
model, group_stock_manager_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'group_stock_manager')
model, company_2_id = self.registry('ir.model.data').get_object_reference(cr, uid, 'stock', 'res_company_2')
self.multicompany_user_id = self.res_users.create(cr, uid,
{'name': 'multicomp', 'login': 'multicomp',
'groups_id': [(6, 0, [group_user_id, group_stock_manager_id])],
'company_id': company_2_id, 'company_ids': [(6,0,[company_2_id])]})
def test_00_multicompany_default_stock_move(self):
"""check no error on getting default stock.move values in multicompany setting"""

View File

@ -159,13 +159,15 @@ class stock_return_picking(osv.osv_memory):
returned_lines = 0
# Create new picking for returned products
seq_obj_name = 'stock.picking'
new_type = 'internal'
if pick.type =='out':
new_type = 'in'
seq_obj_name = 'stock.picking.in'
elif pick.type =='in':
new_type = 'out'
else:
new_type = 'internal'
seq_obj_name = 'stock.picking.' + new_type
seq_obj_name = 'stock.picking.out'
new_pick_name = self.pool.get('ir.sequence').get(cr, uid, seq_obj_name)
new_picking = pick_obj.copy(cr, uid, pick.id, {
'name': _('%s-%s-return') % (new_pick_name, pick.name),