[MERGE] forward port branch saas-14 up to a4d5e64a4c
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
li.oe_share_gdoc > a:after {
|
||||
content: url('/google_drive/static/src/img/drive_icon.png');
|
||||
position: absolute;
|
||||
right: 5px;
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 1.5 KiB |
@@ -41,7 +41,7 @@ Sidebar.include({
|
||||
}
|
||||
if (!already_there){
|
||||
self.add_items('other', [{
|
||||
label: res.name+ '<img style="position:absolute;right:5px;height:20px;width:20px;" title="Google Drive" src="google_drive/static/src/img/drive_icon.png"/>',
|
||||
label: res.name,
|
||||
config_id: res.id,
|
||||
res_id: res_id,
|
||||
res_model: view.dataset.model,
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
<template id="assets_backend" name="google_drive assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<link rel="stylesheet" href="/google_drive/static/src/css/google_drive.css" />
|
||||
<script type="text/javascript" src="/google_drive/static/src/js/gdrive.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
@@ -108,7 +108,7 @@ msgstr ""
|
||||
#. module: hr_timesheet_attendance
|
||||
#: code:addons/hr_timesheet_attendance/models/hr_timesheet_sheet.py:85
|
||||
#, python-format
|
||||
msgid "The timesheet cannot be validated as it contains an attendance record with no Check Out)."
|
||||
msgid "The timesheet cannot be validated as it contains an attendance record with no Check Out."
|
||||
msgstr ""
|
||||
|
||||
#. module: hr_timesheet_attendance
|
||||
|
||||
@@ -82,7 +82,7 @@ class HrTimesheetSheet(models.Model):
|
||||
"""
|
||||
self.ensure_one()
|
||||
if any(self.attendances_ids.filtered(lambda r: not r.check_out)):
|
||||
raise UserError(_("The timesheet cannot be validated as it contains an attendance record with no Check Out)."))
|
||||
raise UserError(_("The timesheet cannot be validated as it contains an attendance record with no Check Out."))
|
||||
return True
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import urllib2
|
||||
import werkzeug
|
||||
|
||||
from odoo import http
|
||||
from odoo.addons.payment.models.payment_acquirer import ValidationError
|
||||
from odoo.http import request
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
@@ -86,7 +87,10 @@ class PaypalController(http.Controller):
|
||||
def paypal_ipn(self, **post):
|
||||
""" Paypal IPN. """
|
||||
_logger.info('Beginning Paypal IPN form_feedback with post data %s', pprint.pformat(post)) # debug
|
||||
self.paypal_validate_data(**post)
|
||||
try:
|
||||
self.paypal_validate_data(**post)
|
||||
except ValidationError:
|
||||
_logger.exception('Unable to validate the Paypal payment')
|
||||
return ''
|
||||
|
||||
@http.route('/payment/paypal/dpn', type='http', auth="none", methods=['POST', 'GET'], csrf=False)
|
||||
|
||||
@@ -24,4 +24,4 @@ class PosInvoiceReport(models.AbstractModel):
|
||||
not_invoiced_orders_names = list(map(lambda a: a.name, not_invoiced_posorders))
|
||||
raise UserError(_('No link to an invoice for %s.') % ', '.join(not_invoiced_orders_names))
|
||||
|
||||
return Report.sudo().render('account.report_invoice', {'docs': self.env['account.invoice'].browse(ids_to_print)})
|
||||
return Report.sudo().render('account.report_invoice', {'docs': self.env['account.invoice'].sudo().browse(ids_to_print)})
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
<div class="text-center">
|
||||
<h2>Sales Details</h2>
|
||||
|
||||
<strong><t t-esc="date_start"/> - <t t-esc="date_stop"/></strong>
|
||||
<strong><t t-esc="date_start" t-options="{'widget': 'datetime'}"/> - <t t-esc="date_stop" t-options="{'widget': 'datetime'}"/></strong>
|
||||
</div>
|
||||
|
||||
<!-- Orderlines -->
|
||||
|
||||
@@ -96,7 +96,7 @@ class ProductPriceHistory(models.Model):
|
||||
|
||||
company_id = fields.Many2one('res.company', default=_get_default_company_id, required=True)
|
||||
product_id = fields.Many2one('product.product', 'Product', ondelete='cascade', required=True)
|
||||
datetime = fields.Datetime('Date', default=fields.Datetime.now())
|
||||
datetime = fields.Datetime('Date', default=fields.Datetime.now)
|
||||
cost = fields.Float('Cost', digits=dp.get_precision('Product Price'))
|
||||
|
||||
|
||||
|
||||
@@ -162,10 +162,16 @@ class AccountInvoice(models.Model):
|
||||
if valuation_price_unit != i_line.price_unit and line['price_unit'] == i_line.price_unit and acc:
|
||||
# price with discount and without tax included
|
||||
price_unit = i_line.price_unit * (1 - (i_line.discount or 0.0) / 100.0)
|
||||
tax_ids = []
|
||||
if line['tax_ids']:
|
||||
#line['tax_ids'] is like [(4, tax_id, None), (4, tax_id2, None)...]
|
||||
taxes = self.env['account.tax'].browse([x[1] for x in line['tax_ids']])
|
||||
price_unit = taxes.compute_all(price_unit, currency=inv.currency_id, quantity=1.0)['total_excluded']
|
||||
for tax in taxes:
|
||||
tax_ids.append((4, tax.id, None))
|
||||
for child in tax.children_tax_ids:
|
||||
if child.type_tax_use != 'none':
|
||||
tax_ids.append((4, child.id, None))
|
||||
price_before = line.get('price', 0.0)
|
||||
line.update({'price': round(valuation_price_unit * line['quantity'], account_prec)})
|
||||
diff_res.append({
|
||||
@@ -178,6 +184,7 @@ class AccountInvoice(models.Model):
|
||||
'product_id': line['product_id'],
|
||||
'uom_id': line['uom_id'],
|
||||
'account_analytic_id': line['account_analytic_id'],
|
||||
'tax_ids': tax_ids,
|
||||
})
|
||||
return diff_res
|
||||
return []
|
||||
|
||||
@@ -21,7 +21,7 @@ class BaseConfigSettings(models.TransientModel):
|
||||
}
|
||||
|
||||
def edit_external_header(self):
|
||||
return self._prepare_report_view_action('report.layout_'+self.external_report_layout)
|
||||
return self._prepare_report_view_action('report.external_layout_' + self.external_report_layout)
|
||||
|
||||
def change_report_template(self):
|
||||
self.ensure_one()
|
||||
|
||||
@@ -919,6 +919,11 @@ class SaleOrderLine(models.Model):
|
||||
product_currency = None
|
||||
if rule_id:
|
||||
pricelist_item = PricelistItem.browse(rule_id)
|
||||
if pricelist_item.pricelist_id.discount_policy == 'without_discount':
|
||||
while pricelist_item.base == 'pricelist' and pricelist_item.base_pricelist_id and pricelist_item.base_pricelist_id.discount_policy == 'without_discount':
|
||||
price, rule_id = pricelist_item.base_pricelist_id.with_context(uom=uom.id).get_product_price_rule(product, qty, self.order_id.partner_id)
|
||||
pricelist_item = PricelistItem.browse(rule_id)
|
||||
|
||||
if pricelist_item.base == 'standard_price':
|
||||
field_name = 'standard_price'
|
||||
if pricelist_item.base == 'pricelist' and pricelist_item.base_pricelist_id:
|
||||
@@ -955,8 +960,8 @@ class SaleOrderLine(models.Model):
|
||||
self.env.user.has_group('sale.group_discount_per_so_line')):
|
||||
return
|
||||
|
||||
context_partner = dict(self.env.context, partner_id=self.order_id.partner_id.id)
|
||||
pricelist_context = dict(context_partner, uom=self.product_uom.id, date=self.order_id.date_order)
|
||||
context_partner = dict(self.env.context, partner_id=self.order_id.partner_id.id, date=self.order_id.date_order)
|
||||
pricelist_context = dict(context_partner, uom=self.product_uom.id)
|
||||
|
||||
price, rule_id = self.order_id.pricelist_id.with_context(pricelist_context).get_product_price_rule(self.product_id, self.product_uom_qty or 1.0, self.order_id.partner_id)
|
||||
new_list_price, currency_id = self.with_context(context_partner)._get_real_price_currency(self.product_id, rule_id, self.product_uom_qty, self.product_uom, self.order_id.pricelist_id.id)
|
||||
@@ -965,8 +970,7 @@ class SaleOrderLine(models.Model):
|
||||
if price != 0 and new_list_price != 0:
|
||||
if self.product_id.company_id and self.order_id.pricelist_id.currency_id != self.product_id.company_id.currency_id:
|
||||
# new_list_price is in company's currency while price in pricelist currency
|
||||
ctx = dict(context_partner, date=self.order_id.date_order)
|
||||
new_list_price = self.env['res.currency'].browse(currency_id).with_context(ctx).compute(new_list_price, self.order_id.pricelist_id.currency_id)
|
||||
new_list_price = self.env['res.currency'].browse(currency_id).with_context(context_partner).compute(new_list_price, self.order_id.pricelist_id.currency_id)
|
||||
discount = (new_list_price - price) / new_list_price * 100
|
||||
if discount > 0:
|
||||
self.discount = discount
|
||||
|
||||
@@ -51,8 +51,8 @@ class SaleConfiguration(models.TransientModel):
|
||||
group_proforma_sales = fields.Boolean(string="Pro-Forma", implied_group='sale.group_proforma_sales',
|
||||
help="Allows you to send pro-forma.")
|
||||
sale_show_tax = fields.Selection([
|
||||
('subtotal', 'Tax-Included Prices'),
|
||||
('total', 'Tax-Excluded Prices')], "Tax Display",
|
||||
('subtotal', 'Tax-Excluded Prices'),
|
||||
('total', 'Tax-Included Prices')], "Tax Display",
|
||||
default='subtotal',
|
||||
required=True)
|
||||
default_invoice_policy = fields.Selection([
|
||||
|
||||
@@ -89,8 +89,13 @@ class Inventory(models.Model):
|
||||
exhausted = fields.Boolean('Include Exhausted Products', readonly=True, states={'draft': [('readonly', False)]})
|
||||
|
||||
@api.one
|
||||
@api.depends('product_id', 'line_ids.product_qty')
|
||||
def _compute_total_qty(self):
|
||||
self.total_qty = sum(self.mapped('line_ids').mapped('product_qty'))
|
||||
""" For single product inventory, total quantity of the counted """
|
||||
if self.product_id:
|
||||
self.total_qty = sum(self.mapped('line_ids').mapped('product_qty'))
|
||||
else:
|
||||
self.total_qty = 0
|
||||
|
||||
@api.model
|
||||
def _selection_filter(self):
|
||||
|
||||
@@ -707,11 +707,14 @@ var FieldBooleanButton = common.AbstractField.extend({
|
||||
this.hover_false = _t("Open");
|
||||
break;
|
||||
default:
|
||||
var terms = typeof this.options["terminology"] === 'string' ? {} : this.options["terminology"];
|
||||
this.string_true = _t(terms.string_true || "On");
|
||||
this.hover_true = _t(terms.hover_true || terms.string_false || "Switch Off");
|
||||
this.string_false = _t(terms.string_false || "Off");
|
||||
this.hover_false = _t(terms.hover_false || terms.string_true || "Switch On");
|
||||
var opt_terms = this.options["terminology"] || {};
|
||||
if (typeof opt_terms === 'string') {
|
||||
opt_terms = {}; //unsupported terminology
|
||||
}
|
||||
this.string_true = _t(opt_terms.string_true) || _t("On");
|
||||
this.hover_true = _t(opt_terms.hover_true) || _t("Switch Off");
|
||||
this.string_false = _t(opt_terms.string_false) || _t("Off");
|
||||
this.hover_false = _t(opt_terms.hover_false) || _t("Switch On");
|
||||
}
|
||||
},
|
||||
render_value: function() {
|
||||
|
||||
@@ -641,7 +641,7 @@ ListView.include(/** @lends instance.web.ListView# */{
|
||||
if (saveInfo.created) {
|
||||
return self.start_edition();
|
||||
}
|
||||
var options = { wraparound: !self.is_action_enabled('create') };
|
||||
options.wraparound = !self.is_action_enabled('create');
|
||||
var record = self.records[next_record](saveInfo.record, options);
|
||||
if (record === undefined) {
|
||||
return self.start_edition();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
odoo.define_section('web.registry', ['web.Registry'], {
|
||||
beforeEach: function () {
|
||||
this.Foo = {};
|
||||
this.Bar = {};
|
||||
this.Foo2 = {};
|
||||
this.Foo = {bar: 1};
|
||||
this.Bar = {foo: 0};
|
||||
this.Foo2 = {fred: -1};
|
||||
},
|
||||
}, function (test) {
|
||||
|
||||
@@ -14,6 +14,8 @@ odoo.define_section('web.registry', ['web.Registry'], {
|
||||
.add('bar', this.Bar);
|
||||
|
||||
assert.strictEqual(registry.get('foo'), this.Foo);
|
||||
// make sure we're comparing actual objects instead of just undefineds
|
||||
assert.deepEqual(registry.get('foo'), {bar: 1});
|
||||
});
|
||||
|
||||
test('extension', function (assert, Registry) {
|
||||
|
||||
@@ -16,7 +16,7 @@ odoo.testing.start_services = function () {
|
||||
};
|
||||
|
||||
odoo.testing.MockRPC = function (session) {
|
||||
this.responses = {};
|
||||
this.clear();
|
||||
};
|
||||
|
||||
odoo.testing.MockRPC.prototype.clear = function () {
|
||||
@@ -81,8 +81,33 @@ odoo.define_section = function (name, section_deps) {
|
||||
section_body = arguments[3];
|
||||
}
|
||||
|
||||
QUnit.module(name, options);
|
||||
mock = new odoo.testing.MockRPC();
|
||||
|
||||
function dummyfunc () {};
|
||||
|
||||
function beforeEach(assert) {
|
||||
var services = odoo.testing.start_services();
|
||||
this.deps = services;
|
||||
this.getServiceDeps = function getServiceDeps(dep_names) {
|
||||
return _.map(dep_names, function (name) { return services[name]; })
|
||||
}
|
||||
services['web.core'].qweb.add_template(odoo.testing.templates);
|
||||
this.mock = mock;
|
||||
this.mock.interceptRPC(services['web.session']);
|
||||
this.assert = assert;
|
||||
(options.beforeEach || dummyfunc).apply(this, [assert].concat(this.getServiceDeps(section_deps)));
|
||||
}
|
||||
function afterEach(assert) {
|
||||
(options.afterEach || dummyfunc).apply(this, [assert].concat(this.getServiceDeps(section_deps)));
|
||||
this.mock.clear();
|
||||
}
|
||||
|
||||
QUnit.module(name, {
|
||||
before: options.before,
|
||||
beforeEach: beforeEach,
|
||||
afterEach: afterEach,
|
||||
after: options.after
|
||||
});
|
||||
|
||||
function test () {
|
||||
var name = arguments[0],
|
||||
@@ -90,21 +115,11 @@ odoo.define_section = function (name, section_deps) {
|
||||
body = arguments[arguments.length - 1];
|
||||
|
||||
QUnit.test(name, function (assert) {
|
||||
var services = odoo.testing.start_services();
|
||||
var deps = _.map(section_deps.concat(dep_names), function (name) { return services[name]; });
|
||||
services['web.core'].qweb.add_template(odoo.testing.templates);
|
||||
mock.clear();
|
||||
mock.interceptRPC(services['web.session']);
|
||||
var info = {
|
||||
assert: assert,
|
||||
mock: mock,
|
||||
deps: _.pick.apply(null, [services].concat(section_deps).concat(dep_names)),
|
||||
}
|
||||
return body.apply(info, [assert].concat(deps));
|
||||
var deps = this.getServiceDeps(section_deps.concat(dep_names));
|
||||
return body.apply(this, [assert].concat(deps));
|
||||
});
|
||||
}
|
||||
|
||||
var mock = new odoo.testing.MockRPC();
|
||||
section_body(test, mock);
|
||||
};
|
||||
|
||||
|
||||
@@ -288,6 +288,7 @@ var FieldTextHtml = widget.extend({
|
||||
return src;
|
||||
},
|
||||
initialize_content: function () {
|
||||
var self = this;
|
||||
this.$el.closest('.modal-body').css('max-height', 'none');
|
||||
this.$iframe = this.$el.find('iframe');
|
||||
this.document = null;
|
||||
@@ -296,6 +297,14 @@ var FieldTextHtml = widget.extend({
|
||||
this.editor = false;
|
||||
window.odoo[this.callback+"_updown"] = null;
|
||||
this.$iframe.attr("src", this.get_url());
|
||||
this.view.on("load_record", this, function(r){
|
||||
if (!self.$body.find('.o_dirty').length){
|
||||
var url = self.get_url();
|
||||
if(url !== self.$iframe.attr("src")){
|
||||
self.$iframe.attr("src", url);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
on_content_loaded: function () {
|
||||
var self = this;
|
||||
|
||||
@@ -328,12 +328,13 @@ class WebsiteSale(http.Controller):
|
||||
|
||||
@http.route(['/shop/pricelist'], type='http', auth="public", website=True)
|
||||
def pricelist(self, promo, **post):
|
||||
redirect = post.get('r', '/shop/cart')
|
||||
pricelist = request.env['product.pricelist'].sudo().search([('code', '=', promo)], limit=1)
|
||||
if pricelist and not request.website.is_pricelist_available(pricelist.id):
|
||||
return request.redirect("/shop/cart?code_not_available=1")
|
||||
if not pricelist or (pricelist and not request.website.is_pricelist_available(pricelist.id)):
|
||||
return request.redirect("%s?code_not_available=1" % redirect)
|
||||
|
||||
request.website.sale_get_order(code=promo)
|
||||
return request.redirect("/shop/cart")
|
||||
return request.redirect(redirect)
|
||||
|
||||
@http.route(['/shop/cart'], type='http', auth="public", website=True)
|
||||
def cart(self, **post):
|
||||
@@ -359,9 +360,6 @@ class WebsiteSale(http.Controller):
|
||||
if post.get('type') == 'popover':
|
||||
return request.render("website_sale.cart_popover", values)
|
||||
|
||||
if post.get('code_not_available'):
|
||||
values['code_not_available'] = post.get('code_not_available')
|
||||
|
||||
return request.render("website_sale.cart", values)
|
||||
|
||||
@http.route(['/shop/cart/update'], type='http', auth="public", methods=['POST'], website=True, csrf=False)
|
||||
|
||||
@@ -650,3 +650,12 @@ a.no-decoration {
|
||||
.o_shadow_animation {
|
||||
box-shadow: 0 0 5px 10px rgba(240, 8, 0, 0.4) !important;
|
||||
}
|
||||
|
||||
#coupon_box form {
|
||||
max-width: 300px;
|
||||
}
|
||||
|
||||
.font-weight-normal {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
|
||||
@@ -554,6 +554,12 @@ a.no-decoration
|
||||
.break-word
|
||||
word-wrap: break-word
|
||||
|
||||
#coupon_box form
|
||||
max-width: 300px
|
||||
|
||||
.font-weight-normal
|
||||
font-weight: normal
|
||||
|
||||
.o_website_sale_animate
|
||||
opacity: 0.7
|
||||
position: absolute
|
||||
|
||||
@@ -204,6 +204,19 @@ odoo.define('website_sale.website_sale', function (require) {
|
||||
event.preventDefault();
|
||||
$(this).closest('form').submit();
|
||||
}
|
||||
if ($(this).hasClass('a-submit-disable')){
|
||||
$(this).addClass("disabled");
|
||||
}
|
||||
if ($(this).hasClass('a-submit-loading')){
|
||||
var loading = '<span class="fa fa-cog fa-spin"/>';
|
||||
var fa_span = $(this).find('span[class*="fa"]');
|
||||
if (fa_span.length){
|
||||
fa_span.replaceWith(loading);
|
||||
}
|
||||
else{
|
||||
$(this).append(loading);
|
||||
}
|
||||
}
|
||||
});
|
||||
$('form.js_attributes input, form.js_attributes select', oe_website_sale).on('change', function (event) {
|
||||
if (!event.isDefaultPrevented()) {
|
||||
@@ -397,7 +410,7 @@ odoo.define('website_sale.website_sale', function (require) {
|
||||
//$("input[name='phone']").attr('placeholder', data.phone_code !== 0 ? '+'+ data.phone_code : '');
|
||||
|
||||
// populate states and display
|
||||
var selectStates = $("select[name='state_id']:visible");
|
||||
var selectStates = $("select[name='state_id']");
|
||||
// dont reload state at first loading (done in qweb)
|
||||
if (selectStates.data('init')===0 || selectStates.find('option').length===1) {
|
||||
if (data.states.length) {
|
||||
|
||||
@@ -1031,24 +1031,31 @@
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="reduction_code" inherit_id="website_sale.cart" active="True" customize_show="True" name="Coupon Code">
|
||||
<template id='coupon_form' name='Coupon form'>
|
||||
<t t-if="request.params.get('code_not_available')" name="code_not_available">
|
||||
<p class="bg-warning">This promo code is not available</p>
|
||||
</t>
|
||||
<form t-if="website_sale_order and website_sale_order.website_order_line" t-att-action="'/shop/pricelist%s' % (redirect and '?r=' + redirect or '')"
|
||||
method="post" class="mb32" name="coupon_code">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
|
||||
<div class="input-group">
|
||||
<input name="promo" class="form-control" type="text" placeholder="code..." t-att-value="website_sale_order.pricelist_id.code or None" />
|
||||
<div class="input-group-btn">
|
||||
<a class="btn btn-default a-submit">Apply</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<template id="reduction_code" inherit_id="website_sale.cart" active="False" customize_show="True" name="Coupon Code">
|
||||
<xpath expr="//div[@id='right_column']" position="inside">
|
||||
<h4>Coupon Code</h4>
|
||||
<p>
|
||||
Have a coupon code? Fill in this field and apply.
|
||||
</p>
|
||||
<t t-if="code_not_available" name="code_not_available">
|
||||
<p class="bg-warning">This promo code is not available</p>
|
||||
<t t-call='website_sale.coupon_form'>
|
||||
<t t-set='redirect'>/shop/cart</t>
|
||||
</t>
|
||||
<form t-if="website_sale_order and website_sale_order.website_order_line" action="/shop/pricelist" method="post" class="mb32" name="coupon_code">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
|
||||
<div class="input-group">
|
||||
<input name="promo" class="form-control" type="text" placeholder="code..." t-att-value="website_sale_order.pricelist_id.code or None" />
|
||||
<div class="input-group-btn">
|
||||
<a class="btn btn-default a-submit">Apply</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
@@ -1157,26 +1164,26 @@
|
||||
<t t-call="website.layout">
|
||||
<div id="wrap">
|
||||
<div class="container oe_website_sale">
|
||||
<div class="row">
|
||||
<div class="col-md-8 col-md-offset-2 oe_cart">
|
||||
<div class='row'>
|
||||
<t t-call="website_sale.wizard_checkout">
|
||||
<t t-set="step" t-value="20" />
|
||||
</t>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-9 oe_cart">
|
||||
<div class="row">
|
||||
<t t-if="mode == ('new', 'billing')">
|
||||
<h2 class="page-header mt16 ml16">Your Address
|
||||
<h3 class="page-header mt32 ml16">Your Address
|
||||
<small> or </small>
|
||||
<t t-set='connect' t-value="request.env['ir.config_parameter'].sudo().get_param('auth_signup.allow_uninvited') == 'True' and ('signup', 'Sign Up') or ('login', 'Log In')"/>
|
||||
<a t-attf-href='/web/{{connect[0]}}?redirect=/shop/checkout' class='btn btn-primary' style="margin-top: -11px"><t t-esc='connect[1]'/></a>
|
||||
</h2>
|
||||
</h3>
|
||||
</t>
|
||||
<t t-if="mode == ('edit', 'billing')">
|
||||
<h2 class="page-header mt16 ml16">Your Address</h2>
|
||||
<h3 class="page-header mt32 ml16">Your Address</h3>
|
||||
</t>
|
||||
<t t-if="mode[1] == 'shipping'">
|
||||
<h2 class="page-header mt16 ml16">Shipping Address </h2>
|
||||
<h3 class="page-header mt32 ml16">Shipping Address </h3>
|
||||
</t>
|
||||
<t t-if="error" t-foreach="error.get('error_message', [])" t-as="err">
|
||||
<h4 class="text-danger" t-esc="err" />
|
||||
@@ -1200,11 +1207,11 @@
|
||||
<div class="clearfix" />
|
||||
<t t-if="mode == ('new', 'billing')">
|
||||
<div t-attf-class="form-group #{error.get('company_name') and 'has-error' or ''} col-md-6">
|
||||
<label class="control-label" for="company_name">Company Name</label>
|
||||
<label class="control-label font-weight-normal" for="company_name">Company Name</label>
|
||||
<input type="text" name="company_name" class="form-control" t-att-value="'company_name' in checkout and checkout['company_name']" />
|
||||
</div>
|
||||
<div t-attf-class="form-group #{error.get('vat') and 'has-error' or ''} col-md-6 div_vat">
|
||||
<label class="control-label" for="vat">TIN / VAT </label>
|
||||
<label class="control-label font-weight-normal" for="vat">TIN / VAT </label>
|
||||
<input type="text" name="vat" class="form-control" t-att-value="'vat' in checkout and checkout['vat']" />
|
||||
</div>
|
||||
</t>
|
||||
@@ -1271,18 +1278,13 @@
|
||||
<a t-att-href="mode == ('new', 'billing') and '/shop/cart' or '/shop/checkout'" class="btn btn-default mb32">
|
||||
<span class="fa fa-long-arrow-left" /> Back
|
||||
</a>
|
||||
<a class="btn btn-default btn-primary pull-right mb32 a-submit">
|
||||
<a class="btn btn-default btn-primary pull-right mb32 a-submit a-submit-disable a-submit-loading">
|
||||
<span>Next </span><span class="fa fa-long-arrow-right" />
|
||||
</a>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-3 text-muted hidden-sm hidden-xs">
|
||||
<h2 class="page-header mt16 text-center">Your Order</h2>
|
||||
<t t-set="website_sale_order" t-value="website.sale_get_order()" />
|
||||
<t t-call="website_sale.total" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1352,15 +1354,24 @@
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-lg-5 col-sm-4 col-md-4 text-muted" id="coupon_box"/>
|
||||
<div class="col-md-12">
|
||||
<div class="col-lg-5 col-sm-6 col-xs-12 text-muted" id="coupon_box">
|
||||
<t t-if="request.env.ref('website_sale.reduction_code').active">
|
||||
<p>
|
||||
Have a coupon code? Fill in this field and apply.
|
||||
</p>
|
||||
<t t-call='website_sale.coupon_form'>
|
||||
<t t-set='redirect'>/shop/payment</t>
|
||||
</t>
|
||||
</t>
|
||||
</div>
|
||||
<t t-call="website_sale.total">
|
||||
<t t-set='extra_class' t-value='"col-md-5 col-md-offset-7 col-xs-8 col-xs-offset-4"'/>
|
||||
</t>
|
||||
</div>
|
||||
<div class="clearfix" />
|
||||
<div class="oe_structure" />
|
||||
<div class="js_payment mb64 row" t-if="acquirers and website_sale_order.amount_total" id="payment_method">
|
||||
<div class="js_payment mb64 col-md-12 row" t-if="acquirers and website_sale_order.amount_total" id="payment_method">
|
||||
<div class="col-lg-5 col-sm-6">
|
||||
<h4>Payment Method:</h4>
|
||||
<ul class="list-unstyled">
|
||||
@@ -1441,26 +1452,6 @@
|
||||
</t>
|
||||
</template>
|
||||
|
||||
<template id="reduction_code_payment" inherit_id="website_sale.payment" active="True" customize_show="True" name="Coupon Code">
|
||||
<xpath expr="//div[@id='coupon_box']" position="inside">
|
||||
<p>
|
||||
Have a coupon code? Fill in this field and apply.
|
||||
</p>
|
||||
<t t-if="code_not_available" name="code_not_available">
|
||||
<p class="bg-warning">This promo code is not available</p>
|
||||
</t>
|
||||
<form t-if="website_sale_order and website_sale_order.website_order_line" action="/shop/pricelist_payment" method="post" class="mb32" name="coupon_code">
|
||||
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()" />
|
||||
<div class="input-group">
|
||||
<input name="promo" class="form-control" type="text" placeholder="code..." t-att-value="website_sale_order.pricelist_id.code or None" />
|
||||
<div class="input-group-btn">
|
||||
<a class="btn btn-default a-submit">Apply</a>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<template id="payment_sale_note" inherit_id="payment" name="Accept Terms & Conditions" customize_show="True" active="False">
|
||||
<xpath expr="//t[@id='acquirers_list']" position="before">
|
||||
<div class="oe_accept_cgv_button">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_slide_slide_public,slide.slide.public,model_slide_slide,base.group_public,1,0,0,0
|
||||
access_slide_slide_portal,slide.slide.portal,model_slide_slide,base.group_portal,1,1,1,0
|
||||
access_slide_slide_portal,slide.slide.portal,model_slide_slide,base.group_portal,1,0,0,0
|
||||
access_slide_slide_user,slide.slide.user,model_slide_slide,base.group_user,1,1,1,1
|
||||
access_slide_tag_public,slide.tag.public,model_slide_tag,base.group_public,1,0,0,0
|
||||
access_slide_tag_portal,slide.tag.portal,model_slide_tag,base.group_portal,1,0,0,0
|
||||
|
||||
|
@@ -17,7 +17,7 @@
|
||||
<record id="rule_slide_channel_public" model="ir.rule">
|
||||
<field name="name">Channel: public: published only</field>
|
||||
<field name="model_id" ref="model_slide_channel"/>
|
||||
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
||||
<field name="groups" eval="[(4, ref('base.group_public')) ,(4, ref('base.group_portal'))]"/>
|
||||
<field name="domain_force">[('website_published', '=', True)]</field>
|
||||
</record>
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
<record id="rule_slide_slide_public" model="ir.rule">
|
||||
<field name="name">Slide: public: published only</field>
|
||||
<field name="model_id" ref="model_slide_slide"/>
|
||||
<field name="groups" eval="[(4, ref('base.group_public'))]"/>
|
||||
<field name="groups" eval="[(4, ref('base.group_public')), (4, ref('base.group_portal'))]"/>
|
||||
<field name="domain_force">[('channel_id.website_published', '=', True), ('website_published', '=', True)]</field>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
Bosnia and Herzegovina, 2017-03-02
|
||||
|
||||
I hereby agree to the terms of the Odoo Individual Contributor License
|
||||
Agreement v1.0.
|
||||
|
||||
I declare that I am authorized and able to make this agreement and sign this
|
||||
declaration.
|
||||
|
||||
Signed,
|
||||
|
||||
Boško Stojaković bluesoft83@gmail.com https://github.com/bluesoft83
|
||||
@@ -617,12 +617,13 @@ class IrActionsServer(models.Model):
|
||||
""", (self.env.uid, 'server', self._cr.dbname, __name__, level, message, "action", action.id, action.name))
|
||||
|
||||
eval_context = super(IrActionsServer, self)._get_eval_context(action=action)
|
||||
model = self.env[action.model_id.model]
|
||||
model_name = action.model_id.sudo().model
|
||||
model = self.env[model_name]
|
||||
record = None
|
||||
records = None
|
||||
if self._context.get('active_model') == action.model_id.model and self._context.get('active_id'):
|
||||
if self._context.get('active_model') == model_name and self._context.get('active_id'):
|
||||
record = model.browse(self._context['active_id'])
|
||||
if self._context.get('active_model') == action.model_id.model and self._context.get('active_ids'):
|
||||
if self._context.get('active_model') == model_name and self._context.get('active_ids'):
|
||||
records = model.browse(self._context['active_ids'])
|
||||
if self._context.get('onchange_self'):
|
||||
record = self._context['onchange_self']
|
||||
|
||||
@@ -7,6 +7,13 @@
|
||||
<field name="mode">primary</field>
|
||||
<field name="inherit_id" ref="base.view_server_action_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<div class="oe_title" position="before">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="toggle_active" type="object" class="oe_stat_button" icon="fa-archive">
|
||||
<field name="active" widget="boolean_button"/>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<xpath expr="//button[@name='create_action']" position="replace">
|
||||
<button name="method_direct_trigger" type="object" string="Run Manually" class="oe_highlight"/>
|
||||
</xpath>
|
||||
|
||||
@@ -164,10 +164,8 @@ class IrModel(models.Model):
|
||||
for model in self:
|
||||
if model.state != 'manual':
|
||||
raise UserError(_("Model '%s' contains module data and cannot be removed!") % model.name)
|
||||
|
||||
# prevent screwing up fields that depend on these models' fields
|
||||
for model in self:
|
||||
model.field_id._prepare_update()
|
||||
# prevent screwing up fields that depend on these models' fields
|
||||
model.field_id._prepare_update()
|
||||
|
||||
self._drop_table()
|
||||
res = super(IrModel, self).unlink()
|
||||
|
||||
@@ -183,7 +183,7 @@ class Users(models.Model):
|
||||
|
||||
def _default_groups(self):
|
||||
default_user = self.env.ref('base.default_user', raise_if_not_found=False)
|
||||
return (default_user or self.env['res.users']).groups_id
|
||||
return (default_user or self.env['res.users']).sudo().groups_id
|
||||
|
||||
def _companies_count(self):
|
||||
return self.env['res.company'].sudo().search_count([])
|
||||
|
||||
Reference in New Issue
Block a user