[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
import werkzeug
import datetime
import time
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
# 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)
if token and not message:
if token:
assert token == order.access_token, 'Access denied!'
body=_('Quotation viewed by customer')
self.__message_post(body, order_id, type='comment')
if not message:
body=_('Quotation viewed by customer')
self.__message_post(body, order_id, type='comment')
days = 0
if order.validity_date:
days = (datetime.datetime.strptime(order.validity_date, '%Y-%m-%d') - datetime.datetime.now()).days + 1
values = {
'quotation': order,
'message': message,
'message': message and int(message) or False,
'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),
'days_valid': max(days, 0)
@ -133,14 +135,25 @@ class sale_quote(http.Controller):
assert token == order.access_token, 'Access denied, wrong token!'
option_obj = request.registry.get('sale.order.option')
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({
'price_unit': option.price_unit,
'website_description': option.website_description,
'name': option.name,
'order_id': order.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_id': option.uom_id.id,
'product_uom': option.uom_id.id,
'discount': option.discount,
})
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="quantity">1</field>
<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="discount">10</field>
<field name="website_description" type="html">

View File

@ -31,7 +31,7 @@ class sale_quote_template(osv.osv):
_description = "Sale Quotation Template"
_columns = {
'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'),
'note': fields.text('Terms and conditions'),
'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"
_columns = {
'quote_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', required=True, ondelete='cascade', select=True),
'name': fields.text('Description', required=True),
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], change_default=True),
'website_description': fields.html('Line Description'),
'name': fields.text('Description', required=True, translate=True),
'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True),
'website_description': fields.html('Line Description', translate=True),
'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')),
'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)
vals.update({
'price_unit': product_obj.list_price,
'product_uom_id': product_obj.uom_id.id,
'website_description': product_obj.website_description,
'name': product_obj.name,
})
@ -120,11 +121,18 @@ class sale_order(osv.osv):
'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 = []
quote_template = self.pool.get('sale.quote.template').browse(cr, uid, template_id, context=context)
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,
'price_unit': line.price_unit,
'discount': line.discount,
@ -133,7 +141,8 @@ class sale_order(osv.osv):
'product_uom': line.product_uom_id.id,
'website_description': line.website_description,
'state': 'draft',
}))
})
lines.append((0, 0, data))
options = []
for option in quote_template.options:
options.append((0, 0, {
@ -167,7 +176,7 @@ class sale_quote_option(osv.osv):
_columns = {
'template_id': fields.many2one('sale.quote.template', 'Quotation Template Reference', ondelete='cascade', select=True, required=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),
'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')),

View File

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

View File

@ -18,7 +18,7 @@
<field name="product_id" on_change="on_change_product_id(product_id)"/>
<field name="name"/>
<field name="quantity"/>
<field name="uom_id"/>
<field name="uom_id" groups="product.group_uom"/>
<field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="website_description" invisible="1"/>
@ -27,7 +27,7 @@
</page>
</xpath>
<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="website_description" invisible="1"/>
</xpath>
@ -88,6 +88,8 @@
<field name="product_id" on_change="on_change_product_id(product_id)"/>
<field name="name"/>
<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="website_description" invisible="1"/>
</tree>
@ -99,7 +101,7 @@
<field name="product_id" on_change="on_change_product_id(product_id)"/>
<field name="name"/>
<field name="quantity"/>
<field name="uom_id"/>
<field name="uom_id" groups="product.group_uom"/>
<field name="price_unit"/>
<field name="discount" groups="sale.group_discount_per_so_line"/>
<field name="website_description" invisible="1"/>
@ -124,7 +126,7 @@
</field>
</record>
<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="res_model">sale.quote.template</field>
<field name="view_type">form</field>