Merge branch 'master-harsh-06072018' into 'master-patch-july-2018'

Master harsh 06072018

See merge request flectra-hq/flectra!98
This commit is contained in:
Parthiv Patel 2018-07-13 09:50:24 +00:00
commit 604cf9e3e0
15 changed files with 122 additions and 34 deletions

View File

@ -42,7 +42,7 @@
<t t-set="page_title">Expense Types</t> <t t-set="page_title">Expense Types</t>
<p class="text-muted"> <p class="text-muted">
The first step if to The first step if to
<a href="https://www.flectra.com/documentation/user/11.0/expense/expense.html#how-to-set-expense-types" target="blank"> <a href="https://www.flectrahq.com/documentation/user/11.0/expense/expense.html#how-to-set-expense-types" target="blank">
configure the expense types configure the expense types
</a> </a>
that your company allows. Here are some examples: that your company allows. Here are some examples:
@ -88,7 +88,7 @@
<t t-set="page_title">Recording Mode</t> <t t-set="page_title">Recording Mode</t>
<p class="text-muted"> <p class="text-muted">
As employees, there are As employees, there are
<a href="https://www.flectra.com/documentation/user/11.0/expense/expense.html#how-to-record-expenses" target="_blank">2 ways to record expenses:</a> <a href="https://www.flectrahq.com/documentation/user/11.0/expense/expense.html#how-to-record-expenses" target="_blank">2 ways to record expenses:</a>
</p> </p>
<div class="row"> <div class="row">
<div class="col-md-6"> <div class="col-md-6">
@ -128,7 +128,7 @@
<a t-att-href="prepare_backend_url('base_setup.action_general_configuration')"> <a t-att-href="prepare_backend_url('base_setup.action_general_configuration')">
Set an email alias Set an email alias
</a> </a>
(e.g. expenses@mycompany.flectra.com) (e.g. expenses@mycompany.flectrahq.com)
</li> </li>
<li> <li>
<a t-att-href="prepare_backend_url('hr.open_view_employee_list_my', 'kanban')"> <a t-att-href="prepare_backend_url('hr.open_view_employee_list_my', 'kanban')">
@ -137,7 +137,7 @@
(only such email addresses are authorized) (only such email addresses are authorized)
</li> </li>
<li> <li>
<a href="mailto:expenses@mycompany.flectra.com?subject=HrExpense%20Planner" target="_blank"> <a href="mailto:expenses@mycompany.flectrahq.com?subject=HrExpense%20Planner" target="_blank">
Send an expense by email Send an expense by email
</a> </a>
</li> </li>
@ -151,7 +151,7 @@
<t t-set="page_title">Submit for Approval</t> <t t-set="page_title">Submit for Approval</t>
<p class="text-muted"> <p class="text-muted">
The next step is to settle an internal policy to The next step is to settle an internal policy to
<a href="https://www.flectra.com/documentation/user/11.0/expense/expense.html#how-to-submit-expenses-to-managers" target="_blank">submit expenses to managers <a href="https://www.flectrahq.com/documentation/user/11.0/expense/expense.html#how-to-submit-expenses-to-managers" target="_blank">submit expenses to managers
</a> </a>
</p> </p>
<div class="row"> <div class="row">
@ -189,7 +189,7 @@
</div> </div>
<p class="text-muted"> <p class="text-muted">
Depending on your company structure, the Depending on your company structure, the
<a href="https://www.flectra.com/documentation/user/11.0/expense/expense.html#how-to-approve-expenses" target="_blank">approval process <a href="https://www.flectrahq.com/documentation/user/11.0/expense/expense.html#how-to-approve-expenses" target="_blank">approval process
</a> can be: </a> can be:
</p> </p>
<div class="row"> <div class="row">
@ -243,7 +243,7 @@
<t t-set="page_title">Reimbursement</t> <t t-set="page_title">Reimbursement</t>
<p class="text-muted"> <p class="text-muted">
Once expense reports approved by managers, the accounting department checks accounts, products and taxes used. Then they Once expense reports approved by managers, the accounting department checks accounts, products and taxes used. Then they
<a href="https://www.flectra.com/documentation/user/11.0/expense/expense.html#how-to-post-expenses-in-accounting" target="_blank"> post them into the books</a> and <a href="https://www.flectra.com/documentation/user/11.0/expense/expense.html#how-to-reimburse-employees" target="blank">proceed with the employee reimbursement</a>. <a href="https://www.flectrahq.com/documentation/user/11.0/expense/expense.html#how-to-post-expenses-in-accounting" target="_blank"> post them into the books</a> and <a href="https://www.flectrahq.com/documentation/user/11.0/expense/expense.html#how-to-reimburse-employees" target="blank">proceed with the employee reimbursement</a>.
</p> </p>
<p> <p>
To do: To do:
@ -258,7 +258,7 @@
<a t-att-href="prepare_backend_url('hr.open_view_employee_list_my', 'kanban')">Set Home Address to employees</a>(used for reimbursement) <a t-att-href="prepare_backend_url('hr.open_view_employee_list_my', 'kanban')">Set Home Address to employees</a>(used for reimbursement)
</li> </li>
<li> <li>
<a href="https://www.flectra.com/documentation/user/11.0/accounting/payables.html" target="blank">See how to manage payables</a> <a href="https://www.flectrahq.com/documentation/user/11.0/accounting/payables.html" target="blank">See how to manage payables</a>
</li> </li>
</ul> </ul>
</p> </p>
@ -267,7 +267,7 @@
<t t-call="web_planner.page"> <t t-call="web_planner.page">
<t t-set="page_title">Invoice Customers</t> <t t-set="page_title">Invoice Customers</t>
<p class="text-muted"> <p class="text-muted">
If you track expenses on customer projects, you can charge them <a href="https://www.flectra.com/documentation/user/11.0/expense/expense.html#how-to-re-invoice-expenses-to-your-customers" target="blank">back to your customers automatically</a>. Here are some advises to avoid conflictual situations: If you track expenses on customer projects, you can charge them <a href="https://www.flectrahq.com/documentation/user/11.0/expense/expense.html#how-to-re-invoice-expenses-to-your-customers" target="blank">back to your customers automatically</a>. Here are some advises to avoid conflictual situations:
</p> </p>
<ul> <ul>
<li>Agree in advance with the customer: <li>Agree in advance with the customer:
@ -286,7 +286,7 @@
<li><a t-att-href="prepare_backend_url('hr_expense.hr_expense_product', 'kanban')">Set invoicing method on expense products</a></li> <li><a t-att-href="prepare_backend_url('hr_expense.hr_expense_product', 'kanban')">Set invoicing method on expense products</a></li>
<li><a t-att-href="prepare_backend_url('base.open_module_tree', 'form', 'sale')">Install Sales app</a></li> <li><a t-att-href="prepare_backend_url('base.open_module_tree', 'form', 'sale')">Install Sales app</a></li>
<li><a t-att-href="prepare_backend_url('base.open_module_tree', 'form', 'account_analytic_default')">Install Analytic Accounting add-on</a></li> <li><a t-att-href="prepare_backend_url('base.open_module_tree', 'form', 'account_analytic_default')">Install Analytic Accounting add-on</a></li>
<li><a href="https://www.flectra.com/documentation/user/11.0/expense/expense.html#how-to-re-invoice-expenses-to-your-customers" target="_blank">See how to invoice expenses</a></li> <li><a href="https://www.flectrahq.com/documentation/user/11.0/expense/expense.html#how-to-re-invoice-expenses-to-your-customers" target="_blank">See how to invoice expenses</a></li>
</ul> </ul>
</p> </p>
</t> </t>

View File

@ -215,3 +215,15 @@ class Employee(models.Model):
('type', '=', 'remove') ('type', '=', 'remove')
]) ])
return [('id', 'in', holidays.mapped('employee_id').ids)] return [('id', 'in', holidays.mapped('employee_id').ids)]
def write(self, values):
res = super(Employee, self).write(values)
if 'parent_id' in values or 'department_id' in values:
holidays = self.env['hr.holidays'].search([('state', 'in', ['draft', 'confirm']), ('employee_id', 'in', self.ids)])
hr_vals = {}
if values.get('parent_id') is not None:
hr_vals['manager_id'] = values['parent_id']
if values.get('department_id') is not None:
hr_vals['department_id'] = values['department_id']
holidays.write(hr_vals)
return res

View File

@ -180,7 +180,7 @@ class Holidays(models.Model):
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}) states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]})
employee_id = fields.Many2one('hr.employee', string='Employee', index=True, readonly=True, employee_id = fields.Many2one('hr.employee', string='Employee', index=True, readonly=True,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, default=_default_employee, track_visibility='onchange') states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, default=_default_employee, track_visibility='onchange')
manager_id = fields.Many2one('hr.employee', related='employee_id.parent_id', string='Manager', readonly=True, store=True) manager_id = fields.Many2one('hr.employee', string='Manager', readonly=True)
notes = fields.Text('Reasons', readonly=True, states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}) notes = fields.Text('Reasons', readonly=True, states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]})
number_of_days_temp = fields.Float( number_of_days_temp = fields.Float(
'Allocation', copy=False, readonly=True, 'Allocation', copy=False, readonly=True,
@ -195,9 +195,9 @@ class Holidays(models.Model):
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]},
help="Choose 'Leave Request' if someone wants to take an off-day. " help="Choose 'Leave Request' if someone wants to take an off-day. "
"\nChoose 'Allocation Request' if you want to increase the number of leaves available for someone") "\nChoose 'Allocation Request' if you want to increase the number of leaves available for someone")
parent_id = fields.Many2one('hr.holidays', string='Parent') parent_id = fields.Many2one('hr.holidays', string='Parent', copy=False)
linked_request_ids = fields.One2many('hr.holidays', 'parent_id', string='Linked Requests') linked_request_ids = fields.One2many('hr.holidays', 'parent_id', string='Linked Requests')
department_id = fields.Many2one('hr.department', related='employee_id.department_id', string='Department', readonly=True, store=True) department_id = fields.Many2one('hr.department', string='Department', readonly=True)
category_id = fields.Many2one('hr.employee.category', string='Employee Tag', readonly=True, category_id = fields.Many2one('hr.employee.category', string='Employee Tag', readonly=True,
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, help='Category of Employee') states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, help='Category of Employee')
holiday_type = fields.Selection([ holiday_type = fields.Selection([
@ -248,7 +248,7 @@ class Holidays(models.Model):
if nholidays: if nholidays:
raise ValidationError(_('You can not have 2 leaves that overlaps on same day!')) raise ValidationError(_('You can not have 2 leaves that overlaps on same day!'))
@api.constrains('state', 'number_of_days_temp') @api.constrains('state', 'number_of_days_temp', 'holiday_status_id')
def _check_holidays(self): def _check_holidays(self):
for holiday in self: for holiday in self:
if holiday.holiday_type != 'employee' or holiday.type != 'remove' or not holiday.employee_id or holiday.holiday_status_id.limit: if holiday.holiday_type != 'employee' or holiday.type != 'remove' or not holiday.employee_id or holiday.holiday_status_id.limit:
@ -274,7 +274,8 @@ class Holidays(models.Model):
self.employee_id = None self.employee_id = None
@api.onchange('employee_id') @api.onchange('employee_id')
def _onchange_employee(self): def _onchange_employee_id(self):
self.manager_id = self.employee_id and self.employee_id.parent_id
self.department_id = self.employee_id.department_id self.department_id = self.employee_id.department_id
def _get_number_of_days(self, date_from, date_to, employee_id): def _get_number_of_days(self, date_from, date_to, employee_id):
@ -358,6 +359,8 @@ class Holidays(models.Model):
values.update({'department_id': self.env['hr.employee'].browse(employee_id).department_id.id}) values.update({'department_id': self.env['hr.employee'].browse(employee_id).department_id.id})
holiday = super(Holidays, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(values) holiday = super(Holidays, self.with_context(mail_create_nolog=True, mail_create_nosubscribe=True)).create(values)
holiday.add_follower(employee_id) holiday.add_follower(employee_id)
if 'employee_id' in values:
holiday._onchange_employee_id()
return holiday return holiday
@api.multi @api.multi
@ -367,6 +370,8 @@ class Holidays(models.Model):
raise AccessError(_('You cannot set a leave request as \'%s\'. Contact a human resource manager.') % values.get('state')) raise AccessError(_('You cannot set a leave request as \'%s\'. Contact a human resource manager.') % values.get('state'))
result = super(Holidays, self).write(values) result = super(Holidays, self).write(values)
self.add_follower(employee_id) self.add_follower(employee_id)
if 'employee_id' in values:
self._onchange_employee_id()
return result return result
@api.multi @api.multi

View File

@ -85,6 +85,11 @@ class HrSalaryRuleCategory(models.Model):
company_id = fields.Many2one('res.company', string='Company', company_id = fields.Many2one('res.company', string='Company',
default=lambda self: self.env['res.company']._company_default_get()) default=lambda self: self.env['res.company']._company_default_get())
@api.constrains('parent_id')
def _check_parent_id(self):
if not self._check_recursion():
raise ValidationError(_('Error! You cannot create recursive hierarchy of Salary Rule Category.'))
class HrSalaryRule(models.Model): class HrSalaryRule(models.Model):
_name = 'hr.salary.rule' _name = 'hr.salary.rule'
@ -165,6 +170,11 @@ class HrSalaryRule(models.Model):
input_ids = fields.One2many('hr.rule.input', 'input_id', string='Inputs', copy=True) input_ids = fields.One2many('hr.rule.input', 'input_id', string='Inputs', copy=True)
note = fields.Text(string='Description') note = fields.Text(string='Description')
@api.constrains('parent_rule_id')
def _check_parent_rule_id(self):
if not self._check_recursion(parent='parent_rule_id'):
raise ValidationError(_('Error! You cannot create recursive hierarchy of Salary Rules.'))
@api.multi @api.multi
def _recursive_search_of_rules(self): def _recursive_search_of_rules(self):
""" """

View File

@ -29,7 +29,7 @@
<record id="chart1181_en" model="account.account.template"> <record id="chart1181_en" model="account.account.template">
<field name="code">1181</field> <field name="code">1181</field>
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/> <field name="user_type_id" ref="account.data_account_type_current_assets"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">GST receivable</field> <field name="name">GST receivable</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -37,7 +37,7 @@
<record id="chart1182_en" model="account.account.template"> <record id="chart1182_en" model="account.account.template">
<field name="code">1182</field> <field name="code">1182</field>
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/> <field name="user_type_id" ref="account.data_account_type_current_assets"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">PST/QST receivable</field> <field name="name">PST/QST receivable</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -45,7 +45,7 @@
<record id="chart11831_en" model="account.account.template"> <record id="chart11831_en" model="account.account.template">
<field name="code">11831</field> <field name="code">11831</field>
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/> <field name="user_type_id" ref="account.data_account_type_current_assets"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">HST receivable - 13%</field> <field name="name">HST receivable - 13%</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -53,7 +53,7 @@
<record id="chart11832_en" model="account.account.template"> <record id="chart11832_en" model="account.account.template">
<field name="code">11832</field> <field name="code">11832</field>
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/> <field name="user_type_id" ref="account.data_account_type_current_assets"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">HST receivable - 14%</field> <field name="name">HST receivable - 14%</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -61,7 +61,7 @@
<record id="chart11833_en" model="account.account.template"> <record id="chart11833_en" model="account.account.template">
<field name="code">11833</field> <field name="code">11833</field>
<field name="user_type_id" ref="account.data_account_type_current_liabilities"/> <field name="user_type_id" ref="account.data_account_type_current_assets"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">HST receivable - 15%</field> <field name="name">HST receivable - 15%</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -79,7 +79,7 @@
<record id="chart2131_en" model="account.account.template"> <record id="chart2131_en" model="account.account.template">
<field name="code">2131</field> <field name="code">2131</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/> <field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">GST to pay</field> <field name="name">GST to pay</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -87,7 +87,7 @@
<record id="chart2132_en" model="account.account.template"> <record id="chart2132_en" model="account.account.template">
<field name="code">2132</field> <field name="code">2132</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/> <field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">PST/QST to pay</field> <field name="name">PST/QST to pay</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -95,7 +95,7 @@
<record id="chart21331_en" model="account.account.template"> <record id="chart21331_en" model="account.account.template">
<field name="code">21331</field> <field name="code">21331</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/> <field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">HST to pay - 13%</field> <field name="name">HST to pay - 13%</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -103,7 +103,7 @@
<record id="chart21332_en" model="account.account.template"> <record id="chart21332_en" model="account.account.template">
<field name="code">21332</field> <field name="code">21332</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/> <field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">HST to pay - 14%</field> <field name="name">HST to pay - 14%</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>
@ -111,7 +111,7 @@
<record id="chart21333_en" model="account.account.template"> <record id="chart21333_en" model="account.account.template">
<field name="code">21333</field> <field name="code">21333</field>
<field name="user_type_id" ref="account.data_account_type_current_assets"/> <field name="user_type_id" ref="account.data_account_type_current_liabilities"/>
<field name="reconcile" eval="False"/> <field name="reconcile" eval="False"/>
<field name="name">HST to pay - 15%</field> <field name="name">HST to pay - 15%</field>
<field name="chart_template_id" ref="ca_en_chart_template_en"/> <field name="chart_template_id" ref="ca_en_chart_template_en"/>

View File

@ -18,7 +18,7 @@
<field name="cash_account_code_prefix">100</field> <field name="cash_account_code_prefix">100</field>
<field name="currency_id" ref="base.CHF"/> <field name="currency_id" ref="base.CHF"/>
<field name="transfer_account_id" ref="transfer_account_id"/> <field name="transfer_account_id" ref="transfer_account_id"/>
<field name="spoken_languages" eval="'it_IT;de_CH'"/> <field name="spoken_languages" eval="'it_IT;de_DE;de_CH'"/>
</record> </record>
<record id="transfer_account_id" model="account.account.template"> <record id="transfer_account_id" model="account.account.template">
<field name="chart_template_id" ref="l10nch_chart_template"/> <field name="chart_template_id" ref="l10nch_chart_template"/>

View File

@ -149,6 +149,9 @@ class ProductProduct(models.Model):
('barcode_uniq', 'unique(barcode)', "A barcode can only be assigned to one product !"), ('barcode_uniq', 'unique(barcode)', "A barcode can only be assigned to one product !"),
] ]
def _get_invoice_policy(self):
return False
def _compute_product_price(self): def _compute_product_price(self):
prices = {} prices = {}
pricelist_id_or_name = self._context.get('pricelist') pricelist_id_or_name = self._context.get('pricelist')
@ -219,6 +222,7 @@ class ProductProduct(models.Model):
for supplier_info in self.seller_ids: for supplier_info in self.seller_ids:
if supplier_info.name.id == self._context.get('partner_id'): if supplier_info.name.id == self._context.get('partner_id'):
self.code = supplier_info.product_code or self.default_code self.code = supplier_info.product_code or self.default_code
break
else: else:
self.code = self.default_code self.code = self.default_code
@ -227,9 +231,10 @@ class ProductProduct(models.Model):
for supplier_info in self.seller_ids: for supplier_info in self.seller_ids:
if supplier_info.name.id == self._context.get('partner_id'): if supplier_info.name.id == self._context.get('partner_id'):
product_name = supplier_info.product_name or self.default_code product_name = supplier_info.product_name or self.default_code
self.partner_ref = '%s%s' % (self.code and '[%s] ' % self.code or '', product_name)
break
else: else:
product_name = self.name self.partner_ref = self.name_get()[0][1]
self.partner_ref = '%s%s' % (self.code and '[%s] ' % self.code or '', product_name)
@api.one @api.one
@api.depends('image_variant', 'product_tmpl_id.image') @api.depends('image_variant', 'product_tmpl_id.image')
@ -428,7 +433,12 @@ class ProductProduct(models.Model):
limit2 = (limit - len(products)) if limit else False limit2 = (limit - len(products)) if limit else False
products += self.search(args + [('name', operator, name), ('id', 'not in', products.ids)], limit=limit2) products += self.search(args + [('name', operator, name), ('id', 'not in', products.ids)], limit=limit2)
elif not products and operator in expression.NEGATIVE_TERM_OPERATORS: elif not products and operator in expression.NEGATIVE_TERM_OPERATORS:
products = self.search(args + ['&', ('default_code', operator, name), ('name', operator, name)], limit=limit) domain = expression.OR([
['&', ('default_code', operator, name), ('name', operator, name)],
['&', ('default_code', '=', False), ('name', operator, name)],
])
domain = expression.AND([args, domain])
products = self.search(domain, limit=limit)
if not products and operator in positive_operators: if not products and operator in positive_operators:
ptrn = re.compile('(\[(.*?)\])') ptrn = re.compile('(\[(.*?)\])')
res = ptrn.search(name) res = ptrn.search(name)

View File

@ -4,6 +4,7 @@
from flectra import api, fields, models, _ from flectra import api, fields, models, _
from flectra.addons import decimal_precision as dp from flectra.addons import decimal_precision as dp
from flectra.exceptions import UserError, ValidationError from flectra.exceptions import UserError, ValidationError
from flectra.osv import expression
class ProductAttribute(models.Model): class ProductAttribute(models.Model):
@ -107,6 +108,6 @@ class ProductAttributeLine(models.Model):
# search on a m2o and one on a m2m, probably this will quickly become # search on a m2o and one on a m2m, probably this will quickly become
# difficult to compute - check if performance optimization is required # difficult to compute - check if performance optimization is required
if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'):
args = ['|', ('attribute_id', operator, name), ('value_ids', operator, name)] args = expression.AND([['|', ('attribute_id', operator, name), ('value_ids', operator, name)], args])
return self.search(args, limit=limit).name_get() return self.search(args, limit=limit).name_get()
return super(ProductAttributeLine, self).name_search(name=name, args=args, operator=operator, limit=limit) return super(ProductAttributeLine, self).name_search(name=name, args=args, operator=operator, limit=limit)

View File

@ -45,6 +45,11 @@
[<span t-esc="product.code"/>] [<span t-esc="product.code"/>]
</t> </t>
<span t-esc="product.name"/> <span t-esc="product.name"/>
<span t-foreach="product.attribute_value_ids" t-as="attribute_value">
<span t-if="attribute_value_first">-</span>
<span t-if="not attribute_value_last" t-esc="attribute_value.name+','"/>
<span t-else="" t-esc="attribute_value.name"/>
</span>
</td> </td>
<t t-foreach="data['quantities']" t-as="quantity"> <t t-foreach="data['quantities']" t-as="quantity">
<td><strong t-esc="categ_data['prices'][product.id][quantity]" <td><strong t-esc="categ_data['prices'][product.id][quantity]"

View File

@ -17,7 +17,9 @@
<tbody> <tbody>
<tr style="width: 1in;"> <tr style="width: 1in;">
<td style="border: 2px solid black;text-align: center; vertical-align: middle;" class="col-xs-5"> <td style="border: 2px solid black;text-align: center; vertical-align: middle;" class="col-xs-5">
<img t-if="product.barcode" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('EAN13', product.barcode, 600, 150)" style="width:100%;height:20%;"/> <img t-if="product.barcode and len(product.barcode) == 13" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('EAN13', product.barcode, 600, 150)" style="width:100%;height:20%;"/>
<img t-elif="product.barcode and len(product.barcode) == 8" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('EAN8', product.barcode, 600, 150)" style="width:100%;height:20%;"/>
<img t-else="" t-att-src="'/report/barcode/?type=%s&amp;value=%s&amp;width=%s&amp;height=%s' % ('Code128', product.barcode, 600, 150)" style="width:100%;height:20%;"/>
<span t-field="product.barcode"/> <span t-field="product.barcode"/>
</td> </td>
<td style="border: 2px solid black; text-align: center;" class="col-xs-7"> <td style="border: 2px solid black; text-align: center;" class="col-xs-7">

View File

@ -1,4 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. # Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
from . import test_variants, test_uom, test_pricelist, test_product_pricelist from . import test_seller, test_variants, test_uom, test_pricelist, test_product_pricelist

View File

@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
from flectra.tests.common import TransactionCase
class TestSeller(TransactionCase):
def setUp(self):
super(TestSeller, self).setUp()
self.product_service = self.env.ref('product.product_product_2')
self.product_service.default_code = 'DEFCODE'
self.asustec = self.env.ref('base.res_partner_1')
self.camptocamp = self.env.ref('base.res_partner_12')
def test_10_sellers(self):
self.product_service.write({'seller_ids': [
(0, 0, {'name': self.asustec.id, 'product_code': 'ASUCODE'}),
(0, 0, {'name': self.camptocamp.id, 'product_code': 'C2CCODE'}),
]})
default_code = self.product_service.code
self.assertEqual("DEFCODE", default_code, "Default code not used in product name")
context_code = self.product_service\
.with_context(partner_id=self.camptocamp.id)\
.code
self.assertEqual('C2CCODE', context_code, "Partner's code not used in product name with context set")

View File

@ -40,6 +40,15 @@ class TestVariantsSearch(TransactionCase):
self.assertIn(self.product_shirt_template, search_value, self.assertIn(self.product_shirt_template, search_value,
'Shirt should be found searching L') 'Shirt should be found searching L')
def test_name_search(self):
self.product_slip_template = self.env['product.template'].create({
'name': 'Slip',
})
res = self.env['product.product'].name_search('Shirt', [], 'not ilike', None)
res_ids = [r[0] for r in res]
self.assertIn(self.product_slip_template.product_variant_ids.id, res_ids,
'Slip should be found searching \'not ilike\'')
class TestVariants(common.TestProductCommon): class TestVariants(common.TestProductCommon):

View File

@ -90,6 +90,11 @@
</group> </group>
</page> </page>
<page string="Notes" name="notes"> <page string="Notes" name="notes">
<group name="description_internal">
<group string="Description for Internal">
<field name="description" nolabel="1" placeholder="This note is only for internal purposes."/>
</group>
</group>
<group name="description"> <group name="description">
<group string="Description for Customers" attrs="{'invisible': [('sale_ok','=',False)]}"> <group string="Description for Customers" attrs="{'invisible': [('sale_ok','=',False)]}">
<field name="description_sale" nolabel="1" placeholder="This note will show up on sales orders."/> <field name="description_sale" nolabel="1" placeholder="This note will show up on sales orders."/>
@ -202,7 +207,7 @@
<field name="image_medium" widget="image" class="oe_avatar"/> <field name="image_medium" widget="image" class="oe_avatar"/>
<div class="oe_title"> <div class="oe_title">
<label class="oe_edit_only" for="name" string="Product Name"/> <label class="oe_edit_only" for="name" string="Product Name"/>
<h1><field name="name" placeholder="e.g. Flectra Enterprise Subscription"/></h1> <h1><field name="name" placeholder="e.g. Flectra Subscription"/></h1>
</div> </div>
<group> <group>
<p>All general settings about this product are managed on <button name="open_product_template" type="object" string="the product template" class="oe_link"/></p> <p>All general settings about this product are managed on <button name="open_product_template" type="object" string="the product template" class="oe_link"/></p>

View File

@ -11,7 +11,8 @@
<field name="name" invisible="1"/> <field name="name" invisible="1"/>
<field name="model" invisible="1"/> <field name="model" invisible="1"/>
<h3 colspan="2">Body</h3> <h3 colspan="2">Body</h3>
<field name="body_html" nolabel="1" colspan="2" widget='text' /> <field name="body_html" nolabel="1" colspan="2" widget="html"
options="{'style-inline': true}" />
<field name="attachment_ids" nolabel="1" colspan="2" <field name="attachment_ids" nolabel="1" colspan="2"
widget="many2many_binary"/> widget="many2many_binary"/>
</group> </group>