[MERGE] forward port of branch saas-1 up to revid 8745 chs@openerp.com-20130613181503-82234mo34wxb0oap
bzr revid: chs@openerp.com-20130614091924-z5ta02kwhmwcrgox
This commit is contained in:
commit
aa133b4d29
|
@ -65,12 +65,11 @@ class bank(osv.osv):
|
|||
# Find the code and parent of the bank account to create
|
||||
dig = 6
|
||||
current_num = 1
|
||||
ids = obj_acc.search(cr, uid, [('type','=','liquidity'), ('company_id', '=', bank.company_id.id)], context=context)
|
||||
ids = obj_acc.search(cr, uid, [('type','=','liquidity'), ('company_id', '=', bank.company_id.id), ('parent_id', '!=', False)], context=context)
|
||||
# No liquidity account exists, no template available
|
||||
if not ids: continue
|
||||
|
||||
ref_acc_bank_temp = obj_acc.browse(cr, uid, ids[0], context=context)
|
||||
ref_acc_bank = ref_acc_bank_temp.parent_id
|
||||
ref_acc_bank = obj_acc.browse(cr, uid, ids[0], context=context).parent_id
|
||||
while True:
|
||||
new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)), '0')) + str(current_num)
|
||||
ids = obj_acc.search(cr, uid, [('code', '=', new_code), ('company_id', '=', bank.company_id.id)])
|
||||
|
@ -82,7 +81,7 @@ class bank(osv.osv):
|
|||
'name': name,
|
||||
'code': new_code,
|
||||
'type': 'liquidity',
|
||||
'user_type': ref_acc_bank_temp.user_type.id,
|
||||
'user_type': ref_acc_bank.user_type.id,
|
||||
'reconcile': False,
|
||||
'parent_id': ref_acc_bank.id,
|
||||
'company_id': bank.company_id.id,
|
||||
|
|
|
@ -51,9 +51,12 @@ class account_invoice(osv.osv):
|
|||
company_id = context.get('company_id', user.company_id.id)
|
||||
type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale_refund', 'in_refund': 'purchase_refund'}
|
||||
journal_obj = self.pool.get('account.journal')
|
||||
res = journal_obj.search(cr, uid, [('type', '=', type2journal.get(type_inv, 'sale')),
|
||||
('company_id', '=', company_id)],
|
||||
limit=1)
|
||||
domain = [('company_id', '=', company_id)]
|
||||
if isinstance(type_inv, list):
|
||||
domain.append(('type', 'in', [type2journal.get(type) for type in type_inv if type2journal.get(type)]))
|
||||
else:
|
||||
domain.append(('type', '=', type2journal.get(type_inv, 'sale')))
|
||||
res = journal_obj.search(cr, uid, domain, limit=1)
|
||||
return res and res[0] or False
|
||||
|
||||
def _get_currency(self, cr, uid, context=None):
|
||||
|
@ -578,6 +581,10 @@ class account_invoice(osv.osv):
|
|||
return {'value': {}}
|
||||
|
||||
def onchange_company_id(self, cr, uid, ids, company_id, part_id, type, invoice_line, currency_id, context=None):
|
||||
#TODO: add the missing context parameter when forward-porting in trunk so we can remove
|
||||
# this hack!
|
||||
context = self.pool['res.users'].context_get(cr, uid)
|
||||
|
||||
val = {}
|
||||
dom = {}
|
||||
obj_journal = self.pool.get('account.journal')
|
||||
|
@ -634,14 +641,13 @@ class account_invoice(osv.osv):
|
|||
else:
|
||||
continue
|
||||
if company_id and type:
|
||||
if type in ('out_invoice'):
|
||||
journal_type = 'sale'
|
||||
elif type in ('out_refund'):
|
||||
journal_type = 'sale_refund'
|
||||
elif type in ('in_refund'):
|
||||
journal_type = 'purchase_refund'
|
||||
else:
|
||||
journal_type = 'purchase'
|
||||
journal_mapping = {
|
||||
'out_invoice': 'sale',
|
||||
'out_refund': 'sale_refund',
|
||||
'in_refund': 'purchase_refund',
|
||||
'in_invoice': 'purchase',
|
||||
}
|
||||
journal_type = journal_mapping[type]
|
||||
journal_ids = obj_journal.search(cr, uid, [('company_id','=',company_id), ('type', '=', journal_type)])
|
||||
if journal_ids:
|
||||
val['journal_id'] = journal_ids[0]
|
||||
|
@ -651,7 +657,12 @@ class account_invoice(osv.osv):
|
|||
if r[1] == 'journal_id' and r[2] in journal_ids:
|
||||
val['journal_id'] = r[2]
|
||||
if not val.get('journal_id', False):
|
||||
raise osv.except_osv(_('Configuration Error!'), (_('Cannot find any account journal of %s type for this company.\n\nYou can create one in the menu: \nConfiguration\Journals\Journals.') % (journal_type)))
|
||||
journal_type_map = dict(obj_journal._columns['type'].selection)
|
||||
journal_type_label = self.pool['ir.translation']._get_source(cr, uid, None, ('code','selection'),
|
||||
context.get('lang'),
|
||||
journal_type_map.get(journal_type))
|
||||
raise osv.except_osv(_('Configuration Error!'),
|
||||
_('Cannot find any account journal of %s type for this company.\n\nYou can create one in the menu: \nConfiguration\Journals\Journals.') % ('"%s"' % journal_type_label))
|
||||
dom = {'journal_id': [('id', 'in', journal_ids)]}
|
||||
else:
|
||||
journal_ids = obj_journal.search(cr, uid, [])
|
||||
|
@ -968,7 +979,7 @@ class account_invoice(osv.osv):
|
|||
total, total_currency, iml = self.compute_invoice_totals(cr, uid, inv, company_currency, ref, iml, context=ctx)
|
||||
acc_id = inv.account_id.id
|
||||
|
||||
name = inv['name'] or '/'
|
||||
name = inv['name'] or inv['supplier_invoice_number'] or '/'
|
||||
totlines = False
|
||||
if inv.payment_term:
|
||||
totlines = payment_term_obj.compute(cr,
|
||||
|
@ -1167,12 +1178,12 @@ class account_invoice(osv.osv):
|
|||
if not ids:
|
||||
return []
|
||||
types = {
|
||||
'out_invoice': 'Invoice ',
|
||||
'in_invoice': 'Sup. Invoice ',
|
||||
'out_refund': 'Refund ',
|
||||
'in_refund': 'Supplier Refund ',
|
||||
'out_invoice': _('Invoice'),
|
||||
'in_invoice': _('Supplier Invoice'),
|
||||
'out_refund': _('Refund'),
|
||||
'in_refund': _('Supplier Refund'),
|
||||
}
|
||||
return [(r['id'], (r['number']) or types[r['type']] + (r['name'] or '')) for r in self.read(cr, uid, ids, ['type', 'number', 'name'], context, load='_classic_write')]
|
||||
return [(r['id'], '%s %s' % (r['number'] or types[r['type']], r['name'] or '')) for r in self.read(cr, uid, ids, ['type', 'number', 'name'], context, load='_classic_write')]
|
||||
|
||||
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100):
|
||||
if not args:
|
||||
|
|
|
@ -1066,12 +1066,12 @@ class account_move_line(osv.osv):
|
|||
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
ctx = context.copy()
|
||||
if ('journal_id' not in ctx):
|
||||
if not ctx.get('journal_id'):
|
||||
if line.move_id:
|
||||
ctx['journal_id'] = line.move_id.journal_id.id
|
||||
else:
|
||||
ctx['journal_id'] = line.journal_id.id
|
||||
if ('period_id' not in ctx):
|
||||
if not ctx.get('period_id'):
|
||||
if line.move_id:
|
||||
ctx['period_id'] = line.move_id.period_id.id
|
||||
else:
|
||||
|
|
|
@ -585,7 +585,10 @@
|
|||
<field name="date"/>
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(partner_id)" domain="['|',('parent_id','=',False),('is_company','=',True)]"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(partner_id)" domain="[
|
||||
'&',
|
||||
'|',('parent_id','=',False),('is_company','=',True),
|
||||
'|',('customer','=',True),('supplier','=',True)]"/>
|
||||
<field name="type" on_change="onchange_type(partner_id, type)"/>
|
||||
<field name="account_id" options='{"no_open":True}' domain="[('journal_id','=',parent.journal_id), ('company_id', '=', parent.company_id)]"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('company_id', '=', parent.company_id), ('type', '<>', 'view')]"/>
|
||||
|
|
|
@ -363,7 +363,7 @@
|
|||
<field name="inherit_id" ref="account.view_account_journal_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="type" position="after">
|
||||
<field name="analytic_journal_id"/>
|
||||
<field name="analytic_journal_id" groups="analytic.group_analytic_accounting"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -239,7 +239,7 @@
|
|||
<td><para style="terp_default_8">[[ line.account_id.code ]]</para></td>
|
||||
<td><para style="terp_default_8">[[ line.partner_id and strip_name(line.partner_id.name,15) ]]</para></td>
|
||||
<td><para style="terp_default_8">[[ strip_name(line.name,25) ]]</para></td>
|
||||
<td><para style="P8">[[ line.tax_code_id and (line.tax_code_id.code + ':') ]]</para></td>
|
||||
<td><para style="P8">[[ line.tax_code_id and line.tax_code_id.code and (line.tax_code_id.code + ':') ]]</para></td>
|
||||
<td><para style="terp_default_8">[[ line.tax_amount and formatLang(line.tax_amount, currency_obj=company.currency_id) ]]</para></td>
|
||||
<td><para style="P8">[[ formatLang(line.debit, currency_obj=company.currency_id) ]]</para></td>
|
||||
<td><para style="P8">[[ formatLang(line.credit, currency_obj=company.currency_id) ]]</para></td>
|
||||
|
@ -292,7 +292,7 @@
|
|||
<td><para style="terp_default_8">[[ line.account_id.code ]]</para></td>
|
||||
<td><para style="terp_default_8">[[ line.partner_id and strip_name(line.partner_id.name,12) ]]</para></td>
|
||||
<td><para style="terp_default_8">[[ strip_name(line.name,16) ]]</para></td>
|
||||
<td><para style="terp_default_8">[[ line.tax_code_id and (line.tax_code_id.code + ':') ]]</para></td>
|
||||
<td><para style="terp_default_8">[[ line.tax_code_id and line.tax_code_id.code and (line.tax_code_id.code + ':') ]]</para></td>
|
||||
<td><para style="P8">[[ line.tax_amount and formatLang(line.tax_amount, currency_obj=company.currency_id) ]]</para></td>
|
||||
<td><para style="P8">[[ formatLang(line.debit, currency_obj=company.currency_id) ]]</para></td>
|
||||
<td><para style="P8">[[ formatLang(line.credit, currency_obj=company.currency_id) ]]</para></td>
|
||||
|
|
|
@ -38,7 +38,7 @@ class account_fiscalyear_close(osv.osv_memory):
|
|||
'report_name': fields.char('Name of new entries',size=64, required=True, help="Give name of the new entries"),
|
||||
}
|
||||
_defaults = {
|
||||
'report_name': _('End of Fiscal Year Entry'),
|
||||
'report_name': lambda self, cr, uid, context: _('End of Fiscal Year Entry'),
|
||||
}
|
||||
|
||||
def data_save(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -72,8 +72,8 @@ class account_invoice_line(osv.osv):
|
|||
_inherit = "account.invoice.line"
|
||||
_description = "Invoice Line"
|
||||
|
||||
def product_id_change(self, cr, uid, ids, product, uom, qty=0, name='', type='out_invoice', partner_id=False, fposition_id=False, price_unit=False, currency_id=False, context=None, company_id=None):
|
||||
res_prod = super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom, qty, name, type, partner_id, fposition_id, price_unit, currency_id=currency_id, context=context, company_id=company_id)
|
||||
def product_id_change(self, cr, uid, ids, product, uom_id, qty=0, name='', type='out_invoice', partner_id=False, fposition_id=False, price_unit=False, currency_id=False, context=None, company_id=None):
|
||||
res_prod = super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom_id, qty, name, type, partner_id, fposition_id, price_unit, currency_id=currency_id, context=context, company_id=company_id)
|
||||
rec = self.pool.get('account.analytic.default').account_get(cr, uid, product, partner_id, uid, time.strftime('%Y-%m-%d'), context=context)
|
||||
if rec:
|
||||
res_prod['value'].update({'account_analytic_id': rec.analytic_id.id})
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<field name="inherit_id" ref="account.view_account_journal_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="centralisation" position="before">
|
||||
<field name="plan_id" />
|
||||
<field name="plan_id" groups="analytic.group_analytic_accounting"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -136,9 +136,9 @@ class account_invoice_line(osv.osv):
|
|||
res += diff_res
|
||||
return res
|
||||
|
||||
def product_id_change(self, cr, uid, ids, product, uom, qty=0, name='', type='out_invoice', partner_id=False, fposition_id=False, price_unit=False, currency_id=False, context=None, company_id=None):
|
||||
def product_id_change(self, cr, uid, ids, product, uom_id, qty=0, name='', type='out_invoice', partner_id=False, fposition_id=False, price_unit=False, currency_id=False, context=None, company_id=None):
|
||||
fiscal_pool = self.pool.get('account.fiscal.position')
|
||||
res = super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom, qty, name, type, partner_id, fposition_id, price_unit, currency_id, context, company_id)
|
||||
res = super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom_id, qty, name, type, partner_id, fposition_id, price_unit, currency_id, context, company_id)
|
||||
if not product:
|
||||
return res
|
||||
if type in ('in_invoice','in_refund'):
|
||||
|
|
|
@ -13,6 +13,17 @@
|
|||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_invoice_asset_category">
|
||||
<field name="name">account.invoice.supplier.form</field>
|
||||
<field name="model">account.invoice</field>
|
||||
<field name="inherit_id" ref="account.invoice_supplier_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='invoice_line']/tree/field[@name='quantity']" position="before">
|
||||
<field name="asset_category_id"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -203,7 +203,9 @@
|
|||
<field name="view_id" ref="crossovered_budget_view_tree"/>
|
||||
<field name="search_view_id" ref="view_crossovered_budget_search"/>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new budget.
|
||||
</p><p>
|
||||
A budget is a forecast of your company's income and/or expenses
|
||||
expected for a period in the future. A budget is defined on some
|
||||
financial accounts and/or analytic accounts (that may represent
|
||||
|
|
|
@ -3,5 +3,5 @@ access_account_followup_followup_line,account_followup.followup.line,model_accou
|
|||
access_account_followup_followup_line_manager,account_followup.followup.line.manager,model_account_followup_followup_line,account.group_account_manager,1,1,1,1
|
||||
access_account_followup_followup_accountant,account_followup.followup user,model_account_followup_followup,account.group_account_invoice,1,0,0,0
|
||||
access_account_followup_followup_manager,account_followup.followup.manager,model_account_followup_followup,account.group_account_manager,1,1,1,1
|
||||
access_account_followup_stat_invoice,account_followup.stat.invoice,model_account_followup_stat,account.group_account_invoice,1,1,1,1
|
||||
access_account_followup_stat_by_partner_manager,account_followup.stat.by.partner,model_account_followup_stat_by_partner,account.group_account_user,1,1,1,1
|
||||
access_account_followup_stat_invoice,account_followup.stat.invoice,model_account_followup_stat,account.group_account_invoice,1,1,0,0
|
||||
access_account_followup_stat_by_partner_manager,account_followup.stat.by.partner,model_account_followup_stat_by_partner,account.group_account_user,1,1,0,0
|
||||
|
|
|
|
@ -88,6 +88,7 @@ class payment_order_create(osv.osv_memory):
|
|||
'order_id': payment.id,
|
||||
'partner_id': line.partner_id and line.partner_id.id or False,
|
||||
'communication': line.ref or '/',
|
||||
'state': line.invoice and line.invoice.reference_type != 'none' and 'structured' or 'normal',
|
||||
'date': date_to_pay,
|
||||
'currency': (line.invoice and line.invoice.currency_id.id) or line.journal_id.currency.id or line.journal_id.company_id.currency_id.id,
|
||||
}, context=context)
|
||||
|
|
|
@ -102,7 +102,10 @@ class OAuthController(oeweb.Controller):
|
|||
registry = RegistryManager.get(dbname)
|
||||
with registry.cursor() as cr:
|
||||
IMD = registry['ir.model.data']
|
||||
model, provider_id = IMD.get_object_reference(cr, SUPERUSER_ID, 'auth_oauth', 'provider_openerp')
|
||||
try:
|
||||
model, provider_id = IMD.get_object_reference(cr, SUPERUSER_ID, 'auth_oauth', 'provider_openerp')
|
||||
except ValueError:
|
||||
return set_cookie_and_redirect(req, '/?db=%s' % dbname)
|
||||
assert model == 'auth.oauth.provider'
|
||||
|
||||
state = {
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
Name,Is a company,Related company,Address type,Customer,Supplier,Street,ZIP,City,State,Country
|
||||
Aurora Shelves,1,,,1,0,25 Pacific Road,95101,San José,CA,United States
|
||||
Roger Martins,0,Aurora Shelves,Invoice,1,0,27 Pacific Road,95102,San José,CA,United States
|
||||
House Sales Direct,1,,,1,0,104 Saint Mary Avenue,94059,Redwood,CA,United States
|
||||
Yvan Holiday,0,House Sales Direct,Default,1,0,104 Saint Mary Avenue,94060,Redwood,CA,United States
|
||||
Jack Unsworth,0,House Sales Direct,Invoice,1,0,227 Jackson Road,94061,Redwood,CA,United States
|
||||
Michael Mason,0,,,1,0,16 5th Avenue,94104,San Francisco,CA,United States
|
||||
International Wood,1,,,1,0,748 White House Boulevard,20004,Washington,DC,United States
|
||||
Sharon Pecker,0,International Wood,Invoice,1,0,755 White House Boulevard,20005,Washington,DC,United States
|
|
|
@ -1,8 +0,0 @@
|
|||
Name,Address type,Street,City,Country,Tags,Supplier,Customer,Is a company,Companies that refers to partner / Parent company
|
||||
Wood y Wood Pecker,,"Snow Street, 25",Kainuu,Finland,Supplier,1,0,1,
|
||||
Roger Pecker,Default,"Snow Street, 27",Kainuu,Finland,Supplier,1,0,0,Wood y Wood Pecker
|
||||
Sharon Pecker,Delivery,"Snow Street, 28",Kainuu,Finland,Supplier,1,0,0,Wood y Wood Pecker
|
||||
Thomas Pecker,Contact,"Snow Street, 27",Kainuu,Finland,Supplier,1,0,0,Wood y Wood Pecker
|
||||
Vicking Direct,,"Atonium Street, 45a",Brussels,Belgium,Supplier,1,0,1,
|
||||
Yvan Holiday,Invoice,"Atonium Street, 45b",Brussels,Belgium,Supplier,1,0,0,Vicking Direct
|
||||
Jack Unsworth,Contact,"Atonium Street, 45a",Brussels,Belgium,Supplier,1,0,0,Vicking Direct
|
|
|
@ -229,8 +229,8 @@
|
|||
orders with their respective purchase order lines:</p>
|
||||
<a href="/base_import/static/csv/o2m_purchase_order_lines.csv">Purchase orders with their respective purchase order lines</a>
|
||||
<p>The following CSV file shows how to import
|
||||
suppliers and their respective contacts</p>
|
||||
<a href="/base_import/static/csv/o2m_suppliers_contacts.csv">Suppliers and their respective contacts</a>
|
||||
customers and their respective contacts</p>
|
||||
<a href="/base_import/static/csv/o2m_customers_contacts.csv">Customers and their respective contacts</a>
|
||||
</dd>
|
||||
</dl>
|
||||
|
||||
|
|
|
@ -61,8 +61,8 @@ class RPCSession(object):
|
|||
protocol = m.group(1)
|
||||
if not m:
|
||||
return -1
|
||||
if protocol == 'http://' or protocol == 'http://':
|
||||
self.gateway = XMLRPCGateway(host, port, 'http')
|
||||
if protocol == 'http://' or protocol == 'https://':
|
||||
self.gateway = XMLRPCGateway(host, port, protocol[:-3])
|
||||
elif protocol == 'socket://':
|
||||
|
||||
self.gateway = NETRPCGateway(host, port)
|
||||
|
|
Binary file not shown.
|
@ -344,7 +344,7 @@ instance.board.AddToDashboard = instance.web.search.Input.extend({
|
|||
},
|
||||
load_data:function(){
|
||||
var board = new instance.web.Model('board.board');
|
||||
return board.call('list');
|
||||
return board.call('list', [board.context()]);
|
||||
},
|
||||
_x:function() {
|
||||
if (!instance.webclient) { return $.Deferred().reject(); }
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
<field name="view_id" ref="crm_case_claims_tree_view"/>
|
||||
<field name="context">{"search_default_user_id":uid, "stage_type":'claim'}</field>
|
||||
<field name="search_view_id" ref="crm_claim.view_crm_case_claims_filter"/>
|
||||
<field name="help">Record and track your customers' claims. Claims may be linked to a sales order or a lot. You can send emails with attachments and keep the full history for a claim (emails sent, intervention type and so on). Claims may automatically be linked to an email address using the mail gateway module.</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Record and track your customers' claims. Claims may be linked to a sales order or a lot.You can send emails with attachments and keep the full history for a claim (emails sent, intervention type and so on).Claims may automatically be linked to an email address using the mail gateway module.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.act_window.view" id="action_crm_tag_tree_claim0">
|
||||
|
|
|
@ -88,7 +88,11 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_wiki_tree"/>
|
||||
<field name="search_view_id" ref="view_wiki_filter"/>
|
||||
<field name="help">Create web pages</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new web page.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem id="menu_page" parent="menu_wiki" name="Pages" action="action_page" sequence="10"/>
|
||||
<record id="action_category" model="ir.actions.act_window">
|
||||
|
|
|
@ -24,8 +24,8 @@ import base64
|
|||
import logging
|
||||
|
||||
import openerp
|
||||
from openerp import SUPERUSER_ID
|
||||
from openerp.osv import osv, fields
|
||||
from openerp.osv import fields
|
||||
from openerp import tools
|
||||
from openerp.tools.translate import _
|
||||
from urllib import urlencode, quote as quote
|
||||
|
@ -191,7 +191,6 @@ class email_template(osv.osv):
|
|||
}
|
||||
|
||||
def create_action(self, cr, uid, ids, context=None):
|
||||
vals = {}
|
||||
action_obj = self.pool.get('ir.actions.act_window')
|
||||
data_obj = self.pool.get('ir.model.data')
|
||||
for template in self.browse(cr, uid, ids, context=context):
|
||||
|
@ -199,7 +198,7 @@ class email_template(osv.osv):
|
|||
model_data_id = data_obj._get_id(cr, uid, 'mail', 'email_compose_message_wizard_form')
|
||||
res_id = data_obj.browse(cr, uid, model_data_id, context=context).res_id
|
||||
button_name = _('Send Mail (%s)') % template.name
|
||||
vals['ref_ir_act_window'] = action_obj.create(cr, uid, {
|
||||
act_id = action_obj.create(cr, SUPERUSER_ID, {
|
||||
'name': button_name,
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'mail.compose.message',
|
||||
|
@ -211,27 +210,29 @@ class email_template(osv.osv):
|
|||
'target': 'new',
|
||||
'auto_refresh':1
|
||||
}, context)
|
||||
vals['ref_ir_value'] = self.pool.get('ir.values').create(cr, uid, {
|
||||
ir_values_id = self.pool.get('ir.values').create(cr, SUPERUSER_ID, {
|
||||
'name': button_name,
|
||||
'model': src_obj,
|
||||
'key2': 'client_action_multi',
|
||||
'value': "ir.actions.act_window," + str(vals['ref_ir_act_window']),
|
||||
'value': "ir.actions.act_window,%s" % act_id,
|
||||
'object': True,
|
||||
}, context)
|
||||
self.write(cr, uid, ids, {
|
||||
'ref_ir_act_window': vals.get('ref_ir_act_window',False),
|
||||
'ref_ir_value': vals.get('ref_ir_value',False),
|
||||
}, context)
|
||||
|
||||
template.write({
|
||||
'ref_ir_act_window': act_id,
|
||||
'ref_ir_value': ir_values_id,
|
||||
})
|
||||
|
||||
return True
|
||||
|
||||
def unlink_action(self, cr, uid, ids, context=None):
|
||||
for template in self.browse(cr, uid, ids, context=context):
|
||||
try:
|
||||
if template.ref_ir_act_window:
|
||||
self.pool.get('ir.actions.act_window').unlink(cr, uid, template.ref_ir_act_window.id, context)
|
||||
self.pool.get('ir.actions.act_window').unlink(cr, SUPERUSER_ID, template.ref_ir_act_window.id, context)
|
||||
if template.ref_ir_value:
|
||||
ir_values_obj = self.pool.get('ir.values')
|
||||
ir_values_obj.unlink(cr, uid, template.ref_ir_value.id, context)
|
||||
ir_values_obj.unlink(cr, SUPERUSER_ID, template.ref_ir_value.id, context)
|
||||
except Exception:
|
||||
raise osv.except_osv(_("Warning"), _("Deletion of the action record failed."))
|
||||
return True
|
||||
|
|
|
@ -54,18 +54,22 @@ class mail_compose_message(osv.TransientModel):
|
|||
Indeed, basic mail.compose.message wizard duplicates attachments in mass
|
||||
mailing mode. But in 'single post' mode, attachments of an email template
|
||||
also have to be duplicated to avoid changing their ownership. """
|
||||
if context is None:
|
||||
context = {}
|
||||
wizard_context = dict(context)
|
||||
for wizard in self.browse(cr, uid, ids, context=context):
|
||||
if wizard.template_id and not wizard.template_id.user_signature:
|
||||
wizard_context['mail_notify_user_signature'] = False # template user_signature is added when generating body_html
|
||||
if not wizard.attachment_ids or wizard.composition_mode == 'mass_mail' or not wizard.template_id:
|
||||
continue
|
||||
template = self.pool.get('email.template').browse(cr, uid, wizard.template_id.id, context=context)
|
||||
new_attachment_ids = []
|
||||
for attachment in wizard.attachment_ids:
|
||||
if attachment in template.attachment_ids:
|
||||
if attachment in wizard.template_id.attachment_ids:
|
||||
new_attachment_ids.append(self.pool.get('ir.attachment').copy(cr, uid, attachment.id, {'res_model': 'mail.compose.message', 'res_id': wizard.id}, context=context))
|
||||
else:
|
||||
new_attachment_ids.append(attachment.id)
|
||||
self.write(cr, uid, wizard.id, {'attachment_ids': [(6, 0, new_attachment_ids)]}, context=context)
|
||||
return super(mail_compose_message, self).send_mail(cr, uid, ids, context=context)
|
||||
return super(mail_compose_message, self).send_mail(cr, uid, ids, context=wizard_context)
|
||||
|
||||
def onchange_template_id(self, cr, uid, ids, template_id, composition_mode, model, res_id, context=None):
|
||||
""" - mass_mailing: we cannot render, so return the template values
|
||||
|
|
|
@ -591,6 +591,9 @@
|
|||
<field name="view_mode">tree,graph</field>
|
||||
<field name="context">{"search_default_groupby_vehicle" : True}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new odometer log.
|
||||
</p>
|
||||
<p>
|
||||
Here you can add various odometer entries for all vehicles.
|
||||
You can also show odometer value for a particular vehicle using
|
||||
|
|
|
@ -210,6 +210,11 @@
|
|||
<field name="context">{"default_hr_expense_ok":1}</field>
|
||||
<field name="domain">[('hr_expense_ok','=',True)]</field>
|
||||
<field name="search_view_id" ref="product.product_search_form_view"/>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new expense category.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_hr_product" name="Expense Categories" parent="hr.menu_hr_configuration" action="hr_expense_product"/>
|
||||
|
|
|
@ -146,6 +146,7 @@
|
|||
<field name="number_of_days" string="Allocated Days" sum="Remaining Days"/>
|
||||
<field name="manager_id" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="date_from" invisible="1"/>
|
||||
<!--field name="type"/-->
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<field name="name">timesheet.report.tree</field>
|
||||
<field name="model">timesheet.report</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree colors="blue:state == 'draft';black:state in ('confirm','new');gray:state == 'cancel'" string="Timesheet">
|
||||
<tree colors="blue:state == 'draft';black:state in ('confirm','new');gray:state == 'cancel'" string="Timesheet" create="false">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="name" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
|
|
|
@ -3,7 +3,7 @@ access_hr_timesheet_sheet_sheet_user,hr_timesheet_sheet.sheet.user,model_hr_time
|
|||
access_hr_timesheet_sheet_sheet_system_employee,hr_timesheet_sheet.sheet.system.employee,model_hr_timesheet_sheet_sheet,base.group_user,1,1,1,0
|
||||
access_hr_timesheet_sheet_sheet_day,hr_timesheet_sheet.sheet.day,model_hr_timesheet_sheet_sheet_day,base.group_hr_user,1,1,1,1
|
||||
access_hr_timesheet_sheet_sheet_account,hr_timesheet_sheet.sheet.account,model_hr_timesheet_sheet_sheet_account,base.group_hr_user,1,1,1,1
|
||||
access_hr_timesheet_report,hr.timesheet.report,model_hr_timesheet_report,base.group_hr_manager,1,1,1,1
|
||||
access_hr_timesheet_report,hr.timesheet.report,model_hr_timesheet_report,base.group_hr_manager,1,1,0,0
|
||||
access_hr_analytic_timesheet_system_user,hr.analytic.timesheet.system.user,model_hr_analytic_timesheet,base.group_user,1,0,0,0
|
||||
access_hr_timesheet_sheet_sheet_day,hr.timesheet.sheet.sheet.day.user,model_hr_timesheet_sheet_sheet_day,base.group_user,1,1,1,0
|
||||
access_timesheet_report,timesheet.report,model_timesheet_report,base.group_hr_manager,1,1,1,1
|
||||
access_timesheet_report,timesheet.report,model_timesheet_report,base.group_hr_manager,1,1,0,0
|
||||
|
|
|
|
@ -190,8 +190,13 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
$(this).val(self.sum_box(account, day_count, true));
|
||||
} else {
|
||||
account.days[day_count].lines[0].unit_amount += num - self.sum_box(account, day_count);
|
||||
self.display_totals();
|
||||
self.sync();
|
||||
var product = (account.days[day_count].lines[0].product_id instanceof Array) ? account.days[day_count].lines[0].product_id[0] : account.days[day_count].lines[0].product_id
|
||||
var journal = (account.days[day_count].lines[0].journal_id instanceof Array) ? account.days[day_count].lines[0].journal_id[0] : account.days[day_count].lines[0].journal_id
|
||||
new instance.web.Model("hr.analytic.timesheet").call("on_change_unit_amount", [[], product, account.days[day_count].lines[0].unit_amount, false, false, journal]).then(function(res) {
|
||||
account.days[day_count].lines[0]['amount'] = res.value.amount || 0;
|
||||
self.display_totals();
|
||||
self.sync();
|
||||
});
|
||||
if(!isNaN($(this).val())){
|
||||
$(this).val(self.sum_box(account, day_count, true));
|
||||
}
|
||||
|
@ -308,10 +313,10 @@ openerp.hr_timesheet_sheet = function(instance) {
|
|||
generate_o2m_value: function() {
|
||||
var self = this;
|
||||
var ops = [];
|
||||
|
||||
|
||||
_.each(self.accounts, function(account) {
|
||||
var auth_keys = _.extend(_.clone(account.account_defaults), {
|
||||
name: true, unit_amount: true, date: true, account_id:true,
|
||||
name: true, amount:true, unit_amount: true, date: true, account_id:true,
|
||||
});
|
||||
_.each(account.days, function(day) {
|
||||
_.each(day.lines, function(line) {
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
<para style="terp_default_9">[[ l['vat'] ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_9">[[ l['code'] (l['intra_code']) ]]</para>
|
||||
<para style="terp_default_9">[[ l['code'] ]]([[ l['intra_code'] ]])</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ formatLang(l['amount'], currency_obj=company.currency_id) ]]</para>
|
||||
|
|
|
@ -35,24 +35,24 @@
|
|||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_account_bank_statement_line_coda_tree" model="ir.ui.view">
|
||||
<record id="view_account_bank_statement_line_coda_tree" model="ir.ui.view">
|
||||
<field name="name">account.bank.statement.line.coda.tree</field>
|
||||
<field name="model">account.bank.statement.line</field>
|
||||
<field name="priority">10</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree editable="bottom" string="Statement lines">
|
||||
<field name="statement_id" readonly="1" invisible="1"/>
|
||||
<field name="sequence" readonly="1" invisible="1"/>
|
||||
<field name="date"/>
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
|
||||
<field name="type" on_change="onchange_type(partner_id, type)"/>
|
||||
<field name="account_id" options='{"no_open":True}' domain="[('journal_id','=',parent.journal_id), ('company_id', '=', parent.company_id)]"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('company_id', '=', parent.company_id), ('type', '<>', 'view')]"/>
|
||||
<field name="amount"/>
|
||||
<field name="note"/>
|
||||
</tree>
|
||||
<tree editable="bottom" string="Statement lines" create="0">
|
||||
<field name="sequence" readonly="1" invisible="1"/>
|
||||
<field name="statement_id" readonly="1" />
|
||||
<field name="date"/>
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(partner_id)"/>
|
||||
<field name="type" on_change="onchange_type(partner_id, type)"/>
|
||||
<field name="account_id" options='{"no_open":True}' domain="[('type', '<>', 'view')]"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" domain="[('type', '<>', 'view')]"/>
|
||||
<field name="amount"/>
|
||||
<field name="note"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -150,11 +150,17 @@ class mail_notification(osv.Model):
|
|||
|
||||
return footer
|
||||
|
||||
def _notify(self, cr, uid, msg_id, partners_to_notify=None, context=None):
|
||||
def _notify(self, cr, uid, msg_id, partners_to_notify=None, context=None,
|
||||
force_send=False, user_signature=True):
|
||||
""" Send by email the notification depending on the user preferences
|
||||
|
||||
:param list partners_to_notify: optional list of partner ids restricting
|
||||
the notifications to process
|
||||
:param bool force_send: if True, the generated mail.mail is
|
||||
immediately sent after being created, as if the scheduler
|
||||
was executed for this message only.
|
||||
:param bool user_signature: if True, the generated mail.mail body is
|
||||
the body of the related mail.message with the author's signature
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
|
@ -189,8 +195,9 @@ class mail_notification(osv.Model):
|
|||
# add signature
|
||||
body_html = msg.body
|
||||
user_id = msg.author_id and msg.author_id.user_ids and msg.author_id.user_ids[0] and msg.author_id.user_ids[0].id or None
|
||||
signature_company = self.get_signature_footer(cr, uid, user_id, res_model=msg.model, res_id=msg.res_id, context=context)
|
||||
body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div')
|
||||
if user_signature:
|
||||
signature_company = self.get_signature_footer(cr, uid, user_id, res_model=msg.model, res_id=msg.res_id, context=context)
|
||||
body_html = tools.append_content_to_html(body_html, signature_company, plaintext=False, container_tag='div')
|
||||
|
||||
references = False
|
||||
if msg.parent_id:
|
||||
|
@ -203,13 +210,9 @@ class mail_notification(osv.Model):
|
|||
'recipient_ids': [(4, id) for id in notify_partner_ids],
|
||||
'references': references,
|
||||
}
|
||||
if msg.email_from:
|
||||
mail_values['email_from'] = msg.email_from
|
||||
if msg.reply_to:
|
||||
mail_values['reply_to'] = msg.reply_to
|
||||
mail_mail = self.pool.get('mail.mail')
|
||||
email_notif_id = mail_mail.create(cr, uid, mail_values, context=context)
|
||||
try:
|
||||
return mail_mail.send(cr, uid, [email_notif_id], context=context)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
if force_send:
|
||||
mail_mail.send(cr, uid, [email_notif_id], context=context)
|
||||
return True
|
||||
|
|
|
@ -55,7 +55,6 @@ class mail_mail(osv.Model):
|
|||
'auto_delete': fields.boolean('Auto Delete',
|
||||
help="Permanently delete this email after sending it, to save space"),
|
||||
'references': fields.text('References', help='Message references, such as identifiers of previous messages', readonly=1),
|
||||
'email_from': fields.char('From', help='Message sender, taken from user preferences.'),
|
||||
'email_to': fields.text('To', help='Message recipients (emails)'),
|
||||
'recipient_ids': fields.many2many('res.partner', string='To (Partners)'),
|
||||
'email_cc': fields.char('Cc', help='Carbon copy message recipients'),
|
||||
|
@ -67,16 +66,13 @@ class mail_mail(osv.Model):
|
|||
}
|
||||
|
||||
def _get_default_from(self, cr, uid, context=None):
|
||||
this = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
|
||||
if this.alias_domain:
|
||||
return '%s <%s@%s>' % (this.name, this.alias_name, this.alias_domain)
|
||||
elif this.email:
|
||||
return '%s <%s>' % (this.name, this.email)
|
||||
raise osv.except_osv(_('Invalid Action!'), _("Unable to send email, please configure the sender's email address or alias."))
|
||||
""" Kept for compatibility
|
||||
TDE TODO: remove me in 8.0
|
||||
"""
|
||||
return self.pool['mail.message']._get_default_from(cr, uid, context=context)
|
||||
|
||||
_defaults = {
|
||||
'state': 'outgoing',
|
||||
'email_from': lambda self, cr, uid, ctx=None: self._get_default_from(cr, uid, ctx),
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fields, context=None):
|
||||
|
@ -93,19 +89,24 @@ class mail_mail(osv.Model):
|
|||
# if value specified: directly return it
|
||||
if values.get('reply_to'):
|
||||
return values.get('reply_to')
|
||||
format_name = True # whether to use a 'Followers of Pigs <pigs@openerp.com' format
|
||||
|
||||
mailgateway = True # tells whether the answer will go through the mailgateway, leading to the formatting of reply_to <Followers of ...>
|
||||
ir_config_parameter = self.pool.get("ir.config_parameter")
|
||||
catchall_domain = ir_config_parameter.get_param(cr, uid, "mail.catchall.domain", context=context)
|
||||
|
||||
# model, res_id, email_from, reply_to: comes from values OR related message
|
||||
message = None
|
||||
# model, res_id, email_from: comes from values OR related message
|
||||
model, res_id, email_from = values.get('model'), values.get('res_id'), values.get('email_from')
|
||||
if values.get('mail_message_id'):
|
||||
message = self.pool.get('mail.message').browse(cr, uid, values.get('mail_message_id'), context=context)
|
||||
model = values.get('model', message and message.model or False)
|
||||
res_id = values.get('res_id', message and message.res_id or False)
|
||||
email_from = values.get('email_from', message and message.email_from or False)
|
||||
email_reply_to = message and message.reply_to or False
|
||||
if message.reply_to:
|
||||
email_reply_to = message.reply_to
|
||||
format_name = False
|
||||
if not model:
|
||||
model = message.model
|
||||
if not res_id:
|
||||
res_id = message.res_id
|
||||
if not email_from:
|
||||
email_from = message.email_from
|
||||
|
||||
# if model and res_id: try to use ``message_get_reply_to`` that returns the document alias
|
||||
if not email_reply_to and model and res_id and hasattr(self.pool[model], 'message_get_reply_to'):
|
||||
|
@ -115,16 +116,12 @@ class mail_mail(osv.Model):
|
|||
catchall_alias = ir_config_parameter.get_param(cr, uid, "mail.catchall.alias", context=context)
|
||||
if catchall_domain and catchall_alias:
|
||||
email_reply_to = '%s@%s' % (catchall_alias, catchall_domain)
|
||||
# no alias reply_to -> reply_to will be the email_from, only the email part
|
||||
if not email_reply_to and email_from:
|
||||
emails = tools.email_split(email_from)
|
||||
if emails:
|
||||
email_reply_to = emails[0]
|
||||
if emails[0].split('@')[1] != catchall_domain:
|
||||
mailgateway = False
|
||||
|
||||
# format 'Document name <email_address>'
|
||||
if email_reply_to and model and res_id and mailgateway:
|
||||
if email_reply_to and model and res_id and format_name:
|
||||
emails = tools.email_split(email_reply_to)
|
||||
if emails:
|
||||
email_reply_to = emails[0]
|
||||
document_name = self.pool[model].name_get(cr, SUPERUSER_ID, [res_id], context=context)[0]
|
||||
if document_name:
|
||||
# sanitize document name
|
||||
|
|
|
@ -115,7 +115,7 @@
|
|||
<field name="res_model">mail.mail</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context">{'search_default_outgoing': 1, 'search_default_type_email': 1}</field>
|
||||
<field name="context">{'search_default_outgoing': 1}</field>
|
||||
<field name="search_view_id" ref="view_mail_search"/>
|
||||
</record>
|
||||
|
||||
|
|
|
@ -196,6 +196,14 @@ class mail_message(osv.Model):
|
|||
def _needaction_domain_get(self, cr, uid, context=None):
|
||||
return [('to_read', '=', True)]
|
||||
|
||||
def _get_default_from(self, cr, uid, context=None):
|
||||
this = self.pool.get('res.users').browse(cr, SUPERUSER_ID, uid, context=context)
|
||||
if this.alias_domain:
|
||||
return '%s <%s@%s>' % (this.name, this.alias_name, this.alias_domain)
|
||||
elif this.email:
|
||||
return '%s <%s>' % (this.name, this.email)
|
||||
raise osv.except_osv(_('Invalid Action!'), _("Unable to send email, please configure the sender's email address or alias."))
|
||||
|
||||
def _get_default_author(self, cr, uid, context=None):
|
||||
return self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
|
||||
|
||||
|
@ -204,7 +212,7 @@ class mail_message(osv.Model):
|
|||
'date': lambda *a: fields.datetime.now(),
|
||||
'author_id': lambda self, cr, uid, ctx=None: self._get_default_author(cr, uid, ctx),
|
||||
'body': '',
|
||||
'email_from': lambda self, cr, uid, ctx=None: self.pool.get('mail.mail')._get_default_from(cr, uid, ctx),
|
||||
'email_from': lambda self, cr, uid, ctx=None: self._get_default_from(cr, uid, ctx),
|
||||
}
|
||||
|
||||
#------------------------------------------------------
|
||||
|
@ -329,8 +337,10 @@ class mail_message(osv.Model):
|
|||
for key, message in message_tree.iteritems():
|
||||
if message.author_id:
|
||||
partner_ids |= set([message.author_id.id])
|
||||
if message.notified_partner_ids:
|
||||
if message.subtype_id and message.notified_partner_ids: # take notified people of message with a subtype
|
||||
partner_ids |= set([partner.id for partner in message.notified_partner_ids])
|
||||
elif not message.subtype_id and message.partner_ids: # take specified people of message without a subtype (log)
|
||||
partner_ids |= set([partner.id for partner in message.partner_ids])
|
||||
if message.attachment_ids:
|
||||
attachment_ids |= set([attachment.id for attachment in message.attachment_ids])
|
||||
# Read partners as SUPERUSER -> display the names like classic m2o even if no access
|
||||
|
@ -350,9 +360,12 @@ class mail_message(osv.Model):
|
|||
else:
|
||||
author = (0, message.email_from)
|
||||
partner_ids = []
|
||||
for partner in message.notified_partner_ids:
|
||||
if partner.id in partner_tree:
|
||||
partner_ids.append(partner_tree[partner.id])
|
||||
if message.subtype_id:
|
||||
partner_ids = [partner_tree[partner.id] for partner in message.notified_partner_ids
|
||||
if partner.id in partner_tree]
|
||||
else:
|
||||
partner_ids = [partner_tree[partner.id] for partner in message.partner_ids
|
||||
if partner.id in partner_tree]
|
||||
attachment_ids = []
|
||||
for attachment in message.attachment_ids:
|
||||
if attachment.id in attachments_tree:
|
||||
|
@ -766,7 +779,9 @@ class mail_message(osv.Model):
|
|||
elif not values.get('message_id'):
|
||||
values['message_id'] = tools.generate_tracking_message_id('private')
|
||||
newid = super(mail_message, self).create(cr, uid, values, context)
|
||||
self._notify(cr, uid, newid, context=context)
|
||||
self._notify(cr, uid, newid, context=context,
|
||||
force_send=context.get('mail_notify_force_send', True),
|
||||
user_signature=context.get('mail_notify_user_signature', True))
|
||||
# TDE FIXME: handle default_starred. Why not setting an inv on starred ?
|
||||
# Because starred will call set_message_starred, that looks for notifications.
|
||||
# When creating a new mail_message, it will create a notification to a message
|
||||
|
@ -880,20 +895,16 @@ class mail_message(osv.Model):
|
|||
return ''
|
||||
return result
|
||||
|
||||
def _notify(self, cr, uid, newid, context=None):
|
||||
def _notify(self, cr, uid, newid, context=None, force_send=False, user_signature=True):
|
||||
""" Add the related record followers to the destination partner_ids if is not a private message.
|
||||
Call mail_notification.notify to manage the email sending
|
||||
"""
|
||||
notification_obj = self.pool.get('mail.notification')
|
||||
message = self.browse(cr, uid, newid, context=context)
|
||||
|
||||
partners_to_notify = set([])
|
||||
# message has no subtype_id: pure log message -> no partners, no one notified
|
||||
if not message.subtype_id:
|
||||
return True
|
||||
|
||||
# all followers of the mail.message document have to be added as partners and notified
|
||||
if message.model and message.res_id:
|
||||
# all followers of the mail.message document have to be added as partners and notified if a subtype is defined (otherwise: log message)
|
||||
if message.subtype_id and message.model and message.res_id:
|
||||
fol_obj = self.pool.get("mail.followers")
|
||||
# browse as SUPERUSER because rules could restrict the search results
|
||||
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [
|
||||
|
@ -903,7 +914,7 @@ class mail_message(osv.Model):
|
|||
], context=context)
|
||||
partners_to_notify |= set(fo.partner_id for fo in fol_obj.browse(cr, SUPERUSER_ID, fol_ids, context=context))
|
||||
# remove me from notified partners, unless the message is written on my own wall
|
||||
if message.author_id and message.model == "res.partner" and message.res_id == message.author_id.id:
|
||||
if message.subtype_id and message.author_id and message.model == "res.partner" and message.res_id == message.author_id.id:
|
||||
partners_to_notify |= set([message.author_id])
|
||||
elif message.author_id:
|
||||
partners_to_notify -= set([message.author_id])
|
||||
|
@ -914,7 +925,8 @@ class mail_message(osv.Model):
|
|||
|
||||
# notify
|
||||
if partners_to_notify:
|
||||
notification_obj._notify(cr, uid, newid, partners_to_notify=[p.id for p in partners_to_notify], context=context)
|
||||
notification_obj._notify(cr, uid, newid, partners_to_notify=[p.id for p in partners_to_notify], context=context,
|
||||
force_send=force_send, user_signature=user_signature)
|
||||
message.refresh()
|
||||
|
||||
# An error appear when a user receive a notification without notifying
|
||||
|
|
|
@ -30,9 +30,9 @@
|
|||
<field name="subject"/>
|
||||
<field name="author_id"/>
|
||||
<field name="email_from"/>
|
||||
<field name="reply_to"/>
|
||||
<field name="date"/>
|
||||
<field name="type"/>
|
||||
<field name="subtype_id"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="model"/>
|
||||
|
@ -40,6 +40,7 @@
|
|||
<field name="parent_id"/>
|
||||
<field name="partner_ids" widget="many2many_tags"/>
|
||||
<field name="notified_partner_ids" widget="many2many_tags"/>
|
||||
<field name="subtype_id"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="body"/>
|
||||
|
|
|
@ -580,7 +580,7 @@ class mail_thread(osv.AbstractModel):
|
|||
ret_dict = {}
|
||||
for model_name in self.pool.obj_list():
|
||||
model = self.pool[model_name]
|
||||
if 'mail.thread' in getattr(model, '_inherit', []):
|
||||
if hasattr(model, "message_process") and hasattr(model, "message_post"):
|
||||
ret_dict[model_name] = model._description
|
||||
return ret_dict
|
||||
|
||||
|
@ -815,6 +815,9 @@ class mail_thread(osv.AbstractModel):
|
|||
else:
|
||||
assert thread_id == 0, "Posting a message without model should be with a null res_id, to create a private message."
|
||||
model_pool = self.pool.get('mail.thread')
|
||||
if not hasattr(model_pool, 'message_post'):
|
||||
context['thread_model'] = model
|
||||
model_pool = self.pool['mail.thread']
|
||||
new_msg_id = model_pool.message_post(cr, uid, [thread_id], context=context, subtype='mail.mt_comment', **msg)
|
||||
|
||||
if partner_ids:
|
||||
|
@ -1149,7 +1152,7 @@ class mail_thread(osv.AbstractModel):
|
|||
model = False
|
||||
if thread_id:
|
||||
model = context.get('thread_model', self._name) if self._name == 'mail.thread' else self._name
|
||||
if model != self._name:
|
||||
if model != self._name and hasattr(self.pool[model], 'message_post'):
|
||||
del context['thread_model']
|
||||
return self.pool[model].message_post(cr, uid, thread_id, body=body, subject=subject, type=type, subtype=subtype, parent_id=parent_id, attachments=attachments, context=context, content_subtype=content_subtype, **kwargs)
|
||||
|
||||
|
@ -1308,7 +1311,10 @@ class mail_thread(osv.AbstractModel):
|
|||
|
||||
def message_subscribe(self, cr, uid, ids, partner_ids, subtype_ids=None, context=None):
|
||||
""" Add partners to the records followers. """
|
||||
user_pid = self.pool.get('res.users').read(cr, uid, uid, ['partner_id'], context=context)['partner_id'][0]
|
||||
mail_followers_obj = self.pool.get('mail.followers')
|
||||
subtype_obj = self.pool.get('mail.message.subtype')
|
||||
|
||||
user_pid = self.pool.get('res.users').browse(cr, uid, uid, context=context).partner_id.id
|
||||
if set(partner_ids) == set([user_pid]):
|
||||
try:
|
||||
self.check_access_rights(cr, uid, 'read')
|
||||
|
@ -1317,27 +1323,35 @@ class mail_thread(osv.AbstractModel):
|
|||
else:
|
||||
self.check_access_rights(cr, uid, 'write')
|
||||
|
||||
# subscribe partners
|
||||
self.write(cr, SUPERUSER_ID, ids, {'message_follower_ids': [(4, pid) for pid in partner_ids]}, context=context)
|
||||
for record in self.browse(cr, SUPERUSER_ID, ids, context=context):
|
||||
existing_pids = set([f.id for f in record.message_follower_ids
|
||||
if f.id in partner_ids])
|
||||
new_pids = set(partner_ids) - existing_pids
|
||||
|
||||
# subtype specified: update the subscriptions
|
||||
fol_obj = self.pool.get('mail.followers')
|
||||
if subtype_ids is not None:
|
||||
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [('res_model', '=', self._name), ('res_id', 'in', ids), ('partner_id', 'in', partner_ids)], context=context)
|
||||
fol_obj.write(cr, SUPERUSER_ID, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context)
|
||||
# no subtypes: default ones for new subscription, do not update existing subscriptions
|
||||
else:
|
||||
# search new subscriptions: subtype_ids is False
|
||||
fol_ids = fol_obj.search(cr, SUPERUSER_ID, [
|
||||
('res_model', '=', self._name),
|
||||
('res_id', 'in', ids),
|
||||
('partner_id', 'in', partner_ids),
|
||||
('subtype_ids', '=', False)
|
||||
], context=context)
|
||||
if fol_ids:
|
||||
subtype_obj = self.pool.get('mail.message.subtype')
|
||||
subtype_ids = subtype_obj.search(cr, uid, [('default', '=', True), '|', ('res_model', '=', self._name), ('res_model', '=', False)], context=context)
|
||||
fol_obj.write(cr, SUPERUSER_ID, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context)
|
||||
# subtype_ids specified: update already subscribed partners
|
||||
if subtype_ids and existing_pids:
|
||||
fol_ids = mail_followers_obj.search(cr, SUPERUSER_ID, [
|
||||
('res_model', '=', self._name),
|
||||
('res_id', '=', record.id),
|
||||
('partner_id', 'in', list(existing_pids)),
|
||||
], context=context)
|
||||
mail_followers_obj.write(cr, SUPERUSER_ID, fol_ids, {'subtype_ids': [(6, 0, subtype_ids)]}, context=context)
|
||||
# subtype_ids not specified: do not update already subscribed partner, fetch default subtypes for new partners
|
||||
else:
|
||||
subtype_ids = subtype_obj.search(cr, uid, [
|
||||
('default', '=', True),
|
||||
'|',
|
||||
('res_model', '=', self._name),
|
||||
('res_model', '=', False)
|
||||
], context=context)
|
||||
# subscribe new followers
|
||||
for new_pid in new_pids:
|
||||
mail_followers_obj.create(cr, SUPERUSER_ID, {
|
||||
'res_model': self._name,
|
||||
'res_id': record.id,
|
||||
'partner_id': new_pid,
|
||||
'subtype_ids': [(6, 0, subtype_ids)],
|
||||
}, context=context)
|
||||
|
||||
return True
|
||||
|
||||
|
|
|
@ -267,6 +267,7 @@ openerp.mail = function (session) {
|
|||
|
||||
//formating and add some fields for render
|
||||
this.date = this.date ? session.web.str_to_datetime(this.date) : false;
|
||||
this.display_date = this.date.toString('ddd MMM dd yyyy HH:mm');
|
||||
if (this.date && new Date().getTime()-this.date.getTime() < 7*24*60*60*1000) {
|
||||
this.timerelative = $.timeago(this.date);
|
||||
}
|
||||
|
@ -986,8 +987,8 @@ openerp.mail = function (session) {
|
|||
expender: function () {
|
||||
this.$('.oe_msg_body:first').expander({
|
||||
slicePoint: this.options.truncate_limit,
|
||||
expandText: 'read more',
|
||||
userCollapseText: 'read less',
|
||||
expandText: _t('read more'),
|
||||
userCollapseText: _t('read less'),
|
||||
detailClass: 'oe_msg_tail',
|
||||
moreClass: 'oe_mail_expand',
|
||||
lessClass: 'oe_mail_reduce',
|
||||
|
|
|
@ -281,16 +281,16 @@
|
|||
<span class='oe_subtle'>•</span>
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="widget.type == 'comment' and ! widget.subtype">
|
||||
<t t-if="widget.type == 'comment' and ! widget.subtype and widget.partner_ids.length == 0">
|
||||
logged a note
|
||||
</t>
|
||||
<t t-if="(widget.type == 'comment' or widget.type == 'email') and widget.subtype">
|
||||
<t t-if="(widget.type == 'comment' or widget.type == 'email') and (widget.subtype or widget.partner_ids.length > 0)">
|
||||
to
|
||||
<t t-if="widget.partner_ids.length == 0">
|
||||
nobody
|
||||
</t>
|
||||
</t>
|
||||
<t t-if="widget.type == 'notification' or ( (widget.type == 'email' or widget.type == 'comment') and widget.subtype)"
|
||||
<t t-if="widget.type == 'notification' or ( (widget.type == 'email' or widget.type == 'comment') and (widget.subtype or widget.partner_ids.length > 0))"
|
||||
t-foreach="widget.partner_ids.slice(0, 3)" t-as="partner">
|
||||
<span t-attf-class="oe_partner_follower">
|
||||
<a t-if="widget.options.show_link" t-attf-href="#model=res.partner&id=#{partner[0]}"><t t-raw="partner[1]"/></a>
|
||||
|
@ -305,7 +305,10 @@
|
|||
notified
|
||||
</t>
|
||||
<span class='oe_subtle'>•</span>
|
||||
<span t-att-title="widget.date"><t t-if="widget.timerelative" t-raw="widget.timerelative"/><t t-if="!widget.timerelative" t-raw="widget.date"/></span>
|
||||
<span t-att-title="widget.date">
|
||||
<t t-if="widget.timerelative" t-raw="widget.timerelative"/>
|
||||
<t t-if="!widget.timerelative" t-raw="widget.display_date"/>
|
||||
</span>
|
||||
<span t-if="!widget.options.readonly" class='oe_subtle'>•</span>
|
||||
<t t-if="!widget.options.readonly" t-call="mail.thread.message.vote"/>
|
||||
</div>
|
||||
|
|
|
@ -69,6 +69,7 @@ class TestMailBase(common.TransactionCase):
|
|||
self.group_employee_id = group_employee_ref and group_employee_ref[1] or False
|
||||
|
||||
# Test users to use through the various tests
|
||||
self.res_users.write(cr, uid, uid, {'name': 'Administrator'})
|
||||
self.user_raoul_id = self.res_users.create(cr, uid,
|
||||
{'name': 'Raoul Grosbedon', 'signature': 'SignRaoul', 'email': 'raoul@raoul.fr', 'login': 'raoul', 'groups_id': [(6, 0, [self.group_employee_id])]})
|
||||
self.user_bert_id = self.res_users.create(cr, uid,
|
||||
|
|
|
@ -124,6 +124,102 @@ class TestMailgateway(TestMailBase):
|
|||
self.assertEqual(partner_info['partner_id'], p_b_id,
|
||||
'mail_thread: message_find_partner_from_emails wrong partner found')
|
||||
|
||||
def test_05_mail_message_mail_mail(self):
|
||||
""" Tests designed for testing email values based on mail.message, aliases, ... """
|
||||
cr, uid, user_raoul_id = self.cr, self.uid, self.user_raoul_id
|
||||
|
||||
# Data: update + generic variables
|
||||
reply_to1 = '_reply_to1@example.com'
|
||||
reply_to2 = '_reply_to2@example.com'
|
||||
email_from1 = 'from@example.com'
|
||||
alias_domain = 'schlouby.fr'
|
||||
raoul_from = 'Raoul Grosbedon <raoul@raoul.fr>'
|
||||
raoul_from_alias = 'Raoul Grosbedon <raoul@schlouby.fr>'
|
||||
raoul_reply = '"Followers of Pigs" <raoul@raoul.fr>'
|
||||
raoul_reply_alias = '"Followers of Pigs" <group+pigs@schlouby.fr>'
|
||||
# Data: remove alias_domain to see emails with alias
|
||||
param_ids = self.registry('ir.config_parameter').search(cr, uid, [('key', '=', 'mail.catchall.domain')])
|
||||
self.registry('ir.config_parameter').unlink(cr, uid, param_ids)
|
||||
|
||||
# Do: free message; specified values > default values
|
||||
msg_id = self.mail_message.create(cr, user_raoul_id, {'reply_to': reply_to1, 'email_from': email_from1})
|
||||
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
|
||||
# Test: message content
|
||||
self.assertIn('reply_to', msg.message_id,
|
||||
'mail_message: message_id should be specific to a mail_message with a given reply_to')
|
||||
self.assertEqual(msg.reply_to, reply_to1,
|
||||
'mail_message: incorrect reply_to: should come from values')
|
||||
self.assertEqual(msg.email_from, email_from1,
|
||||
'mail_message: incorrect email_from: should come from values')
|
||||
# Do: create a mail_mail with the previous mail_message
|
||||
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
|
||||
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
|
||||
# Test: mail_mail content
|
||||
self.assertEqual(mail.reply_to, reply_to1,
|
||||
'mail_mail: incorrect reply_to: should come from mail.message')
|
||||
self.assertEqual(mail.email_from, email_from1,
|
||||
'mail_mail: incorrect email_from: should come from mail.message')
|
||||
# Do: create a mail_mail with the previous mail_message + specified reply_to
|
||||
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel', 'reply_to': reply_to2})
|
||||
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
|
||||
# Test: mail_mail content
|
||||
self.assertEqual(mail.reply_to, reply_to2,
|
||||
'mail_mail: incorrect reply_to: should come from values')
|
||||
self.assertEqual(mail.email_from, email_from1,
|
||||
'mail_mail: incorrect email_from: should come from mail.message')
|
||||
|
||||
# Do: mail_message attached to a document
|
||||
msg_id = self.mail_message.create(cr, user_raoul_id, {'model': 'mail.group', 'res_id': self.group_pigs_id})
|
||||
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
|
||||
# Test: message content
|
||||
self.assertIn('mail.group', msg.message_id,
|
||||
'mail_message: message_id should contain model')
|
||||
self.assertIn('%s' % self.group_pigs_id, msg.message_id,
|
||||
'mail_message: message_id should contain res_id')
|
||||
self.assertFalse(msg.reply_to,
|
||||
'mail_message: incorrect reply_to: should not be generated if not specified')
|
||||
self.assertEqual(msg.email_from, raoul_from,
|
||||
'mail_message: incorrect email_from: should be Raoul')
|
||||
# Do: create a mail_mail based on the previous mail_message
|
||||
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
|
||||
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
|
||||
# Test: mail_mail content
|
||||
self.assertEqual(mail.reply_to, raoul_reply,
|
||||
'mail_mail: incorrect reply_to: should be Raoul')
|
||||
|
||||
# Data: set catchall domain
|
||||
self.registry('ir.config_parameter').set_param(cr, uid, 'mail.catchall.domain', alias_domain)
|
||||
|
||||
# Update message
|
||||
self.mail_message.write(cr, user_raoul_id, [msg_id], {'email_from': False, 'reply_to': False})
|
||||
msg.refresh()
|
||||
# Do: create a mail_mail based on the previous mail_message
|
||||
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
|
||||
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
|
||||
# Test: mail_mail content
|
||||
self.assertEqual(mail.reply_to, raoul_reply_alias,
|
||||
'mail_mail: incorrect reply_to: should be Pigs alias')
|
||||
|
||||
# Update message: test alias on email_from
|
||||
msg_id = self.mail_message.create(cr, user_raoul_id, {})
|
||||
msg = self.mail_message.browse(cr, user_raoul_id, msg_id)
|
||||
# Do: create a mail_mail based on the previous mail_message
|
||||
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
|
||||
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
|
||||
# Test: mail_mail content
|
||||
self.assertEqual(mail.reply_to, raoul_from_alias,
|
||||
'mail_mail: incorrect reply_to: should be message email_from using Raoul alias')
|
||||
|
||||
# Update message
|
||||
self.mail_message.write(cr, user_raoul_id, [msg_id], {'res_id': False, 'email_from': 'someone@schlouby.fr', 'reply_to': False})
|
||||
msg.refresh()
|
||||
# Do: create a mail_mail based on the previous mail_message
|
||||
mail_id = self.mail_mail.create(cr, user_raoul_id, {'mail_message_id': msg_id, 'state': 'cancel'})
|
||||
mail = self.mail_mail.browse(cr, user_raoul_id, mail_id)
|
||||
# Test: mail_mail content
|
||||
self.assertEqual(mail.reply_to, msg.email_from,
|
||||
'mail_mail: incorrect reply_to: should be message email_from')
|
||||
|
||||
def test_05_mail_message_mail_mail(self):
|
||||
""" Tests designed for testing email values based on mail.message, aliases, ... """
|
||||
cr, uid = self.cr, self.uid
|
||||
|
|
|
@ -126,7 +126,6 @@ class mail_compose_message(osv.TransientModel):
|
|||
|
||||
_defaults = {
|
||||
'composition_mode': 'comment',
|
||||
'email_from': lambda self, cr, uid, ctx={}: self.pool.get('mail.mail')._get_default_from(cr, uid, context=ctx),
|
||||
'body': lambda self, cr, uid, ctx={}: '',
|
||||
'subject': lambda self, cr, uid, ctx={}: False,
|
||||
'partner_ids': lambda self, cr, uid, ctx={}: [],
|
||||
|
@ -158,7 +157,7 @@ class mail_compose_message(osv.TransientModel):
|
|||
|
||||
return super(mail_compose_message, self).check_access_rule(cr, uid, ids, operation, context=context)
|
||||
|
||||
def _notify(self, cr, uid, newid, context=None):
|
||||
def _notify(self, cr, uid, newid, context=None, force_send=False, user_signature=True):
|
||||
""" Override specific notify method of mail.message, because we do
|
||||
not want that feature in the wizard. """
|
||||
return
|
||||
|
@ -235,6 +234,9 @@ class mail_compose_message(osv.TransientModel):
|
|||
for wizard in self.browse(cr, uid, ids, context=context):
|
||||
mass_mail_mode = wizard.composition_mode == 'mass_mail'
|
||||
active_model_pool = self.pool[wizard.model if wizard.model else 'mail.thread']
|
||||
if not hasattr(active_model_pool, 'message_post'):
|
||||
context['thread_model'] = wizard.model
|
||||
active_model_pool = self.pool['mail.thread']
|
||||
|
||||
# wizard works in batch mode: [res_id] or active_ids
|
||||
res_ids = active_ids if mass_mail_mode and wizard.model and active_ids else [wizard.res_id]
|
||||
|
@ -257,13 +259,15 @@ class mail_compose_message(osv.TransientModel):
|
|||
new_attach_id = ir_attachment_obj.copy(cr, uid, attach_id, {'res_model': self._name, 'res_id': wizard.id}, context=context)
|
||||
attachment_ids.append(new_attach_id)
|
||||
post_values['attachment_ids'] = attachment_ids
|
||||
post_values.update(email_dict)
|
||||
# email_from: mass mailing only can specify another email_from
|
||||
if email_dict.get('email_from'):
|
||||
post_values['email_from'] = email_dict.pop('email_from')
|
||||
# replies redirection: mass mailing only
|
||||
if not wizard.same_thread:
|
||||
post_values['reply_to'] = email_dict.pop('reply_to')
|
||||
else:
|
||||
email_dict.pop('reply_to')
|
||||
post_values.update(email_dict)
|
||||
# clean the context (hint: mass mailing sets some default values that
|
||||
# could be wrongly interpreted by mail_mail)
|
||||
context.pop('default_email_to', None)
|
||||
|
@ -280,11 +284,10 @@ class mail_compose_message(osv.TransientModel):
|
|||
elif mass_mail_mode: # mass mail: is a log pushed to recipients unless specified, author not added
|
||||
if not wizard.notify:
|
||||
subtype = False
|
||||
context = dict(context, mail_create_nosubscribe=True) # add context key to avoid subscribing the author
|
||||
msg_id = active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype=subtype, context=context, **post_values)
|
||||
# mass_mailing, post without notify: notify specific partners
|
||||
if mass_mail_mode and not wizard.notify and post_values['partner_ids']:
|
||||
self.pool.get('mail.notification')._notify(cr, uid, msg_id, post_values['partner_ids'], context=context)
|
||||
context = dict(context,
|
||||
mail_notify_force_send=False, # do not send emails directly but use the queue instead
|
||||
mail_create_nosubscribe=True) # add context key to avoid subscribing the author
|
||||
active_model_pool.message_post(cr, uid, [res_id], type='comment', subtype=subtype, context=context, **post_values)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
// hide()s
|
||||
|
||||
function openerp_pos_screens(instance, module){ //module is instance.point_of_sale
|
||||
var QWeb = instance.web.qweb;
|
||||
var QWeb = instance.web.qweb,
|
||||
_t = instance.web._t;
|
||||
|
||||
module.ScreenSelector = instance.web.Class.extend({
|
||||
init: function(options){
|
||||
|
@ -264,7 +265,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
// we add the help button by default. we do this because the buttons are cleared on each refresh so that
|
||||
// the button stay local to each screen
|
||||
this.pos_widget.left_action_bar.add_new_button({
|
||||
label: 'help',
|
||||
label: _t('Help'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/help.png',
|
||||
click: function(){ self.help_button_action(); },
|
||||
});
|
||||
|
@ -454,7 +455,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
},500);
|
||||
|
||||
this.add_action_button({
|
||||
label: 'back',
|
||||
label: _t('Back'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/go-previous.png',
|
||||
click: function(){
|
||||
clearInterval(this.intervalID);
|
||||
|
@ -483,7 +484,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
|
||||
this.add_action_button({
|
||||
label: 'back',
|
||||
label: _t('Back'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/go-previous.png',
|
||||
click: function(){
|
||||
self.pos_widget.screen_selector.set_current_screen(self.previous_screen);
|
||||
|
@ -491,7 +492,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
});
|
||||
|
||||
this.validate_button = this.add_action_button({
|
||||
label: 'Validate',
|
||||
label: _t('Validate'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/validate.png',
|
||||
click: function(){
|
||||
self.order_product();
|
||||
|
@ -674,7 +675,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
}
|
||||
|
||||
this.add_action_button({
|
||||
label: 'back',
|
||||
label: _t('Back'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/go-previous.png',
|
||||
click: function(){
|
||||
self.queue.schedule(self.cancel);
|
||||
|
@ -714,7 +715,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
var self = this;
|
||||
|
||||
this.add_action_button({
|
||||
label: 'help',
|
||||
label: _t('Help'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/help.png',
|
||||
click: function(){
|
||||
$('.goodbye-message').css({opacity:1}).hide();
|
||||
|
@ -768,7 +769,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
|
||||
if(this.pos_widget.screen_selector.current_mode === 'client'){
|
||||
this.add_action_button({
|
||||
label: 'pay',
|
||||
label: _t('Pay'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/go-next.png',
|
||||
click: function(){
|
||||
self.pos_widget.screen_selector.set_current_screen(self.client_next_screen);
|
||||
|
@ -808,13 +809,13 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
var self = this;
|
||||
|
||||
this.add_action_button({
|
||||
label: 'Print',
|
||||
label: _t('Print'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/printer.png',
|
||||
click: function(){ self.print(); },
|
||||
});
|
||||
|
||||
this.add_action_button({
|
||||
label: 'Next Order',
|
||||
label: _t('Next Order'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/go-next.png',
|
||||
click: function() { self.finishOrder(); },
|
||||
});
|
||||
|
@ -870,7 +871,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
this.set_numpad_state(this.pos_widget.numpad.state);
|
||||
|
||||
this.back_button = this.add_action_button({
|
||||
label: 'Back',
|
||||
label: _t('Back'),
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/go-previous.png',
|
||||
click: function(){
|
||||
self.pos_widget.screen_selector.set_current_screen(self.back_screen);
|
||||
|
@ -878,7 +879,7 @@ function openerp_pos_screens(instance, module){ //module is instance.point_of_sa
|
|||
});
|
||||
|
||||
this.validate_button = this.add_action_button({
|
||||
label: 'Validate',
|
||||
label: _t('Validate'),
|
||||
name: 'validation',
|
||||
icon: '/point_of_sale/static/src/img/icons/png48/validate.png',
|
||||
click: function(){
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
function openerp_pos_widgets(instance, module){ //module is instance.point_of_sale
|
||||
var QWeb = instance.web.qweb;
|
||||
var QWeb = instance.web.qweb,
|
||||
_t = instance.web._t;
|
||||
|
||||
// The ImageCache is used to hide the latency of the application cache on-disk access in chrome
|
||||
// that causes annoying flickering on product pictures. Why the hell a simple access to
|
||||
|
@ -980,13 +981,13 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
this.onscreen_keyboard.appendTo($(".point-of-sale #content"));
|
||||
|
||||
this.close_button = new module.HeaderButtonWidget(this,{
|
||||
label:'Close',
|
||||
label: _t('Close'),
|
||||
action: function(){ self.try_close(); },
|
||||
});
|
||||
this.close_button.appendTo(this.$('#rightheader'));
|
||||
|
||||
this.client_button = new module.HeaderButtonWidget(this,{
|
||||
label:'Self-Checkout',
|
||||
label: _t('Self-Checkout'),
|
||||
action: function(){ self.screen_selector.set_user_mode('client'); },
|
||||
});
|
||||
this.client_button.appendTo(this.$('#rightheader'));
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
<field name="model">hr.employee</field>
|
||||
<field name="inherit_id" eval="False"/>
|
||||
<field name="arch" type="xml">
|
||||
<kanban>
|
||||
<kanban create="false">
|
||||
<field name="last_login"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
|
|
|
@ -256,7 +256,7 @@
|
|||
<field name="search_view_id" ref="warehouse_orderpoint_search" />
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to add a reordering rules.
|
||||
Click to add a reordering rule.
|
||||
</p><p>You can define your minimum stock rules, so that OpenERP will automatically create draft manufacturing orders or request for quotations according to the stock level. Once the virtual stock of a product (= stock on hand minus all confirmed orders and reservations) is below the minimum quantity, OpenERP will generate a procurement request to increase the stock up to the maximum quantity.</p>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Procurement Request" version="7.0">
|
||||
<p class="oe_gray">
|
||||
Fill is this for to launch a procurement request for this
|
||||
Use this assistant to generate a procurement request for this
|
||||
product. According to the product configuration, this may
|
||||
trigger a draft purchase order, a manufacturing order or
|
||||
a new task.
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
<field name="arch" type="xml">
|
||||
<page string="Sales & Purchases" position="inside">
|
||||
<group>
|
||||
<group name="pricelists" groups="product.group_sale_pricelist" attrs="{'invisible': [('is_company','=',False),('parent_id','!=',False)]}">
|
||||
<field name="property_product_pricelist"/>
|
||||
<group name="pricelists" attrs="{'invisible': [('is_company','=',False),('parent_id','!=',False)]}">
|
||||
<field name="property_product_pricelist" groups="product.group_sale_pricelist"/>
|
||||
</group>
|
||||
<div name="parent_pricelists" groups="product.group_sale_pricelist" attrs="{'invisible': ['|',('is_company','=',True),('parent_id','=',False)]}">
|
||||
<p>Pricelists are managed on <button name="open_commercial_entity" type="object" string="the parent company" class="oe_link"/></p>
|
||||
|
|
|
@ -60,6 +60,8 @@
|
|||
</xsl:if>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:param name="pmaxChars" as="xs:integer" select="80"/>
|
||||
|
||||
<xsl:template match="lot-line" mode="story">
|
||||
<blockTable style="mytable" colWidths="2.8cm,5.4cm">
|
||||
<tr>
|
||||
|
@ -75,7 +77,7 @@
|
|||
<barCode><xsl:value-of select="ean13" /></barCode>
|
||||
</td>
|
||||
<td>
|
||||
<para style="nospace"><xsl:value-of select="product"/></para><xsl:text>, </xsl:text>
|
||||
<para style="nospace"><xsl:value-of select="substring(product, 1, pmaxChars)"/></para><xsl:text>, </xsl:text>
|
||||
<para style="nospace"><xsl:value-of select="variant"/></para>
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -98,10 +98,10 @@ class sale_order_line(osv.osv):
|
|||
class account_invoice_line(osv.osv):
|
||||
_inherit = "account.invoice.line"
|
||||
|
||||
def product_id_change(self, cr, uid, ids, product, uom, qty=0, name='', type='out_invoice', partner_id=False, fposition_id=False, price_unit=False, currency_id=False, context=None, company_id=None):
|
||||
res = super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom, qty, name, type, partner_id, fposition_id, price_unit,currency_id, context=context, company_id=company_id)
|
||||
def product_id_change(self, cr, uid, ids, product, uom_id, qty=0, name='', type='out_invoice', partner_id=False, fposition_id=False, price_unit=False, currency_id=False, context=None, company_id=None):
|
||||
res = super(account_invoice_line, self).product_id_change(cr, uid, ids, product, uom_id, qty, name, type, partner_id, fposition_id, price_unit,currency_id, context=context, company_id=company_id)
|
||||
|
||||
def get_real_price(res_dict, product_id, qty, uom, pricelist):
|
||||
def get_real_price(res_dict, product_id, qty, uom_id, pricelist):
|
||||
item_obj = self.pool.get('product.pricelist.item')
|
||||
price_type_obj = self.pool.get('product.price.type')
|
||||
product_obj = self.pool.get('product.product')
|
||||
|
@ -119,7 +119,7 @@ class account_invoice_line(osv.osv):
|
|||
product_read = product_obj.read(cr, uid, product_id, [field_name], context=context)
|
||||
|
||||
factor = 1.0
|
||||
if uom and uom != product.uom_id.id:
|
||||
if uom_id and uom_id != product.uom_id.id:
|
||||
product_uom_obj = self.pool.get('product.uom')
|
||||
uom_data = product_uom_obj.browse(cr, uid, product.uom_id.id)
|
||||
factor = uom_data.factor
|
||||
|
@ -137,18 +137,18 @@ class account_invoice_line(osv.osv):
|
|||
pricelist =partner_obj.browse(cr, uid, partner_id).property_product_pricelist_purchase.id
|
||||
if not pricelist:
|
||||
raise osv.except_osv(_('No Purchase Pricelist Found!'),_("You must first define a pricelist on the supplier form!"))
|
||||
price_unit_res = pricelist_obj.price_get(cr, uid, [pricelist], product.id, qty or 1.0, partner_id, {'uom': uom})
|
||||
price_unit_res = pricelist_obj.price_get(cr, uid, [pricelist], product.id, qty or 1.0, partner_id, {'uom': uom_id})
|
||||
price_unit = price_unit_res[pricelist]
|
||||
real_price = get_real_price(price_unit_res, product.id, qty, uom, pricelist)
|
||||
real_price = get_real_price(price_unit_res, product.id, qty, uom_id, pricelist)
|
||||
else:
|
||||
if partner_id:
|
||||
pricelist = partner_obj.browse(cr, uid, partner_id).property_product_pricelist.id
|
||||
if not pricelist:
|
||||
raise osv.except_osv(_('No Sale Pricelist Found!'),_("You must first define a pricelist on the customer form!"))
|
||||
price_unit_res = pricelist_obj.price_get(cr, uid, [pricelist], product.id, qty or 1.0, partner_id, {'uom': uom})
|
||||
price_unit_res = pricelist_obj.price_get(cr, uid, [pricelist], product.id, qty or 1.0, partner_id, {'uom': uom_id})
|
||||
price_unit = price_unit_res[pricelist]
|
||||
|
||||
real_price = get_real_price(price_unit_res, product.id, qty, uom, pricelist)
|
||||
real_price = get_real_price(price_unit_res, product.id, qty, uom_id, pricelist)
|
||||
if pricelist:
|
||||
pricelists=pricelist_obj.read(cr,uid,[pricelist],['visible_discount'])
|
||||
if(len(pricelists)>0 and pricelists[0]['visible_discount'] and real_price != 0):
|
||||
|
|
|
@ -29,6 +29,14 @@ class res_partner(osv.osv):
|
|||
'task_ids': fields.one2many('project.task', 'partner_id', 'Tasks'),
|
||||
}
|
||||
|
||||
def copy(self, cr, uid, record_id, default=None, context=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
|
||||
default['task_ids'] = []
|
||||
return super(res_partner, self).copy(
|
||||
cr, uid, record_id, default=default, context=context)
|
||||
|
||||
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<field name="priority">36</field>
|
||||
<field name="arch" type="xml">
|
||||
<field name="property_product_pricelist" position="after">
|
||||
<field name="property_product_pricelist_purchase" />
|
||||
<field name="property_product_pricelist_purchase" groups="product.group_purchase_pricelist"/>
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -65,7 +65,9 @@
|
|||
<field name="context">{"default_type": "in", "contact_display": "partner_address", "search_default_done": 1, "search_default_to_invoice": 1}</field>
|
||||
<field name="search_view_id" ref="stock.view_picking_in_search"/>
|
||||
<field name="help" type="html">
|
||||
<p>
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a new incoming shipment.
|
||||
</p><p>
|
||||
Here you can track all the product receptions of purchase
|
||||
orders where the invoicing is "Based on Incoming Shipments",
|
||||
and for which you have not received a supplier invoice yet.
|
||||
|
|
|
@ -242,8 +242,13 @@ class WebKitParser(report_sxw):
|
|||
def translate_call(self, src):
|
||||
"""Translate String."""
|
||||
ir_translation = self.pool['ir.translation']
|
||||
name = self.tmpl and 'addons/' + self.tmpl or None
|
||||
res = ir_translation._get_source(self.parser_instance.cr, self.parser_instance.uid,
|
||||
None, 'report', self.parser_instance.localcontext.get('lang', 'en_US'), src)
|
||||
name, 'report', self.parser_instance.localcontext.get('lang', 'en_US'), src)
|
||||
if res == src:
|
||||
# no translation defined, fallback on None (backward compatibility)
|
||||
res = ir_translation._get_source(self.parser_instance.cr, self.parser_instance.uid,
|
||||
None, 'report', self.parser_instance.localcontext.get('lang', 'en_US'), src)
|
||||
if not res :
|
||||
return src
|
||||
return res
|
||||
|
|
|
@ -90,7 +90,11 @@
|
|||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" eval="False"/>
|
||||
<field name="search_view_id" ref="view_resource_calendar_search"/>
|
||||
<field name="help">Define working hours and time table that could be scheduled to your project members</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Define working hours and time table that could be scheduled to your project members
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_resource_calendar_attendance_tree" model="ir.ui.view">
|
||||
|
|
|
@ -78,11 +78,13 @@ class crm_make_sale(osv.osv_memory):
|
|||
['default', 'invoice', 'delivery', 'contact'])
|
||||
pricelist = partner.property_product_pricelist.id
|
||||
fpos = partner.property_account_position and partner.property_account_position.id or False
|
||||
payment_term = partner.property_payment_term and partner.property_payment_term.id or False
|
||||
new_ids = []
|
||||
for case in case_obj.browse(cr, uid, data, context=context):
|
||||
if not partner and case.partner_id:
|
||||
partner = case.partner_id
|
||||
fpos = partner.property_account_position and partner.property_account_position.id or False
|
||||
payment_term = partner.property_payment_term and partner.property_payment_term.id or False
|
||||
partner_addr = partner_obj.address_get(cr, uid, [partner.id],
|
||||
['default', 'invoice', 'delivery', 'contact'])
|
||||
pricelist = partner.property_product_pricelist.id
|
||||
|
@ -100,6 +102,7 @@ class crm_make_sale(osv.osv_memory):
|
|||
'partner_shipping_id': partner_addr['delivery'],
|
||||
'date_order': fields.date.context_today(self,cr,uid,context=context),
|
||||
'fiscal_position': fpos,
|
||||
'payment_term':payment_term,
|
||||
}
|
||||
if partner.id:
|
||||
vals['user_id'] = partner.user_id and partner.user_id.id or uid
|
||||
|
|
|
@ -587,9 +587,6 @@ class sale_order_line(osv.osv):
|
|||
return res
|
||||
|
||||
#update of result obtained in super function
|
||||
res_packing = self.product_packaging_change(cr, uid, ids, pricelist, product, qty, uom, partner_id, packaging, context=context)
|
||||
res['value'].update(res_packing.get('value', {}))
|
||||
warning_msgs = res_packing.get('warning') and res_packing['warning']['message'] or ''
|
||||
product_obj = product_obj.browse(cr, uid, product, context=context)
|
||||
res['value']['delay'] = (product_obj.sale_delay or 0.0)
|
||||
res['value']['type'] = product_obj.procure_method
|
||||
|
@ -602,6 +599,11 @@ class sale_order_line(osv.osv):
|
|||
uom = False
|
||||
if not uom2:
|
||||
uom2 = product_obj.uom_id
|
||||
|
||||
# Calling product_packaging_change function after updating UoM
|
||||
res_packing = self.product_packaging_change(cr, uid, ids, pricelist, product, qty, uom, partner_id, packaging, context=context)
|
||||
res['value'].update(res_packing.get('value', {}))
|
||||
warning_msgs = res_packing.get('warning') and res_packing['warning']['message'] or ''
|
||||
compare_qty = float_compare(product_obj.virtual_available * uom2.factor, qty * product_obj.uom_id.factor, precision_rounding=product_obj.uom_id.rounding)
|
||||
if (product_obj.type=='product') and int(compare_qty) == -1 \
|
||||
and (product_obj.procure_method=='make_to_stock'):
|
||||
|
|
|
@ -14,7 +14,7 @@ openerp.share = function(session) {
|
|||
else rec_name = '';
|
||||
session.web.pyeval.eval_domains_and_contexts({
|
||||
domains: [domain],
|
||||
contexts: [view.dataset.context]
|
||||
contexts: [Share.get_context()]
|
||||
}).done(function (result) {
|
||||
Share.create({
|
||||
name: action.name,
|
||||
|
@ -25,7 +25,7 @@ openerp.share = function(session) {
|
|||
view_type: view.fields_view.type,
|
||||
invite: invite || false,
|
||||
}).done(function(share_id) {
|
||||
var step1 = Share.call('go_step_1', [[share_id]]).done(function(result) {
|
||||
var step1 = Share.call('go_step_1', [[share_id], Share.get_context()]).done(function(result) {
|
||||
var action = result;
|
||||
self.do_action(action);
|
||||
});
|
||||
|
|
|
@ -258,7 +258,9 @@
|
|||
<para style="terp_default_Centre_9">[[ (move_lines.prodlot_id and move_lines.prodlot_id.name) or '' ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_9">[[ move_lines.state ]]</para>
|
||||
<para style="terp_default_9">Waiting Availability[[ move_lines.state == 'confirmed' and ' ' or removeParentNode('para') ]]</para>
|
||||
<para style="terp_default_9">Done[[ move_lines.state == 'done' and ' ' or removeParentNode('para') ]]</para>
|
||||
<para style="terp_default_9">Available[[ move_lines.state == 'assigned' and ' ' or removeParentNode('para') ]]</para>
|
||||
</td>
|
||||
<td>
|
||||
<para style="terp_default_Right_9">[[ (move_lines.location_id and move_lines.location_id.name) or '' ]] </para>
|
||||
|
|
|
@ -1637,7 +1637,7 @@ class stock_move(osv.osv):
|
|||
"* Waiting Availability: This state is reached when the procurement resolution is not straight forward. It may need the scheduler to run, a component to me manufactured...\n"\
|
||||
"* Available: When products are reserved, it is set to \'Available\'.\n"\
|
||||
"* Done: When the shipment is processed, the state is \'Done\'."),
|
||||
'price_unit': fields.float('Unit Price', digits_compute= dp.get_precision('Account'), help="Technical field used to record the product cost set by the user during a picking confirmation (when average price costing method is used)"),
|
||||
'price_unit': fields.float('Unit Price', digits_compute= dp.get_precision('Product Price'), help="Technical field used to record the product cost set by the user during a picking confirmation (when average price costing method is used)"),
|
||||
'price_currency_id': fields.many2one('res.currency', 'Currency for average price', help="Technical field used to record the currency chosen by the user during a picking confirmation (when average price costing method is used)"),
|
||||
'company_id': fields.many2one('res.company', 'Company', required=True, select=True),
|
||||
'backorder_id': fields.related('picking_id','backorder_id',type='many2one', relation="stock.picking", string="Back Order of", select=True),
|
||||
|
@ -2192,7 +2192,7 @@ class stock_move(osv.osv):
|
|||
if move.picking_id:
|
||||
pickings.add(move.picking_id.id)
|
||||
if move.move_dest_id and move.move_dest_id.state == 'waiting':
|
||||
self.write(cr, uid, [move.move_dest_id.id], {'state': 'assigned'})
|
||||
self.write(cr, uid, [move.move_dest_id.id], {'state': 'confirmed'})
|
||||
if context.get('call_unlink',False) and move.move_dest_id.picking_id:
|
||||
wf_service.trg_write(uid, 'stock.picking', move.move_dest_id.picking_id.id, cr)
|
||||
self.write(cr, uid, ids, {'state': 'cancel', 'move_dest_id': False})
|
||||
|
@ -2412,8 +2412,8 @@ class stock_move(osv.osv):
|
|||
# or if it's the same as that of the secondary amount being posted.
|
||||
account_obj = self.pool.get('account.account')
|
||||
src_acct, dest_acct = account_obj.browse(cr, uid, [src_account_id, dest_account_id], context=context)
|
||||
src_main_currency_id = src_acct.currency_id and src_acct.currency_id.id or src_acct.company_id.currency_id.id
|
||||
dest_main_currency_id = dest_acct.currency_id and dest_acct.currency_id.id or dest_acct.company_id.currency_id.id
|
||||
src_main_currency_id = src_acct.company_id.currency_id.id
|
||||
dest_main_currency_id = dest_acct.company_id.currency_id.id
|
||||
cur_obj = self.pool.get('res.currency')
|
||||
if reference_currency_id != src_main_currency_id:
|
||||
# fix credit line:
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
from openerp.osv import fields, osv
|
||||
from openerp.tools.misc import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
import time
|
||||
from openerp.tools.translate import _
|
||||
|
||||
class stock_partial_move_line(osv.osv_memory):
|
||||
_inherit = "stock.partial.picking.line"
|
||||
|
@ -67,6 +68,8 @@ class stock_partial_move(osv.osv_memory):
|
|||
}
|
||||
moves_ids = []
|
||||
for move in partial.move_ids:
|
||||
if not move.move_id:
|
||||
raise osv.except_osv(_('Warning !'), _("You have manually created product lines, please delete them to proceed"))
|
||||
move_id = move.move_id.id
|
||||
partial_data['move%s' % (move_id)] = {
|
||||
'product_id': move.product_id.id,
|
||||
|
|
|
@ -180,6 +180,8 @@ class stock_return_picking(osv.osv_memory):
|
|||
for v in val_id:
|
||||
data_get = data_obj.browse(cr, uid, v, context=context)
|
||||
mov_id = data_get.move_id.id
|
||||
if not mov_id:
|
||||
raise osv.except_osv(_('Warning !'), _("You have manually created product lines, please delete them to proceed"))
|
||||
new_qty = data_get.quantity
|
||||
move = move_obj.browse(cr, uid, mov_id, context=context)
|
||||
new_location = move.location_dest_id.id
|
||||
|
|
|
@ -498,7 +498,7 @@ class survey_question(osv.osv):
|
|||
def create(self, cr, uid, vals, context=None):
|
||||
minimum_ans = 0
|
||||
maximum_ans = 0
|
||||
page = self.pool.get('survey.page').browse(cr, uid, vals['page_id'], context=context).title
|
||||
page = self.pool.get('survey.page').browse(cr, uid, int(vals.get('page_id', 0)), context=context).title
|
||||
if vals.has_key('answer_choice_ids') and not len(vals['answer_choice_ids']):
|
||||
if vals.has_key('type') and vals['type'] not in ['descriptive_text', 'single_textbox', 'comment','table']:
|
||||
raise osv.except_osv(_('Warning!'),_('You must enter one or more answers for question "%s" of page %s .') % (vals['question'], page))
|
||||
|
|
|
@ -772,6 +772,7 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Survey Question">
|
||||
<field name="question" colspan="4"/>
|
||||
<field name="page_id"/>
|
||||
<field name="sequence"/>
|
||||
<field name="tot_resp"/>
|
||||
<field name="type" on_change="on_change_type(type)"/>
|
||||
|
|
|
@ -1038,6 +1038,7 @@ class survey_question_wiz(osv.osv_memory):
|
|||
'type': 'ir.actions.act_window',
|
||||
'target': 'new',
|
||||
'view_id': view_id,
|
||||
'page_id': int(context.get('page_id',0)),
|
||||
'context': context
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
<record id="product_warning_form_view" model="ir.ui.view">
|
||||
<field name="name">product.warning.form.inherit</field>
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit_id" ref="procurement.product_template_form_view_procurement"/>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page string="Warnings">
|
||||
|
|
Loading…
Reference in New Issue