[MERGE] forward port branch 10.0 up to caf6b4a7c7
This commit is contained in:
@@ -1417,7 +1417,14 @@ class AccountInvoiceTax(models.Model):
|
|||||||
currency_id = fields.Many2one('res.currency', related='invoice_id.currency_id', store=True, readonly=True)
|
currency_id = fields.Many2one('res.currency', related='invoice_id.currency_id', store=True, readonly=True)
|
||||||
base = fields.Monetary(string='Base', compute='_compute_base_amount', store=True)
|
base = fields.Monetary(string='Base', compute='_compute_base_amount', store=True)
|
||||||
|
|
||||||
|
# DO NOT FORWARD-PORT!!! ONLY FOR v10
|
||||||
|
def create(self, vals):
|
||||||
|
inv_tax = super(AccountInvoiceTax, self).create(vals)
|
||||||
|
# Workaround to make sure the tax amount is rounded to the currency precision since the ORM
|
||||||
|
# won't round it automatically at creation.
|
||||||
|
if inv_tax.company_id.tax_calculation_rounding_method == 'round_globally':
|
||||||
|
inv_tax.amount = inv_tax.currency_id.round(inv_tax.amount)
|
||||||
|
return inv_tax
|
||||||
|
|
||||||
|
|
||||||
class AccountPaymentTerm(models.Model):
|
class AccountPaymentTerm(models.Model):
|
||||||
|
|||||||
@@ -453,7 +453,7 @@ class AccountMoveLine(models.Model):
|
|||||||
raise ValidationError(_("You cannot create journal items with a secondary currency without filling both 'currency' and 'amount currency' field."))
|
raise ValidationError(_("You cannot create journal items with a secondary currency without filling both 'currency' and 'amount currency' field."))
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
@api.constrains('amount_currency')
|
@api.constrains('amount_currency', 'debit', 'credit')
|
||||||
def _check_currency_amount(self):
|
def _check_currency_amount(self):
|
||||||
for line in self:
|
for line in self:
|
||||||
if line.amount_currency:
|
if line.amount_currency:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import math
|
import math
|
||||||
|
|
||||||
from odoo import models, fields, api, _
|
from odoo import models, fields, api, _
|
||||||
from odoo.tools import amount_to_text_en, float_round
|
from odoo.tools import amount_to_text_en, float_round, float_is_zero
|
||||||
from odoo.exceptions import UserError, ValidationError
|
from odoo.exceptions import UserError, ValidationError
|
||||||
|
|
||||||
|
|
||||||
@@ -55,7 +55,7 @@ class AccountPayment(models.Model):
|
|||||||
check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(amount), lang='en', currency='')
|
check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(amount), lang='en', currency='')
|
||||||
check_amount_in_words = check_amount_in_words.replace(' and Zero Cent', '') # Ugh
|
check_amount_in_words = check_amount_in_words.replace(' and Zero Cent', '') # Ugh
|
||||||
decimals = amount % 1
|
decimals = amount % 1
|
||||||
if decimals >= 10**-2:
|
if not float_is_zero(decimals, precision_digits=2):
|
||||||
check_amount_in_words += _(' and %s/100') % str(int(round(float_round(decimals*100, precision_rounding=1))))
|
check_amount_in_words += _(' and %s/100') % str(int(round(float_round(decimals*100, precision_rounding=1))))
|
||||||
return check_amount_in_words
|
return check_amount_in_words
|
||||||
|
|
||||||
|
|||||||
@@ -853,7 +853,7 @@ class Meeting(models.Model):
|
|||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
def _compute_color_partner(self):
|
def _compute_color_partner(self):
|
||||||
for meeting in self:
|
for meeting in self.sudo():
|
||||||
meeting.color_partner_id = meeting.user_id.partner_id.id
|
meeting.color_partner_id = meeting.user_id.partner_id.id
|
||||||
|
|
||||||
@api.constrains('start_datetime', 'stop_datetime', 'start_date', 'stop_date')
|
@api.constrains('start_datetime', 'stop_datetime', 'start_date', 'stop_date')
|
||||||
|
|||||||
@@ -55,20 +55,20 @@
|
|||||||
<field name="model_id">crm.opportunity.report</field>
|
<field name="model_id">crm.opportunity.report</field>
|
||||||
<field name="domain">[('probability', '=', 100)]</field>
|
<field name="domain">[('probability', '=', 100)]</field>
|
||||||
<field name="user_id" eval="False"/>
|
<field name="user_id" eval="False"/>
|
||||||
<field name="context">{'group_by': ['date_closed:month'],'col_group_by': ['create_date:month'], 'measures': ['__count']}</field>
|
<field name="context">{'group_by': ['date_closed:month'],'col_group_by': ['create_date:month'], 'measures': ['__count__']}</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="filter_opportunity_opportunities_won_per_team" model="ir.filters">
|
<record id="filter_opportunity_opportunities_won_per_team" model="ir.filters">
|
||||||
<field name="name">Opportunities Won Per Team</field>
|
<field name="name">Opportunities Won Per Team</field>
|
||||||
<field name="model_id">crm.opportunity.report</field>
|
<field name="model_id">crm.opportunity.report</field>
|
||||||
<field name="domain">[('probability', '=', 100)]</field>
|
<field name="domain">[('probability', '=', 100)]</field>
|
||||||
<field name="user_id" eval="False"/>
|
<field name="user_id" eval="False"/>
|
||||||
<field name="context">{'group_by': ['team_id'], 'col_group_by': ['date_last_stage_update:month'], 'measures': ['expected revenue']}</field>
|
<field name="context">{'group_by': ['team_id'], 'col_group_by': ['date_last_stage_update:month'], 'measures': ['expected_revenue']}</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="filter_opportunity_salesperson" model="ir.filters">
|
<record id="filter_opportunity_salesperson" model="ir.filters">
|
||||||
<field name="name">Leads By Salespersons</field>
|
<field name="name">Leads By Salespersons</field>
|
||||||
<field name="model_id">crm.opportunity.report</field>
|
<field name="model_id">crm.opportunity.report</field>
|
||||||
<field name="user_id" eval="False"/>
|
<field name="user_id" eval="False"/>
|
||||||
<field name="context">{'col_group_by': ['create_date:month'], 'group_by': ['user_id'], 'measures': ['__count']}</field>
|
<field name="context">{'col_group_by': ['create_date:month'], 'group_by': ['user_id'], 'measures': ['__count__']}</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="filter_opportunity_country" model="ir.filters">
|
<record id="filter_opportunity_country" model="ir.filters">
|
||||||
<field name="name">Won By Country</field>
|
<field name="name">Won By Country</field>
|
||||||
@@ -81,7 +81,7 @@
|
|||||||
<field name="name">Expected Revenue by Team</field>
|
<field name="name">Expected Revenue by Team</field>
|
||||||
<field name="model_id">crm.opportunity.report</field>
|
<field name="model_id">crm.opportunity.report</field>
|
||||||
<field name="user_id" eval="False"/>
|
<field name="user_id" eval="False"/>
|
||||||
<field name="context">{'group_by': ['create_date:month', 'team_id'], 'measures': ['expected_revenue', '__count']}</field>
|
<field name="context">{'group_by': ['create_date:month', 'team_id'], 'measures': ['expected_revenue', '__count__']}</field>
|
||||||
</record>
|
</record>
|
||||||
<record id="ir_filters_crm_opportunity_report_next_action" model="ir.filters">
|
<record id="ir_filters_crm_opportunity_report_next_action" model="ir.filters">
|
||||||
<field name="name">Team Activities</field>
|
<field name="name">Team Activities</field>
|
||||||
|
|||||||
@@ -164,7 +164,7 @@
|
|||||||
<filter domain="[('state', '=', 'draft')]" string="To Submit" name="to_report" help="New Expense"/>
|
<filter domain="[('state', '=', 'draft')]" string="To Submit" name="to_report" help="New Expense"/>
|
||||||
<filter domain="[('state', '=', 'reported')]" string="Reported" name="submitted" help="Confirmed Expenses"/>
|
<filter domain="[('state', '=', 'reported')]" string="Reported" name="submitted" help="Confirmed Expenses"/>
|
||||||
<filter domain="[('state', '=', 'refused')]" string="Refused" name="refused" help="Refused Expenses"/>
|
<filter domain="[('state', '=', 'refused')]" string="Refused" name="refused" help="Refused Expenses"/>
|
||||||
<filter domain="[('state', '!=', 'cancel')]" string="Not Refused" name="uncancelled" help="Actual expense sheets, not the refused ones"/>
|
<filter domain="[('state', '!=', 'refused')]" string="Not Refused" name="uncancelled" help="Actual expense sheets, not the refused ones"/>
|
||||||
<separator />
|
<separator />
|
||||||
<filter string="My Team Expenses" domain="[('employee_id.parent_id.user_id', '=', uid)]" groups="hr_expense.group_hr_expense_manager" help="Expenses of Your Team Member"/>
|
<filter string="My Team Expenses" domain="[('employee_id.parent_id.user_id', '=', uid)]" groups="hr_expense.group_hr_expense_manager" help="Expenses of Your Team Member"/>
|
||||||
<filter string="My Expenses" domain="[('employee_id.user_id', '=', uid)]"/>
|
<filter string="My Expenses" domain="[('employee_id.user_id', '=', uid)]"/>
|
||||||
|
|||||||
@@ -9,12 +9,17 @@ class AccountAnalyticLine(models.Model):
|
|||||||
|
|
||||||
task_id = fields.Many2one('project.task', 'Task')
|
task_id = fields.Many2one('project.task', 'Task')
|
||||||
project_id = fields.Many2one('project.project', 'Project', domain=[('allow_timesheets', '=', True)])
|
project_id = fields.Many2one('project.project', 'Project', domain=[('allow_timesheets', '=', True)])
|
||||||
department_id = fields.Many2one('hr.department', "Department", related='user_id.employee_ids.department_id', store=True, readonly=True)
|
department_id = fields.Many2one('hr.department', "Department", compute='_compute_department_id', store=True)
|
||||||
|
|
||||||
@api.onchange('project_id')
|
@api.onchange('project_id')
|
||||||
def onchange_project_id(self):
|
def onchange_project_id(self):
|
||||||
self.task_id = False
|
self.task_id = False
|
||||||
|
|
||||||
|
@api.depends('user_id')
|
||||||
|
def _compute_department_id(self):
|
||||||
|
for line in self:
|
||||||
|
line.department_id = line.user_id.employee_ids[:1].department_id
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def create(self, vals):
|
def create(self, vals):
|
||||||
if vals.get('project_id'):
|
if vals.get('project_id'):
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import logging
|
import logging
|
||||||
import time
|
import time
|
||||||
from os import listdir
|
from os import listdir
|
||||||
from os.path import join
|
from os.path import join, isdir
|
||||||
from Queue import Queue, Empty
|
from Queue import Queue, Empty
|
||||||
from select import select
|
from select import select
|
||||||
from threading import Thread, Lock
|
from threading import Thread, Lock
|
||||||
@@ -121,7 +121,7 @@ class Scanner(Thread):
|
|||||||
if not evdev:
|
if not evdev:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
if not os.path.isdir(self.input_dir):
|
if not isdir(self.input_dir):
|
||||||
return []
|
return []
|
||||||
|
|
||||||
new_devices = [device for device in listdir(self.input_dir)
|
new_devices = [device for device in listdir(self.input_dir)
|
||||||
|
|||||||
@@ -37,11 +37,11 @@ class AccountChartTemplate(models.Model):
|
|||||||
'type': 'model',
|
'type': 'model',
|
||||||
'res_id': out_ids[counter].id,
|
'res_id': out_ids[counter].id,
|
||||||
'lang': lang,
|
'lang': lang,
|
||||||
'src': element.name,
|
'src': element[in_field],
|
||||||
'value': value[element.id],
|
'value': value[element.id],
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
_logger.info('Language: %s. Translation from template: there is no translation available for %s!' % (lang, element.name))
|
_logger.info('Language: %s. Translation from template: there is no translation available for %s!' % (lang, element[in_field]))
|
||||||
counter += 1
|
counter += 1
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|||||||
@@ -126,8 +126,18 @@ class PaymentAcquirerAuthorize(models.Model):
|
|||||||
for field_name in mandatory_fields:
|
for field_name in mandatory_fields:
|
||||||
if not data.get(field_name):
|
if not data.get(field_name):
|
||||||
error[field_name] = 'missing'
|
error[field_name] = 'missing'
|
||||||
if data['cc_expiry'] and datetime.now().strftime('%y%m') > datetime.strptime(data['cc_expiry'], '%m / %y').strftime('%y%m'):
|
if data['cc_expiry']:
|
||||||
return False
|
# FIX we split the date into their components and check if there is two components containing only digits
|
||||||
|
# this fixes multiples crashes, if there was no space between the '/' and the components the code was crashing
|
||||||
|
# the code was also crashing if the customer was proving non digits to the date.
|
||||||
|
cc_expiry = [i.strip() for i in data['cc_expiry'].split('/')]
|
||||||
|
if len(cc_expiry) != 2 or any(not i.isdigit() for i in cc_expiry):
|
||||||
|
return False
|
||||||
|
try:
|
||||||
|
if datetime.now().strftime('%y%m') > datetime.strptime('/'.join(cc_expiry), '%m/%y').strftime('%y%m'):
|
||||||
|
return False
|
||||||
|
except ValueError:
|
||||||
|
return False
|
||||||
return False if error else True
|
return False if error else True
|
||||||
|
|
||||||
@api.multi
|
@api.multi
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<field name="lang">${object.partner_id.lang}</field>
|
<field name="lang">${object.partner_id.lang}</field>
|
||||||
<field name="body_html"><![CDATA[
|
<field name="body_html"><![CDATA[
|
||||||
<p>Dear
|
<p>Dear
|
||||||
% if object.partner_id.is_company and object.child_ids:
|
% if object.partner_id.is_company and object.partner_id.child_ids:
|
||||||
${object.partner_id.child_ids[0].name}
|
${object.partner_id.child_ids[0].name}
|
||||||
% else :
|
% else :
|
||||||
${object.partner_id.name}
|
${object.partner_id.name}
|
||||||
@@ -55,7 +55,7 @@ from ${object.company_id.name}.
|
|||||||
<field name="report_name">PO_${(object.name or '').replace('/','_')}</field>
|
<field name="report_name">PO_${(object.name or '').replace('/','_')}</field>
|
||||||
<field name="lang">${object.partner_id.lang}</field>
|
<field name="lang">${object.partner_id.lang}</field>
|
||||||
<field name="body_html"><![CDATA[
|
<field name="body_html"><![CDATA[
|
||||||
<p>Dear ${object.partner_id.name}
|
<p>Dear ${object.partner_id.name}
|
||||||
% if object.partner_id.parent_id:
|
% if object.partner_id.parent_id:
|
||||||
(<i>${object.partner_id.parent_id.name}</i>)
|
(<i>${object.partner_id.parent_id.name}</i>)
|
||||||
% endif
|
% endif
|
||||||
|
|||||||
@@ -145,7 +145,6 @@ watch your stock valuation, and track production lots (based on serial numbers).
|
|||||||
|
|
||||||
|
|
||||||
<record id="warehouse0" model="stock.warehouse">
|
<record id="warehouse0" model="stock.warehouse">
|
||||||
<field model="res.company" name="name" search="[]" use="name"/>
|
|
||||||
<field name="partner_id" ref="base.main_partner"/>
|
<field name="partner_id" ref="base.main_partner"/>
|
||||||
<field name="code">WH</field>
|
<field name="code">WH</field>
|
||||||
</record>
|
</record>
|
||||||
|
|||||||
@@ -395,7 +395,8 @@ class InventoryLine(models.Model):
|
|||||||
if existings:
|
if existings:
|
||||||
raise UserError(_("You cannot have two inventory adjustements in state 'in Progess' with the same product"
|
raise UserError(_("You cannot have two inventory adjustements in state 'in Progess' with the same product"
|
||||||
"(%s), same location(%s), same package, same owner and same lot. Please first validate"
|
"(%s), same location(%s), same package, same owner and same lot. Please first validate"
|
||||||
"the first inventory adjustement with this product before creating another one.") % (res.product_id.name, res.location_id.name))
|
"the first inventory adjustement with this product before creating another one.") %
|
||||||
|
(res.product_id.display_name, res.location_id.display_name))
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _get_quants(self):
|
def _get_quants(self):
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class Warehouse(models.Model):
|
|||||||
# namedtuple used in helper methods generating values for routes
|
# namedtuple used in helper methods generating values for routes
|
||||||
Routing = namedtuple('Routing', ['from_loc', 'dest_loc', 'picking_type'])
|
Routing = namedtuple('Routing', ['from_loc', 'dest_loc', 'picking_type'])
|
||||||
|
|
||||||
name = fields.Char('Warehouse Name', index=True, required=True)
|
name = fields.Char('Warehouse Name', index=True, required=True, default=lambda self: self.env['res.company']._company_default_get('stock.inventory').name)
|
||||||
active = fields.Boolean('Active', default=True)
|
active = fields.Boolean('Active', default=True)
|
||||||
company_id = fields.Many2one(
|
company_id = fields.Many2one(
|
||||||
'res.company', 'Company', default=lambda self: self.env['res.company']._company_default_get('stock.inventory'),
|
'res.company', 'Company', default=lambda self: self.env['res.company']._company_default_get('stock.inventory'),
|
||||||
|
|||||||
@@ -120,12 +120,37 @@ var WebClient = Widget.extend({
|
|||||||
// crash manager integration
|
// crash manager integration
|
||||||
session.on('error', crash_manager, crash_manager.rpc_error);
|
session.on('error', crash_manager, crash_manager.rpc_error);
|
||||||
window.onerror = function (message, file, line, col, error) {
|
window.onerror = function (message, file, line, col, error) {
|
||||||
var traceback = error ? error.stack : '';
|
// Scripts injected in DOM (eg: google API's js files) won't return a clean error on window.onerror.
|
||||||
crash_manager.show_error({
|
// The browser will just give you a 'Script error.' as message and nothing else for security issue.
|
||||||
type: _t("Odoo Client Error"),
|
// To enable onerror to work properly with CORS file, you should:
|
||||||
message: message,
|
// 1. add crossorigin="anonymous" to your <script> tag loading the file
|
||||||
data: {debug: file + ':' + line + "\n" + _t('Traceback:') + "\n" + traceback}
|
// 2. enabling 'Access-Control-Allow-Origin' on the server serving the file.
|
||||||
});
|
// Since in some case it wont be possible to to this, this handle should have the possibility to be
|
||||||
|
// handled by the script manipulating the injected file. For this, you will use window.onOriginError
|
||||||
|
// If it is not handled, we should display something clearer than the common crash_manager error dialog
|
||||||
|
// since it won't show anything except "Script error."
|
||||||
|
// This link will probably explain it better: https://blog.sentry.io/2016/05/17/what-is-script-error.html
|
||||||
|
if (!file && !line && !col) {
|
||||||
|
// Chrome and Opera set "Script error." on the `message` and hide the `error`
|
||||||
|
// Firefox handles the "Script error." directly. It sets the error thrown by the CORS file into `error`
|
||||||
|
if (window.onOriginError) {
|
||||||
|
window.onOriginError();
|
||||||
|
delete window.onOriginError;
|
||||||
|
} else {
|
||||||
|
crash_manager.show_error({
|
||||||
|
type: _t("Odoo Client Error"),
|
||||||
|
message: _t("Unknown CORS error"),
|
||||||
|
data: {debug: _t("An unknown CORS error occured. The error probably originates from a JavaScript file served from a different origin. (Opening your browser console might give you a hint on the error.)")},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var traceback = error ? error.stack : '';
|
||||||
|
crash_manager.show_error({
|
||||||
|
type: _t("Odoo Client Error"),
|
||||||
|
message: message,
|
||||||
|
data: {debug: file + ':' + line + "\n" + _t('Traceback:') + "\n" + traceback},
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
set_action_manager: function() {
|
set_action_manager: function() {
|
||||||
|
|||||||
@@ -457,7 +457,7 @@ return core.Class.extend({
|
|||||||
this._stop_running_tour_timeout();
|
this._stop_running_tour_timeout();
|
||||||
this.running_tour_timeout = setTimeout((function() {
|
this.running_tour_timeout = setTimeout((function() {
|
||||||
this._consume_tour(tour_name, _.str.sprintf("Tour %s failed at step %s", tour_name, step.trigger));
|
this._consume_tour(tour_name, _.str.sprintf("Tour %s failed at step %s", tour_name, step.trigger));
|
||||||
}).bind(this), RUNNING_TOUR_TIMEOUT + this.running_step_delay);
|
}).bind(this), (step.timeout || RUNNING_TOUR_TIMEOUT) + this.running_step_delay);
|
||||||
},
|
},
|
||||||
_stop_running_tour_timeout: function () {
|
_stop_running_tour_timeout: function () {
|
||||||
clearTimeout(this.running_tour_timeout);
|
clearTimeout(this.running_tour_timeout);
|
||||||
|
|||||||
@@ -174,6 +174,10 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
|
|||||||
$analytics_components.empty();
|
$analytics_components.empty();
|
||||||
// 1. Authorize component
|
// 1. Authorize component
|
||||||
var $analytics_auth = $('<div>').addClass('col-md-12');
|
var $analytics_auth = $('<div>').addClass('col-md-12');
|
||||||
|
window.onOriginError = function () {
|
||||||
|
$analytics_components.find('.js_unauthorized_message').remove();
|
||||||
|
self.display_unauthorized_message($analytics_components, 'not_initialized');
|
||||||
|
};
|
||||||
gapi.analytics.auth.authorize({
|
gapi.analytics.auth.authorize({
|
||||||
container: $analytics_auth[0],
|
container: $analytics_auth[0],
|
||||||
clientid: client_id
|
clientid: client_id
|
||||||
@@ -182,6 +186,7 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
|
|||||||
|
|
||||||
self.handle_analytics_auth($analytics_components);
|
self.handle_analytics_auth($analytics_components);
|
||||||
gapi.analytics.auth.on('signIn', function() {
|
gapi.analytics.auth.on('signIn', function() {
|
||||||
|
delete window.onOriginError;
|
||||||
self.handle_analytics_auth($analytics_components);
|
self.handle_analytics_auth($analytics_components);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,7 @@
|
|||||||
<div t-name="website.unauthorized_analytics" class="col-xs-12 js_unauthorized_message mb16">
|
<div t-name="website.unauthorized_analytics" class="col-xs-12 js_unauthorized_message mb16">
|
||||||
<span t-if="reason === 'not_connected'">You need to log in to your Google Account before: </span>
|
<span t-if="reason === 'not_connected'">You need to log in to your Google Account before: </span>
|
||||||
<span t-if="reason === 'no_right'">You do not seem to have access to this Analytics Account.</span>
|
<span t-if="reason === 'no_right'">You do not seem to have access to this Analytics Account.</span>
|
||||||
|
<span t-if="reason === 'not_initialized'">Google Analytics initialization failed. Maybe this domain is not whitelisted in your Google Analytics project for this client ID.</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div t-name="website.ga_dialog_content">
|
<div t-name="website.ga_dialog_content">
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ class Website(models.Model):
|
|||||||
_inherit = 'website'
|
_inherit = 'website'
|
||||||
|
|
||||||
pricelist_id = fields.Many2one('product.pricelist', compute='_compute_pricelist_id', string='Default Pricelist')
|
pricelist_id = fields.Many2one('product.pricelist', compute='_compute_pricelist_id', string='Default Pricelist')
|
||||||
currency_id = fields.Many2one('res.currency', related='pricelist_id.currency_id', string='Default Currency')
|
currency_id = fields.Many2one('res.currency', related='pricelist_id.currency_id', related_sudo=False, string='Default Currency')
|
||||||
salesperson_id = fields.Many2one('res.users', string='Salesperson')
|
salesperson_id = fields.Many2one('res.users', string='Salesperson')
|
||||||
salesteam_id = fields.Many2one('crm.team', string='Sales Channel')
|
salesteam_id = fields.Many2one('crm.team', string='Sales Channel')
|
||||||
pricelist_ids = fields.One2many('product.pricelist', compute="_compute_pricelist_ids",
|
pricelist_ids = fields.One2many('product.pricelist', compute="_compute_pricelist_ids",
|
||||||
|
|||||||
@@ -290,29 +290,33 @@
|
|||||||
<div class="col-xs-6 col-sm-4">
|
<div class="col-xs-6 col-sm-4">
|
||||||
<span class="menu_title">Services</span>
|
<span class="menu_title">Services</span>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.odoo.com/pricing">Editions</a></li>
|
<li><a href="https://www.odoo.sh">Odoo Cloud Platform</a></li>
|
||||||
<li><a href="http://www.odoo.com/pricing-online">Cloud Pricing</a></li>
|
<li class="divider"></li>
|
||||||
<li><a href="http://www.odoo.com/page/upgrade">Upgrade</a></li>
|
<li><a href="http://www.odoo.com/help">Support</a></li>
|
||||||
|
<li><a href="https://upgrade.odoo.com">Upgrade</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="http://www.odoo.com/partners">Find a partner</a></li>
|
<li><a href="http://www.odoo.com/partners">Find a partner</a></li>
|
||||||
<li><a href="http://www.odoo.com/page/become-a-partner">Become a partner</a></li>
|
<li><a href="http://www.odoo.com/page/become-a-partner">Become a partner</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
|
<li><a href="http://training.odoo.com/courses/odoo-functional">Training Center</a></li>
|
||||||
<li><a href="http://www.odoo.com/page/education-program">Education</a></li>
|
<li><a href="http://www.odoo.com/page/education-program">Education</a></li>
|
||||||
<li class="divider"></li>
|
<li class="divider"></li>
|
||||||
<li><a href="http://www.odoo.com/page/security">Security</a></li>
|
<li><a href="http://www.odoo.com/page/security">Security</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4 mb64">
|
<div class="col-xs-12 col-sm-4 mb64">
|
||||||
<span class="menu_title">About us</span>
|
<span class="menu_title">About us</span>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="http://www.odoo.com/page/about-us">Our company</a></li>
|
<li><a href="http://www.odoo.com/page/about-us">Our company</a></li>
|
||||||
<li><a href="http://www.odoo.com/page/contactus">Contact</a></li>
|
<li><a href="http://www.odoo.com/page/contactus">Contact</a></li>
|
||||||
<li class="divider" />
|
<li class="divider" />
|
||||||
<li><a href="http://www.odoo.com/event">Events</a></li>
|
<li><a href="http://www.odoo.com/event">Events</a></li>
|
||||||
<li><a href="http://www.odoo.com/blog/">Blog</a></li>
|
<li><a href="http://www.odoo.com/blog">Blog</a></li>
|
||||||
<li><a href="http://www.odoo.com/blog/6">Customers</a></li>
|
<li><a href="http://www.odoo.com/blog/6">Customers</a></li>
|
||||||
<li class="divider" />
|
<li class="divider" />
|
||||||
<li><a href="http://www.odoo.com/jobs">Jobs</a></li>
|
<li><a href="http://www.odoo.com/jobs">Jobs</a></li>
|
||||||
|
<li class="divider" />
|
||||||
|
<li><a href="http://www.odoo.com/page/legal">Legal</a> | <a href="http://www.odoo.com/privacy">Privacy</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
Croatia, 2017-10-31
|
||||||
|
|
||||||
|
DAJ MI 5 agrees to the terms of the Odoo Corporate Contributor License
|
||||||
|
Agreement v1.0.
|
||||||
|
|
||||||
|
I declare that I am authorized and able to make this agreement and sign this
|
||||||
|
declaration.
|
||||||
|
|
||||||
|
Signed,
|
||||||
|
|
||||||
|
Davor Bojkić bole@dajmi5.com https://github.com/dajmi5
|
||||||
|
|
||||||
|
List of contributors:
|
||||||
|
|
||||||
|
Davor Bojkić bole@dajmi5.com https://github.com/badbole
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
Ukraine, 2018-03-16
|
||||||
|
|
||||||
|
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,
|
||||||
|
|
||||||
|
Panarin Mykhailo Ihorevich m.panarin@mobilunity.com https://github.com/mpanarin
|
||||||
|
|
||||||
@@ -630,6 +630,9 @@ Model Reference
|
|||||||
|
|
||||||
If set to ``False``, override :meth:`.init` to create the database
|
If set to ``False``, override :meth:`.init` to create the database
|
||||||
table
|
table
|
||||||
|
|
||||||
|
.. tip:: To create a model without any table, inherit
|
||||||
|
from ``odoo.models.AbstractModel``
|
||||||
|
|
||||||
.. attribute:: _table
|
.. attribute:: _table
|
||||||
|
|
||||||
|
|||||||
@@ -172,7 +172,7 @@
|
|||||||
<record id="JPY" model="res.currency">
|
<record id="JPY" model="res.currency">
|
||||||
<field name="name">JPY</field>
|
<field name="name">JPY</field>
|
||||||
<field name="symbol">¥</field>
|
<field name="symbol">¥</field>
|
||||||
<field name="rounding">0.01</field>
|
<field name="rounding">1.00</field>
|
||||||
<field name="active" eval="False"/>
|
<field name="active" eval="False"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user