[MERGE] forward port branch saas-15 up to 0d55241185
This commit is contained in:
@@ -263,7 +263,6 @@ class AccountInvoice(models.Model):
|
||||
], string='Status', index=True, readonly=True, default='draft',
|
||||
track_visibility='onchange', copy=False,
|
||||
help=" * The 'Draft' status is used when a user is encoding a new and unconfirmed Invoice.\n"
|
||||
" * The 'Pro-forma' status is used when the invoice does not have an invoice number.\n"
|
||||
" * The 'Open' status is used when user creates invoice, an invoice number is generated. It stays in the open status till the user pays the invoice.\n"
|
||||
" * The 'Paid' status is set automatically when the invoice is paid. Its related journal entries may or may not be reconciled.\n"
|
||||
" * The 'Cancelled' status is used when user cancel invoice.")
|
||||
|
||||
@@ -497,7 +497,7 @@ class AccountMoveLine(models.Model):
|
||||
raise ValidationError(_("You cannot create journal items with a secondary currency without filling both 'currency' and 'amount currency' field."))
|
||||
|
||||
@api.multi
|
||||
@api.constrains('amount_currency')
|
||||
@api.constrains('amount_currency', 'debit', 'credit')
|
||||
def _check_currency_amount(self):
|
||||
for line in self:
|
||||
if line.amount_currency:
|
||||
|
||||
@@ -55,20 +55,20 @@
|
||||
<field name="model_id">crm.opportunity.report</field>
|
||||
<field name="domain">[('probability', '=', 100)]</field>
|
||||
<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 id="filter_opportunity_opportunities_won_per_team" model="ir.filters">
|
||||
<field name="name">Opportunities Won Per Team</field>
|
||||
<field name="model_id">crm.opportunity.report</field>
|
||||
<field name="domain">[('probability', '=', 100)]</field>
|
||||
<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 id="filter_opportunity_salesperson" model="ir.filters">
|
||||
<field name="name">Leads By Salespersons</field>
|
||||
<field name="model_id">crm.opportunity.report</field>
|
||||
<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 id="filter_opportunity_country" model="ir.filters">
|
||||
<field name="name">Won By Country</field>
|
||||
@@ -81,7 +81,7 @@
|
||||
<field name="name">Expected Revenue by Team</field>
|
||||
<field name="model_id">crm.opportunity.report</field>
|
||||
<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 id="ir_filters_crm_opportunity_report_next_action" model="ir.filters">
|
||||
<field name="name">Team Activities</field>
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
<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', '=', '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 />
|
||||
<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)]"/>
|
||||
|
||||
@@ -18,7 +18,7 @@ class AccountAnalyticLine(models.Model):
|
||||
project_id = fields.Many2one('project.project', 'Project', domain=[('allow_timesheets', '=', True)])
|
||||
|
||||
employee_id = fields.Many2one('hr.employee', "Employee")
|
||||
department_id = fields.Many2one('hr.department', "Department", related='employee_id.department_id', store=True, readonly=True)
|
||||
department_id = fields.Many2one('hr.department', "Department", compute='_compute_department_id', store=True)
|
||||
|
||||
@api.onchange('project_id')
|
||||
def onchange_project_id(self):
|
||||
@@ -28,6 +28,11 @@ class AccountAnalyticLine(models.Model):
|
||||
def _onchange_employee_id(self):
|
||||
self.user_id = self.employee_id.user_id
|
||||
|
||||
@api.depends('employee_id')
|
||||
def _compute_department_id(self):
|
||||
for line in self:
|
||||
line.department_id = line.employee_id.department_id
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
vals = self._timesheet_preprocess(vals)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import logging
|
||||
import time
|
||||
from os import listdir
|
||||
from os.path import join
|
||||
from os.path import join, isdir
|
||||
try:
|
||||
from queue import Queue, Empty
|
||||
except ImportError:
|
||||
@@ -124,7 +124,7 @@ class Scanner(Thread):
|
||||
if not evdev:
|
||||
return []
|
||||
|
||||
if not os.path.isdir(self.input_dir):
|
||||
if not isdir(self.input_dir):
|
||||
return []
|
||||
|
||||
new_devices = [device for device in listdir(self.input_dir)
|
||||
|
||||
@@ -37,11 +37,11 @@ class AccountChartTemplate(models.Model):
|
||||
'type': 'model',
|
||||
'res_id': out_ids[counter].id,
|
||||
'lang': lang,
|
||||
'src': element.name,
|
||||
'src': element[in_field],
|
||||
'value': value[element.id],
|
||||
})
|
||||
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
|
||||
return True
|
||||
|
||||
|
||||
@@ -126,8 +126,18 @@ class PaymentAcquirerAuthorize(models.Model):
|
||||
for field_name in mandatory_fields:
|
||||
if not data.get(field_name):
|
||||
error[field_name] = 'missing'
|
||||
if data['cc_expiry'] and datetime.now().strftime('%y%m') > datetime.strptime(data['cc_expiry'], '%m / %y').strftime('%y%m'):
|
||||
return False
|
||||
if data['cc_expiry']:
|
||||
# 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
|
||||
|
||||
@api.multi
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<field name="lang">${object.partner_id.lang}</field>
|
||||
<field name="body_html"><![CDATA[
|
||||
<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}
|
||||
% else :
|
||||
${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="lang">${object.partner_id.lang}</field>
|
||||
<field name="body_html"><![CDATA[
|
||||
<p>Dear ${object.partner_id.name}
|
||||
<p>Dear ${object.partner_id.name}
|
||||
% if object.partner_id.parent_id:
|
||||
(<i>${object.partner_id.parent_id.name}</i>)
|
||||
% endif
|
||||
|
||||
@@ -130,7 +130,6 @@
|
||||
|
||||
|
||||
<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="code">WH</field>
|
||||
</record>
|
||||
|
||||
@@ -386,7 +386,8 @@ class InventoryLine(models.Model):
|
||||
if existings:
|
||||
raise UserError(_("You cannot have two inventory adjustements in state 'in Progress' with the same product "
|
||||
"(%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.display_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
|
||||
|
||||
@api.constrains('product_id')
|
||||
|
||||
@@ -21,7 +21,7 @@ class Warehouse(models.Model):
|
||||
# namedtuple used in helper methods generating values for routes
|
||||
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)
|
||||
company_id = fields.Many2one(
|
||||
'res.company', 'Company', default=lambda self: self.env['res.company']._company_default_get('stock.inventory'),
|
||||
|
||||
@@ -211,6 +211,7 @@ var Dashboard = Widget.extend(ControlPanelMixin, {
|
||||
|
||||
self.handle_analytics_auth($analytics_components);
|
||||
gapi.analytics.auth.on('signIn', function() {
|
||||
delete window.onOriginError;
|
||||
self.handle_analytics_auth($analytics_components);
|
||||
});
|
||||
|
||||
|
||||
@@ -289,29 +289,33 @@
|
||||
<div class="col-xs-6 col-sm-4">
|
||||
<span class="menu_title">Services</span>
|
||||
<ul>
|
||||
<li><a href="http://www.odoo.com/pricing">Editions</a></li>
|
||||
<li><a href="http://www.odoo.com/pricing-online">Cloud Pricing</a></li>
|
||||
<li><a href="http://www.odoo.com/page/upgrade">Upgrade</a></li>
|
||||
<li><a href="https://www.odoo.sh">Odoo Cloud Platform</a></li>
|
||||
<li class="divider"></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><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 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 class="divider"></li>
|
||||
<li><a href="http://www.odoo.com/page/security">Security</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col-sm-4 mb64">
|
||||
<div class="col-xs-12 col-sm-4 mb64">
|
||||
<span class="menu_title">About us</span>
|
||||
<ul>
|
||||
<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 class="divider" />
|
||||
<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 class="divider" />
|
||||
<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>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -635,6 +635,9 @@ Model Reference
|
||||
|
||||
If set to ``False``, override :meth:`.init` to create the database
|
||||
table
|
||||
|
||||
.. tip:: To create a model without any table, inherit
|
||||
from ``odoo.models.AbstractModel``
|
||||
|
||||
.. attribute:: _table
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@
|
||||
<record id="JPY" model="res.currency">
|
||||
<field name="name">JPY</field>
|
||||
<field name="symbol">¥</field>
|
||||
<field name="rounding">0.01</field>
|
||||
<field name="rounding">1.00</field>
|
||||
<field name="active" eval="False"/>
|
||||
<field name="currency_unit_label">Yen</field>
|
||||
<field name="currency_subunit_label">Cen</field>
|
||||
|
||||
Reference in New Issue
Block a user