Merge branch '1.0' of gitlab.com:flectra-hq/flectra into 1.0

This commit is contained in:
Flectra 2018-02-26 05:31:39 -08:00
commit 8d151a8bf5
87 changed files with 896 additions and 401 deletions

View File

@ -12,6 +12,7 @@ Purchase Management and many more.
Flectra Apps can be used as stand-alone applications, but they also integrate seamlessly so you get
a full-featured <a href="https://flectrahq.com">Open Source ERP</a> when you install several Apps.
Additional Apps for Flectra are available here : https://gitlab.com/flectra-hq/extra-addons
Getting started with Flectra
----------------------------

View File

@ -102,7 +102,7 @@ class account_abstract_payment(models.AbstractModel):
class account_register_payments(models.TransientModel):
_name = "account.register.payments"
_inherit = 'account.abstract.payment'
_inherit = ['account.abstract.payment']
_description = "Register payments on multiple invoices"
invoice_ids = fields.Many2many('account.invoice', string='Invoices', copy=False)
@ -240,7 +240,7 @@ class account_register_payments(models.TransientModel):
class account_payment(models.Model):
_name = "account.payment"
_inherit = ['mail.thread', 'account.abstract.payment', 'ir.branch.company.mixin']
_inherit = ['mail.thread', 'account.abstract.payment']
_description = "Payments"
_order = "payment_date desc, name desc"
@ -269,6 +269,15 @@ class account_payment(models.Model):
else:
self.payment_difference = self._compute_total_invoices_amount() - self.amount
@api.depends('journal_id')
def _compute_branch(self):
for payment in self:
if payment.journal_id:
payment.branch_id = \
payment.journal_id.branch_id
company_id = fields.Many2one(store=True)
name = fields.Char(readonly=True, copy=False, default="Draft Payment") # The name is attributed upon post()
state = fields.Selection([('draft', 'Draft'), ('posted', 'Posted'), ('sent', 'Sent'), ('reconciled', 'Reconciled'), ('cancelled', 'Cancelled')], readonly=True, default='draft', copy=False, string="Status")
@ -297,6 +306,8 @@ class account_payment(models.Model):
# FIXME: ondelete='restrict' not working (eg. cancel a bank statement reconciliation with a payment)
move_line_ids = fields.One2many('account.move.line', 'payment_id', readonly=True, copy=False, ondelete='restrict')
move_reconciled = fields.Boolean(compute="_get_move_reconciled", readonly=True)
branch_id = fields.Many2one('res.branch', 'Branch',
compute='_compute_branch', readonly=True, store=True)
def open_payment_matching_screen(self):
# Open reconciliation view for customers/suppliers
@ -461,7 +472,6 @@ class account_payment(models.Model):
If the payment is a transfer, a second journal entry is created in the destination journal to receive money from the transfer account.
"""
for rec in self:
if rec.state != 'draft':
raise UserError(_("Only a draft payment can be posted."))
@ -524,9 +534,7 @@ class account_payment(models.Model):
#if all the invoices selected share the same currency, record the paiement in that currency too
invoice_currency = self.invoice_ids[0].currency_id
debit, credit, amount_currency, currency_id = aml_obj.with_context(date=self.payment_date).compute_amount_fields(amount, self.currency_id, self.company_id.currency_id, invoice_currency)
move = self.env['account.move'].create(self._get_move_vals())
#Write line corresponding to invoice payment
counterpart_aml_dict = self._get_shared_move_line_vals(debit, credit, amount_currency, move.id, False)
counterpart_aml_dict.update(self._get_counterpart_move_line_vals(self.invoice_ids))
@ -598,6 +606,7 @@ class account_payment(models.Model):
dst_liquidity_aml_dict.update({
'name': _('Transfer from %s') % self.journal_id.name,
'account_id': self.destination_journal_id.default_credit_account_id.id,
'branch_id': self.destination_journal_id.branch_id.id or False,
'currency_id': self.destination_journal_id.currency_id.id,
'journal_id': self.destination_journal_id.id})
aml_obj.create(dst_liquidity_aml_dict)
@ -606,6 +615,7 @@ class account_payment(models.Model):
transfer_debit_aml_dict.update({
'name': self.name,
'account_id': self.company_id.transfer_account_id.id,
'branch_id': self.journal_id.branch_id.id or False,
'journal_id': self.destination_journal_id.id})
if self.currency_id != self.company_id.currency_id:
transfer_debit_aml_dict.update({
@ -666,10 +676,15 @@ class account_payment(models.Model):
for inv in invoice:
if inv.move_id:
name += inv.number + ', '
name = name[:len(name)-2]
name = name[:len(name)-2]
if len(invoice) == 1:
branch_id = invoice.branch_id.id or False
else:
branch_id = self.branch_id.id or False
return {
'name': name,
'account_id': self.destination_account_id.id,
'branch_id': branch_id,
'journal_id': self.journal_id.id,
'currency_id': self.currency_id != self.company_id.currency_id and self.currency_id.id or False,
}
@ -693,5 +708,5 @@ class account_payment(models.Model):
'amount_currency': amount_currency,
'currency_id': self.journal_id.currency_id.id,
})
vals['branch_id'] = self.journal_id.branch_id.id or False
return vals

View File

@ -7,15 +7,26 @@ class TestPaymentsBranch(test_account_branch.TestAccountBranch):
def test_payment_branch(self):
self.invoice_id = self.model_account_invoice.sudo(self.user_id.id).create(
self.invoice_values(self.branch_2.id))
self.invoice_values(self.branch_1.id))
self.invoice_id.sudo(self.user_id.id).action_invoice_open()
self.journal_model = self.env['account.journal']
self.account_model = self.env['account.account']
self.company = self.env.ref('base.main_company')
user_type = self.env.ref('account.data_account_type_liquidity')
self.cash1_account_id = self.account_model.create(
{'name': 'Cash 1 - Test', 'code': 'test_cash_1',
'user_type_id': user_type.id, 'company_id': self.company.id, })
self.cash_journal_1 = self.journal_model.create(
{'name': 'Cash Journal 1 - Test', 'code': 'test_cash_1',
'type': 'cash', 'company_id': self.company.id,
'default_debit_account_id': self.cash1_account_id.id,
'default_credit_account_id': self.cash1_account_id.id,
'branch_id': self.branch_1.id})
context = {'active_ids': [self.invoice_id.id], 'active_model': 'account.invoice'}
create_payments = self.env['account.register.payments'].sudo(self.user_id.id).with_context(context).create({
'payment_method_id': self.env.ref("account.account_payment_method_manual_in").id,
'journal_id': self.cash_journal.id,
'journal_id': self.cash_journal_1.id,
'payment_date': time.strftime('%Y') + '-12-17',
})
create_payments.create_payments()
payment = self.env['account.payment'].sudo(self.user_2.id).search([('branch_id', '=', self.branch_2.id)])

View File

@ -10,6 +10,7 @@
<field name="payment_date"/>
<field name="name"/>
<field name="journal_id"/>
<field name="branch_id" groups="base_branch_company.group_multi_branch"/>
<field name="payment_method_id"/>
<field name="partner_id" string="Customer"/>
<field name="amount" sum="Amount"/>
@ -29,6 +30,7 @@
<field name="payment_date"/>
<field name="name"/>
<field name="journal_id"/>
<field name="branch_id" groups="base_branch_company.group_multi_branch"/>
<field name="payment_method_id"/>
<field name="partner_id" string="Vendor"/>
<field name="amount" sum="Amount"/>
@ -152,6 +154,7 @@
<field name="currency_id" options="{'no_create': True, 'no_open': True}" groups="base.group_multi_currency" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
</div>
<field name="journal_id" widget="selection" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
<field name="branch_id" groups="base_branch_company.group_multi_branch"/>
<field name="destination_journal_id" widget="selection" attrs="{'required': [('payment_type', '=', 'transfer')], 'invisible': [('payment_type', '!=', 'transfer')], 'readonly': [('state', '!=', 'draft')]}"/>
<field name="hide_payment_method" invisible="1"/>
<field name="payment_method_id" string=" " widget="radio" attrs="{'invisible': [('hide_payment_method', '=', True)], 'readonly': [('state', '!=', 'draft')]}"/>

View File

@ -284,6 +284,9 @@
</group>
<group>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field name="branch_id" options="{'no_create': True}"
groups="base_branch_company.group_multi_branch"
attrs="{'invisible':[('type','not in', ['bank', 'cash'])]}"/>
</group>
</group>
<notebook>

View File

@ -117,13 +117,11 @@ class AccountInvoice(models.Model):
@api.onchange('discount_amount')
def onchange_discount_amount(self):
if self.discount_method == 'per':
return True
values = self.get_maximum_per_amount()
if self.discount < 0:
raise Warning(_("Discount should be less than Gross Amount"))
discount = self.discount or self.discount_amount
if discount > self.gross_amount:
if self.gross_amount and discount > self.gross_amount:
raise Warning(_("Discount (%s) should be less than "
"Gross Amount (%s).") % (
formatLang(self.env, discount, digits=2),

View File

@ -2,3 +2,4 @@
# Part of flectra. See LICENSE file for full copyright and licensing details.
from . import models
from . import wizard

View File

@ -24,9 +24,11 @@ Main Features
'depends': ['base'],
'data': [
'demo/branch_data.xml',
'wizard/branch_config_view.xml',
'security/branch_security.xml',
'security/ir.model.access.csv',
'views/res_branch_view.xml',
'views/res_branch_config_view.xml',
],
'demo': [
'demo/branch_demo.xml',

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<flectra>
<record id="res_config_settings_view_form" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.base.setup</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="100"/>
<field name="inherit_id" ref="base.res_config_settings_view_form"/>
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block">
<h2>Multi-Branch</h2>
<div class="row mt16 o_settings_container" id="emails">
<div class="col-xs-12 col-md-6 o_setting_box">
<div class="o_setting_left_pane"/>
<div class="o_setting_right_pane">
<label string="Branches"/>
<div class="text-muted">
Configure your Branch
</div>
<div class="content-group">
<div class="mt16">
<button name="%(action_view_branch_config)d" string="Branch Configuration" type="action" class="oe_link" groups="base.group_no_one" icon="fa-arrow-right"/>
</div>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</flectra>

View File

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

View File

@ -0,0 +1,71 @@
# -*- coding: utf-8 -*-
# Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details.
from flectra import api, models, fields
class BarnchConfiguration(models.TransientModel):
_name = 'branch.config'
name = fields.Char(string='Name', required=True)
code = fields.Char(string='Code', required=True)
branch_id = fields.Many2one('res.branch', 'Branch')
company_id = fields.Many2one('res.company', string="Company",
default=lambda self: self.env.user.company_id, required=True)
partner_id = fields.Many2one('res.partner', string='Partner')
street = fields.Char()
street2 = fields.Char()
zip = fields.Char(change_default=True)
city = fields.Char()
state_id = fields.Many2one("res.country.state", string='State',
ondelete='restrict')
country_id = fields.Many2one('res.country', string='Country',
ondelete='restrict')
email = fields.Char()
phone = fields.Char()
mobile = fields.Char()
state = fields.Selection([('draft', 'Draft'), ('confirm', 'Confirm')],
default='draft')
user_ids = fields.Many2many('res.users', 'res_users_branch_rel',
'user_id', 'branch_id', 'Allowed Branch for users',
domain="[('company_id','=',company_id)]")
default_user_ids = fields.Many2many('res.users', 'res_users_branch_default_rel',
'user_id', 'branch_id', 'Default Branch for users',
domain="[('company_id','=',company_id)]")
@api.multi
def branch_config(self):
s_ids = self.search_read([('id', '=', self.id)], [])[0]
branch = self.env['res.branch'].create({
'name': s_ids['name'],
'code': s_ids['code'],
'street': s_ids['street'],
'street2': s_ids['street2'],
'zip': s_ids['zip'],
'city': s_ids['city'],
'state_id': s_ids['state_id'] and s_ids['state_id'][0],
'country_id': s_ids['country_id'] and s_ids['country_id'][0],
'email': s_ids['email'],
'phone': s_ids['phone'],
'company_id': s_ids['company_id'] and s_ids['company_id'][0],
'mobile': s_ids['mobile'],
})
self.write({'state': 'confirm',
'partner_id': branch.partner_id.id,
'branch_id': branch.id})
view_id = self.env.ref(
'base_branch_company.view_branch_config')
context = dict(self._context)
return {'views': [(view_id.id, 'form')], 'view_id': view_id.id,
'type': 'ir.actions.act_window', 'view_type': 'form',
'view_mode': 'form', 'res_model': 'branch.config',
'target': 'new', 'res_id': self.id, 'context': context, }
@api.multi
def finish_branch_config(self):
for user_id in self.user_ids:
user_id.write({'branch_ids': [(4, self.branch_id.id)]})
for user_id in self.user_ids:
user_id.write({'default_branch_id': self.branch_id.id})

View File

@ -0,0 +1,59 @@
<?xml version="1.0" encoding="utf-8"?>
<flectra>
<record id="view_branch_config" model="ir.ui.view">
<field name="name">Branch Configuration</field>
<field name="model">branch.config</field>
<field name="arch" type="xml">
<form string="Branch Configuration">
<group col="4" attrs="{'invisible': [('state', '!=', 'draft')]}">
<field name="name"/>
<field name="code"/>
<field name="company_id" groups="base.group_multi_company"/>
<field name="state" invisible="1"/>
</group>
<group attrs="{'invisible': [('state', '=', 'draft')]}">
<field name="branch_id" readonly="1"/>
<!--<field name="partner_id" invisible="1"/>-->
</group>
<group col="4" attrs="{'invisible': [('state', '=', 'draft')]}">
<field name="user_ids" widget="many2many_tags"/>
<field name="default_user_ids" widget="many2many_tags"/>
</group>
<group attrs="{'invisible': [('state', '!=', 'draft')]}">
<group>
<label for="street" string="Address"/>
<div class="o_address_format">
<field name="street" placeholder="Street..." class="o_address_street"/>
<field name="street2" placeholder="Street 2..." class="o_address_street"/>
<field name="city" placeholder="City" class="o_address_city"/>
<field name="state_id" class="o_address_state" placeholder="State" options='{"no_open": True}'
context="{'country_id': country_id, 'zip': zip}"/>
<field name="zip" placeholder="ZIP" class="o_address_zip"/>
<field name="country_id" placeholder="Country" class="o_address_country" options='{"no_open": True, "no_create": True}'/>
</div>
</group>
<group>
<field name="phone" widget="phone"/>
<field name="mobile" widget="phone"/>
<field name="email" widget="email" context="{'gravatar_image': True}"/>
</group>
</group>
<footer>
<button string='Next' name="branch_config" attrs="{'invisible': [('state', '!=', 'draft')]}" type="object" class="btn-primary"/>
<button string='Finish' name="finish_branch_config" attrs="{'invisible': [('state', '=', 'draft')]}" type="object" class="btn-primary"/>
<button string="Cancel" class="btn-default" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_view_branch_config" model="ir.actions.act_window">
<field name="name">Branch Configuration</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">branch.config</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</flectra>

View File

@ -13,6 +13,19 @@
<field eval="False" name="doall"/>
</record>
<record forcecreate="True" id="ir_cron_mail_unlink" model="ir.cron">
<field name="name">Mail: Email Unlink</field>
<field name="model_id" ref="model_mail_mail"/>
<field name="state">code</field>
<field name="code">model.process_email_unlink()</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field eval="False" name="doall"/>
</record>
<record id="ir_cron_module_update_notification" model="ir.cron">
<field name="name">Publisher: Update Notification</field>
<field name="model_id" ref="model_publisher_warranty_contract"/>

View File

@ -50,12 +50,31 @@ class MailMail(models.Model):
auto_delete = fields.Boolean(
'Auto Delete',
help="Permanently delete this email after sending it, to save space")
keep_days = fields.Integer('Keep days', default=-1,
help="This value defines the no. of days "
"the emails should be recorded "
"in the system: \n -1 = Email will be deleted "
"immediately once it is send \n greater than 0 = Email "
"will be deleted after "
"the no. of days are met.")
delete_date = fields.Date(compute='_compute_delete_on_date',
string='Delete on.', store=True)
failure_reason = fields.Text(
'Failure Reason', readonly=1,
help="Failure reason. This is usually the exception thrown by the email server, stored to ease the debugging of mailing issues.")
scheduled_date = fields.Char('Scheduled Send Date',
help="If set, the queue manager will send the email after the date. If not set, the email will be send as soon as possible.")
@api.depends('keep_days')
def _compute_delete_on_date(self):
mail_date = fields.Datetime.from_string(self.date)
if self.keep_days > 0:
delete_on = mail_date + datetime.timedelta(days=self.keep_days)
self.delete_date = delete_on
else:
self.delete_date = mail_date.date()
@api.model
def create(self, values):
# notification field: if not set, set if mail comes from an existing mail.message
@ -89,6 +108,12 @@ class MailMail(models.Model):
def cancel(self):
return self.write({'state': 'cancel'})
@api.model
def process_email_unlink(self):
mail_ids = self.sudo().search([('delete_date', '=', datetime.datetime.now().date())])
mail_ids.filtered('auto_delete').unlink()
@api.model
def process_email_queue(self, ids=None):
"""Send immediately queued messages, committing after each
@ -146,6 +171,8 @@ class MailMail(models.Model):
'email_status': 'exception',
})
if mail_sent:
if self.keep_days > 0:
return True
self.sudo().filtered(lambda self: self.auto_delete).unlink()
return True
@ -254,7 +281,8 @@ class MailMail(models.Model):
try:
mail = self.browse(mail_id)
if mail.state != 'outgoing':
if mail.state != 'exception' and mail.auto_delete:
if mail.state != 'exception' and mail.auto_delete and \
mail.keep_days < 0:
mail.sudo().unlink()
continue
# TDE note: remove me when model_id field is present on mail.message - done here to avoid doing it multiple times in the sub method

View File

@ -176,6 +176,13 @@ class MailTemplate(models.Model):
help="You may attach files to this template, to be added to all "
"emails created from this template")
auto_delete = fields.Boolean('Auto Delete', default=True, help="Permanently delete this email after sending it, to save space")
keep_days = fields.Integer('Keep days', default=-1,
help="This value defines the no. of days "
"the emails should be recorded "
"in the system: \n -1 = Email will be deleted "
"immediately once it is send \n greater than 0 = Email "
"will be deleted after "
"the no. of days are met.")
# Fake fields used to implement the placeholder assistant
model_object_field = fields.Many2one('ir.model.fields', string="Field",
@ -201,6 +208,14 @@ class MailTemplate(models.Model):
else:
self.model = False
@api.onchange('mail_server_id')
def onchange_mail_server_id(self):
if self.mail_server_id and self.mail_server_id.keep_days > 0 \
and self.keep_days < 0:
self.keep_days = self.mail_server_id.keep_days
else:
self.keep_days = -1
def build_expression(self, field_name, sub_field_name, null_value):
"""Returns a placeholder expression for use in a template field,
based on the values provided in the placeholder assistant.
@ -493,6 +508,7 @@ class MailTemplate(models.Model):
values.update(
mail_server_id=template.mail_server_id.id or False,
auto_delete=template.auto_delete,
keep_days=template.keep_days,
model=template.model,
res_id=res_id or False,
attachment_ids=[attach.id for attach in template.attachment_ids],

View File

@ -105,6 +105,7 @@ class Partner(models.Model):
'mail_message_id': message.id,
'mail_server_id': message.mail_server_id.id,
'auto_delete': self._context.get('mail_auto_delete', True),
'keep_days': self._context.get('mail_keep_days', -1),
'references': references,
}
mail_values.update(custom_values)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 556 B

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@ -37,6 +37,8 @@
<group>
<group string="Status">
<field name="auto_delete"/>
<field name="keep_days"/>
<field name="delete_date"/>
<field name="notification"/>
<field name="message_type"/>
<field name="mail_server_id"/>

View File

@ -67,6 +67,7 @@
<field name="lang"/>
<field name="mail_server_id"/>
<field name="auto_delete"/>
<field name="keep_days"/>
<field name="report_template" domain="[('model','=',model)]"/>
<field name="report_name" attrs="{'invisible':[('report_template','=',False)]}"/>
</group>

View File

@ -117,6 +117,13 @@ class MailComposer(models.TransientModel):
# mass mode options
notify = fields.Boolean('Notify followers', help='Notify followers of the document (mass post only)')
auto_delete = fields.Boolean('Delete Emails', help='Delete sent emails (mass mailing only)')
keep_days = fields.Integer('Keep days', default=-1,
help="This value defines the no. of days "
"the emails should be recorded "
"in the system: \n -1 = Email will be deleted "
"immediately once it is send \n greater than 0 = Email "
"will be deleted after "
"the no. of days are met.")
auto_delete_message = fields.Boolean('Delete Message Copy', help='Do not keep a copy of the email in the document communication history (mass mailing only)')
template_id = fields.Many2one(
'mail.template', 'Use template', index=True,
@ -220,7 +227,8 @@ class MailComposer(models.TransientModel):
# template user_signature is added when generating body_html
# mass mailing: use template auto_delete value -> note, for emails mass mailing only
Mail = Mail.with_context(mail_notify_user_signature=False)
ActiveModel = ActiveModel.with_context(mail_notify_user_signature=False, mail_auto_delete=wizard.template_id.auto_delete)
ActiveModel = ActiveModel.with_context(mail_notify_user_signature=False, mail_auto_delete=wizard.template_id.auto_delete,
mail_keep_days=wizard.template_id.keep_days)
if not hasattr(ActiveModel, 'message_post'):
ActiveModel = self.env['mail.thread'].with_context(thread_model=wizard.model)
if wizard.composition_mode == 'mass_post':
@ -305,6 +313,8 @@ class MailComposer(models.TransientModel):
# auto deletion of mail_mail
if self.auto_delete or self.template_id.auto_delete:
mail_values['auto_delete'] = True
mail_values['keep_days'] = \
self.keep_days or self.template_id.keep_days
# rendered values using template
email_dict = rendered_values[res_id]
mail_values['partner_ids'] += email_dict.pop('partner_ids', [])

View File

@ -63,6 +63,7 @@
<field name="team_type" groups="base.group_no_one"/>
<field name="user_id" domain="[('share', '=', False)]"/>
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field name="branch_id" options="{'no_create': True}" groups="base_branch_company.group_multi_branch"/>
</group>
<group name="right">
</group>

View File

@ -393,6 +393,12 @@
border-radius: 0 !important;
opacity: 0.8;
}
&.o_fullscreen {
.o_main .f_launcher {
display: none;
}
}
}
@media (max-width: 767px) {

View File

@ -1154,7 +1154,7 @@
</option>
</select>
</t>
<div t-name="SearchView.GroupByMenu" class="btn-group hidden-xs o_dropdown">
<div t-name="SearchView.GroupByMenu" class="btn-group o_dropdown">
<button class="o_dropdown_toggler_btn btn btn-sm dropdown-toggle" data-toggle="dropdown">
<span class="fa fa-bars"/> Group By <span class="caret"/>
</button>

View File

@ -41,7 +41,7 @@
<t name="Home" priority="29" t-name="website.homepage">
<t t-call="website.layout">
<t t-set="pageName" t-value="'homepage'"/>
<div id="wrap" class="oe_structure oe_empty"/>
<div id="wrap" t-att-data-website-domain="website.domain" class="oe_structure oe_empty"/>
</t>
</t>
</field>

View File

@ -126,6 +126,9 @@ response = request.render("website.template_partner_comment", {
<record id="default_website" model="website">
<field name="name">Website localhost</field>
</record>
<record id="website2" model="website">
<field name="name">Website 0.0.0.0</field>
<field name="domain">0.0.0.0</field>
</record>
</data>
</flectra>

View File

@ -45,7 +45,7 @@ var EditPageMenu = websiteNavbarData.WebsiteNavbarActionWidget.extend({
}
// If readonly empty page, show the welcome message
this.$welcomeMessage = $(core.qweb.render('website.homepage_editor_welcome_message'));
this.$welcomeMessage = $(core.qweb.render('website.homepage_editor_welcome_message', {'website_domain': $('#wrapwrap.homepage #wrap').attr('data-website-domain')}));
this.$welcomeMessage.css('min-height', $wrap.parent('main').height() - ($wrap.outerHeight(true) - $wrap.height()));
$wrap.empty().append(this.$welcomeMessage);

View File

@ -2,6 +2,10 @@
<templates id="template" xml:space="preserve">
<div t-name="website.homepage_editor_welcome_message" class="container text-center o_homepage_editor_welcome_message">
<h2 class="mt0">Welcome to your <b>Homepage</b>!</h2>
<t t-if="website_domain">
<h4>of</h4>
<h3 class="mt0"><u><t t-esc="website_domain"/></u></h3>
</t>
<p class="lead hidden-xs">Let's start designing.</p>
<div class="o_tooltip_container hidden-xs">Follow all the <div class="o_tooltip bottom"/> signs to get your website ready in no time.</div>
</div>

View File

@ -24,7 +24,7 @@ class WebsiteBlog(http.Controller):
dom = blog and [('blog_id', '=', blog.id)] or []
if not request.env.user.has_group('website.group_website_designer'):
dom += [('post_date', '<=', fields.Datetime.now()),
'|', ("website_ids", "in", request.website.id), ('website_ids', '=', False)]
("website_ids", "in", request.website.id)]
groups = request.env['blog.post']._read_group_raw(
dom,
['name', 'post_date'],
@ -64,7 +64,7 @@ class WebsiteBlog(http.Controller):
page=page,
step=self._blog_post_per_page,
)
posts = BlogPost.search(['|', ("website_ids", "in", request.website.id), ('website_ids', '=', False)], offset=(page - 1) * self._blog_post_per_page, limit=self._blog_post_per_page)
posts = BlogPost.search([('website_ids', 'in', request.website.id)], offset=(page - 1) * self._blog_post_per_page, limit=self._blog_post_per_page)
blog_url = QueryURL('', ['blog', 'tag'])
return request.render("website_blog.latest_blogs", {
'posts': posts,
@ -114,16 +114,16 @@ class WebsiteBlog(http.Controller):
domain += [("post_date", ">=", date_begin), ("post_date", "<=", date_end)]
if request.env.user.has_group('website.group_website_designer'):
count_domain = domain + [("website_published", "=", True), '|', ("website_ids", "in", request.website.id), ('website_ids', '=', False), ("post_date", "<=", fields.Datetime.now())]
count_domain = domain + [("website_published", "=", True), ("website_ids", "in", request.website.id), ("post_date", "<=", fields.Datetime.now())]
published_count = BlogPost.search_count(count_domain)
unpublished_count = BlogPost.search_count(domain) - published_count
if state == "published":
domain += [("website_published", "=", True), '|', ("website_ids", "in", request.website.id), ('website_ids', '=', False), ("post_date", "<=", fields.Datetime.now())]
domain += [("website_published", "=", True), ("website_ids", "in", request.website.id), ("post_date", "<=", fields.Datetime.now())]
elif state == "unpublished":
domain += ['|', ("website_published", "=", False), '|', ("website_ids", "in", request.website.id), ('website_ids', '=', False), ("post_date", ">", fields.Datetime.now())]
domain += ['|', ("website_published", "=", False), ("website_ids", "in", request.website.id), ("post_date", ">", fields.Datetime.now())]
else:
domain += [("post_date", "<=", fields.Datetime.now()), '|', ("website_ids", "in", request.website.id), ('website_ids', '=', False)]
domain += [("post_date", "<=", fields.Datetime.now()), ("website_ids", "in", request.website.id)]
blog_url = QueryURL('', ['blog', 'tag'], blog=blog, tag=tag, date_begin=date_begin, date_end=date_end)
@ -198,6 +198,10 @@ class WebsiteBlog(http.Controller):
- 'nav_list': a dict [year][month] for archives navigation
- 'next_post': next blog post, to direct the user towards the next interesting post
"""
if not request.env.user.has_group('website.group_website_publisher') \
and request.website.id not in blog_post.website_ids.ids:
return request.render('website.404')
BlogPost = request.env['blog.post']
date_begin, date_end = post.get('date_begin'), post.get('date_end')
@ -225,7 +229,7 @@ class WebsiteBlog(http.Controller):
tags = request.env['blog.tag'].search([])
# Find next Post
all_post = BlogPost.search([('blog_id', '=', blog.id)])
all_post = BlogPost.search([('blog_id', '=', blog.id), ("website_published", "=", True), ("website_ids", "in", request.website.id)])
if not request.env.user.has_group('website.group_website_designer'):
all_post = all_post.filtered(lambda r: r.post_date <= fields.Datetime.now())
@ -331,7 +335,7 @@ class WebsiteBlog(http.Controller):
#check current user belongs to website publisher group
publish = request.env.user.has_group('website.group_website_publisher')
if not publish:
domain.append(('website_published', '=', True), '|', ("website_ids", "in", request.website.id), ('website_ids', '=', False))
domain.append(('website_published', '=', True), ("website_ids", "in", request.website.id))
messages = request.env['mail.message'].sudo().search(domain, count=count)
if count:
return messages.ids

View File

@ -16,7 +16,6 @@
<field name="blog_id" ref="blog_blog_1"/>
<field name="tag_ids" eval="[(6, 0, [ref('blog_tag_1')])]"/>
<field name="website_published" eval="True"/>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="published_date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="website_meta_keywords">Flectra, email</field>
<field name="website_meta_description">The Future of Emails</field>
@ -132,7 +131,6 @@
<field name="subtitle">Building your company's website and selling your products online easy.</field>
<field name="blog_id" ref="blog_blog_1"/>
<field name="website_published" eval="True"/>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="published_date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/>
<field name="tag_ids" eval="[(6, 0, [ref('blog_tag_1'), ref('blog_tag_2')])]"/>
<field name="cover_properties">{"background-image": "url(/web/image/website_blog.blog_post_cover_02)", "resize_class": "cover container-fluid cover_full", "background-color": "oe_black", "opacity": "0.0"}</field>

View File

@ -127,6 +127,10 @@ class BlogPost(models.Model):
</section>
'''
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
name = fields.Char('Title', required=True, translate=True, default='')
subtitle = fields.Char('Sub Title', translate=True)
author_id = fields.Many2one('res.partner', 'Author', default=lambda self: self.env.user.partner_id)
@ -155,9 +159,10 @@ class BlogPost(models.Model):
ranking = fields.Float(compute='_compute_ranking', string='Ranking')
website_ids = fields.Many2many('website', 'website_blog_pub_rel',
'website_id', 'blog_id',
default=_default_website,
string='Websites', copy=False,
help='List of websites in which '
'Blog Post is published.')
'Blog Post will published.')
@api.multi
@api.depends('content', 'teaser_manual')

View File

@ -17,7 +17,7 @@ class TestWebsiteBlogFlow(TestWebsiteBlogCommon):
- if someone subscribe to the post or comment it, it become follower
and receive notification for future comments. """
self.website = self.env['website'].browse(1)
website = self.env['website'].browse(1)
# Create a new blog, subscribe the employee to the blog
test_blog = self.env['blog.blog'].sudo(self.user_blogmanager).create({
'name': 'New Blog',
@ -40,7 +40,7 @@ class TestWebsiteBlogFlow(TestWebsiteBlogCommon):
'website_blog: subscribing to a blog should not subscribe to its posts')
# Publish the blog
test_blog_post.write({'website_published': True, 'website_ids': [(6, 0, [self.website.id])]})
test_blog_post.write({'website_published': True, 'website_ids': [(6, 0, [website.id])]})
# Check publish message has been sent to blog followers
publish_message = next((m for m in test_blog_post.blog_id.message_ids if m.subtype_id.id == self.ref('website_blog.mt_blog_blog_published')), None)

View File

@ -133,7 +133,7 @@
</p>
</div>
<div t-foreach="blog_posts" t-as="blog_post" class="mb32" name="blog_post" t-attf-data-publish="#{not blog_post.website_ids or website in blog_post.website_ids and 'on' or 'off'}">
<div t-foreach="blog_posts" t-as="blog_post" class="mb32" name="blog_post" t-att-data-publish="blog_post.website_published and website in blog_post.website_ids and 'on' or 'off'">
<a t-attf-href="/blog/#{ slug(blog_post.blog_id) }/post/#{ slug(blog_post) }">
<h2 t-field="blog_post.name" class="mb4 o_blog_post_title">Untitled Post</h2>
</a>

View File

@ -185,14 +185,14 @@ class WebsiteCrmPartnerAssign(WebsitePartnerPage):
yield {'loc': '/partners'}
Grade = env['res.partner.grade']
dom = [('website_published', '=', True), '|', ('website_ids', 'in', request.website.id), ('website_ids', '=', False)]
dom = [('website_published', '=', True), ('website_ids', 'in', request.website.id)]
dom += sitemap_qs2dom(qs=qs, route='/partners/grade/', field=Grade._rec_name)
for grade in env['res.partner.grade'].search(dom):
loc = '/partners/grade/%s' % slug(grade)
if not qs or qs.lower() in loc:
yield {'loc': loc}
partners_dom = [('is_company', '=', True), ('grade_id', '!=', False), ('website_published', '=', True), '|', ('website_ids', 'in', request.website.id), ('website_ids', '=', False), ('grade_id.website_published', '=', True)]
partners_dom = [('is_company', '=', True), ('grade_id', '!=', False), ('website_published', '=', True), ('website_ids', 'in', request.website.id), ('grade_id.website_published', '=', True)]
dom += sitemap_qs2dom(qs=qs, route='/partners/country/')
countries = env['res.partner'].sudo().read_group(partners_dom, fields=['id', 'country_id'], groupby='country_id')
for country in countries:
@ -219,9 +219,9 @@ class WebsiteCrmPartnerAssign(WebsitePartnerPage):
country_obj = request.env['res.country']
search = post.get('search', '')
base_partner_domain = [('is_company', '=', True), ('grade_id', '!=', False), ('website_published', '=', True)]
base_partner_domain = [('is_company', '=', True), ('grade_id', '!=', False), ('website_published', '=', True), ('website_ids', 'in', request.website.id)]
if not request.env['res.users'].has_group('website.group_website_publisher'):
base_partner_domain += [('grade_id.website_published', '=', True), '|', ('grade_id.website_ids', 'in', request.website.id), ('grade_id.website_ids', '=', False)]
base_partner_domain += [('grade_id.website_published', '=', True), ('grade_id.website_ids', 'in', request.website.id)]
if search:
base_partner_domain += ['|', ('name', 'ilike', search), ('website_description', 'ilike', search)]
@ -327,7 +327,7 @@ class WebsiteCrmPartnerAssign(WebsitePartnerPage):
if partner_id:
partner = request.env['res.partner'].sudo().browse(partner_id)
is_website_publisher = request.env['res.users'].has_group('website.group_website_publisher')
if partner.exists() and ((partner.website_published and request.website in partner.website_ids) or is_website_publisher):
if partner.exists() and ((partner.website_published and request.website in partner.website_ids) or is_website_publisher):
values = {
'main_object': partner,
'partner': partner,

View File

@ -3,19 +3,15 @@
<data noupdate="1">
<record id="website_crm_partner_assign.res_partner_grade_platinium" model="res.partner.grade">
<field name="website_published" eval="True" />
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="website_crm_partner_assign.res_partner_grade_gold" model="res.partner.grade">
<field name="website_published" eval="True" />
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="website_crm_partner_assign.res_partner_grade_silver" model="res.partner.grade">
<field name="website_published" eval="True" />
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="website_crm_partner_assign.res_partner_grade_bronze" model="res.partner.grade">
<field name="website_published" eval="True" />
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.partner_demo_portal" model="res.partner">
<field name="grade_id" ref="website_crm_partner_assign.res_partner_grade_platinium"/>

View File

@ -9,6 +9,10 @@ class ResPartnerGrade(models.Model):
_name = 'res.partner.grade'
_inherit = ['website.published.mixin']
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
website_published = fields.Boolean(default=True)
sequence = fields.Integer('Sequence')
active = fields.Boolean('Active', default=lambda *args: 1)
@ -18,8 +22,9 @@ class ResPartnerGrade(models.Model):
website_ids = fields.Many2many('website', 'website_partner_grade_pub_rel',
'website_id', 'partner_grade_id',
string='Websites', copy=False,
default=_default_website,
help='List of websites in which '
'Partner Grade is published.')
'Partner Grade will published.')
@api.multi
def _compute_website_url(self):

View File

@ -162,7 +162,7 @@
<template id="grade_in_detail" inherit_id="website_partner.partner_detail">
<xpath expr="//*[@id='partner_name']" position="after">
<h3 class="col-md-12 text-center text-muted" t-if="partner.grade_id and partner.grade_id.website_published and (website in partner.grade_id.website_ids or not partner.grade_id.website_ids)">
<h3 class="col-md-12 text-center text-muted" t-if="partner.grade_id and partner.grade_id.website_published and website in partner.grade_id.website_ids">
<span t-field="partner.grade_id"/> Partner</h3>
</xpath>
</template>
@ -171,7 +171,7 @@
<t t-if="any([p.website_published for p in partner.implemented_partner_ids])">
<h3 id="references">References</h3>
<div t-foreach="partner.implemented_partner_ids" t-as="reference" class="media">
<t t-if="(not reference.website_ids or website in reference.website_ids) and reference.website_published">
<t t-if="website in reference.website_ids and reference.website_published">
<a class="pull-left" t-attf-href="/customers/#{slug(reference)}">
<span t-field="reference.image_small" t-options='{"widget": "image", "class": "center-block"}'/>
</a>

View File

@ -47,7 +47,7 @@ class WebsiteCustomer(http.Controller):
Partner = request.env['res.partner']
search_value = post.get('search')
domain = [('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id), ('assigned_partner_id', '!=', False)]
domain = [('website_published', '=', True), ('website_ids', 'in', request.website.id), ('assigned_partner_id', '!=', False)]
if search_value:
domain += [
'|', '|',
@ -118,7 +118,7 @@ class WebsiteCustomer(http.Controller):
google_map_partner_ids = ','.join(str(it) for it in partners.ids)
google_maps_api_key = request.env['ir.config_parameter'].sudo().get_param('google_maps_api_key')
tags = Tag.search([('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id), ('partner_ids', 'in', partners.ids)], order='classname, name ASC')
tags = Tag.search([('website_published', '=', True), ('website_ids', 'in', request.website.id), ('partner_ids', 'in', partners.ids)], order='classname, name ASC')
tag = tag_id and Tag.browse(tag_id) or False
values = {
@ -145,7 +145,7 @@ class WebsiteCustomer(http.Controller):
_, partner_id = unslug(partner_id)
if partner_id:
partner = request.env['res.partner'].sudo().browse(partner_id)
if partner.exists() and partner.website_published and (request.website in partner.website_ids or not partner.website_ids):
if partner.exists() and partner.website_published and request.website in partner.website_ids:
values = {}
values['main_object'] = values['partner'] = partner
return request.render("website_customer.details", values)

View File

@ -4,7 +4,6 @@
<record id="base.res_partner_2" model="res.partner">
<field name="website_published" eval="True"/>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="website_short_description">Agrolait designs, develops, integrates and supports HR and Supply Chain processes in order to make our customers more productive, responsive and profitable.</field>
<field name="website_description" type="xml">
<p>
@ -35,7 +34,6 @@
</record>
<record id="base.res_partner_3" model="res.partner">
<field name="website_published" eval="True"/>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="website_short_description">A non-profit international educational and scientific organisation, hosting three departments (aeronautics and aerospace, environmental and applied fluid dynamics, and turbomachinery and propulsion).</field>
<field name="website_description" type="xml">
<p>
@ -64,7 +62,6 @@
</record>
<record id="base.res_partner_4" model="res.partner">
<field name="website_published" eval="True"/>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="website_short_description">Agrolait designs, develops, integrates and supports HR and Supply Chain processes in order to make our customers more productive, responsive and profitable.</field>
<field name="website_description" type="xml">
<p>
@ -95,7 +92,6 @@
</record>
<record id="base.res_partner_3" model="res.partner">
<field name="website_published" eval="True"/>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="website_short_description">A non-profit international educational and scientific organisation, hosting three departments (aeronautics and aerospace, environmental and applied fluid dynamics, and turbomachinery and propulsion).</field>
<field name="website_description" type="xml">
<p>

View File

@ -22,6 +22,10 @@ class Tags(models.Model):
classname = ['default', 'primary', 'success', 'warning', 'danger']
return [(x, str.title(x)) for x in classname]
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
name = fields.Char('Category Name', required=True, translate=True)
partner_ids = fields.Many2many('res.partner', 'res_partner_res_partner_tag_rel', 'tag_id', 'partner_id', string='Partners')
classname = fields.Selection(get_selection_class, 'Class', default='default', help="Bootstrap class to customize the color", required=True)
@ -30,5 +34,6 @@ class Tags(models.Model):
website_ids = fields.Many2many('website', 'website_partner_tag_pub_rel',
'website_id', 'partner_tag_id',
string='Websites', copy=False,
default=_default_website,
help='List of websites in which '
'Partner Tag is published.')
'Partner Tag will published.')

View File

@ -37,7 +37,6 @@
<field name="name"/>
<field name="classname"/>
<field name="website_published"/>
<field name="website_ids" widget="many2many_tags"/>
<field name="active"/>
</tree>
</field>

View File

@ -189,7 +189,7 @@
</template>
<template id="implemented_by_block" name="Partner Implemented By Block">
<t t-if="partner.assigned_partner_id and partner.assigned_partner_id.website_published and (website in partner.assigned_partner_id.website_ids or not partner.assigned_partner_id.website_ids)">
<t t-if="partner.assigned_partner_id and partner.assigned_partner_id.website_published and website in partner.assigned_partner_id.website_ids">
<div class="panel panel-default">
<div class="panel-heading">
<h4>Implemented By</h4>
@ -198,7 +198,7 @@
<h4>
<a t-attf-href="/partners/#{slug(partner.assigned_partner_id)}">
<span t-field="partner.assigned_partner_id"/>
<span class="small"> (<t t-esc="len([p for p in partner.assigned_partner_id.implemented_partner_ids if p.website_published and (p.website_ids or website in p.website_ids)])"/> reference(s))</span>
<span class="small"> (<t t-esc="len([p for p in partner.assigned_partner_id.implemented_partner_ids if p.website_published and website in p.website_ids])"/> reference(s))</span>
</a>
</h4>
<div><a t-attf-href="/partners/#{slug(partner.assigned_partner_id)}"
@ -221,7 +221,7 @@
<t t-if="any([p.website_published and (website in p.website_ids or not p.website_ids) for p in partner.implemented_partner_ids])">
<h3 id="references">References</h3>
<div t-foreach="partner.implemented_partner_ids" t-as="reference" class="media">
<t t-if="reference.website_published and (website in reference.website_ids or not reference.website_ids)">
<t t-if="reference.website_published and website in reference.website_ids">
<a class="pull-left" t-attf-href="/customers/#{slug(reference)}">
<span t-field="reference.image_small" t-options='{"widget": "image", "class": "center-block"}'/>
</a>

View File

@ -83,7 +83,7 @@ class WebsiteEventController(http.Controller):
def dom_without(without):
domain = [('state', "in", ['draft', 'confirm', 'done'])]
domain += ['|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id)] if \
domain += [('website_id', '=', request.website.id)] if \
not request.env.user.has_group('website.group_website_publisher') else []
for key, search in domain_search.items():
if key != without:
@ -171,6 +171,9 @@ class WebsiteEventController(http.Controller):
@http.route(['/event/<model("event.event"):event>/register'], type='http', auth="public", website=True, sitemap=False)
def event_register(self, event, **post):
if not request.env.user.has_group('website.group_website_publisher') \
and request.website != event.website_id:
return request.render('website.404')
values = {
'event': event,
'main_object': event,
@ -257,7 +260,6 @@ class WebsiteEventController(http.Controller):
for registration in registrations:
registration['event_id'] = event
registration['website_id'] = request.website.id
Attendees += Attendees.sudo().create(
Attendees._prepare_attendee_values(registration))

View File

@ -3,12 +3,11 @@
<record id="base.res_partner_1" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="event.event_0" model="event.event">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="website_id" ref="website.default_website"/>
<field name="twitter_hashtag">flectra</field>
<field name="description"><![CDATA[
<section class="s_text_block_image_fw oe_img_bg" style="background-position: 50% 100%; background-image: url(/web/image/website.s_background_image_02);">
@ -165,11 +164,10 @@
<record id="base.res_partner_3" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="event.event_1" model="event.event">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="website_id" ref="website.default_website"/>
<field name="twitter_hashtag">flectra</field>
<field name="description"><![CDATA[
<section class="s_text_block_image_fw oe_img_bg" style="background-position: 50% 100%; background-image: url(/web/image/website.s_background_image_01);">
@ -326,25 +324,22 @@
<record id="base.res_partner_4" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="event.event_2" model="event.event">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="website_id" ref="website.default_website"/>
<field name="twitter_hashtag">flectra</field>
</record>
<record id="base.res_partner_2" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_address_4" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="event.event_3" model="event.event">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
<field name="website_id" ref="website.default_website"/>
<field name="twitter_hashtag">flectra</field>
<field name="description"><![CDATA[
<section class="s_text_block_image_fw oe_img_bg oe_custom_bg" style="background-image: url(/web/image/website.s_cover_default_image); background-position: 50% 100%">

View File

@ -17,11 +17,11 @@ class Event(models.Model):
_inherit = ['event.event', 'website.seo.metadata', 'website.published.mixin']
website_published = fields.Boolean(track_visibility='onchange')
website_ids = fields.Many2many('website', 'website_event_pub_rel',
'website_id', 'event_id',
string='Websites', copy=False,
help='List of websites in which '
'Event is published.')
website_id = fields.Many2one('website', string='Website', copy=False,
default=lambda self: self.env.ref(
'website.default_website'),
help='Website in which '
'Event will published.')
is_participating = fields.Boolean("Is Participating", compute="_compute_is_participating")
@ -136,29 +136,3 @@ class Event(models.Model):
'target': 'new',
'url': '/report/html/%s/%s?enable_editor' % ('event.event_event_report_template_badge', self.id),
}
class EventRegistration(models.Model):
_inherit = 'event.registration'
website_id = fields.Many2one('website', string="Website")
@api.model
def _prepare_attendee_values(self, registration):
""" Method preparing the values to create new attendees based on a
sale order line. It takes some registration data (dict-based) that are
optional values coming from an external input like a web page. This method
is meant to be inherited in various addons that sell events. """
partner_id = registration.pop('partner_id', self.env.user.partner_id)
event_id = registration.pop('event_id', False)
data = {
'name': registration.get('name', partner_id.name),
'phone': registration.get('phone', partner_id.phone),
'email': registration.get('email', partner_id.email),
'partner_id': partner_id.id,
'website_id': registration.get('website_id', partner_id.email),
'event_id': event_id and event_id.id or False,
}
data.update({key: registration[key] for key in registration.keys() if key in self._fields})
return data

View File

@ -53,12 +53,12 @@
</div>
<ul class="media-list">
<li t-foreach="event_ids" t-as="event" class="media">
<div itemscope="itemscope" itemtype="http://schema.org/Event" class="media-body" t-attf-data-publish="#{not event.website_ids or website in event.website_ids and 'on' or 'off'}">
<div itemscope="itemscope" itemtype="http://schema.org/Event" class="media-body" t-att-data-publish="event.website_published and website.id in event.website_id.ids and 'on' or 'off'">
<h4 class="media-heading">
<a itemprop="url" t-att-class="event.state == 'done' and 'text-success'" t-attf-href="/event/#{ slug(event) }/#{(not event.menu_id) and 'register' or ''}"><span itemprop="name" t-field="event.name"> </span></a>
<small t-if="event.is_participating" class="label label-info">Participating</small>
<small t-if="not event.is_online" class="label label-info">Online</small>
<small t-if="not event.website_published and (not event.website_ids or website not in event.website_ids)" class="label label-danger">unpublished</small>
<small t-if="event.is_online" class="label label-info">Online</small>
<small t-if="not event.website_published" class="label label-danger">unpublished</small>
</h4>
<div>
<t t-if="event.organizer_id">
@ -680,7 +680,7 @@
<h4><b>Upcoming Events</b></h4>
</t>
<div t-foreach="events[:5]" t-as="event_dict" class="oe_website_overflow_ellipsis mb8">
<t t-if="not event_dict['event'].website_published and (website not in event_dict['event'].wesite_ids or not event_dict['event'].wesite_ids)">
<t t-if="not event_dict['event'].website_published and not event_dict['event'].website_id">
<span class="label label-danger"><i class="fa fa-ban"></i></span>
</t>
<t t-if="event_dict['event'].address_id">

View File

@ -55,20 +55,9 @@
string="Edit Badges"/>
</xpath>
<xpath expr="//field[@name='auto_confirm']" position="before">
<field name="website_ids" widget="many2many_tags"/>
<field name="website_id"/>
</xpath>
</field>
</record>
<record model="ir.ui.view" id="view_event_registration_form_inherit">
<field name="name">view.event.registration.form.inherit</field>
<field name="model">event.registration</field>
<field name="inherit_id" ref="event.view_event_registration_form"/>
<field name="arch" type="xml">
<field name="partner_id" position="after">
<field name="website_id"/>
</field>
</field>
</record>
</flectra>

View File

@ -83,7 +83,7 @@ class WebsiteForum(http.Controller):
def forum(self, **kwargs):
domain = []
if not request.env.user.has_group('website.group_website_designer'):
domain += ['|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id)]
domain += [('website_ids', 'in', request.website.id)]
forums = request.env['forum.forum'].search(domain)
return request.render("website_forum.forum_all", {'forums': forums})
@ -119,8 +119,10 @@ class WebsiteForum(http.Controller):
], type='http', auth="public", website=True, sitemap=sitemap_forum)
def questions(self, forum, tag=None, page=1, filters='all', sorting=None, search='', post_type=None, **post):
Post = request.env['forum.post']
domain = [('forum_id', '=', forum.id), ('parent_id', '=', False), ('state', '=', 'active'), '|', ('website_id', '=', request.website.id), ('website_id', '=', False)]
if not request.env.user.has_group('website.group_website_publisher') \
and request.website.id not in forum.website_ids.ids:
return request.render('website.404')
domain = [('forum_id', '=', forum.id), ('parent_id', '=', False), ('state', '=', 'active'), ('website_id', '=', request.website.id)]
if search:
domain += ['|', ('name', 'ilike', search), ('content', 'ilike', search)]
if tag:
@ -237,6 +239,10 @@ class WebsiteForum(http.Controller):
@http.route(['''/forum/<model("forum.forum"):forum>/question/<model("forum.post", "[('forum_id','=',forum[0]),('parent_id','=',False),('can_view', '=', True)]"):question>'''], type='http', auth="public", website=True)
def question(self, forum, question, **post):
if not request.env.user.has_group('website.group_website_publisher') \
and request.website != question.website_id:
return request.render('website.404')
# Hide posts from abusers (negative karma), except for moderators
if not question.can_view:
raise werkzeug.exceptions.NotFound()
@ -411,7 +417,7 @@ class WebsiteForum(http.Controller):
'name': kwargs.get('post_name'),
'content': kwargs.get('content'),
'content_link': kwargs.get('content_link'),
'website_id': request.website.id,
'website_id': request.website and request.website.id,
}
post.write(vals)
question = post.parent_id if post.parent_id else post
@ -555,9 +561,9 @@ class WebsiteForum(http.Controller):
def users(self, forum, page=1, **searches):
User = request.env['res.users']
step = 30
tag_count = User.sudo().search_count([('karma', '>', 1), ('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id)])
tag_count = User.sudo().search_count([('karma', '>', 1), ('website_published', '=', True), ('website_ids', 'in', request.website.id)])
pager = request.website.pager(url="/forum/%s/users" % slug(forum), total=tag_count, page=page, step=step, scope=30)
user_obj = User.sudo().search([('karma', '>', 1), ('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id)], limit=step, offset=pager['offset'], order='karma DESC')
user_obj = User.sudo().search([('karma', '>', 1), ('website_published', '=', True), ('website_ids', 'in', request.website.id)], limit=step, offset=pager['offset'], order='karma DESC')
# put the users in block of 3 to display them as a table
users = [[] for i in range(len(user_obj) // 3 + 1)]
for index, user in enumerate(user_obj):

View File

@ -28,7 +28,6 @@
<!-- Questions -->
<record id="question_0" model="forum.post">
<field name="name">How to configure alerts for employee contract expiration</field>
<field name="website_id" ref="website.default_website"/>
<field name="forum_id" ref="website_forum.forum_help"/>
<field name="post_type">question</field>
<field name="views">3</field>
@ -36,7 +35,6 @@
</record>
<record id="question_1" model="forum.post">
<field name="name">CMS replacement for ERP and eCommerce</field>
<field name="website_id" ref="website.default_website"/>
<field name="views">8</field>
<field name="forum_id" ref="website_forum.forum_help"/>
<field name="content"><![CDATA[<p>I use Wordpress as a CMS and eCommerce platform. The developing in Wordpress is quite easy and solid but it missing ERP feature (there is single plugin to integrate with Frontaccounting) so I wonder:
@ -51,7 +49,6 @@ In simple words does Flectra became CMS+ERP platform?</p>]]></field>
<!-- Answer -->
<record id="answer_0" model="forum.post">
<field name="forum_id" ref="website_forum.forum_help"/>
<field name="website_id" ref="website.default_website"/>
<field name="content"><![CDATA[<p>Just for posterity so other can see. Here are the steps to set automatic alerts on any contract.. i.e. HR Employee, or Fleet for example. I will use fleet as an example.</p>
<ul>
<li>Step 1. As a user who has access rights to Technical Features, go to Settings --> Automated Actions. Create A new Automated Action. For the Related Document Model choose.. Contract information on a vehicle (you can also type in the actual model name.. fleet.vehicle.log.contract ) . Set the trigger date to ... Contract Expiration Date. The Next Field (Delay After Trigger Date) is a bit ridiculous. Who wants to be reminded of a contract expiration AFTER the fact? The field should say Days Before Date to Fire Action and the number should be converted to a negative. IMHO. Any way... to get a workable solution you must enter in the number in the negative. So for instance like me if you want to be warned 35 days BEFORE the expiration... put in Delay After Trigger Date.. the number -35 But the sake of testing, right now just put in -1 for 1 day before. Save the Action.
@ -64,7 +61,6 @@ In simple words does Flectra became CMS+ERP platform?</p>]]></field>
</record>
<record id="answer_1" model="forum.post">
<field name="forum_id" ref="website_forum.forum_help"/>
<field name="website_id" ref="website.default_website"/>
<field name="content"><![CDATA[
<p>Flectra v8 (next release) provides a web module and an e-commerce module: www.flectra.com/page/website-builder
The CMS editor in Flectra web is nice but I prefer Drupal for customization and there is a Drupal module for Flectra. I think WP is better than Flectra web too.
@ -77,7 +73,6 @@ The CMS editor in Flectra web is nice but I prefer Drupal for customization and
<record id="article_0" model="forum.post">
<field name="content_link">https://www.flectra.com</field>
<field name="name">Discover Flectra, an open source ERP.</field>
<field name="website_id" ref="website.default_website"/>
<field name="forum_id" ref="website_forum.forum_help"/>
<field name="post_type">link</field>
<field name="views">6</field>
@ -87,7 +82,6 @@ The CMS editor in Flectra web is nice but I prefer Drupal for customization and
<!-- Discussion-->
<record id="discussion_0" model="forum.post">
<field name="name">How to setup a regular PostgreSQL database backup</field>
<field name="website_id" ref="website.default_website"/>
<field name="content">I'm not familiar with PostgreSQL database administration , so I figured I might ask for help from someone more knowledgeable on the subject.
What would you recommend in order to setup a regular (daily) OpenERP database backup?
@ -104,7 +98,6 @@ Are there any automation scripts available I might use?
<record id="reply_1" model="forum.post">
<field name="forum_id" ref="website_forum.forum_help"/>
<field name="website_id" ref="website.default_website"/>
<field name="content"><![CDATA[<p>I use the following setup:</p>
<ol>
<li>Backup-Script</li>

View File

@ -41,6 +41,10 @@ class Forum(models.Model):
with misc.file_open('website_forum/data/forum_default_faq.html', 'r') as f:
return f.read()
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
# description and use
name = fields.Char('Forum Name', required=True, translate=True)
active = fields.Boolean(default=True)
@ -131,8 +135,9 @@ class Forum(models.Model):
website_ids = fields.Many2many('website', 'website_forum_pub_rel',
'website_id', 'forum_id',
string='Websites', copy=False,
default=_default_website,
help='List of websites in which '
'Forum is published.')
'Forum will published.')
@api.one
@api.constrains('allow_question', 'allow_discussion', 'allow_link', 'default_post_type')
@ -276,8 +281,8 @@ class Post(models.Model):
can_post = fields.Boolean('Can Automatically be Validated', compute='_get_post_karma_rights')
can_flag = fields.Boolean('Can Flag', compute='_get_post_karma_rights')
can_moderate = fields.Boolean('Can Moderate', compute='_get_post_karma_rights')
website_id = fields.Many2one('website', string="Website")
website_id = fields.Many2one('website', string="Website",
default=lambda self: self.env.ref('website.default_website'))
def _search_can_view(self, operator, value):
if operator not in ('=', '!=', '<>'):

View File

@ -4,26 +4,31 @@
<record id="hr.employee_niv" model="hr.employee">
<field name="website_published" eval="True"/>
<field name="public_info">Designer, UI Expert</field>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="hr.employee_root" model="hr.employee">
<field name="website_published" eval="True"/>
<field name="public_info">Lean Management Expert</field>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="hr.employee_qdp" model="hr.employee">
<field name="website_published" eval="True"/>
<field name="public_info">Designer, UI Expert</field>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="hr.employee_fpi" model="hr.employee">
<field name="website_published" eval="True"/>
<field name="public_info">Customer Service Oriented</field>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="hr.employee_al" model="hr.employee">
<field name="website_published" eval="True"/>
<field name="public_info">Like Coding</field>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="hr.employee_jgo" model="hr.employee">

View File

@ -7,11 +7,17 @@ class HrEmployee(models.Model):
_name = 'hr.employee'
_inherit = ['hr.employee', 'website.published.mixin']
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
public_info = fields.Char(string='Public Info')
website_ids = fields.Many2many('website', 'website_hr_emp_pub_rel',
'website_id', 'emp_id',
default=_default_website,
string='Websites', copy=False,
help='List of websites in which Employee is published.')
help='List of websites in which Employee '
'will published.')
@api.multi
def _compute_website_url(self):

View File

@ -11,7 +11,7 @@
<xpath expr="//div[hasclass('oe_structure')]" position="after">
<section class="container" id="team">
<t t-set="is_publisher" t-value="request.env['res.users'].has_group('website.group_website_publisher')" />
<t t-set="employees_domain" t-value="[] if is_publisher else [('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', website)]" />
<t t-set="employees_domain" t-value="[] if is_publisher else [('website_published', '=', True), ('website_ids', 'in', website)]" />
<t t-set="employees" t-value="request.env['hr.employee'].search(employees_domain)" />
<div class="col-sm-12 text-center" t-if="len(employees)">
<h2>Our Team</h2>
@ -22,7 +22,7 @@
<t t-set="publish_edit" t-value="True"/>
</t>
<div class="clearfix"/>
<div class="emp" t-attf-data-publish="#{employee.website_published &amp; (not employee.website_ids or website in employee.website_ids) and 'on' or 'off'}">
<div class="emp" t-att-data-publish="employee.website_published and website in employee.website_ids and 'on' or 'off'}">
<img t-att-src="website.image_url(employee, 'image_medium')" class="img shadow img-rounded"/>
<div class="mt8">
<strong t-field="employee.name"></strong>

View File

@ -30,7 +30,7 @@ class WebsiteHrRecruitment(http.Controller):
# List jobs available to current UID
job_ids = Jobs.search([], order="website_published desc,no_of_recruitment desc").ids
if not request.env['res.users'].has_group('website.group_website_publisher'):
job_ids = Jobs.search(['|',('website_ids', '=', False), ('website_ids', 'in', request.website.id)], order="website_published desc, no_of_recruitment desc").ids
job_ids = Jobs.search([('website_ids', 'in', request.website.id)], order="website_published desc, no_of_recruitment desc").ids
# Browse jobs as superuser, because address is restricted
jobs = Jobs.sudo().browse(job_ids)
@ -81,6 +81,9 @@ class WebsiteHrRecruitment(http.Controller):
@http.route('/jobs/detail/<model("hr.job"):job>', type='http', auth="public", website=True)
def jobs_detail(self, job, **kwargs):
if not request.env.user.has_group('website.group_website_publisher') \
and request.website.id not in job.website_ids.ids:
return request.render('website.404')
return request.render("website_hr_recruitment.detail", {
'job': job,
'main_object': job,

View File

@ -3,6 +3,7 @@
<record id="hr.job_marketing" model="hr.job">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
<field name="website_description" type="html">
<section class="mt16 mb16 oe_dark">
<div class="container">
@ -135,6 +136,7 @@
<record id="hr.job_developer" model="hr.job">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
<field name="website_description" type="html">
<section class="mt16 mb16 oe_dark">
<div class="container">
@ -268,6 +270,7 @@
<record id="hr.job_consultant" model="hr.job">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
<field name="website_description" type="html">
<section class="mt16 mb16 oe_dark">
<div class="container">

View File

@ -29,6 +29,7 @@ class RecruitmentSource(models.Model):
class Applicant(models.Model):
_inherit = 'hr.applicant'
website_id = fields.Many2one('website', string="Website")
def website_form_input_filter(self, request, values):
@ -46,11 +47,17 @@ class Job(models.Model):
default_description = self.env["ir.model.data"].xmlid_to_object("website_hr_recruitment.default_website_description")
return (default_description.render() if default_description else "")
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
website_description = fields.Html('Website description', translate=html_translate, sanitize_attributes=False, default=_get_default_website_description)
website_ids = fields.Many2many('website', 'website_hr_job_pub_rel',
'website_id', 'job_id',
default=_default_website,
string='Websites', copy=False,
help='List of websites in which Job is published.')
help='List of websites in which Job '
'will published.')
@api.multi
def _compute_website_url(self):

View File

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from flectra import models, fields, api, _
from flectra import models, fields
class LinkTracker(models.Model):
_inherit = "link.tracker"
website_id = fields.Many2one('website', string="Link For Website")
website_id = fields.Many2one('website', string='Website',
help='Define website in which this '
'link will enabled!')

View File

@ -12,24 +12,17 @@
</field>
</record>
<record id="view_link_tracker_filter" model="ir.ui.view">
<field name="name">view.link.tracker.filter</field>
<!-- Search -->
<record id="view_link_tracker_filter_website" model="ir.ui.view">
<field name="name">Links</field>
<field name="model">link.tracker</field>
<field name="inherit_id" ref="link_tracker.view_link_tracker_filter"/>
<field name="arch" type="xml">
<search string="Search Link Tracker">
<separator/>
<xpath expr="//field[@name='title']" position="after">
<filter name="website_id" string="Website"
context="{'group_by':'website_id'}"/>
</search>
</xpath>
</field>
</record>
<!-- Action for website links-->
<record model="ir.actions.act_window" id="link_tracker.action_link_tracker">
<field name="name">Link Tracker</field>
<field name="res_model">link.tracker</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form,graph</field>
<field name="search_view_id" ref="view_link_tracker_filter"/>
</record>
</flectra>

View File

@ -84,7 +84,6 @@
<label class="col-sm-3 control-label text-left hidden">
Website
</label>
<div class="col-sm-9">
<input type="hidden" id="website_id" class="form-control" t-att-value="website.id"/>
</div>

View File

@ -43,7 +43,7 @@ class WebsiteMembership(http.Controller):
# base domain for groupby / searches
base_line_domain = [
("partner.website_published", "=", True), ('state', '=', 'paid'),
'|', ('partner.website_ids', '=', False), ('partner.website_ids', 'in', request.website.id),
('partner.website_ids', 'in', request.website.id),
('date_to', '>=', today), ('date_from', '<=', today)
]
if membership_id and membership_id != 'free':
@ -64,7 +64,7 @@ class WebsiteMembership(http.Controller):
if post_name:
country_domain += ['|', ('name', 'ilike', post_name), ('website_description', 'ilike', post_name)]
countries = Partner.sudo().read_group(country_domain + [("website_published", "=", True), '|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id)], ["id", "country_id"], groupby="country_id", orderby="country_id")
countries = Partner.sudo().read_group(country_domain + [("website_published", "=", True), ('website_ids', 'in', request.website.id)], ["id", "country_id"], groupby="country_id", orderby="country_id")
countries_total = sum(country_dict['country_id_count'] for country_dict in countries)
line_domain = list(base_line_domain)
@ -107,7 +107,7 @@ class WebsiteMembership(http.Controller):
if request.env.ref('website_membership.opt_index_google_map').customize_show:
google_map_partner_ids = MembershipLine.search(line_domain).get_published_companies(limit=2000)
search_domain = [('membership_state', '=', 'free'), ('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id),]
search_domain = [('membership_state', '=', 'free'), ('website_published', '=', True), ('website_ids', 'in', request.website.id)]
if post_name:
search_domain += ['|', ('name', 'ilike', post_name), ('website_description', 'ilike', post_name)]
if country_id:
@ -168,7 +168,7 @@ class WebsiteMembership(http.Controller):
_, partner_id = unslug(partner_id)
if partner_id:
partner = request.env['res.partner'].sudo().browse(partner_id)
if partner.exists() and partner.website_published and not partner.website_ids or request.website in partner.website_ids: # TODO should be done with access rules
if partner.exists() and partner.website_published and request.website in partner.website_ids: # TODO should be done with access rules
values = {}
values['main_object'] = values['partner'] = partner
return request.render("website_membership.partner", values)

View File

@ -13,6 +13,9 @@ class WebsitePartnerPage(http.Controller):
_, partner_id = unslug(partner_id)
if partner_id:
partner_sudo = request.env['res.partner'].sudo().browse(partner_id)
if not request.env.user.has_group('website.group_website_publisher') \
and request.website.id not in partner_sudo.website_ids.ids:
return request.render('website.404')
is_website_publisher = request.env['res.users'].has_group('website.group_website_publisher')
if partner_sudo.exists() and (partner_sudo.website_published or is_website_publisher):
values = {

View File

@ -3,56 +3,45 @@
<record id="base.partner_root" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.partner_demo" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_12" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_12" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_2" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_1" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_12" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_3" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_3" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_2" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_18" model="res.partner">
<field name="website_published">True</field>
<field name="website_ids" eval="[(4,ref('website.default_website'))]"/>
</record>
<record id="base.res_partner_10" model="res.partner">

View File

@ -8,13 +8,18 @@ class WebsiteResPartner(models.Model):
_name = 'res.partner'
_inherit = ['res.partner', 'website.seo.metadata', 'website.published.mixin']
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
website_description = fields.Html('Website Partner Full Description', strip_style=True)
website_short_description = fields.Text('Website Partner Short Description')
website_ids = fields.Many2many('website', 'website_partner_pub_rel',
'website_id', 'partner_id',
string='Websites', copy=False,
default=_default_website,
help='List of websites in which '
'Partner is published.')
'Partner will published.')
@api.multi
def _compute_website_url(self):

View File

@ -5,6 +5,6 @@ from flectra import fields, models
class PaymentAcquirer(models.Model):
_inherit = "payment.acquirer"
website_id = fields.Many2many('website', 'website_payment_rel',
'website_id', 'payment_id',
string='Website')
website_id = fields.Many2one('website', string='Website', copy=False,
help='Define website in which Payment '
'Gateway will published.')

View File

@ -25,7 +25,7 @@
<field name="inherit_id" ref="payment.acquirer_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='provider']" position='after'>
<field name="website_id" widget="many2many_tags"/>
<field name="website_id"/>
</xpath>
<xpath expr="//group[@name='acquirer_left']" position="after">
<group nama="acquirer_right">

View File

@ -191,7 +191,7 @@ class WebsiteSale(http.Controller):
if attrib:
domain += [('attribute_line_ids.value_ids', 'in', ids)]
if not request.env.user.has_group('website.group_website_publisher'):
domain += ['|', ('website_ids', '=', False), ('website_ids', 'in', request.website.id)]
domain += [('website_ids', 'in', request.website.id)]
if tag_values:
domain += [('tag_ids', 'in', tag_values)]
@ -245,10 +245,8 @@ class WebsiteSale(http.Controller):
post["search"] = search
if category:
category = request.env['product.public.category'].browse(int(category))
website = []
for web in category.website_ids:
website.append(web.id)
if request.website.id not in website:
if not category.website_ids or \
request.website.id not in category.website_ids.ids:
return request.render('website.404')
url = "/shop/category/%s" % slug(category)
if attrib_list:
@ -316,10 +314,13 @@ class WebsiteSale(http.Controller):
}
if category:
values['main_object'] = category
return request.render("website_sale.products", values)
return request.render("website_sale.main_shop_page", values)
@http.route(['/shop/product/<model("product.template"):product>'], type='http', auth="public", website=True)
def product(self, product, category='', search='', **kwargs):
if not request.env.user.has_group('website.group_website_publisher') \
and request.website.id not in product.website_ids.ids:
return request.render('website.404')
product_context = dict(request.env.context,
active_id=product.id,
partner=request.env.user.partner_id)
@ -364,7 +365,7 @@ class WebsiteSale(http.Controller):
@http.route(['/shop/change_pricelist/<model("product.pricelist"):pl_id>'], type='http', auth="public", website=True)
def pricelist_change(self, pl_id, **post):
if (pl_id.website_id or pl_id == request.env.user.partner_id.property_product_pricelist) \
if (pl_id.selectable or pl_id == request.env.user.partner_id.property_product_pricelist) \
and request.website.is_pricelist_available(pl_id.id):
request.session['website_sale_current_pl'] = pl_id.id
request.website.sale_get_order(force_pricelist=pl_id.id)
@ -790,7 +791,7 @@ class WebsiteSale(http.Controller):
)
acquirers = request.env['payment.acquirer'].search(
[('website_published', '=', True), ('company_id', '=', order.company_id.id), '|', ('website_id', '=', False), ('website_id', '=', request.website.id)]
[('website_published', '=', True), ('company_id', '=', order.company_id.id), ('website_id', '=', request.website.id)]
)
values['access_token'] = order.access_token
@ -798,7 +799,7 @@ class WebsiteSale(http.Controller):
values['s2s_acquirers'] = [acq for acq in acquirers if acq.payment_flow == 's2s' and acq.registration_view_template_id]
values['tokens'] = request.env['payment.token'].search(
[('partner_id', '=', order.partner_id.id),
('acquirer_id', 'in', [acq.id for acq in values['s2s_acquirers']])])
('acquirer_id', 'in', acquirers.ids)])
for acq in values['form_acquirers']:
acq.form = acq.with_context(submit_class='btn btn-primary', submit_txt=_('Pay Now')).sudo().render(

View File

@ -29,6 +29,11 @@
<field name="salesteam_id" ref="sales_team.salesteam_website_sales"/>
</record>
<record model="product.pricelist" id="product.list0">
<field name="selectable" eval="False" />
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
</data>
<data>
<record id="sale.model_sale_order" model="ir.model">

View File

@ -630,75 +630,99 @@ Weight: 31 grams</field>
<record id="product.product_product_1_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('services')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_2_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('services')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_3_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Computer_all_in_one')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_4_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Computer_all_in_one')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_5_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Computer_all_in_one')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_5b_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Speakers')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_6_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Screen')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_7_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Headset')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_8_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Computer_all_in_one')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_9_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Keyboard_Mouse')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_10_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Keyboard_Mouse')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_11_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Computer_all_in_one')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_12_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Keyboard_Mouse')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_13_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Components')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_16_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Components')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_17_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Components')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_20_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Components')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_22_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Components')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_24_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Components')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_25_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('laptops')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_product_27_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('laptops')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_delivery_02_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('External_Hard_Drive')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_order_01_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Software')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_delivery_01_product_template" model="product.template">
<field name="public_categ_ids" eval="[(6,0,[ref('Components')])]"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
<record id="product.product_attribute_value_3" model="product.attribute.value">
<field name="html_color">#FFFFFF</field>
@ -709,7 +733,8 @@ Weight: 31 grams</field>
<record model="product.pricelist" id="product.list0">
<field name="name">USD</field>
<!--<field name="website_id" eval="[(6, 0, [ref('website.default_website').id])]"/>-->
<field name="selectable" eval="True" />
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
<field name="sequence">3</field>
<field name="currency_id" ref="base.USD"/>
</record>
@ -722,7 +747,8 @@ Weight: 31 grams</field>
<record id="list_christmas" model="product.pricelist">
<field name="name">Christmas</field>
<!--<field name="website_id" eval="[(6, 0, [ref('website.default_website').id])]"/>-->
<field name="selectable" eval="False" />
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
<field name="country_group_ids" eval="[(6,0,[ref('base.europe')])]" />
<field name="sequence">20</field>
</record>
@ -735,7 +761,8 @@ Weight: 31 grams</field>
<record id="list_benelux" model="product.pricelist">
<field name="name">Benelux</field>
<!--<field name="website_id" eval="[(6, 0, [ref('website.default_website').id])]"/>-->
<field name="selectable" eval="False" />
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
<field name="country_group_ids" eval="[(6,0,[ref('benelux')])]" />
<field name="sequence">2</field>
</record>
@ -750,7 +777,8 @@ Weight: 31 grams</field>
<record id="list_europe" model="product.pricelist">
<field name="name">EUR</field>
<!--<field name="website_id" eval="[(6, 0, [ref('website.default_website').id])]"/>-->
<field name="selectable" eval="False" />
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
<field name="country_group_ids" eval="[(6,0,[ref('base.europe')])]" />
<field name="sequence">3</field>
<field name="currency_id" ref="base.EUR"/>

View File

@ -10,10 +10,11 @@ from flectra.tools import float_is_zero
class ProductTags(models.Model):
_name = 'product.tags'
_description = 'Product Tags'
_order = 'sequence'
sequence = fields.Integer(help="Gives the sequence order when "
"displaying a list of rules.")
"displaying a list of tags.")
name = fields.Char(string='Name', required=True, translate=True)
_sql_constraints = [('name_uniq', 'unique (name)',
@ -26,7 +27,7 @@ class ProductBrand(models.Model):
_order = 'sequence'
sequence = fields.Integer(help="Gives the sequence order when displaying "
"a list of rules.")
"a list of brands.")
name = fields.Char(string='Name', required=True, translate=True)
brand_image = fields.Binary(string='Brand Image')
@ -36,7 +37,7 @@ class ProductBrand(models.Model):
class ProductRibbon(models.Model):
_name = 'product.ribbon'
_description = 'Product Brand'
_description = 'Product Ribbon'
_order = 'name'
name = fields.Char(string='Name', size=20, required=True, translate=True)
@ -44,29 +45,30 @@ class ProductRibbon(models.Model):
ribbon_color_text = fields.Char(string='Font Color', required=True)
class ProductStyle(models.Model):
_name = "product.style"
class ProductViewLimit(models.Model):
_name = 'product.view.limit'
_order = 'sequence'
name = fields.Char(string='Style Name', required=True)
html_class = fields.Char(string='HTML Classes')
sequence = fields.Integer(help="Gives the sequence order when "
"displaying a list of rules.")
name = fields.Integer(string='Limit', required=True)
class WebsitePriceList(models.Model):
_name = "website.product.pricelist"
pricelist_id = fields.Many2one('product.pricelist',
string='Website Pricelist')
website_id = fields.Many2one('website', string='Website')
selectable = fields.Boolean(string="selectable", default=True)
_sql_constraints = [('name', 'unique(name)', 'This must be unique!')]
class ProductPricelist(models.Model):
_inherit = "product.pricelist"
def _default_website(self):
return self.env['website'].search([], limit=1)
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
website_id = fields.One2many('website.product.pricelist', 'pricelist_id', string='Website')
website_ids = fields.Many2many('website', 'website_pricelist_rule_rel',
'pricelist_id', 'website_id',
string="website", default=_default_website,
help='List of websites in which price-list '
'will published.')
selectable = fields.Boolean(help="Allow the end user to choose this price list")
code = fields.Char(string='E-commerce Promotional Code', groups="base.group_user")
def clear_cache(self):
@ -95,24 +97,16 @@ class ProductPricelist(models.Model):
return res
class WebsiteProductLimit(models.Model):
_name = 'product.view.limit'
_order = 'sequence'
sequence = fields.Integer(help="Gives the sequence order when "
"displaying a list of rules.")
name = fields.Integer(string='Limit', required=True)
_sql_constraints = [('name', 'unique(name)', 'This must be unique!')]
class ProductPublicCategory(models.Model):
_name = "product.public.category"
_inherit = ["website.seo.metadata"]
_description = "Website Product Category"
_order = "sequence, name"
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
name = fields.Char(required=True, translate=True)
parent_id = fields.Many2one('product.public.category', string='Parent Category', index=True)
child_id = fields.One2many('product.public.category', 'parent_id', string='Children Categories')
@ -133,15 +127,17 @@ class ProductPublicCategory(models.Model):
"Use this field anywhere a small image is required.")
website_ids = fields.Many2many('website', 'website_prod_public_categ_rel',
'website_id', 'category_id',
default=_default_website,
string='Websites', copy=False,
help='List of websites in which '
'category is published.')
'category will published.')
@api.model
def create(self, vals):
tools.image_resize_images(vals)
res = super(ProductPublicCategory, self).create(vals)
# @todo Check different test-case: child & parent category
# @todo Flectra:
# Multi-Website: Check different test-cases for child & parent category
if res.parent_id:
res.parent_id.write({
'website_ids': [(4, website_id.id) for website_id in res.website_ids]
@ -152,7 +148,8 @@ class ProductPublicCategory(models.Model):
def write(self, vals):
tools.image_resize_images(vals)
res = super(ProductPublicCategory, self).write(vals)
# @todo Check different test-case: child & parent category
# @todo Flectra:
# Multi-Website: Check different test-cases for child & parent category
if self.parent_id and self.website_ids.ids:
self.parent_id.write({
'website_ids': [(4, website_id.id) for website_id in self.website_ids]
@ -190,6 +187,10 @@ class ProductTemplate(models.Model):
_name = 'product.template'
_mail_post_access = 'read'
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
website_description = fields.Html('Description for the website', sanitize_attributes=False, translate=html_translate)
alternative_product_ids = fields.Many2many('product.template', 'product_alternative_rel', 'src_id', 'dest_id',
string='Alternative Products', help='Suggest more expensive alternatives to '
@ -214,11 +215,12 @@ class ProductTemplate(models.Model):
website_ids = fields.Many2many('website', 'website_prod_pub_rel',
'website_id', 'product_id',
string='Websites', copy=False,
default=_default_website,
help='List of websites in which '
'Product is published.')
ribbon_id = fields.Many2one('product.ribbon', string='Product Ribbon')
brand_id = fields.Many2one('product.brand', string="Product's Brand")
tag_ids = fields.Many2many('product.tags', string='Product Tags')
'Product will published.')
ribbon_id = fields.Many2one('product.ribbon', string="Product Ribbon")
brand_id = fields.Many2one('product.brand', string="Product Brand")
tag_ids = fields.Many2many('product.tags', string="Product Tags")
def _website_price(self):
# First filter out the ones that have no variant:
@ -267,11 +269,6 @@ class ProductTemplate(models.Model):
class Product(models.Model):
_inherit = "product.product"
def _get_default_website_ids(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
website_ids = fields.Many2many('website', string="Publish Product On Website", default=_get_default_website_ids)
website_price = fields.Float('Website price', compute='_website_price', digits=dp.get_precision('Product Price'))
website_public_price = fields.Float('Website public price', compute='_website_price', digits=dp.get_precision('Product Price'))
website_price_difference = fields.Boolean('Website price difference', compute='_website_price')

View File

@ -17,14 +17,12 @@ class Website(models.Model):
currency_id = fields.Many2one('res.currency', related='pricelist_id.currency_id', string='Default Currency')
salesperson_id = fields.Many2one('res.users', string='Salesperson')
salesteam_id = fields.Many2one('crm.team', string='Sales Channel')
pricelist_ids = fields.One2many('website.product.pricelist', compute="_compute_pricelist_ids",
string='Price list available for this Ecommerce/Website')
pricelist_ids = fields.One2many('product.pricelist', compute="_compute_pricelist_ids",
string='Price list available for this Ecommerce/Website')
@api.one
def _compute_pricelist_ids(self):
for website in self:
website.pricelist_ids = website.env["website.product.pricelist"].search([("website_id", "=", website.id)])
# self.pricelist_ids = self.env["product.pricelist"].search([("website_id", "=", self.id)])
self.pricelist_ids = self.env["product.pricelist"].search([("website_ids", "in", self.id)])
@api.multi
def _compute_pricelist_id(self):
@ -34,8 +32,8 @@ class Website(models.Model):
website.pricelist_id = website.get_current_pricelist()
# This method is cached, must not return records! See also #8795
@tools.ormcache('self.env.uid', 'country_code', 'show_visible', 'website_pl', 'current_pl', 'all_pls', 'partner_pl', 'order_pl')
def _get_pl_partner_order(self, country_code, show_visible, website_pl, current_pl, all_pls, partner_pl=False, order_pl=False):
@tools.ormcache('self.env.uid', 'country_code', 'show_visible', 'website_pl', 'current_pl', 'all_pl', 'partner_pl', 'order_pl')
def _get_pl_partner_order(self, country_code, show_visible, website_pl, current_pl, all_pl, partner_pl=False, order_pl=False):
""" Return the list of pricelists that can be used on website for the current user.
:param str country_code: code iso or False, If set, we search only price list available for this country
:param bool show_visible: if True, we don't display pricelist where selectable is False (Eg: Code promo)
@ -51,21 +49,19 @@ class Website(models.Model):
if country_code:
for cgroup in self.env['res.country.group'].search([('country_ids.code', '=', country_code)]):
for group_pricelists in cgroup.pricelist_ids:
if not show_visible or group_pricelists.website_id.filtered(lambda web_pl: web_pl.website_id == self.get_current_website() and web_pl.selectable) or group_pricelists.id in (current_pl, order_pl):
if not show_visible or group_pricelists.selectable or group_pricelists.id in (current_pl, order_pl):
pricelists |= group_pricelists
partner = self.env.user.partner_id
is_public = self.user_id.id == self.env.user.id
if not is_public and (not pricelists or (partner_pl or partner.property_product_pricelist.id) != website_pl):
if partner.property_product_pricelist.website_id:
if partner.property_product_pricelist.website_ids:
pricelists |= partner.property_product_pricelist
if not pricelists: # no pricelist for this country, or no GeoIP
for all_pl in all_pls:
pricelists |= all_pl.pricelist_id.filtered(lambda pl: not show_visible or (all_pl.pricelist_id == pl and all_pl.selectable) or pl.id in (current_pl, order_pl))
pricelists |= all_pl.filtered(lambda pl: not show_visible or pl.selectable or pl.id in (current_pl, order_pl))
else:
for all_pl in all_pls:
pricelists |= all_pl.pricelist_id.filtered(lambda pl: not show_visible and pl.sudo().code)
pricelists |= all_pl.filtered(lambda pl: not show_visible and pl.sudo().code)
# This method is cached, must not return records! See also #8795
return pricelists.ids

View File

@ -18,9 +18,7 @@ access_account_tax_user,account.tax,account.model_account_tax,base.group_public,
access_product_image_public,product.image public,model_product_image,,1,0,0,0
access_product_image_publisher,product.image wbesite publisher,model_product_image,website.group_website_publisher,1,1,1,1
access_product_image_sale,product.image sale,model_product_image,sales_team.group_sale_manager,1,1,1,1
access_website_product_pricelist,access_website_product_pricelist,model_website_product_pricelist,,1,0,0,0
access_product_view_limit,access_product_view_limit,model_product_view_limit,,1,0,0,0
access_product_ribbon,product_ribbon,model_product_ribbon,,1,0,0,0
access_product_tags,access_product_tags,model_product_tags,,1,0,0,0
access_product_brand,access_product_brand,model_product_brand,,1,0,0,0
access_product_style,access_product_style,model_product_style,,1,0,0,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
18 access_product_image_public product.image public model_product_image 1 0 0 0
19 access_product_image_publisher product.image wbesite publisher model_product_image website.group_website_publisher 1 1 1 1
20 access_product_image_sale product.image sale model_product_image sales_team.group_sale_manager 1 1 1 1
access_website_product_pricelist access_website_product_pricelist model_website_product_pricelist 1 0 0 0
21 access_product_view_limit access_product_view_limit model_product_view_limit 1 0 0 0
22 access_product_ribbon product_ribbon model_product_ribbon 1 0 0 0
23 access_product_tags access_product_tags model_product_tags 1 0 0 0
24 access_product_brand access_product_brand model_product_brand 1 0 0 0
access_product_style access_product_style model_product_style 1 0 0 0

View File

@ -45,3 +45,29 @@
color: #666666 !important;
}
/* share Option end */
/* Categorized Shop Page START */
.main-categ{
display: block;
background: #e7e7e7;
padding: 5px;
margin-bottom: 5px;
font-weight: bold;
font-size: 16px;
color: @brand-primary;
&:hover {
text-decoration: none;
}
}
.child-categ {
padding: 7px 15px;
a {
text-decoration: underline;
color: #444;
&:hover {
color: @brand-primary;
}
}
}
/* Categorized Shop Page END */

View File

@ -19,33 +19,25 @@ class TestWebsitePriceList(TransactionCase):
self.website = self.env['website'].browse(1)
self.website.user_id = self.env.user
self.env['product.pricelist'].search([]).write({'website_id': False})
self.env['product.pricelist'].search([]).write({'website_ids': []})
website_pls = ('list_benelux', 'list_christmas', 'list_europe')
for pl in website_pls:
self.env['website.product.pricelist'].create({
'pricelist_id': self.env.ref('website_sale.' + pl).id,
'website_id': self.website.id,
'selectable': False if pl == 'list_christmas' else True
})
self.env['website.product.pricelist'].create({
'pricelist_id': self.env.ref('product.list0').id,
'website_id': self.website.id
})
self.env.ref('website_sale.' + pl).website_ids = [(6, 0, [self.website.id])]
self.env.ref('product.list0').website_ids = [(6, 0, [self.website.id])]
self.env.ref('website_sale.list_benelux').selectable = True
self.website.pricelist_id = self.ref('product.list0')
ca_group = self.env['res.country.group'].create({
'name': 'Canada',
'country_ids': [(6, 0, [self.ref('base.ca')])]
})
ppl = self.env['product.pricelist'].create({
self.env['product.pricelist'].create({
'name': 'Canada',
'selectable': True,
'website_ids': [(6, 0, [self.website.id])],
'country_group_ids': [(6, 0, [ca_group.id])],
'sequence': 10
})
self.env['website.product.pricelist'].create({
'pricelist_id': ppl.id,
'website_id': self.website.id
})
patcher = patch('flectra.addons.website_sale.models.website.Website.get_pricelist_available', wraps=self._get_pricelist_available)
patcher.start()
self.addCleanup(patcher.stop)
@ -126,7 +118,7 @@ class TestWebsitePriceList(TransactionCase):
country_list = {
False: ['USD', 'EUR', 'Benelux', 'Canada'],
'BE': ['EUR', 'Benelux'],
'IT': ['EUR'],
'IT': ['Benelux', 'USD', 'Canada'],
'CA': ['EUR', 'Canada'],
'US': ['USD', 'EUR', 'Benelux', 'Canada']
}

View File

@ -75,8 +75,8 @@
<field name="ribbon_id"/>
<field name="tag_ids" widget="many2many_tags"/>
<field name="brand_id" options="{'no_create': True}"/>
<field name="website_ids" widget="many2many_tags"/>
</group>
<field name="website_ids"/>
</group>
<button name="toggle_active" position="before">
<button class="oe_stat_button" name="website_publish_button"
@ -197,12 +197,20 @@
<field name="model">product.pricelist</field>
<field name="arch" type="xml">
<field name='currency_id' position='after'>
<field name="website_id" string='Allow to use on '>
<tree editable='bottom' string="Website Store">
<field name="website_id"/>
<field name="selectable"/>
</tree>
</field>
<field name="selectable"/>
<field name="website_ids" string='Allow to use on '
widget="many2many_tags"/>
</field>
</field>
</record>
<record id="website_sale_pricelist_tree_view" model="ir.ui.view">
<field name="name">product.pricelist.tree.inherit.product</field>
<field name="model">product.pricelist</field>
<field name="inherit_id" ref="product.product_pricelist_view_tree"/>
<field name="arch" type="xml">
<field name="currency_id" position="after">
<field name="selectable" />
</field>
</field>
</record>
@ -338,7 +346,6 @@
</field>
</record>
<!-- Product Brand Action -->
<record id="product_by_brand_action" model="ir.actions.act_window">
<field name="name">Brands</field>

View File

@ -131,11 +131,6 @@
action="base.action_partner_customer_form"
parent="menu_orders" sequence="4"/>
<!-- Product Limit Menu -->
<menuitem action="website_product_limit_action" id="menu_view_limit"
name="Website Product View Limit" parent="website_sale.menu_ecommerce_settings"/>
<!-- <menuitem id="menu_orders_invoices" name="Invoices" parent="menu_orders" action="action_invoices_ecommerce" sequence="4"/> -->
<!-- Catalog sub-menus -->
@ -156,11 +151,15 @@
<!-- Product Brands Menu -->
<menuitem action="product_by_brand_action" id="menu_product_by_brand"
parent="website_sale.menu_catalog"/>
name="Brands" parent="website_sale.menu_product_settings"/>
<!-- Product Tags Menu -->
<menuitem action="product_tags_action" id="menu_product_tags" name="Tags"
parent="website_sale.menu_catalog"/>
<menuitem action="product_tags_action" id="menu_product_tags"
name="Tags" parent="website_sale.menu_product_settings"/>
<!-- Product Limit Menu -->
<menuitem action="website_product_limit_action" id="menu_view_limit"
name="Product View Limit per Page" parent="website_sale.menu_ecommerce_settings"/>
<!-- Configuration sub-menus -->
<menuitem id="menu_ecommerce_payment_acquirers"

View File

@ -184,6 +184,11 @@
</div>
</template>
<!-- /shop Main Template -->
<template id="main_shop_page" name="Shop Page Variants (Use Any One)">
<t t-call="website_sale.products"/>
</template>
<!-- /shop product listing -->
<template id="products" name="Products">
<t t-call="website.layout">
@ -207,7 +212,7 @@
<t t-foreach="products" t-as="product">
<div id="grid_list"
class="col-md-4 oe_product oe_grid oe_product_cart oe-height-4"
t-attf-data-publish="#{product.website_published &amp; (not product.website_ids or website in product.website_ids) and 'on' or 'off'}">
t-att-data-publish="product.website_published and website in product.website_ids and 'on' or 'off'">
<t t-call="website_sale.products_item">
</t>
</div>
@ -229,6 +234,71 @@
</t>
</template>
<!-- /shop blank page (design your own shop page) -->
<template id="blank_shop_page" inherit_id="website_sale.main_shop_page"
name="Blank Shop Page" active="False" customize_show="True">
<xpath expr="//t[@t-call='website_sale.products']" position="replace">
<t t-if="category">
<t t-call="website_sale.products"/>
</t>
<t t-else="">
<t t-call="website.layout">
<t t-set="additional_title">Shop</t>
<div id="wrap" class="oe_structure oe_empty"/>
</t>
</t>
</xpath>
</template>
<!-- /shop category listing,
Supported to level-1 (Main Category & Child Category) -->
<template id="categorized_shop_page" inherit_id="website_sale.main_shop_page"
name="Categorized Shop Page" active="False" customize_show="True">
<xpath expr="//t[@t-call='website_sale.products']" position="replace">
<t t-if="category">
<t t-call="website_sale.products"/>
</t>
<t t-else="">
<t t-call="website.layout">
<t t-set="additional_title">Shop</t>
<div id="wrap">
<div class="oe_structure" />
<div class="container mt32 mb32 s_product_categories">
<div class="col-md-12" id="filter-cm">
<t t-foreach="categories" t-as="c">
<t t-call="website_sale.categories_recursive_snippet"/>
</t>
</div>
</div>
<div class="oe_structure" />
</div>
</t>
</t>
</xpath>
</template>
<!-- /shop category listing: Parent Category -->
<template id="categories_recursive_snippet" name="Category list">
<div class="col-md-6 mb16" t-if="website in c.website_ids or not c.website_ids">
<a t-att-href="keep('/shop/category/' + slug(c), category=0)" class="main-categ">
<span t-field="c.name"/>
<i class="fa fa-caret-right"/>
</a>
<div t-if="c.child_id">
<t t-foreach="c.child_id" t-as="c">
<t t-call="website_sale.categories_recursive_snippet_child"/>
</t>
</div>
</div>
</template>
<!-- /shop category listing: Child Category -->
<template id="categories_recursive_snippet_child" name="Category list">
<div class="col-md-6 child-categ" t-if="website in c.website_ids or not c.website_ids">
<a t-att-href="keep('/shop/category/' + slug(c), category=0)" t-field="c.name"/>
</div>
</template>
<template id="sort" inherit_id="website_sale.products" active="True" customize_show="True" name="Show Sort by">
<xpath expr="//div[hasclass('products_pager')]/div/t[@t-call][last()]" position="after">
<t t-set="new_arrivals_label">New Arrivals</t>
@ -411,7 +481,7 @@
<template id="products_list_view" inherit_id="website_sale.products" name="List View" active="False">
<xpath expr="//div[@id='products_grid']/t/div[@id='grid_list']" position="replace">
<div class="oe_product oe_list oe_product_cart"
t-attf-data-publish="#{product.website_published &amp; (not product.website_ids or website in product.website_ids) and 'on' or 'off'}">
t-att-data-publish="product.website_published and website in product.website_ids and 'on' or 'off'">
<t t-call="website_sale.products_item">
<t t-set="show_publish" t-value="True" />
</t>

View File

@ -2,5 +2,6 @@
<flectra>
<record id="delivery.free_delivery_carrier" model="delivery.carrier">
<field name="website_published" eval="True"/>
<field name="website_ids" eval="[(4, ref('website.default_website'))]"/>
</record>
</flectra>

View File

@ -8,7 +8,15 @@ class DeliveryCarrier(models.Model):
_name = 'delivery.carrier'
_inherit = ['delivery.carrier', 'website.published.mixin']
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
website_description = fields.Text(related='product_id.description_sale', string='Description for Online Quotations')
website_published = fields.Boolean(default=False)
website_ids = fields.Many2many('website', 'website_del_carrier_pub_rel', 'website_id', 'del_carrier_id', string='Websites', copy=False,
help='List of websites in which Product is published.')
website_ids = fields.Many2many('website', 'website_del_carrier_pub_rel',
'website_id', 'del_carrier_id',
default=_default_website,
string='Websites', copy=False,
help='List of websites in which Delivery '
'Carrier will published.')

View File

@ -73,8 +73,8 @@ class SaleOrder(models.Model):
def _get_delivery_methods(self):
address = self.partner_shipping_id
domain = self.env['website'].get_current_website()
return self.env['delivery.carrier'].sudo().search([('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', domain.id)]).available_carriers(address)
website = self.env['website'].get_current_website()
return self.env['delivery.carrier'].sudo().search([('website_published', '=', True), ('website_ids', 'in', website.id)]).available_carriers(address)
@api.multi
def _cart_update(self, product_id=None, line_id=None, add_qty=0, set_qty=0, **kwargs):

View File

@ -59,7 +59,7 @@ class WebsiteSlides(http.Controller):
"""
domain = []
if not request.env.user.has_group('website.group_website_designer'):
domain += ['|', ('website_ids', '=', False), ("website_ids", "in", request.website.id)]
domain += [("website_ids", "in", request.website.id)]
channels = request.env['slide.channel'].search(domain, order='sequence, id')
if not channels:
return request.render("website_slides.channel_not_found")
@ -98,7 +98,11 @@ class WebsiteSlides(http.Controller):
def channel(self, channel, category=None, tag=None, page=1, slide_type=None, sorting='creation', search=None, **kw):
user = request.env.user
Slide = request.env['slide.slide']
domain = [('channel_id', '=', channel.id)]
if not request.env.user.has_group('website.group_website_publisher') \
and request.website.id not in channel.website_ids.ids:
return request.render('website.404')
domain = [('channel_id', '=', channel.id),
('website_ids', 'in', request.website.id)]
pager_url = "/slides/%s" % (channel.id)
pager_args = {}

View File

@ -32,6 +32,10 @@ class Channel(models.Model):
'latest': 'date_published desc',
}
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
name = fields.Char('Name', translate=True, required=True)
active = fields.Boolean(default=True)
description = fields.Html('Description', translate=html_translate, sanitize_attributes=False)
@ -51,7 +55,7 @@ class Channel(models.Model):
@api.depends('custom_slide_id', 'promote_strategy', 'slide_ids.likes',
'slide_ids.total_views', "slide_ids.date_published")
def _compute_promoted_slide_id(self):
domain = self.env['website'].get_current_website()
website = self.env['website'].get_current_website()
for record in self:
if record.promote_strategy == 'none':
record.promoted_slide_id = False
@ -59,7 +63,7 @@ class Channel(models.Model):
record.promoted_slide_id = record.custom_slide_id
elif record.promote_strategy:
slides = self.env['slide.slide'].search(
[('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', domain.id), ('channel_id', '=', record.id)],
[('website_published', '=', True), ('website_ids', 'in', website.id), ('channel_id', '=', record.id)],
limit=1, order=self._order_by_strategy[record.promote_strategy])
record.promoted_slide_id = slides and slides[0] or False
@ -72,9 +76,9 @@ class Channel(models.Model):
@api.depends('slide_ids.slide_type', 'slide_ids.website_published')
def _count_presentations(self):
result = dict.fromkeys(self.ids, dict())
domain = self.env['website'].get_current_website()
website = self.env['website'].get_current_website()
res = self.env['slide.slide'].read_group(
[('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', domain.id), ('channel_id', 'in', self.ids)],
[('website_published', '=', True), ('website_ids', 'in', website.id), ('channel_id', 'in', self.ids)],
['channel_id', 'slide_type'], ['channel_id', 'slide_type'],
lazy=False)
for res_group in res:
@ -113,11 +117,12 @@ class Channel(models.Model):
can_see = fields.Boolean('Can See', compute='_compute_access', search='_search_can_see')
can_see_full = fields.Boolean('Full Access', compute='_compute_access')
can_upload = fields.Boolean('Can Upload', compute='_compute_access')
website_ids = fields.Many2many('website', 'website_slide_channel_pub_rel',
'website_id', 'slide_channel_id',
string='Websites', copy=False,
help='List of websites in which Slide channel is published.')
default=_default_website,
help='List of websites in which '
'Slide Channel will published.')
def _search_can_see(self, operator, value):
if operator not in ('=', '!=', '<>'):
@ -209,7 +214,7 @@ class Category(models.Model):
result = dict.fromkeys(self.ids, dict())
domain = self.env['website'].get_current_website()
res = self.env['slide.slide'].read_group(
[('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', domain.id), ('category_id', 'in', self.ids)],
[('website_published', '=', True), ('website_ids', 'in', domain.id), ('category_id', 'in', self.ids)],
['category_id', 'slide_type'], ['category_id', 'slide_type'],
lazy=False)
for res_group in res:
@ -282,6 +287,10 @@ class Slide(models.Model):
('name_uniq', 'UNIQUE(channel_id, name)', 'The slide name must be unique within a channel')
]
def _default_website(self):
default_website_id = self.env.ref('website.default_website')
return [default_website_id.id] if default_website_id else None
# description
name = fields.Char('Title', required=True, translate=True)
active = fields.Boolean(default=True)
@ -296,9 +305,12 @@ class Slide(models.Model):
image = fields.Binary('Image', attachment=True)
image_medium = fields.Binary('Medium', compute="_get_image", store=True, attachment=True)
image_thumb = fields.Binary('Thumbnail', compute="_get_image", store=True, attachment=True)
website_ids = fields.Many2many('website', 'website_slide_pub_rel', 'website_id', 'slide_id',
website_ids = fields.Many2many('website', 'website_slide_pub_rel',
'website_id', 'slide_id',
string='Websites', copy=False,
help='List of websites in which Slide is published.')
default=_default_website,
help='List of websites in which Slide '
'will published.')
@api.depends('image')
def _get_image(self):
@ -475,16 +487,16 @@ class Slide(models.Model):
return groups
def get_related_slides(self, limit=20):
domain = self.env['website'].get_current_website()
domain = [('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', domain.id), ('channel_id.visibility', '!=', 'private'), ('id', '!=', self.id)]
website = self.env['website'].get_current_website()
domain = [('website_published', '=', True), ('website_ids', 'in', website.id), ('channel_id.visibility', '!=', 'private'), ('id', '!=', self.id)]
if self.category_id:
domain += [('category_id', '=', self.category_id.id)]
for record in self.search(domain, limit=limit):
yield record
def get_most_viewed_slides(self, limit=20):
domain = self.env['website'].get_current_website()
for record in self.search([('website_published', '=', True), '|', ('website_ids', '=', False), ('website_ids', 'in', domain.id), ('channel_id.visibility', '!=', 'private'), ('id', '!=', self.id)], limit=limit, order='total_views desc'):
website = self.env['website'].get_current_website()
for record in self.search([('website_published', '=', True), ('website_ids', 'in', website.id), ('channel_id.visibility', '!=', 'private'), ('id', '!=', self.id)], limit=limit, order='total_views desc'):
yield record
def _post_publication(self):

View File

@ -39,7 +39,7 @@
<div class="row">
<t t-foreach="channels" t-as="channel">
<div t-if="channel_index % 3 == 0" class="clearfix"/>
<div class="col-sm-4 mb32" t-attf-data-publish="#{channel.website_published &amp; (not channel.website_ids or website in channel.website_ids) and 'on' or 'off'}">
<div class="col-sm-4 mb32" t-att-data-publish="channel.website_published and website in channel.website_ids and 'on' or 'off'">
<div class="well well-sm">
<div>
<a t-attf-href="/slides/#{slug(channel)}">

View File

@ -53,7 +53,9 @@ class ir_cron(models.Model):
cron_name = fields.Char('Name', related='ir_actions_server_id.name', store=True)
user_id = fields.Many2one('res.users', string='Scheduler User', default=lambda self: self.env.user, required=True)
active = fields.Boolean(default=True)
fail = fields.Boolean('Failer Log', default=True)
interval_number = fields.Integer(default=1, help="Repeat every x.")
total_fail = fields.Integer('Total Fail')
interval_type = fields.Selection([('minutes', 'Minutes'),
('hours', 'Hours'),
('days', 'Days'),
@ -76,14 +78,24 @@ class ir_cron(models.Model):
return True
@api.model
def _handle_callback_exception(self, cron_name, server_action_id, job_id, job_exception):
def _handle_callback_exception(self, cron_name, server_action_id, job_id, job_exception, cron_cr):
""" Method called when an exception is raised by a job.
Simply logs the exception and rollback the transaction. """
self._cr.rollback()
cron_id = self.browse(job_id)
if cron_id.fail:
self.env['ir.cronjob.logs'].create(
{'cron_status': 'fail',
'name': cron_id.name + ' - ' + str(datetime.now().date()),
'start_date': datetime.now(),
'log': str(job_exception)})
query = """UPDATE ir_cron set total_fail=%s where id=%s""" % (
(cron_id.total_fail or 0) + 1, cron_id.id)
cron_cr.execute(query)
@api.model
def _callback(self, cron_name, server_action_id, job_id):
def _callback(self, cron_name, server_action_id, job_id, cron_cr):
""" Run the method associated to a given job. It takes care of logging
and exception handling. Note that the user running the server action
is the user calling this method. """
@ -107,7 +119,7 @@ class ir_cron(models.Model):
self.pool.reset_changes()
_logger.exception("Call from cron %s for server action #%s failed in Job #%s",
cron_name, server_action_id, job_id)
self._handle_callback_exception(cron_name, server_action_id, job_id, e)
self._handle_callback_exception(cron_name, server_action_id, job_id, e, cron_cr)
@classmethod
def _process_job(cls, job_cr, job, cron_cr):
@ -134,7 +146,7 @@ class ir_cron(models.Model):
if numbercall > 0:
numbercall -= 1
if not ok or job['doall']:
cron._callback(job['cron_name'], job['ir_actions_server_id'], job['id'])
cron._callback(job['cron_name'], job['ir_actions_server_id'], job['id'], cron_cr)
if numbercall:
nextcall += _intervalTypes[job['interval_type']](job['interval_number'])
ok = True
@ -309,3 +321,15 @@ class ir_cron(models.Model):
def toggle(self, model, domain):
active = bool(self.env[model].search_count(domain))
return self.try_write({'active': active})
class ScheduledLogs(models.Model):
_name = 'ir.cronjob.logs'
name = fields.Char("Name", readonly=True, track_visibility='always')
object_name = fields.Char(string="Object", readonly=True, track_visibility='always')
start_date = fields.Datetime("Start Date", readonly=True)
cron_id = fields.Many2one("ir.cron", "Cron", readonly=True, track_visibility='always')
cron_status = fields.Selection([('fail', 'Fail'), ('success', 'Success')],
'Status', readonly=True)
log = fields.Text("Logs", readonly=True, track_visibility='always')

View File

@ -32,6 +32,10 @@
<field name="priority"/>
<field name="doall"/>
</group>
<group>
<field name="fail"/>
<field name="total_fail"/>
</group>
</xpath>
</field>
</record>
@ -86,4 +90,53 @@
</record>
<menuitem id="menu_ir_cron_act" action="ir_cron_act" parent="base.menu_automation"/>
<record id="cronlogs_form_view" model="ir.ui.view">
<field name="name">ir.cronjob.logs.form</field>
<field name="model">ir.cronjob.logs</field>
<field name="mode">primary</field>
<field name="arch" type="xml">
<form string="Logs">
<sheet string="Logs">
<group>
<group>
<field name="name"/>
</group>
<group>
<field name="start_date"/>
<field name="cron_status"/>
</group>
</group>
<notebook>
<page string="Error Log">
<field name="log"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.ui.view" id="cronjob_tree_view">
<field name="name">ir.cronjob.logs.tree</field>
<field name="model">ir.cronjob.logs</field>
<field name="arch" type="xml">
<tree string="Logs">
<field name="name"/>
<field name="start_date"/>
<field name="cron_status"/>
</tree>
</field>
</record>
<record id="ir_cronjob_act_logs" model="ir.actions.act_window">
<field name="name">Scheduled Logs</field>
<field name="res_model">ir.cronjob.logs</field>
<field name="view_type">form</field>
<field name="view_mode">form,tree</field>
<field name="view_id" ref="cronjob_tree_view"/>
</record>
<menuitem id="menu_ir_cronjob_logs" action="ir_cronjob_act_logs" parent="base.menu_automation"/>
</flectra>

View File

@ -149,6 +149,7 @@ class IrMailServer(models.Model):
sequence = fields.Integer(string='Priority', default=10, help="When no specific mail server is requested for a mail, the highest priority one "
"is used. Default priority is 10 (smaller number = higher priority)")
active = fields.Boolean(default=True)
keep_days = fields.Integer('Keep days', default=-1)
@api.multi
def name_get(self):

View File

@ -14,6 +14,7 @@
<field name="smtp_host"/>
<field name="smtp_port"/>
<field name="smtp_debug" groups="base.group_no_one"/>
<field name="keep_days"/>
</group>
<group string="Security and Authentication" colspan="4">
<field name="smtp_encryption"/>

View File

@ -1,100 +1,101 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_ir_attachment_all","ir_attachment all","model_ir_attachment",,1,0,0,0
"access_ir_attachment_group_user","ir_attachment group_user","model_ir_attachment","group_user",1,1,1,1
"access_ir_attachment_portal","ir.attachment.portal","model_ir_attachment","group_portal",1,0,1,0
"access_ir_cron_group_cron","ir_cron group_cron","model_ir_cron","group_system",1,1,1,1
"access_ir_exports_group_system","ir_exports group_system","model_ir_exports","base.group_user",1,1,1,1
"access_ir_exports_line_group_system","ir_exports_line group_system","model_ir_exports_line","base.group_user",1,1,1,1
"access_ir_model_group_erp_manager","ir_model group_erp_manager","model_ir_model","group_erp_manager",1,1,1,1
"access_ir_model_constraint_group_erp_manager","ir_model_constraint group_erp_manager","model_ir_model_constraint","group_erp_manager",1,1,1,1
"access_ir_model_relation_group_erp_manager","ir_model_relation group_erp_manager","model_ir_model_relation","group_erp_manager",1,1,1,1
"access_ir_model_access_group_erp_manager","ir_model_access_group_erp_manager","model_ir_model_access","group_erp_manager",1,1,1,1
"access_ir_model_data_group_erp_manager","ir_model_data group_erp_manager","model_ir_model_data","group_erp_manager",1,1,1,1
"access_ir_model_fields_group_erp_manager","ir_model_fields group_erp_manager","model_ir_model_fields","group_erp_manager",1,1,1,1
"access_ir_model_user","ir_model_all","model_ir_model",base.group_user,1,0,0,0
"access_ir_model_data_user","ir_model_data user","model_ir_model_data",base.group_user,1,0,1,0
"access_ir_model_fields_user","ir_model_fields all","model_ir_model_fields",base.group_user,1,0,0,0
"access_ir_module_category_group_user","ir_module_category group_user","model_ir_module_category","group_erp_manager",1,0,0,0
"access_ir_module_module_group_user","ir_module_module group_user","model_ir_module_module","group_system",1,1,1,1
"access_ir_module_module_dependency_group_system","ir_module_module_dependency group_system","model_ir_module_module_dependency","group_system",1,1,1,1
"access_ir_module_module_exclusion_group_system","ir_module_module_exclusion group_system","model_ir_module_module_exclusion","group_system",1,1,1,1
"access_ir_property_group_user","ir_property group_user","model_ir_property",,1,0,0,0
"access_ir_property_group_user_manager","ir_property group_manager","model_ir_property","base.group_partner_manager",1,1,1,0
"access_ir_rule_group_erp_manager","ir_rule group_erp_manager","model_ir_rule","group_erp_manager",1,1,1,1
"access_ir_sequence_group_user","ir_sequence group_user","model_ir_sequence","group_user",1,0,0,0
"access_ir_sequence_group_system","ir_sequence group_system","model_ir_sequence","group_system",1,1,1,1
"access_ir_sequence_date_range_group_user","ir_sequence_date_range group_user","model_ir_sequence_date_range","group_user",1,0,0,0
"access_ir_sequence_date_range_group_system","ir_sequence_date_range group_system","model_ir_sequence_date_range","group_system",1,1,1,1
"access_ir_translation_all","ir_translation all","model_ir_translation","group_user",1,1,1,1
"access_ir_translation_group_system","ir_translation group_system","model_ir_translation","group_system",1,1,1,1
"access_ir_ui_menu_group_user","ir_ui_menu group_user","model_ir_ui_menu",base.group_user,1,0,0,0
"access_ir_ui_menu_group_system","ir_ui_menu group_system","model_ir_ui_menu","group_system",1,1,1,1
"access_ir_ui_view_group_user","ir_ui_view group_user","model_ir_ui_view",,1,0,0,0
"access_ir_ui_view_group_system","ir_ui_view group_system","model_ir_ui_view","group_system",1,1,1,1
"access_ir_ui_view_custom_group_user","ir_ui_view_custom_group_user","model_ir_ui_view_custom",,1,1,1,1
"access_ir_default_all","ir_default all","model_ir_default",,1,0,0,0
"access_ir_default_group_user","ir_default group_user","model_ir_default","group_user",1,1,1,1
"access_ir_default_group_system","ir_default group_system","model_ir_default","group_system",1,1,1,1
"access_res_company_group_erp_manager","res_company group_erp_manager","model_res_company","group_erp_manager",1,1,1,1
"access_res_company_group_user","res_company group_user","model_res_company",,1,0,0,0
"access_res_country_group_all","res_country group_user_all","model_res_country",,1,0,0,0
"access_res_country_state_group_all","res_country_state group_user_all","model_res_country_state",,1,0,0,0
"access_res_country_group_group_all","res_country_group group_user_all","model_res_country_group",,1,0,0,0
"access_res_country_group_user","res_country group_user","model_res_country","group_partner_manager",1,1,1,1
"access_res_country_state_group_user","res_country_state group_user","model_res_country_state","group_partner_manager",1,1,1,1
"access_res_country_group_group_user","res_country_group group_user","model_res_country_group","group_partner_manager",1,1,1,1
"access_res_currency_group_all","res_currency group_all","model_res_currency",,1,0,0,0
"access_res_currency_rate_group_all","res_currency_rate group_all","model_res_currency_rate",,1,0,0,0
"access_res_currency_group_system","res_currency group_system","model_res_currency","group_system",1,1,1,1
"access_res_currency_rate_group_system","res_currency_rate group_system","model_res_currency_rate","group_system",1,1,1,1
"access_res_groups_group_erp_manager","res_groups group_erp_manager","model_res_groups","group_erp_manager",1,1,1,1
"access_res_groups_group_user","res_groups group_user","model_res_groups",group_user,1,0,0,0
"access_res_lang_group_all","res_lang group_all","model_res_lang",,1,0,0,0
"access_res_lang_group_user","res_lang group_user","model_res_lang","group_system",1,1,1,1
"access_res_partner_public","res_partner group_public","model_res_partner","group_public",1,0,0,0
"access_res_partner_portal","res_partner group_portal","model_res_partner","group_portal",1,0,0,0
"access_res_partner_group_partner_manager","res_partner group_partner_manager","model_res_partner","group_partner_manager",1,1,1,1
"access_res_partner_group_user","res_partner group_user","model_res_partner","group_user",1,0,0,0
"access_res_partner_bank_group_user","res_partner_bank group_user","model_res_partner_bank","group_user",1,0,0,0
"access_res_partner_bank_group_partner_manager","res_partner_bank group_partner_manager","model_res_partner_bank","group_partner_manager",1,1,1,1
"access_res_partner_category_group_user","res_partner_category group_user","model_res_partner_category","group_user",1,0,0,0
"access_res_partner_category_group_partner_manager","res_partner_category group_partner_manager","model_res_partner_category","group_partner_manager",1,1,1,1
"access_res_partner_industry_group_user","res_partner_industry group_user","model_res_partner_industry","group_user",1,0,0,0
"access_res_partner_industry_group_system","res_partner_industry group_system","model_res_partner_industry","group_system",1,1,1,1
"access_res_partner_title_group_user","res_partner_title group_user","model_res_partner_title","group_partner_manager",1,1,1,1
"access_res_partner_title_group_partner_manager","res_partner_title group_partner_manager","model_res_partner_title",,1,0,0,0
"access_res_request_link_group_system","res_request_link group_system","model_res_request_link","group_system",1,1,1,1
"access_res_request_link_group_user","res_request_link group_user","model_res_request_link",,1,0,0,0
"access_res_users_all","res_users all","model_res_users",,1,0,0,0
"access_res_users_group_erp_manager","res_users group_erp_manager","model_res_users","group_erp_manager",1,1,1,1
"access_res_users_log_all","res_users_log_all","model_res_users_log",,1,0,1,0
"access_ir_actions_all","ir_actions_all","model_ir_actions_actions",,1,0,0,0
"access_ir_actions_group_system","ir_actions_group_system","model_ir_actions_actions","group_system",1,1,1,1
"access_ir_actions_act_window_all","ir_actions_act_window_all","model_ir_actions_act_window",,1,0,0,0
"access_ir_actions_act_window_system","ir_actions_act_window_system","model_ir_actions_act_window","group_system",1,1,1,1
"access_ir_actions_act_window_close_all","ir_actions_act_window_close_all","model_ir_actions_act_window_close",,1,0,0,0
"access_ir_actions_act_window_close_group_system","ir_actions_act_window_close_group_system","model_ir_actions_act_window_close","group_system",1,1,1,1
"access_ir_actions_report_all","ir_actions_report","model_ir_actions_report",,1,0,0,0
"access_ir_actions_report_group_system","ir_actions_report_group_system","model_ir_actions_report","group_system",1,1,1,1
"access_ir_actions_todo_group_system","ir_actions_todo group system","model_ir_actions_todo","group_system",1,1,1,1
"access_ir_actions_act_window_view_all","ir_actions_act_window_view_all","model_ir_actions_act_window_view",,1,0,0,0
"access_ir_actions_act_window_view_group_system","ir_actions_act_window_view_group_system","model_ir_actions_act_window_view","group_system",1,1,1,1
"access_ir_actions_act_url_all","ir_actions_act_url_all","model_ir_actions_act_url",,1,0,0,0
"access_ir_actions_act_url_group_system","ir_actions_act_url_group_system","model_ir_actions_act_url","group_system",1,1,1,1
"access_ir_server_object_lines_all","ir_server_object_lines_all","model_ir_server_object_lines",,1,0,0,0
"access_ir_server_object_lines_group_system","ir_server_object_lines_group_system","model_ir_server_object_lines","group_system",1,1,1,1
"access_ir_actions_server_all","ir_actions_server_all","model_ir_actions_server",,1,0,0,0
"access_ir_actions_server_group_system","ir_actions_server_group_system","model_ir_actions_server","group_system",1,1,1,1
"access_res_bank_group_system","res_bank_group_system","model_res_bank","group_system",1,1,1,1
"access_res_bank_group_partner_manager","res_bank_group_partner_manager","model_res_bank","group_partner_manager",1,1,1,1
"access_res_bank_user","res_bank user","model_res_bank","group_user",1,0,0,0
"access_ir_filter_erp_manager","ir_filters all","model_ir_filters","group_erp_manager",1,1,1,1
"access_ir_filter_user","ir_filters all","model_ir_filters","group_user",1,1,1,1
"access_ir_filter_portal","ir_filters all","model_ir_filters","group_portal",1,1,1,1
"access_ir_filter_public","ir_filters all","model_ir_filters","group_public",1,1,1,1
"access_ir_config_parameter_system","ir_config_parameter_system","model_ir_config_parameter","group_system",1,1,1,1
"access_ir_mail_server","ir_mail_server","model_ir_mail_server","group_system",1,1,1,1
"access_ir_actions_client","ir_actions_client all","model_ir_actions_client",,1,0,0,0
"access_ir_logging","ir_logging admin","model_ir_logging","group_erp_manager",1,1,1,1
"paperformat_access_portal","ir_actions_report_paperformat group_portal","model_report_paperformat",,1,0,0,0
"paperformat_access_employee","ir_actions_report_paperformat group_hr_user","model_report_paperformat",,1,0,1,0
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_ir_attachment_all,ir_attachment all,model_ir_attachment,,1,0,0,0
access_ir_attachment_group_user,ir_attachment group_user,model_ir_attachment,group_user,1,1,1,1
access_ir_attachment_portal,ir.attachment.portal,model_ir_attachment,group_portal,1,0,1,0
access_ir_cron_group_cron,ir_cron group_cron,model_ir_cron,group_system,1,1,1,1
access_ir_exports_group_system,ir_exports group_system,model_ir_exports,base.group_user,1,1,1,1
access_ir_exports_line_group_system,ir_exports_line group_system,model_ir_exports_line,base.group_user,1,1,1,1
access_ir_model_group_erp_manager,ir_model group_erp_manager,model_ir_model,group_erp_manager,1,1,1,1
access_ir_model_constraint_group_erp_manager,ir_model_constraint group_erp_manager,model_ir_model_constraint,group_erp_manager,1,1,1,1
access_ir_model_relation_group_erp_manager,ir_model_relation group_erp_manager,model_ir_model_relation,group_erp_manager,1,1,1,1
access_ir_model_access_group_erp_manager,ir_model_access_group_erp_manager,model_ir_model_access,group_erp_manager,1,1,1,1
access_ir_model_data_group_erp_manager,ir_model_data group_erp_manager,model_ir_model_data,group_erp_manager,1,1,1,1
access_ir_model_fields_group_erp_manager,ir_model_fields group_erp_manager,model_ir_model_fields,group_erp_manager,1,1,1,1
access_ir_model_user,ir_model_all,model_ir_model,base.group_user,1,0,0,0
access_ir_model_data_user,ir_model_data user,model_ir_model_data,base.group_user,1,0,1,0
access_ir_model_fields_user,ir_model_fields all,model_ir_model_fields,base.group_user,1,0,0,0
access_ir_module_category_group_user,ir_module_category group_user,model_ir_module_category,group_erp_manager,1,0,0,0
access_ir_module_module_group_user,ir_module_module group_user,model_ir_module_module,group_system,1,1,1,1
access_ir_module_module_dependency_group_system,ir_module_module_dependency group_system,model_ir_module_module_dependency,group_system,1,1,1,1
access_ir_module_module_exclusion_group_system,ir_module_module_exclusion group_system,model_ir_module_module_exclusion,group_system,1,1,1,1
access_ir_property_group_user,ir_property group_user,model_ir_property,,1,0,0,0
access_ir_property_group_user_manager,ir_property group_manager,model_ir_property,base.group_partner_manager,1,1,1,0
access_ir_rule_group_erp_manager,ir_rule group_erp_manager,model_ir_rule,group_erp_manager,1,1,1,1
access_ir_sequence_group_user,ir_sequence group_user,model_ir_sequence,group_user,1,0,0,0
access_ir_sequence_group_system,ir_sequence group_system,model_ir_sequence,group_system,1,1,1,1
access_ir_sequence_date_range_group_user,ir_sequence_date_range group_user,model_ir_sequence_date_range,group_user,1,0,0,0
access_ir_sequence_date_range_group_system,ir_sequence_date_range group_system,model_ir_sequence_date_range,group_system,1,1,1,1
access_ir_translation_all,ir_translation all,model_ir_translation,group_user,1,1,1,1
access_ir_translation_group_system,ir_translation group_system,model_ir_translation,group_system,1,1,1,1
access_ir_ui_menu_group_user,ir_ui_menu group_user,model_ir_ui_menu,base.group_user,1,0,0,0
access_ir_ui_menu_group_system,ir_ui_menu group_system,model_ir_ui_menu,group_system,1,1,1,1
access_ir_ui_view_group_user,ir_ui_view group_user,model_ir_ui_view,,1,0,0,0
access_ir_ui_view_group_system,ir_ui_view group_system,model_ir_ui_view,group_system,1,1,1,1
access_ir_ui_view_custom_group_user,ir_ui_view_custom_group_user,model_ir_ui_view_custom,,1,1,1,1
access_ir_default_all,ir_default all,model_ir_default,,1,0,0,0
access_ir_default_group_user,ir_default group_user,model_ir_default,group_user,1,1,1,1
access_ir_default_group_system,ir_default group_system,model_ir_default,group_system,1,1,1,1
access_res_company_group_erp_manager,res_company group_erp_manager,model_res_company,group_erp_manager,1,1,1,1
access_res_company_group_user,res_company group_user,model_res_company,,1,0,0,0
access_res_country_group_all,res_country group_user_all,model_res_country,,1,0,0,0
access_res_country_state_group_all,res_country_state group_user_all,model_res_country_state,,1,0,0,0
access_res_country_group_group_all,res_country_group group_user_all,model_res_country_group,,1,0,0,0
access_res_country_group_user,res_country group_user,model_res_country,group_partner_manager,1,1,1,1
access_res_country_state_group_user,res_country_state group_user,model_res_country_state,group_partner_manager,1,1,1,1
access_res_country_group_group_user,res_country_group group_user,model_res_country_group,group_partner_manager,1,1,1,1
access_res_currency_group_all,res_currency group_all,model_res_currency,,1,0,0,0
access_res_currency_rate_group_all,res_currency_rate group_all,model_res_currency_rate,,1,0,0,0
access_res_currency_group_system,res_currency group_system,model_res_currency,group_system,1,1,1,1
access_res_currency_rate_group_system,res_currency_rate group_system,model_res_currency_rate,group_system,1,1,1,1
access_res_groups_group_erp_manager,res_groups group_erp_manager,model_res_groups,group_erp_manager,1,1,1,1
access_res_groups_group_user,res_groups group_user,model_res_groups,group_user,1,0,0,0
access_res_lang_group_all,res_lang group_all,model_res_lang,,1,0,0,0
access_res_lang_group_user,res_lang group_user,model_res_lang,group_system,1,1,1,1
access_res_partner_public,res_partner group_public,model_res_partner,group_public,1,0,0,0
access_res_partner_portal,res_partner group_portal,model_res_partner,group_portal,1,0,0,0
access_res_partner_group_partner_manager,res_partner group_partner_manager,model_res_partner,group_partner_manager,1,1,1,1
access_res_partner_group_user,res_partner group_user,model_res_partner,group_user,1,0,0,0
access_res_partner_bank_group_user,res_partner_bank group_user,model_res_partner_bank,group_user,1,0,0,0
access_res_partner_bank_group_partner_manager,res_partner_bank group_partner_manager,model_res_partner_bank,group_partner_manager,1,1,1,1
access_res_partner_category_group_user,res_partner_category group_user,model_res_partner_category,group_user,1,0,0,0
access_res_partner_category_group_partner_manager,res_partner_category group_partner_manager,model_res_partner_category,group_partner_manager,1,1,1,1
access_res_partner_industry_group_user,res_partner_industry group_user,model_res_partner_industry,group_user,1,0,0,0
access_res_partner_industry_group_system,res_partner_industry group_system,model_res_partner_industry,group_system,1,1,1,1
access_res_partner_title_group_user,res_partner_title group_user,model_res_partner_title,group_partner_manager,1,1,1,1
access_res_partner_title_group_partner_manager,res_partner_title group_partner_manager,model_res_partner_title,,1,0,0,0
access_res_request_link_group_system,res_request_link group_system,model_res_request_link,group_system,1,1,1,1
access_res_request_link_group_user,res_request_link group_user,model_res_request_link,,1,0,0,0
access_res_users_all,res_users all,model_res_users,,1,0,0,0
access_res_users_group_erp_manager,res_users group_erp_manager,model_res_users,group_erp_manager,1,1,1,1
access_res_users_log_all,res_users_log_all,model_res_users_log,,1,0,1,0
access_ir_actions_all,ir_actions_all,model_ir_actions_actions,,1,0,0,0
access_ir_actions_group_system,ir_actions_group_system,model_ir_actions_actions,group_system,1,1,1,1
access_ir_actions_act_window_all,ir_actions_act_window_all,model_ir_actions_act_window,,1,0,0,0
access_ir_actions_act_window_system,ir_actions_act_window_system,model_ir_actions_act_window,group_system,1,1,1,1
access_ir_actions_act_window_close_all,ir_actions_act_window_close_all,model_ir_actions_act_window_close,,1,0,0,0
access_ir_actions_act_window_close_group_system,ir_actions_act_window_close_group_system,model_ir_actions_act_window_close,group_system,1,1,1,1
access_ir_actions_report_all,ir_actions_report,model_ir_actions_report,,1,0,0,0
access_ir_actions_report_group_system,ir_actions_report_group_system,model_ir_actions_report,group_system,1,1,1,1
access_ir_actions_todo_group_system,ir_actions_todo group system,model_ir_actions_todo,group_system,1,1,1,1
access_ir_actions_act_window_view_all,ir_actions_act_window_view_all,model_ir_actions_act_window_view,,1,0,0,0
access_ir_actions_act_window_view_group_system,ir_actions_act_window_view_group_system,model_ir_actions_act_window_view,group_system,1,1,1,1
access_ir_actions_act_url_all,ir_actions_act_url_all,model_ir_actions_act_url,,1,0,0,0
access_ir_actions_act_url_group_system,ir_actions_act_url_group_system,model_ir_actions_act_url,group_system,1,1,1,1
access_ir_server_object_lines_all,ir_server_object_lines_all,model_ir_server_object_lines,,1,0,0,0
access_ir_server_object_lines_group_system,ir_server_object_lines_group_system,model_ir_server_object_lines,group_system,1,1,1,1
access_ir_actions_server_all,ir_actions_server_all,model_ir_actions_server,,1,0,0,0
access_ir_actions_server_group_system,ir_actions_server_group_system,model_ir_actions_server,group_system,1,1,1,1
access_res_bank_group_system,res_bank_group_system,model_res_bank,group_system,1,1,1,1
access_res_bank_group_partner_manager,res_bank_group_partner_manager,model_res_bank,group_partner_manager,1,1,1,1
access_res_bank_user,res_bank user,model_res_bank,group_user,1,0,0,0
access_ir_filter_erp_manager,ir_filters all,model_ir_filters,group_erp_manager,1,1,1,1
access_ir_filter_user,ir_filters all,model_ir_filters,group_user,1,1,1,1
access_ir_filter_portal,ir_filters all,model_ir_filters,group_portal,1,1,1,1
access_ir_filter_public,ir_filters all,model_ir_filters,group_public,1,1,1,1
access_ir_config_parameter_system,ir_config_parameter_system,model_ir_config_parameter,group_system,1,1,1,1
access_ir_mail_server,ir_mail_server,model_ir_mail_server,group_system,1,1,1,1
access_ir_actions_client,ir_actions_client all,model_ir_actions_client,,1,0,0,0
access_ir_logging,ir_logging admin,model_ir_logging,group_erp_manager,1,1,1,1
paperformat_access_portal,ir_actions_report_paperformat group_portal,model_report_paperformat,,1,0,0,0
paperformat_access_employee,ir_actions_report_paperformat group_hr_user,model_report_paperformat,,1,0,1,0
access_ir_cronjob_logs,access_ir_cronjob_logs,model_ir_cronjob_logs,group_system,1,1,1,1

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_ir_attachment_all ir_attachment all model_ir_attachment 1 0 0 0
3 access_ir_attachment_group_user ir_attachment group_user model_ir_attachment group_user 1 1 1 1
4 access_ir_attachment_portal ir.attachment.portal model_ir_attachment group_portal 1 0 1 0
5 access_ir_cron_group_cron ir_cron group_cron model_ir_cron group_system 1 1 1 1
6 access_ir_exports_group_system ir_exports group_system model_ir_exports base.group_user 1 1 1 1
7 access_ir_exports_line_group_system ir_exports_line group_system model_ir_exports_line base.group_user 1 1 1 1
8 access_ir_model_group_erp_manager ir_model group_erp_manager model_ir_model group_erp_manager 1 1 1 1
9 access_ir_model_constraint_group_erp_manager ir_model_constraint group_erp_manager model_ir_model_constraint group_erp_manager 1 1 1 1
10 access_ir_model_relation_group_erp_manager ir_model_relation group_erp_manager model_ir_model_relation group_erp_manager 1 1 1 1
11 access_ir_model_access_group_erp_manager ir_model_access_group_erp_manager model_ir_model_access group_erp_manager 1 1 1 1
12 access_ir_model_data_group_erp_manager ir_model_data group_erp_manager model_ir_model_data group_erp_manager 1 1 1 1
13 access_ir_model_fields_group_erp_manager ir_model_fields group_erp_manager model_ir_model_fields group_erp_manager 1 1 1 1
14 access_ir_model_user ir_model_all model_ir_model base.group_user 1 0 0 0
15 access_ir_model_data_user ir_model_data user model_ir_model_data base.group_user 1 0 1 0
16 access_ir_model_fields_user ir_model_fields all model_ir_model_fields base.group_user 1 0 0 0
17 access_ir_module_category_group_user ir_module_category group_user model_ir_module_category group_erp_manager 1 0 0 0
18 access_ir_module_module_group_user ir_module_module group_user model_ir_module_module group_system 1 1 1 1
19 access_ir_module_module_dependency_group_system ir_module_module_dependency group_system model_ir_module_module_dependency group_system 1 1 1 1
20 access_ir_module_module_exclusion_group_system ir_module_module_exclusion group_system model_ir_module_module_exclusion group_system 1 1 1 1
21 access_ir_property_group_user ir_property group_user model_ir_property 1 0 0 0
22 access_ir_property_group_user_manager ir_property group_manager model_ir_property base.group_partner_manager 1 1 1 0
23 access_ir_rule_group_erp_manager ir_rule group_erp_manager model_ir_rule group_erp_manager 1 1 1 1
24 access_ir_sequence_group_user ir_sequence group_user model_ir_sequence group_user 1 0 0 0
25 access_ir_sequence_group_system ir_sequence group_system model_ir_sequence group_system 1 1 1 1
26 access_ir_sequence_date_range_group_user ir_sequence_date_range group_user model_ir_sequence_date_range group_user 1 0 0 0
27 access_ir_sequence_date_range_group_system ir_sequence_date_range group_system model_ir_sequence_date_range group_system 1 1 1 1
28 access_ir_translation_all ir_translation all model_ir_translation group_user 1 1 1 1
29 access_ir_translation_group_system ir_translation group_system model_ir_translation group_system 1 1 1 1
30 access_ir_ui_menu_group_user ir_ui_menu group_user model_ir_ui_menu base.group_user 1 0 0 0
31 access_ir_ui_menu_group_system ir_ui_menu group_system model_ir_ui_menu group_system 1 1 1 1
32 access_ir_ui_view_group_user ir_ui_view group_user model_ir_ui_view 1 0 0 0
33 access_ir_ui_view_group_system ir_ui_view group_system model_ir_ui_view group_system 1 1 1 1
34 access_ir_ui_view_custom_group_user ir_ui_view_custom_group_user model_ir_ui_view_custom 1 1 1 1
35 access_ir_default_all ir_default all model_ir_default 1 0 0 0
36 access_ir_default_group_user ir_default group_user model_ir_default group_user 1 1 1 1
37 access_ir_default_group_system ir_default group_system model_ir_default group_system 1 1 1 1
38 access_res_company_group_erp_manager res_company group_erp_manager model_res_company group_erp_manager 1 1 1 1
39 access_res_company_group_user res_company group_user model_res_company 1 0 0 0
40 access_res_country_group_all res_country group_user_all model_res_country 1 0 0 0
41 access_res_country_state_group_all res_country_state group_user_all model_res_country_state 1 0 0 0
42 access_res_country_group_group_all res_country_group group_user_all model_res_country_group 1 0 0 0
43 access_res_country_group_user res_country group_user model_res_country group_partner_manager 1 1 1 1
44 access_res_country_state_group_user res_country_state group_user model_res_country_state group_partner_manager 1 1 1 1
45 access_res_country_group_group_user res_country_group group_user model_res_country_group group_partner_manager 1 1 1 1
46 access_res_currency_group_all res_currency group_all model_res_currency 1 0 0 0
47 access_res_currency_rate_group_all res_currency_rate group_all model_res_currency_rate 1 0 0 0
48 access_res_currency_group_system res_currency group_system model_res_currency group_system 1 1 1 1
49 access_res_currency_rate_group_system res_currency_rate group_system model_res_currency_rate group_system 1 1 1 1
50 access_res_groups_group_erp_manager res_groups group_erp_manager model_res_groups group_erp_manager 1 1 1 1
51 access_res_groups_group_user res_groups group_user model_res_groups group_user 1 0 0 0
52 access_res_lang_group_all res_lang group_all model_res_lang 1 0 0 0
53 access_res_lang_group_user res_lang group_user model_res_lang group_system 1 1 1 1
54 access_res_partner_public res_partner group_public model_res_partner group_public 1 0 0 0
55 access_res_partner_portal res_partner group_portal model_res_partner group_portal 1 0 0 0
56 access_res_partner_group_partner_manager res_partner group_partner_manager model_res_partner group_partner_manager 1 1 1 1
57 access_res_partner_group_user res_partner group_user model_res_partner group_user 1 0 0 0
58 access_res_partner_bank_group_user res_partner_bank group_user model_res_partner_bank group_user 1 0 0 0
59 access_res_partner_bank_group_partner_manager res_partner_bank group_partner_manager model_res_partner_bank group_partner_manager 1 1 1 1
60 access_res_partner_category_group_user res_partner_category group_user model_res_partner_category group_user 1 0 0 0
61 access_res_partner_category_group_partner_manager res_partner_category group_partner_manager model_res_partner_category group_partner_manager 1 1 1 1
62 access_res_partner_industry_group_user res_partner_industry group_user model_res_partner_industry group_user 1 0 0 0
63 access_res_partner_industry_group_system res_partner_industry group_system model_res_partner_industry group_system 1 1 1 1
64 access_res_partner_title_group_user res_partner_title group_user model_res_partner_title group_partner_manager 1 1 1 1
65 access_res_partner_title_group_partner_manager res_partner_title group_partner_manager model_res_partner_title 1 0 0 0
66 access_res_request_link_group_system res_request_link group_system model_res_request_link group_system 1 1 1 1
67 access_res_request_link_group_user res_request_link group_user model_res_request_link 1 0 0 0
68 access_res_users_all res_users all model_res_users 1 0 0 0
69 access_res_users_group_erp_manager res_users group_erp_manager model_res_users group_erp_manager 1 1 1 1
70 access_res_users_log_all res_users_log_all model_res_users_log 1 0 1 0
71 access_ir_actions_all ir_actions_all model_ir_actions_actions 1 0 0 0
72 access_ir_actions_group_system ir_actions_group_system model_ir_actions_actions group_system 1 1 1 1
73 access_ir_actions_act_window_all ir_actions_act_window_all model_ir_actions_act_window 1 0 0 0
74 access_ir_actions_act_window_system ir_actions_act_window_system model_ir_actions_act_window group_system 1 1 1 1
75 access_ir_actions_act_window_close_all ir_actions_act_window_close_all model_ir_actions_act_window_close 1 0 0 0
76 access_ir_actions_act_window_close_group_system ir_actions_act_window_close_group_system model_ir_actions_act_window_close group_system 1 1 1 1
77 access_ir_actions_report_all ir_actions_report model_ir_actions_report 1 0 0 0
78 access_ir_actions_report_group_system ir_actions_report_group_system model_ir_actions_report group_system 1 1 1 1
79 access_ir_actions_todo_group_system ir_actions_todo group system model_ir_actions_todo group_system 1 1 1 1
80 access_ir_actions_act_window_view_all ir_actions_act_window_view_all model_ir_actions_act_window_view 1 0 0 0
81 access_ir_actions_act_window_view_group_system ir_actions_act_window_view_group_system model_ir_actions_act_window_view group_system 1 1 1 1
82 access_ir_actions_act_url_all ir_actions_act_url_all model_ir_actions_act_url 1 0 0 0
83 access_ir_actions_act_url_group_system ir_actions_act_url_group_system model_ir_actions_act_url group_system 1 1 1 1
84 access_ir_server_object_lines_all ir_server_object_lines_all model_ir_server_object_lines 1 0 0 0
85 access_ir_server_object_lines_group_system ir_server_object_lines_group_system model_ir_server_object_lines group_system 1 1 1 1
86 access_ir_actions_server_all ir_actions_server_all model_ir_actions_server 1 0 0 0
87 access_ir_actions_server_group_system ir_actions_server_group_system model_ir_actions_server group_system 1 1 1 1
88 access_res_bank_group_system res_bank_group_system model_res_bank group_system 1 1 1 1
89 access_res_bank_group_partner_manager res_bank_group_partner_manager model_res_bank group_partner_manager 1 1 1 1
90 access_res_bank_user res_bank user model_res_bank group_user 1 0 0 0
91 access_ir_filter_erp_manager ir_filters all model_ir_filters group_erp_manager 1 1 1 1
92 access_ir_filter_user ir_filters all model_ir_filters group_user 1 1 1 1
93 access_ir_filter_portal ir_filters all model_ir_filters group_portal 1 1 1 1
94 access_ir_filter_public ir_filters all model_ir_filters group_public 1 1 1 1
95 access_ir_config_parameter_system ir_config_parameter_system model_ir_config_parameter group_system 1 1 1 1
96 access_ir_mail_server ir_mail_server model_ir_mail_server group_system 1 1 1 1
97 access_ir_actions_client ir_actions_client all model_ir_actions_client 1 0 0 0
98 access_ir_logging ir_logging admin model_ir_logging group_erp_manager 1 1 1 1
99 paperformat_access_portal ir_actions_report_paperformat group_portal model_report_paperformat 1 0 0 0
100 paperformat_access_employee ir_actions_report_paperformat group_hr_user model_report_paperformat 1 0 1 0
101 access_ir_cronjob_logs access_ir_cronjob_logs model_ir_cronjob_logs group_system 1 1 1 1

View File

Before

Width:  |  Height:  |  Size: 5.3 KiB

After

Width:  |  Height:  |  Size: 5.3 KiB