Hi all,
I've made a new view for quotation which is totally seperate from tha normal sale order view.
my_module.py
class sale_quote(osv.osv):
_name = 'sale.quote'
_inherit = ['mail.thread', 'ir.needaction_mixin']
_description = "Quotation"def _get_order(self, cr, uid, ids, context=None):
result = {}
for line in self.pool.get('quote.line').browse(cr, uid, ids, context=context):
result[line.order_id.id] = True
return result.keys()
_columns = {
'name': fields.char('Order Reference', size=64, required=True,
select=True),
'origin': fields.char('Source Document', size=64, help="Reference of the document that generated this quotation request."),
'client_order_ref': fields.char('Customer Reference', size=64),
'date_order': fields.date('Date', required=True, select=True),
'create_date': fields.datetime('Creation Date', readonly=True, select=True, help="Date on which quotation is created."),
'user_id': fields.many2one('res.users', 'Salesperson', select=True, track_visibility='onchange'),
'partner_id': fields.many2one('res.partner', 'Customer', required=True, change_default=True, select=True, track_visibility='always'),
'partner_invoice_id': fields.many2one('res.partner', 'Invoice Address', required=True, help="Invoice address for current quotation."),
'partner_shipping_id': fields.many2one('res.partner', 'Delivery Address', required=True, help="Delivery address for current quotation."),
'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, help="Pricelist for current sales order."),
'currency_id': fields.related('pricelist_id', 'currency_id', type="many2one", relation="res.currency", string="Currency", readonly=True, required=True),
'order_line': fields.one2many('quote.line', 'order_id', 'Order Lines'),
'note': fields.text('Terms and conditions'),
'payment_term': fields.many2one('account.payment.term', 'Payment Term'),
'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position'),
'company_id': fields.many2one('res.company',string='Company',store=True,readonly=True)
}
_defaults = {
'date_order': fields.date.context_today,
'user_id': lambda obj, cr, uid, context: uid,
'name': lambda obj, cr, uid, context: '/',
'partner_invoice_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['invoice'])['invoice'],
'partner_shipping_id': lambda self, cr, uid, context: context.get('partner_id', False) and self.pool.get('res.partner').address_get(cr, uid, [context['partner_id']], ['delivery'])['delivery'],
}def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, order_lines, context=None):
context = context or {}
if not pricelist_id:
return {}
value = {
'currency_id': self.pool.get('product.pricelist').browse(cr, uid, pricelist_id, context=context).currency_id.id
}
if not order_lines:
return {'value': value}
warning = {
'title': _('Pricelist Warning!'),
'message' : _('If you change the pricelist of this order (and eventually the currency), prices of existing order lines will not be updated.')
}
return {'warning': warning, 'value': value}def onchange_partner_id(self, cr, uid, ids, part, context=None):
if not part:
return {'value': {'partner_invoice_id': False, 'partner_shipping_id': False}}part = self.pool.get('res.partner').browse(cr, uid, part, context=context)
addr = self.pool.get('res.partner').address_get(cr, uid, [part.id], ['delivery', 'invoice', 'contact'])
pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
payment_term = False
fiscal_position = False
dedicated_salesman = part.user_id and part.user_id.id or uid
val = {
'partner_invoice_id': addr['invoice'],
'partner_shipping_id': addr['delivery'],
'user_id': dedicated_salesman,
}
if pricelist:
val['pricelist_id'] = pricelist
return {'value': val}def action_quotation_send(self, cr, uid, ids, context=None):
'''
This function opens a window to compose an email, with the edi sale template message loaded by default
'''
assert len(ids) == 1, 'This option should only be used for a single id at a time.'
ir_model_data = self.pool.get('ir.model.data')
try:
template_id = ir_model_data.get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1]
except ValueError:
template_id = False
try:
compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1]
except ValueError:
compose_form_id = False
ctx = dict(context)
ctx.update({
'default_model': 'sale.order',
'default_res_id': ids[0],
'default_use_template': bool(template_id),
'default_template_id': template_id,
'default_composition_mode': 'comment',
})
return {
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.compose.message',
'views': [(compose_form_id, 'form')],
'view_id': compose_form_id,
'target': 'new',
'context': ctx,
}
def create(self, cr, uid, vals, context=None):
if vals.get('name','/')=='/':
vals['name'] = self.pool.get('ir.sequence').get(cr, uid, 'sale.quote') or '/'
return super(sale_quote, self).create(cr, uid, vals, context=context)
sale_quote()class quote_line(osv.osv):
_name = 'quote.line'
_description = 'Quote Line'
_columns = {
'order_id': fields.many2one('sale.quote', 'Order Reference', required=True, ondelete='cascade', select=True, readonly=False),
'name': fields.text('Description', required=True, readonly=False),
'sequence': fields.char('Sequence', help="Gives the sequence order when displaying a list of sales order lines."),
'qty_range': fields.char('QTY', size=64),
'dly_week': fields.char('DLY Weeks', size=64),
'remark': fields.text('Remarks'),
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price'), readonly=False),
'order_partner_id': fields.related('order_id', 'partner_id', type='many2one', relation='res.partner', store=True, string='Customer'),
'salesman_id':fields.related('order_id', 'user_id', type='many2one', relation='res.users', store=True, string='Salesperson'),
'company_id': fields.related('order_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True),
}_defaults = {
'sequence': 10,
'price_unit': 0.0,
}def product_id_change(self, cr, uid, ids, pricelist, product, name='', partner_id=False,
lang=False, date_order=False, packaging=False, fiscal_position=False, flag=False, context=None):
context = context or {}
lang = lang or context.get('lang',False)
if not partner_id:
raise osv.except_osv(_('No Customer Defined!'), _('Before choosing a product,\n select a customer in the sales form.'))
warning = {}
partner_obj = self.pool.get('res.partner')
product_obj = self.pool.get('product.product')
context = {'lang': lang, 'partner_id': partner_id}
if partner_id:
lang = partner_obj.browse(cr, uid, partner_id).lang
context_partner = {'lang': lang, 'partner_id': partner_id}if not date_order:
date_order = time.strftime(DEFAULT_SERVER_DATE_FORMAT)result = {}
warning_msgs = ''
product_obj = product_obj.browse(cr, uid, product, context=context_partner)
if not flag:
result['name'] = self.pool.get('product.product').name_get(cr, uid, [product_obj.id], context=context_partner)[0][1]
if product_obj.description_sale:
result['name'] += '\n'+product_obj.description_sale
domain = {}
if not pricelist:
warn_msg = _('You have to select a pricelist or a customer in the sales form !\n'
'Please set one before choosing a product.')
warning_msgs += _("No Pricelist ! : ") + warn_msg +"\n\n"
else:
price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist],
product, partner_id, {
'date': date_order,
})[pricelist]
if price is False:
warn_msg = _("Cannot find a pricelist line matching this product and quantity.\n"
"You have to change either the product, the quantity or the pricelist.")warning_msgs += _("No valid pricelist line found ! :") + warn_msg +"\n\n"
else:
result.update({'price_unit': price})
if warning_msgs:
warning = {
'title': _('Configuration Error!'),
'message' : warning_msgs
}
return {'value': result, 'domain': domain, 'warning': warning}quote_line()
my_module.xml
<record id="view_quote_name_form" model="ir.ui.view">
<field name="name">view.quote.name.form</field>
<field name="model">sale.quote</field>
<field name="arch" type="xml">
<form string="Quote" version="7.0">
<header>
<button name="action_quotation_send" string="Send by Email" type="object" class="oe_highlight"/>
</header>
<sheet>
<h1>
<label string="Quotation "/>
<field name="name" class="oe_inline" readonly="1"/>
</h1>
<group>
<group>
<field name="partner_id" on_change="onchange_partner_id(partner_id, context)" domain="[('customer','=',True)]" context="{'search_default_customer':1, 'show_address': 1}" options='{"always_reload": True}'/>
<field name="partner_invoice_id" context="{'default_type':'invoice'}"/>
<field name="partner_shipping_id" context="{'default_type':'delivery'}"/>
</group>
<group>
<field name="date_order"/>
<field name="client_order_ref"/>
<field domain="[('type','=','sale')]" name="pricelist_id" on_change="onchange_pricelist_id(pricelist_id,order_line)"/>
<field name="currency_id"/>
</group>
</group>
<notebook>
<page string="Quotation Lines">
<field name="order_line">
<form string="Quotation Lines" version="7.0">
<group>
<group>
<field name="sequence"/>
<field name="product_id"
context="{'partner_id':parent.partner_id, 'pricelist':parent.pricelist_id}"/>
<field name="name"/>
<field name="qty_range"/>
<field name="price_unit"/>
<field name="dly_week"/>
<field name="remark"/>
</group>
</group>
</form>
<tree string="Quote Lines" editable="bottom">
<field name="sequence"/>
<field name="product_id"
context="{'partner_id':parent.partner_id, 'pricelist':parent.pricelist_id}"/>
<field name="name"/>
<field name="qty_range"/>
<field name="price_unit"/>
<field name="dly_week"/>
<field name="remark"/>
</tree>
</field>
<div class="oe_clear"/>
<field name="note" class="oe_inline" placeholder="Terms and conditions..."/>
</page>
<page string="Other Information">
<group>
<group name="sales_person">
<field name="user_id"/>
<field name="origin"/>
</group>
<group name="sale_pay">
<field name="payment_term" widget="selection"/>
<field name="fiscal_position" widget="selection"/>
<field name="company_id" widget="selection"/>
</group>
</group>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" groups="base.group_user"/>
<field name="message_ids" widget="mail_thread"/>
</div>
</form>
</field>
</record>
<record id="view_quote_name_tree" model="ir.ui.view">
<field name="name">view.quote.name.tree</field>
<field name="model">sale.quote</field>
<field name="arch" type="xml">
<tree string="Quotations" version="7.0">
<field name="name" string="Quote Number"/>
<field name="date_order"/>
<field name="partner_id"/>
<field name="user_id"/>
</tree>
</field>
</record>
<record id="action_quote_name" model="ir.actions.act_window">
<field name="name">Quotations</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.quote</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="view_quote_name_tree"/>
</record><menuitem id="menu_tc_name_config" action="action_quote_name" name="Quotes" parent="base.menu_sales" sequence="3"/>
this is my code and I've called the quote list in normal sale order view
sale.py
'quote_no': fields.many2one('sale.quote','Quote No.',required=True),
and I wrote an on change method to pull the customer and the pricelist from the new view
def onchange_quoteno(self, cr, uid, ids, quote, context=None):
value = {}
if quote:
quot = self.pool.get('sale.quote').browse(cr, uid, quote, context=context)
value = {
'partner_id': quot.partner_id,
'pricelist_id': quot.pricelist_id.id,
}
return {'value': value}
sale_view.xml
<field name="quote_no" string="Quote No." on_change="onchange_quoteno(quote_no)"/>
I'm getting the drop down list of new quote form but when i select any of them I get this Error
XmlHttpRequestError INTERNAL SERVER ERROR
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <title>500 Internal Server Error</title> <h1>Internal Server Error</h1> <p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>
I don't know wer I'm going wrong. Can anyone help me out..?