[FIX] misc fixes

bzr revid: fp@tinyerp.com-20140125221059-6e9m7g9hy3mic6o2
This commit is contained in:
Fabien Pinckaers 2014-01-25 23:10:59 +01:00
parent 6af3677c0a
commit f65b9b1022
5 changed files with 109 additions and 44 deletions

View File

@ -25,6 +25,7 @@ from openerp.addons.web.http import request
from openerp.addons.website.models import website from openerp.addons.website.models import website
import werkzeug import werkzeug
import datetime import datetime
import time
from openerp.tools.translate import _ from openerp.tools.translate import _
@ -37,16 +38,17 @@ class sale_quote(http.Controller):
# use SUPERUSER_ID allow to access/view order for public user # use SUPERUSER_ID allow to access/view order for public user
# only if he knows the private token # only if he knows the private token
order = request.registry.get('sale.order').browse(request.cr, token and SUPERUSER_ID or request.uid, order_id) order = request.registry.get('sale.order').browse(request.cr, token and SUPERUSER_ID or request.uid, order_id)
if token and not message: if token:
assert token == order.access_token, 'Access denied!' assert token == order.access_token, 'Access denied!'
body=_('Quotation viewed by customer') if not message:
self.__message_post(body, order_id, type='comment') body=_('Quotation viewed by customer')
self.__message_post(body, order_id, type='comment')
days = 0 days = 0
if order.validity_date: if order.validity_date:
days = (datetime.datetime.strptime(order.validity_date, '%Y-%m-%d') - datetime.datetime.now()).days + 1 days = (datetime.datetime.strptime(order.validity_date, '%Y-%m-%d') - datetime.datetime.now()).days + 1
values = { values = {
'quotation': order, 'quotation': order,
'message': message, 'message': message and int(message) or False,
'option': bool(filter(lambda x: not x.line_id, order.options)), 'option': bool(filter(lambda x: not x.line_id, order.options)),
'order_valid': (not order.validity_date) or (datetime.datetime.now().strftime('%Y-%m-%d') <= order.validity_date), 'order_valid': (not order.validity_date) or (datetime.datetime.now().strftime('%Y-%m-%d') <= order.validity_date),
'days_valid': max(days, 0) 'days_valid': max(days, 0)
@ -133,14 +135,25 @@ class sale_quote(http.Controller):
assert token == order.access_token, 'Access denied, wrong token!' assert token == order.access_token, 'Access denied, wrong token!'
option_obj = request.registry.get('sale.order.option') option_obj = request.registry.get('sale.order.option')
option = option_obj.browse(request.cr, SUPERUSER_ID, option_id) option = option_obj.browse(request.cr, SUPERUSER_ID, option_id)
res = request.registry.get('sale.order.line').product_id_change(request.cr, SUPERUSER_ID, order_id,
False, option.product_id.id, option.quantity, option.uom_id.id, option.quantity, option.uom_id.id,
option.name, order.partner_id.id, False, True, time.strftime('%Y-%m-%d'),
False, order.fiscal_position.id, True, request.context)
vals = res.get('value', {})
if 'tax_id' in vals:
vals['tax_id'] = [(6, 0, vals['tax_id'])]
vals.update({ vals.update({
'price_unit': option.price_unit, 'price_unit': option.price_unit,
'website_description': option.website_description, 'website_description': option.website_description,
'name': option.name, 'name': option.name,
'order_id': order.id, 'order_id': order.id,
'product_id' : option.product_id.id, 'product_id' : option.product_id.id,
'product_uos_qty': option.quantity,
'product_uos': option.uom_id.id,
'product_uom_qty': option.quantity, 'product_uom_qty': option.quantity,
'product_uom_id': option.uom_id.id, 'product_uom': option.uom_id.id,
'discount': option.discount, 'discount': option.discount,
}) })
line = request.registry.get('sale.order.line').create(request.cr, SUPERUSER_ID, vals, context=request.context) line = request.registry.get('sale.order.line').create(request.cr, SUPERUSER_ID, vals, context=request.context)

View File

@ -427,7 +427,6 @@
<field name="product_id" ref="product_product_quote_3"/> <field name="product_id" ref="product_product_quote_3"/>
<field name="quantity">1</field> <field name="quantity">1</field>
<field name="uom_id" ref="product.product_uom_unit"/> <field name="uom_id" ref="product.product_uom_unit"/>
<field name="product_uom_id" ref="product.product_uom_unit"/>
<field name="price_unit">9000.00</field> <field name="price_unit">9000.00</field>
<field name="discount">10</field> <field name="discount">10</field>
<field name="website_description" type="html"> <field name="website_description" type="html">

View File

@ -31,7 +31,7 @@ class sale_quote_template(osv.osv):
_description = "Sale Quotation Template" _description = "Sale Quotation Template"
_columns = { _columns = {
'name': fields.char('Quotation Template', size=256, required=True), 'name': fields.char('Quotation Template', size=256, required=True),
'website_description': fields.html('Description'), 'website_description': fields.html('Description', translate=True),
'quote_line': fields.one2many('sale.quote.line', 'quote_id', 'Quote Template Lines'), 'quote_line': fields.one2many('sale.quote.line', 'quote_id', 'Quote Template Lines'),
'note': fields.text('Terms and conditions'), 'note': fields.text('Terms and conditions'),
'options': fields.one2many('sale.quote.option', 'template_id', 'Optional Products Lines'), 'options': fields.one2many('sale.quote.option', 'template_id', 'Optional Products Lines'),
@ -49,9 +49,9 @@ class sale_quote_line(osv.osv):
_description = "Quotation Template Lines" _description = "Quotation Template Lines"
_columns = { _columns = {
'quote_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', required=True, ondelete='cascade', select=True), 'quote_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', required=True, ondelete='cascade', select=True),
'name': fields.text('Description', required=True), 'name': fields.text('Description', required=True, translate=True),
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True), 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True),
'website_description': fields.html('Line Description'), 'website_description': fields.html('Line Description', translate=True),
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')), 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')),
'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')), 'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')),
'product_uom_qty': fields.float('Quantity', required=True, digits_compute= dp.get_precision('Product UoS')), 'product_uom_qty': fields.float('Quantity', required=True, digits_compute= dp.get_precision('Product UoS')),
@ -66,6 +66,7 @@ class sale_quote_line(osv.osv):
product_obj = self.pool.get('product.product').browse(cr, uid, product, context=context) product_obj = self.pool.get('product.product').browse(cr, uid, product, context=context)
vals.update({ vals.update({
'price_unit': product_obj.list_price, 'price_unit': product_obj.list_price,
'product_uom_id': product_obj.uom_id.id,
'website_description': product_obj.website_description, 'website_description': product_obj.website_description,
'name': product_obj.name, 'name': product_obj.name,
}) })
@ -120,11 +121,18 @@ class sale_order(osv.osv):
'url': '/quote/%s' % (quote.id) 'url': '/quote/%s' % (quote.id)
} }
def onchange_template_id(self, cr, uid, ids, template_id, context=None): def onchange_template_id(self, cr, uid, ids, template_id, partner=False, fiscal_position=False, context=None):
lines = [] lines = []
quote_template = self.pool.get('sale.quote.template').browse(cr, uid, template_id, context=context) quote_template = self.pool.get('sale.quote.template').browse(cr, uid, template_id, context=context)
for line in quote_template.quote_line: for line in quote_template.quote_line:
lines.append((0, 0, { res = self.pool.get('sale.order.line').product_id_change(cr, uid, False,
False, line.product_id.id, line.product_uom_qty, line.product_uom_id.id, line.product_uom_qty,
line.product_uom_id.id, line.name, partner, False, True, time.strftime('%Y-%m-%d'),
False, fiscal_position, True, context)
data = res.get('value', {})
if 'tax_id' in data:
data['tax_id'] = [(6, 0, data['tax_id'])]
data.update({
'name': line.name, 'name': line.name,
'price_unit': line.price_unit, 'price_unit': line.price_unit,
'discount': line.discount, 'discount': line.discount,
@ -133,7 +141,8 @@ class sale_order(osv.osv):
'product_uom': line.product_uom_id.id, 'product_uom': line.product_uom_id.id,
'website_description': line.website_description, 'website_description': line.website_description,
'state': 'draft', 'state': 'draft',
})) })
lines.append((0, 0, data))
options = [] options = []
for option in quote_template.options: for option in quote_template.options:
options.append((0, 0, { options.append((0, 0, {
@ -167,7 +176,7 @@ class sale_quote_option(osv.osv):
_columns = { _columns = {
'template_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', ondelete='cascade', select=True, required=True), 'template_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', ondelete='cascade', select=True, required=True),
'name': fields.text('Description', required=True, translate=True), 'name': fields.text('Description', required=True, translate=True),
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)]), 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True),
'website_description': fields.html('Option Description', translate=True), 'website_description': fields.html('Option Description', translate=True),
'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')), 'price_unit': fields.float('Unit Price', required=True, digits_compute= dp.get_precision('Product Price')),
'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')), 'discount': fields.float('Discount (%)', digits_compute= dp.get_precision('Discount')),

View File

@ -6,11 +6,12 @@
<h1 class="page-header">Pricing</h1> <h1 class="page-header">Pricing</h1>
</section> </section>
<section id="quote"> <section id="quote">
<table class="table table-hover"> <table class="table">
<thead> <thead>
<tr> <tr>
<th>Products</th> <th>Products</th>
<th>Quantity</th> <th>Quantity</th>
<th>Taxes</th>
<th></th> <th></th>
<th class="text-right">Unit Price</th> <th class="text-right">Unit Price</th>
<th class="text-right">Price</th> <th class="text-right">Price</th>
@ -27,6 +28,11 @@
<span t-field="line.product_uom"/> <span t-field="line.product_uom"/>
</div> </div>
</td> </td>
<td>
<div t-foreach="line.tax_id" t-as="tax">
<t t-esc="tax.name"/>
</div>
</td>
<td> <td>
<strong t-if="line.discount" class="text-info"> <strong t-if="line.discount" class="text-info">
<t t-esc="((line.discount % 1) and '%s' or '%d') % line.discount"/>% discount <t t-esc="((line.discount % 1) and '%s' or '%d') % line.discount"/>% discount
@ -56,14 +62,24 @@
</td> </td>
</tr> </tr>
<tr> <tr>
<td></td> <td></td><td></td><td></td><td></td>
<td></td> <td class="text-right"><strong>Subtotal:</strong></td>
<td></td> <td class="text-right">
<td><h3 class="text-right">Total</h3></td> <strong data-id="total_amount" t-field="quotation.amount_untaxed" t-field-options='{"widget": "monetary","display_currency": "quotation.pricelist_id.currency_id"}'/>
<td class="text-right" colspan="2"> </td>
<h3> </tr>
<strong data-id="total_amount" t-field="quotation.amount_total" t-field-options='{"widget": "monetary","display_currency": "quotation.pricelist_id.currency_id"}'/> <tr>
</h3> <td></td><td></td><td></td><td></td>
<td class="text-right">Taxes:</td>
<td class="text-right">
<span data-id="total_amount" t-field="quotation.amount_tax" t-field-options='{"widget": "monetary","display_currency": "quotation.pricelist_id.currency_id"}'/>
</td>
</tr>
<tr>
<td></td><td></td><td></td><td></td>
<td class="text-right"><strong>Total:</strong></td>
<td class="text-right">
<strong data-id="total_amount" t-field="quotation.amount_total" t-field-options='{"widget": "monetary","display_currency": "quotation.pricelist_id.currency_id"}'/>
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -158,11 +174,11 @@
<a t-if="order_valid" class="btn btn-primary btn-block fa fa-check" data-toggle="modal" data-target="#modelaccept"> <a t-if="order_valid" class="btn btn-primary btn-block fa fa-check" data-toggle="modal" data-target="#modelaccept">
Accept Order Accept Order
</a> </a>
<a t-if="not order_valid"> <a t-if="not order_valid" href="#discussion" class="btn btn-info btn-block">
<strong>This offer expired!.</strong> <strong>This offer expired!</strong><br/>
<br/><a href="#discussion">Contact us</a> for new quote. Contact us for new quote.
</a> </a>
<div class="mt8"> <div class="mt8" t-if="order_valid">
<a type="submit" href="#discussion"> <a type="submit" href="#discussion">
Ask Changes Ask Changes
</a> or </a> or
@ -203,6 +219,7 @@
</div> </div>
</div> </div>
<div class="col-md-9"> <div class="col-md-9">
<p>Message <t t-esc="message"/></p>
<div class="alert alert-success alert-dismissable" t-if="message==1"> <div class="alert alert-success alert-dismissable" t-if="message==1">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button>
Your message has been successfully sent! Your message has been successfully sent!
@ -450,26 +467,51 @@
<div class="col-md-3"> <div class="col-md-3">
<div class="bs-sidebar"> <div class="bs-sidebar">
<div class="hidden-print navspy" role="complementary"> <div class="hidden-print navspy" role="complementary">
<ul class="nav bs-sidenav" data-id="quote_sidebar"> <ul class="nav bs-sidenav" data-id="quote_sidebar"/>
</ul>
</div> </div>
</div> </div>
</div> </div>
<div class="col-md-9"> <div class="col-md-9">
<div id="template_introduction" t-field="template.website_description"/> <div class="alert alert-info alert-dismissable" t-ignore="True">
<t t-foreach="template.quote_line" t-as="line"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button>
<a t-att-id="line.id"/> <p>
<div t-field="line.website_description"/> <strong>Template Header:</strong> this content
</t> will appear on all quotations using this
<div class="oe_structure"/> template.
<section id="terms" class="container" t-if="template.note"> </p>
<h2 class="page-header">Terms &amp; Conditions</h2> <p class="text-muted">
<p t-field="template.note"/> Titles with style <i>Heading 1</i> and
</section> <i>Heading 2</i> will be used to generate the
table of content automatically.
</p>
</div> </div>
<div id="template_introduction" t-field="template.website_description"/>
<t t-foreach="template.quote_line" t-as="line">
<div class="alert alert-info alert-dismissable" t-ignore="True">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button>
Product: <strong t-esc="line.product_id.name"/>:
this content will appear on the quotation only if this
product is put on the quote.
</div>
<div t-field="line.website_description"/>
</t>
<t t-foreach="template.options" t-as="option_line">
<div class="alert alert-info alert-dismissable" t-ignore="True">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&amp;times;</button>
Optional Product: <strong t-esc="option_line.product_id.name"/>:
this content will appear on the quotation only if this
product is used in the quote.
</div>
<div t-field="option_line.website_description"/>
</t>
<section id="terms" class="container" t-if="template.note">
<h1 class="page-header" t-ignore="True">Terms &amp; Conditions</h1>
<p t-field="template.note"/>
</section>
</div> </div>
</div> </div>
</body> </div>
</body>
</t> </t>
</template> </template>

View File

@ -18,7 +18,7 @@
<field name="product_id" on_change="on_change_product_id(product_id)"/> <field name="product_id" on_change="on_change_product_id(product_id)"/>
<field name="name"/> <field name="name"/>
<field name="quantity"/> <field name="quantity"/>
<field name="uom_id"/> <field name="uom_id" groups="product.group_uom"/>
<field name="price_unit"/> <field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line"/> <field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="website_description" invisible="1"/> <field name="website_description" invisible="1"/>
@ -27,7 +27,7 @@
</page> </page>
</xpath> </xpath>
<xpath expr="//field[@name='client_order_ref']" position="after"> <xpath expr="//field[@name='client_order_ref']" position="after">
<field name="template_id" on_change="onchange_template_id(template_id)"/> <field name="template_id" on_change="onchange_template_id(template_id, partner_id, fiscal_position)"/>
<field name="validity_date"/> <field name="validity_date"/>
<field name="website_description" invisible="1"/> <field name="website_description" invisible="1"/>
</xpath> </xpath>
@ -88,6 +88,8 @@
<field name="product_id" on_change="on_change_product_id(product_id)"/> <field name="product_id" on_change="on_change_product_id(product_id)"/>
<field name="name"/> <field name="name"/>
<field name="product_uom_qty"/> <field name="product_uom_qty"/>
<field name="product_uom_id" groups="product.group_uom"/>
<field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="price_unit"/> <field name="price_unit"/>
<field name="website_description" invisible="1"/> <field name="website_description" invisible="1"/>
</tree> </tree>
@ -99,7 +101,7 @@
<field name="product_id" on_change="on_change_product_id(product_id)"/> <field name="product_id" on_change="on_change_product_id(product_id)"/>
<field name="name"/> <field name="name"/>
<field name="quantity"/> <field name="quantity"/>
<field name="uom_id"/> <field name="uom_id" groups="product.group_uom"/>
<field name="price_unit"/> <field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line"/> <field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="website_description" invisible="1"/> <field name="website_description" invisible="1"/>
@ -124,7 +126,7 @@
</field> </field>
</record> </record>
<record id="action_sale_quotation_template" model="ir.actions.act_window"> <record id="action_sale_quotation_template" model="ir.actions.act_window">
<field name="name">Sales Template</field> <field name="name">Quotation Templates</field>
<field name="type">ir.actions.act_window</field> <field name="type">ir.actions.act_window</field>
<field name="res_model">sale.quote.template</field> <field name="res_model">sale.quote.template</field>
<field name="view_type">form</field> <field name="view_type">form</field>