[MERGE] forward port branch 10.0 up to e336dc38ca
This commit is contained in:
@@ -700,7 +700,7 @@ class AccountInvoice(models.Model):
|
||||
total_currency = 0
|
||||
for line in invoice_move_lines:
|
||||
if self.currency_id != company_currency:
|
||||
currency = self.currency_id.with_context(date=self.date or self.date_invoice or fields.Date.context_today(self))
|
||||
currency = self.currency_id.with_context(date=self._get_currency_rate_date() or fields.Date.context_today(self))
|
||||
if not (line.get('currency_id') and line.get('amount_currency')):
|
||||
line['currency_id'] = currency.id
|
||||
line['amount_currency'] = currency.round(line['price'])
|
||||
@@ -848,7 +848,7 @@ class AccountInvoice(models.Model):
|
||||
if inv.payment_term_id:
|
||||
totlines = inv.with_context(ctx).payment_term_id.with_context(currency_id=company_currency.id).compute(total, inv.date_invoice)[0]
|
||||
res_amount_currency = total_currency
|
||||
ctx['date'] = inv.date or inv.date_invoice
|
||||
ctx['date'] = inv._get_currency_rate_date()
|
||||
for i, t in enumerate(totlines):
|
||||
if inv.currency_id != company_currency:
|
||||
amount_currency = company_currency.with_context(ctx).compute(t[1], inv.currency_id)
|
||||
@@ -1035,6 +1035,9 @@ class AccountInvoice(models.Model):
|
||||
copy_fields = ['company_id', 'user_id', 'fiscal_position_id']
|
||||
return self._get_refund_common_fields() + self._get_refund_prepare_fields() + copy_fields
|
||||
|
||||
def _get_currency_rate_date(self):
|
||||
return self.date or self.date_invoice
|
||||
|
||||
@api.model
|
||||
def _prepare_refund(self, invoice, date_invoice=None, date=None, description=None, journal_id=None):
|
||||
""" Prepare the dict of values to create the new refund from the invoice.
|
||||
@@ -1194,7 +1197,7 @@ class AccountInvoiceLine(models.Model):
|
||||
@api.one
|
||||
@api.depends('price_unit', 'discount', 'invoice_line_tax_ids', 'quantity',
|
||||
'product_id', 'invoice_id.partner_id', 'invoice_id.currency_id', 'invoice_id.company_id',
|
||||
'invoice_id.date_invoice')
|
||||
'invoice_id.date_invoice', 'invoice_id.date')
|
||||
def _compute_price(self):
|
||||
currency = self.invoice_id and self.invoice_id.currency_id or None
|
||||
price = self.price_unit * (1 - (self.discount or 0.0) / 100.0)
|
||||
@@ -1203,7 +1206,7 @@ class AccountInvoiceLine(models.Model):
|
||||
taxes = self.invoice_line_tax_ids.compute_all(price, currency, self.quantity, product=self.product_id, partner=self.invoice_id.partner_id)
|
||||
self.price_subtotal = price_subtotal_signed = taxes['total_excluded'] if taxes else self.quantity * price
|
||||
if self.invoice_id.currency_id and self.invoice_id.company_id and self.invoice_id.currency_id != self.invoice_id.company_id.currency_id:
|
||||
price_subtotal_signed = self.invoice_id.currency_id.with_context(date=self.invoice_id.date_invoice).compute(price_subtotal_signed, self.invoice_id.company_id.currency_id)
|
||||
price_subtotal_signed = self.invoice_id.currency_id.with_context(date=self.invoice_id._get_currency_rate_date()).compute(price_subtotal_signed, self.invoice_id.company_id.currency_id)
|
||||
sign = self.invoice_id.type in ['in_refund', 'out_refund'] and -1 or 1
|
||||
self.price_subtotal_signed = price_subtotal_signed * sign
|
||||
|
||||
|
||||
@@ -165,6 +165,8 @@ class AccountMove(models.Model):
|
||||
if not move.journal_id.update_posted:
|
||||
raise UserError(_('You cannot modify a posted entry of this journal.\nFirst you should set the journal to allow cancelling entries.'))
|
||||
if self.ids:
|
||||
self.check_access_rights('write')
|
||||
self.check_access_rule('write')
|
||||
self._check_lock_date()
|
||||
self._cr.execute('UPDATE account_move '\
|
||||
'SET state=%s '\
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</p>
|
||||
|
||||
<t t-if="Lines[o.id]">
|
||||
<span t-field="res_company.overdue_msg"/>
|
||||
<span t-field="res_company.with_context(lang=o.lang).overdue_msg"/>
|
||||
<table class="table table-condensed" t-foreach="Lines[o.id]" t-as="currency">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
<field name="crossovered_budget_line" context="{'default_date_from': date_from,'default_date_to': date_to}" colspan="4" nolabel="1" attrs="{'readonly':[('state','!=','draft')]}">
|
||||
<tree string="Budget Lines">
|
||||
<field name="general_budget_id"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" required="1"/>
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
<field name="paid_date" groups="base.group_no_one"/>
|
||||
@@ -110,7 +110,7 @@
|
||||
<group>
|
||||
<field name="general_budget_id"/>
|
||||
<field name="planned_amount" widget="monetary"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting" required="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<label for="date_from" string="Period"/>
|
||||
|
||||
@@ -586,7 +586,7 @@ class Import(models.TransientModel):
|
||||
# Check that currency exists
|
||||
currency = self.env['res.currency'].search([('symbol', '=', split_value[currency_index].strip())])
|
||||
if len(currency):
|
||||
return split_value[currency_index + 1 % 2] if not negative else '-' + split_value[currency_index + 1 % 2]
|
||||
return split_value[(currency_index + 1) % 2] if not negative else '-' + split_value[(currency_index + 1) % 2]
|
||||
# Otherwise it is not a float with a currency symbol
|
||||
return False
|
||||
|
||||
|
||||
@@ -13,6 +13,8 @@ class AccountMoveLine(models.Model):
|
||||
res = super(AccountMoveLine, self).reconcile(writeoff_acc_id=writeoff_acc_id, writeoff_journal_id=writeoff_journal_id)
|
||||
account_move_ids = [l.move_id.id for l in self if float_compare(l.move_id.matched_percentage, 1, precision_digits=5) == 0]
|
||||
if account_move_ids:
|
||||
expense_sheets = self.env['hr.expense.sheet'].search([('account_move_id', 'in', account_move_ids)])
|
||||
expense_sheets = self.env['hr.expense.sheet'].search([
|
||||
('account_move_id', 'in', account_move_ids), ('state', '!=', 'done')
|
||||
])
|
||||
expense_sheets.set_to_paid()
|
||||
return res
|
||||
|
||||
@@ -417,18 +417,20 @@ class HrExpenseSheet(models.Model):
|
||||
|
||||
@api.multi
|
||||
def check_consistency(self):
|
||||
if any(sheet.employee_id != self[0].employee_id for sheet in self):
|
||||
raise UserError(_("Expenses must belong to the same Employee."))
|
||||
|
||||
expense_lines = self.mapped('expense_line_ids')
|
||||
if expense_lines and any(expense.payment_mode != expense_lines[0].payment_mode for expense in expense_lines):
|
||||
raise UserError(_("Expenses must have been paid by the same entity (Company or employee)"))
|
||||
for rec in self:
|
||||
expense_lines = rec.expense_line_ids
|
||||
if not expense_lines:
|
||||
continue
|
||||
if any(expense.employee_id != rec.employee_id for expense in expense_lines):
|
||||
raise UserError(_("Expenses must belong to the same Employee."))
|
||||
if any(expense.payment_mode != expense_lines[0].payment_mode for expense in expense_lines):
|
||||
raise UserError(_("Expenses must have been paid by the same entity (Company or employee)"))
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
self._create_set_followers(vals)
|
||||
sheet = super(HrExpenseSheet, self).create(vals)
|
||||
self.check_consistency()
|
||||
sheet.check_consistency()
|
||||
return sheet
|
||||
|
||||
@api.multi
|
||||
@@ -588,7 +590,7 @@ class HrExpenseSheet(models.Model):
|
||||
|
||||
|
||||
@api.one
|
||||
@api.constrains('expense_line_ids')
|
||||
@api.constrains('expense_line_ids', 'employee_id')
|
||||
def _check_employee(self):
|
||||
employee_ids = self.expense_line_ids.mapped('employee_id')
|
||||
if len(employee_ids) > 1 or (len(employee_ids) == 1 and employee_ids != self.employee_id):
|
||||
|
||||
@@ -19,6 +19,16 @@
|
||||
<field name="tax_dest_id" ref="vat_O_import" />
|
||||
</record>
|
||||
|
||||
<record id="fiscal_position_tax_template_5" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_37_purchase" />
|
||||
<field name="tax_dest_id" ref="vat_O_import" />
|
||||
</record>
|
||||
<record id="fiscal_position_tax_template_6" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_37_invest" />
|
||||
<field name="tax_dest_id" ref="vat_O_import" />
|
||||
</record>
|
||||
<record id="fiscal_position_tax_template_7" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_38_purchase" />
|
||||
@@ -29,6 +39,16 @@
|
||||
<field name="tax_src_id" ref="vat_38_invest" />
|
||||
<field name="tax_dest_id" ref="vat_O_import" />
|
||||
</record>
|
||||
<record id="fiscal_position_tax_template_9" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_77_purchase" />
|
||||
<field name="tax_dest_id" ref="vat_O_import" />
|
||||
</record>
|
||||
<record id="fiscal_position_tax_template_10" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_77_invest" />
|
||||
<field name="tax_dest_id" ref="vat_O_import" />
|
||||
</record>
|
||||
|
||||
<record id="fiscal_position_tax_template_11" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
@@ -46,13 +66,21 @@
|
||||
<field name="tax_src_id" ref="vat_25" />
|
||||
<field name="tax_dest_id" ref="vat_XO" />
|
||||
</record>
|
||||
|
||||
<record id="fiscal_position_tax_template_15" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_37" />
|
||||
<field name="tax_dest_id" ref="vat_XO" />
|
||||
</record>
|
||||
<record id="fiscal_position_tax_template_16" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_38" />
|
||||
<field name="tax_dest_id" ref="vat_XO" />
|
||||
</record>
|
||||
|
||||
<record id="fiscal_position_tax_template_17" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_77" />
|
||||
<field name="tax_dest_id" ref="vat_XO" />
|
||||
</record>
|
||||
<record id="fiscal_position_tax_template_18" model="account.fiscal.position.tax.template">
|
||||
<field name="position_id" ref="fiscal_position_template_import" />
|
||||
<field name="tax_src_id" ref="vat_80" />
|
||||
|
||||
@@ -32,6 +32,10 @@
|
||||
<field name="name">Switzerland VAT Form: grid 301 base</field>
|
||||
<field name="applicability">taxes</field>
|
||||
</record>
|
||||
<record id="vat_tag_302_a" model="account.account.tag">
|
||||
<field name="name">Switzerland VAT Form: grid 302 base</field>
|
||||
<field name="applicability">taxes</field>
|
||||
</record>
|
||||
<record id="vat_tag_311_a" model="account.account.tag">
|
||||
<field name="name">Switzerland VAT Form: grid 311 base</field>
|
||||
<field name="applicability">taxes</field>
|
||||
@@ -40,6 +44,10 @@
|
||||
<field name="name">Switzerland VAT Form: grid 341 base</field>
|
||||
<field name="applicability">taxes</field>
|
||||
</record>
|
||||
<record id="vat_tag_342_a" model="account.account.tag">
|
||||
<field name="name">Switzerland VAT Form: grid 342 base</field>
|
||||
<field name="applicability">taxes</field>
|
||||
</record>
|
||||
<record id="vat_tag_381_a" model="account.account.tag">
|
||||
<field name="name">Switzerland VAT Form: grid 381 base</field>
|
||||
<field name="applicability">taxes</field>
|
||||
@@ -48,6 +56,10 @@
|
||||
<field name="name">Switzerland VAT Form: grid 301 tax</field>
|
||||
<field name="applicability">taxes</field>
|
||||
</record>
|
||||
<record id="vat_tag_302_b" model="account.account.tag">
|
||||
<field name="name">Switzerland VAT Form: grid 302 tax</field>
|
||||
<field name="applicability">taxes</field>
|
||||
</record>
|
||||
<record id="vat_tag_311_b" model="account.account.tag">
|
||||
<field name="name">Switzerland VAT Form: grid 311 tax</field>
|
||||
<field name="applicability">taxes</field>
|
||||
@@ -56,6 +68,10 @@
|
||||
<field name="name">Switzerland VAT Form: grid 341 tax</field>
|
||||
<field name="applicability">taxes</field>
|
||||
</record>
|
||||
<record id="vat_tag_342_b" model="account.account.tag">
|
||||
<field name="name">Switzerland VAT Form: grid 342 tax</field>
|
||||
<field name="applicability">taxes</field>
|
||||
</record>
|
||||
<record id="vat_tag_381_b" model="account.account.tag">
|
||||
<field name="name">Switzerland VAT Form: grid 381 tax</field>
|
||||
<field name="applicability">taxes</field>
|
||||
@@ -160,6 +176,75 @@
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_405')])]"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.template" id="vat_37">
|
||||
<field name="name">TVA due a 3.7% (TS)</field>
|
||||
<field name="description">3.7%</field>
|
||||
<field name="amount" eval="3.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="refund_account_id" ref="ch_coa_2200"/>
|
||||
<field name="account_id" ref="ch_coa_2200"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_342_a'), ref('vat_tag_342_b')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_37_incl">
|
||||
<field name="name">TVA due à 3.7% (Incl. TS)</field>
|
||||
<field name="description">3.7% Incl.</field>
|
||||
<field name="price_include" eval="1"/>
|
||||
<field name="amount" eval="3.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="refund_account_id" ref="ch_coa_2200"/>
|
||||
<field name="account_id" ref="ch_coa_2200"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_342_a'), ref('vat_tag_342_b')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_37_purchase">
|
||||
<field name="name">TVA 3.7% sur achat B&S (TS)</field>
|
||||
<field name="description">3.7% achat</field>
|
||||
<field name="amount" eval="3.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="refund_account_id" ref="ch_coa_1170"/>
|
||||
<field name="account_id" ref="ch_coa_1170"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_400')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_37_purchase_incl">
|
||||
<field name="name">TVA 3.7% sur achat B&S (Incl. TS)</field>
|
||||
<field name="description">3.7% achat Incl.</field>
|
||||
<field name="price_include" eval="1"/>
|
||||
<field name="amount" eval="3.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="refund_account_id" ref="ch_coa_1170"/>
|
||||
<field name="account_id" ref="ch_coa_1170"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_400')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_37_invest">
|
||||
<field name="name">TVA 3.7% sur invest. et autres ch. (TS)</field>
|
||||
<field name="description">3.7% invest</field>
|
||||
<field name="amount" eval="3.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="refund_account_id" ref="ch_coa_1171"/>
|
||||
<field name="account_id" ref="ch_coa_1171"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_405')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_37_invest_incl">
|
||||
<field name="name">TVA 3.7% sur invest. et autres ch. (Incl. TS)</field>
|
||||
<field name="description">3.7% invest Incl.</field>
|
||||
<field name="price_include" eval="1"/>
|
||||
<field name="amount" eval="3.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="refund_account_id" ref="ch_coa_1171"/>
|
||||
<field name="account_id" ref="ch_coa_1171"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_405')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_38">
|
||||
<field name="name">TVA due a 3.8% (TS)</field>
|
||||
<field name="description">3.8%</field>
|
||||
@@ -229,6 +314,80 @@
|
||||
<field name="account_id" ref="ch_coa_1171"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_405')])]"/>
|
||||
</record>
|
||||
|
||||
<record model="account.tax.template" id="vat_77">
|
||||
<field name="name">TVA due a 7.7% (TN)</field>
|
||||
<field name="description">7.7%</field>
|
||||
<field name="amount" eval="7.7"/>
|
||||
<field name="sequence" eval="0"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="refund_account_id" ref="ch_coa_2200"/>
|
||||
<field name="account_id" ref="ch_coa_2200"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_302_a'), ref('vat_tag_302_b')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_77_incl">
|
||||
<field name="name">TVA due à 7.7% (Incl. TN)</field>
|
||||
<field name="description">7.7% Incl.</field>
|
||||
<field name="price_include" eval="1"/>
|
||||
<field name="amount" eval="7.7"/>
|
||||
<field name="sequence" eval="0"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">sale</field>
|
||||
<field name="refund_account_id" ref="ch_coa_2200"/>
|
||||
<field name="account_id" ref="ch_coa_2200"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_302_a'), ref('vat_tag_302_b')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_77_purchase">
|
||||
<field name="name">TVA 7.7% sur achat B&S (TN)</field>
|
||||
<field name="description">7.7% achat</field>
|
||||
<field name="amount" eval="7.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="sequence" eval="0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="refund_account_id" ref="ch_coa_1170"/>
|
||||
<field name="account_id" ref="ch_coa_1170"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_400')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_77_purchase_incl">
|
||||
<field name="name">TVA 7.7% sur achat B&S (Incl. TN)</field>
|
||||
<field name="description">7.7% achat Incl.</field>
|
||||
<field name="price_include" eval="1"/>
|
||||
<field name="amount" eval="7.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="sequence" eval="0"/>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="refund_account_id" ref="ch_coa_1170"/>
|
||||
<field name="account_id" ref="ch_coa_1170"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_400')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_77_invest">
|
||||
<field name="name">TVA 7.7% sur invest. et autres ch. (TN)</field>
|
||||
<field name="description">7.7% invest.</field>
|
||||
<field name="amount" eval="7.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="refund_account_id" ref="ch_coa_1171"/>
|
||||
<field name="account_id" ref="ch_coa_1171"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_405')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_77_invest_incl">
|
||||
<field name="name">TVA 7.7% sur invest. et autres ch. (Incl. TN)</field>
|
||||
<field name="description">7.7% invest. Incl.</field>
|
||||
<field name="price_include" eval="1"/>
|
||||
<field name="amount" eval="7.7"/>
|
||||
<field name="amount_type">percent</field>
|
||||
<field name="chart_template_id" ref="l10nch_chart_template"/>
|
||||
<field name="type_tax_use">purchase</field>
|
||||
<field name="refund_account_id" ref="ch_coa_1171"/>
|
||||
<field name="account_id" ref="ch_coa_1171"/>
|
||||
<field name="tag_ids" eval="[(6,0,[ref('vat_tag_405')])]"/>
|
||||
</record>
|
||||
<record model="account.tax.template" id="vat_80">
|
||||
<field name="name">TVA due a 8.0% (TN)</field>
|
||||
<field name="description">8.0%</field>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from hashlib import sha256
|
||||
from json import dumps
|
||||
import pytz
|
||||
@@ -41,7 +41,7 @@ class pos_session(models.Model):
|
||||
self.ensure_one()
|
||||
date_today = datetime.utcnow()
|
||||
session_start = Datetime.from_string(self.start_at)
|
||||
if not date_today - datetime.timedelta(hours=24) <= session_start:
|
||||
if not date_today - timedelta(hours=24) <= session_start:
|
||||
raise UserError(_("This session has been opened another day. To comply with the French law, you should close sessions on a daily basis. Please close session %s and open a new one.") % self.name)
|
||||
return True
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ or (contract.wage * 0.10))</field>
|
||||
<field name="name">Arrears</field>
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.ARS.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.ARS and inputs.ARS.amount</field>
|
||||
<field eval="0.0" name="amount_fix"/>
|
||||
<field name="sequence" eval="28"/>
|
||||
<field name="note">Generally arrears are fully taxable, but employee may claim exemption u/s 89(1).
|
||||
@@ -185,7 +185,7 @@ Now difference of income tax between payment year and actual year would be allow
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="condition_select">none</field>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.LE.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.LE and inputs.LE.amount</field>
|
||||
<field name="sequence" eval="30"/>
|
||||
<field name="note">Payment by way of leave encashment received by Central and State Govt.employees at the time of retirement in respect of the period of earned leave at credit is fully exempt. In case of other employees, the exemption is to be limited to minimum of all below:
|
||||
1.The actual amount received
|
||||
@@ -199,7 +199,7 @@ Now difference of income tax between payment year and actual year would be allow
|
||||
<field name="name">Performance Incentive</field>
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.PERF.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.PERF and inputs.PERF.amount</field>
|
||||
<field name="sequence" eval="31"/>
|
||||
<field name="note">This would be fully taxable based on incentive.</field>
|
||||
</record>
|
||||
@@ -209,7 +209,7 @@ Now difference of income tax between payment year and actual year would be allow
|
||||
<field name="name">Bonus</field>
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.BNS.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.BNS and inputs.BNS.amount</field>
|
||||
<field name="sequence" eval="41"/>
|
||||
<field name="note">This would be fully taxable based on Bonus.</field>
|
||||
</record>
|
||||
@@ -229,7 +229,7 @@ Now difference of income tax between payment year and actual year would be allow
|
||||
<field name="name">Medical Reimbursement</field>
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.MR.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.MR and inputs.MR.amount</field>
|
||||
<field name="sequence" eval="32"/>
|
||||
<field name="note">This component is on-taxable up to 15000 per year (or Rs 1250 per month) on producing medical bills.</field>
|
||||
</record>
|
||||
@@ -250,7 +250,7 @@ Now difference of income tax between payment year and actual year would be allow
|
||||
<field name="name">Periodical Journals</field>
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.PJ.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.PJ and inputs.PJ.amount</field>
|
||||
<field name="sequence" eval="34"/>
|
||||
<field name="note">Some employers may provide component for buying magazines, journals and books as a part of knowledge enhancement for business growth.This part would become non taxable on providing original bills.</field>
|
||||
</record>
|
||||
@@ -280,7 +280,7 @@ Now difference of income tax between payment year and actual year would be allow
|
||||
<field name="name">Telephone Reimbursement</field>
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.TR.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.TR and inputs.TR.amount</field>
|
||||
<field name="sequence" eval="36"/>
|
||||
<field name="note">In some of the cases, companies may provide a component for telephone bills.Employees may provide actual phone usage bills to reimburse this component and make it non-taxable.
|
||||
</field>
|
||||
@@ -300,7 +300,7 @@ Now difference of income tax between payment year and actual year would be allow
|
||||
<field name="name">Car Expenses Reimbursement</field>
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.CEI.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.CEI and inputs.CEI.amount</field>
|
||||
<field name="sequence" eval="38"/>
|
||||
<field name="note">In case company provides component for this and employee use self owned car for official and personal purposes, Rs 1800 per month would be non-taxable on showing bills for fuel or can maintenance. This amount would be Rs 2400 in case car is more capacity than 1600cc.</field>
|
||||
</record>
|
||||
@@ -310,7 +310,7 @@ Now difference of income tax between payment year and actual year would be allow
|
||||
<field name="name">Internet Expense</field>
|
||||
<field name="category_id" ref="hr_payroll.ALW"/>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = inputs.IE.amount</field>
|
||||
<field name="amount_python_compute">result = inputs.IE and inputs.IE.amount</field>
|
||||
<field name="sequence" eval="39"/>
|
||||
<field name="note">Employer may also provide reimbursement of internet expenses and thus this would become non taxable.</field>
|
||||
</record>
|
||||
@@ -463,7 +463,7 @@ or - (contract.wage * contract.voluntary_provident_fund / 100))</field>
|
||||
<field name="category_id" ref="hr_payroll.DED"/>
|
||||
<field name="condition_select">none</field>
|
||||
<field name="amount_select">code</field>
|
||||
<field name="amount_python_compute">result = - (inputs.LAI.amount)</field>
|
||||
<field name="amount_python_compute">result = inputs.LAI and - (inputs.LAI.amount)</field>
|
||||
<field name="register_id" ref="hr_leave_availed_register"/>
|
||||
<field name="sequence" eval="180"/>
|
||||
</record>
|
||||
|
||||
@@ -179,20 +179,17 @@ tag_lu_177,I.B.5. Tabacs fabriqués,taxes
|
||||
tag_lu_178,Base - Vente Biens Tabacs - Extracommunautaire,taxes
|
||||
tag_lu_179,Base - Vente Biens Tabacs - Intracommunautaire,taxes
|
||||
tag_lu_180,Base - Vente Biens Tabacs - Pays,taxes
|
||||
tag_lu_181,I.B.6.a) Livraisons subséquentes à des acquisitions intracommunautaires dans
|
||||
le cadre d'opérations triangulaires, lorsque le destinataire identifié à la TVA dans l'Etat membre de destination des biens y est le redevable de la taxe (4),taxes
|
||||
tag_lu_181,"I.B.6.a) Livraisons subséquentes à des acquisitions intracommunautaires dans le cadre d'opérations triangulaires, lorsque le destinataire identifié à la TVA dans l'Etat membre de destination des biens y est le redevable de la taxe (4)",taxes
|
||||
tag_lu_182,Base - Vente Biens – Triangulaire Intracommunautaire,taxes
|
||||
tag_lu_183,I.B.6.d) Autres opérations réalisées (imposables) à l'étranger,taxes
|
||||
tag_lu_184,Base - Vente Prestations - Extracommunautaire,taxes
|
||||
tag_lu_185,I.B.6.c) Opérations réalisées dans le cadre du régime particulier de l'article 56sexies,taxes
|
||||
tag_lu_186,I.B.7. Opérations à l'intérieur du pays pour lesquelles le preneur est le redevable,taxes
|
||||
tag_lu_187,I.B.6.b)1) Prestations de services à des identifiés à la TVA dans un autre
|
||||
Etat membre non exonérées dans l'Etat membre du preneur redevable (art.17/1/b) (5),taxes
|
||||
tag_lu_187,I.B.6.b)1) Prestations de services à des identifiés à la TVA dans un autre Etat membre non exonérées dans l'Etat membre du preneur redevable (art.17/1/b) (5),taxes
|
||||
tag_lu_188,Base - Vente Prestations - Intracommunautaire,taxes
|
||||
tag_lu_189,I.B.6.b)2) Prestations de services à des identifiés à la TVA dans un autre
|
||||
Etat membre exonérées dans l'Etat membre du preneur (art.17/1/b),taxes
|
||||
tag_lu_189,I.B.6.b)2) Prestations de services à des identifiés à la TVA dans un autre Etat membre exonérées dans l'Etat membre du preneur (art.17/1/b),taxes
|
||||
tag_lu_190,Base - Vente Prestations - Intracommunautaire exonérées dans l'état membre,taxes
|
||||
tag_lu_191,I.B.1. Livraisons intracommunautaires de biens à des personnes identifiées à la TVA dans unautre Etat membre (art.43/1/d e et f) (3),taxes
|
||||
tag_lu_191,I.B.1. Livraisons intracommunautaires de biens à des personnes identifiées à la TVA dans un autre Etat membre (art.43/1/d e et f) (3),taxes
|
||||
tag_lu_192,Base - Vente Biens - Intracommunautaire,taxes
|
||||
tag_lu_193,I.C. Chiffre d'affaires imposable,taxes
|
||||
tag_lu_194,II.A. Ventilation du chiffre d'affaires imposable – base,taxes
|
||||
@@ -598,4 +595,4 @@ tag_lu_594,Taxe - Investissement Prestations 17% - Intracommunautaire (-),taxes
|
||||
tag_lu_595,Taxe - Investissement Prestations 3% - Intracommunautaire (-),taxes
|
||||
tag_lu_596,Taxe - Investissement Prestations 6% - Intracommunautaire (-),taxes
|
||||
tag_lu_597,Taxe - Investissement Prestations 8% - Intracommunautaire (-),taxes
|
||||
tag_lu_598,Base - Sans Taxe,taxes
|
||||
tag_lu_598,Base - Sans Taxe,taxes
|
||||
|
||||
|
@@ -18,4 +18,5 @@ import res_config
|
||||
import update
|
||||
import ir_actions
|
||||
import ir_autovacuum
|
||||
import ir_model
|
||||
import html2text
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models
|
||||
|
||||
|
||||
class IrModel(models.Model):
|
||||
_inherit = 'ir.model'
|
||||
|
||||
def unlink(self):
|
||||
# Delete followers for models that will be unlinked.
|
||||
query = "DELETE FROM mail_followers WHERE res_model IN %s"
|
||||
self.env.cr.execute(query, [tuple(self.mapped('model'))])
|
||||
return super(IrModel, self).unlink()
|
||||
@@ -2130,7 +2130,7 @@ class MailThread(models.AbstractModel):
|
||||
|
||||
# add followers coming from res.users relational fields that are tracked
|
||||
user_ids = [values[name] for name in user_field_lst if values.get(name)]
|
||||
user_pids = [user.partner_id.id for user in self.env['res.users'].sudo().browse(user_ids)]
|
||||
user_pids = [user.partner_id.id for user in self.env['res.users'].sudo().browse(user_ids) if user.partner_id.active]
|
||||
for partner_id in user_pids:
|
||||
new_partners.setdefault(partner_id, None)
|
||||
|
||||
|
||||
@@ -103,9 +103,11 @@
|
||||
<field name="name">Work Orders Performance</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">mrp.workorder</field>
|
||||
<field name="domain">[('state','=','done')]</field>
|
||||
<field name="domain">[]</field>
|
||||
<field name="context">{'search_default_done': True}</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">graph,pivot,tree,form,gantt</field>
|
||||
<field name="search_view_id" ref="view_mrp_production_work_order_search"/>
|
||||
</record>
|
||||
|
||||
<!-- Workcenter Kanban view-->
|
||||
@@ -567,4 +569,4 @@
|
||||
groups="group_mrp_routings"
|
||||
sequence="12"/>
|
||||
</data>
|
||||
</odoo>
|
||||
</odoo>
|
||||
|
||||
@@ -201,7 +201,7 @@
|
||||
<tree>
|
||||
<field name="date_start"/>
|
||||
<field name="date_end"/>
|
||||
<field name="duration" widget="float_time"/>
|
||||
<field name="duration" widget="float_time" sum="Total duration"/>
|
||||
<field name="user_id"/>
|
||||
<field name="loss_id" string="Efficiency"/>
|
||||
</tree>
|
||||
@@ -459,4 +459,4 @@
|
||||
<field name="view_id" ref="view_work_center_load_graph"/>
|
||||
<field name="act_window_id" ref="action_mrp_workcenter_load_report_graph"/>
|
||||
</record>
|
||||
</odoo>
|
||||
</odoo>
|
||||
|
||||
@@ -203,7 +203,7 @@ exports.PosModel = Backbone.Model.extend({
|
||||
},{
|
||||
model: 'account.tax',
|
||||
fields: ['name','amount', 'price_include', 'include_base_amount', 'amount_type', 'children_tax_ids'],
|
||||
domain: null,
|
||||
domain: function(self) {return [['company_id', '=', self.company && self.company.id || false]]},
|
||||
loaded: function(self, taxes){
|
||||
self.taxes = taxes;
|
||||
self.taxes_by_id = {};
|
||||
|
||||
@@ -1977,6 +1977,7 @@ var PaymentScreenWidget = ScreenWidget.extend({
|
||||
}
|
||||
|
||||
order.initialize_validation_date();
|
||||
order.finalized = true;
|
||||
|
||||
if (order.is_to_invoice()) {
|
||||
var invoiced = this.pos.push_and_invoice_order(order);
|
||||
|
||||
@@ -106,7 +106,7 @@ class Pricelist(models.Model):
|
||||
"""
|
||||
self.ensure_one()
|
||||
if not date:
|
||||
date = self._context.get('date') or fields.Date.today()
|
||||
date = self._context.get('date') or fields.Date.context_today(self)
|
||||
if not uom_id and self._context.get('uom'):
|
||||
uom_id = self._context['uom']
|
||||
if uom_id:
|
||||
|
||||
@@ -112,7 +112,7 @@ class AccountInvoiceLine(models.Model):
|
||||
prod_moves = [m for m in moves if m.product_id.id == product_id]
|
||||
prod_qty_done = factor * qty_done
|
||||
prod_quantity = factor * quantity
|
||||
average_price_unit += self._compute_average_price(prod_qty_done, prod_quantity, prod_moves)
|
||||
average_price_unit += factor * self._compute_average_price(prod_qty_done, prod_quantity, prod_moves)
|
||||
price_unit = average_price_unit or price_unit
|
||||
price_unit = self.product_id.uom_id._compute_price(price_unit, self.uom_id)
|
||||
return price_unit
|
||||
|
||||
@@ -35,8 +35,17 @@ class StockHistory(models.Model):
|
||||
group_lines.setdefault(str(domain), self.search(domain))
|
||||
stock_history |= group_lines[str(domain)]
|
||||
|
||||
# get data of stock_history in one shot to speed things up (the view can be very slow)
|
||||
stock_history_data = {}
|
||||
if stock_history:
|
||||
self._cr.execute("""SELECT id, product_id, price_unit_on_quant, company_id, quantity
|
||||
FROM stock_history WHERE id in %s""", (tuple(stock_history.ids),))
|
||||
stock_history_data = {line['id']: line for line in self._cr.dictfetchall()}
|
||||
|
||||
histories_dict = {}
|
||||
not_real_cost_method_products = stock_history.mapped('product_id').filtered(lambda product: product.cost_method != 'real')
|
||||
not_real_cost_method_products = self.env['product.product'].browse(
|
||||
record['product_id'] for record in stock_history_data.values()
|
||||
).filtered(lambda product: product.cost_method != 'real')
|
||||
if not_real_cost_method_products:
|
||||
self._cr.execute("""SELECT DISTINCT ON (product_id, company_id) product_id, company_id, cost
|
||||
FROM product_price_history
|
||||
@@ -48,12 +57,13 @@ class StockHistory(models.Model):
|
||||
for line in res:
|
||||
inv_value = 0.0
|
||||
for stock_history in group_lines.get(str(line.get('__domain', domain))):
|
||||
product = stock_history.product_id
|
||||
if product.cost_method == 'real':
|
||||
price = stock_history.price_unit_on_quant
|
||||
history_data = stock_history_data[stock_history.id]
|
||||
product_id = history_data['product_id']
|
||||
if self.env['product.product'].browse(product_id).cost_method == 'real':
|
||||
price = history_data['price_unit_on_quant']
|
||||
else:
|
||||
price = histories_dict.get((product.id, stock_history.company_id.id), 0.0)
|
||||
inv_value += price * stock_history.quantity
|
||||
price = histories_dict.get((product_id, history_data['company_id']), 0.0)
|
||||
inv_value += price * history_data['quantity']
|
||||
line['inventory_value'] = inv_value
|
||||
|
||||
return res
|
||||
|
||||
@@ -586,7 +586,7 @@ class WebClient(http.Controller):
|
||||
def version_info(self):
|
||||
return odoo.service.common.exp_version()
|
||||
|
||||
@http.route('/web/tests', type='http', auth="none")
|
||||
@http.route('/web/tests', type='http', auth="user")
|
||||
def index(self, mod=None, **kwargs):
|
||||
return request.render('web.qunit_suite')
|
||||
|
||||
|
||||
@@ -385,6 +385,10 @@ var ActionManager = Widget.extend({
|
||||
return this.inner_widget;
|
||||
},
|
||||
history_back: function() {
|
||||
if (this.dialog) {
|
||||
this.dialog_stop();
|
||||
return;
|
||||
}
|
||||
var nb_views = this.inner_action.get_nb_views();
|
||||
if (nb_views > 1) {
|
||||
// Stay on this action, but select the previous view
|
||||
@@ -861,7 +865,7 @@ var ActionManager = Widget.extend({
|
||||
});
|
||||
});
|
||||
},
|
||||
ir_actions_act_url: function (action) {
|
||||
ir_actions_act_url: function (action, options) {
|
||||
var url = action.url;
|
||||
if (session.debug && url && url.length && url[0] === '/') {
|
||||
url = $.param.querystring(url, {debug: session.debug});
|
||||
@@ -872,6 +876,7 @@ var ActionManager = Widget.extend({
|
||||
return $.Deferred(); // The action is finished only when the redirection is done
|
||||
} else {
|
||||
window.open(url, '_blank');
|
||||
options.on_close();
|
||||
}
|
||||
return $.when();
|
||||
},
|
||||
|
||||
@@ -5,7 +5,18 @@ var translation = require('web.translation');
|
||||
|
||||
var _t = translation._t;
|
||||
|
||||
function QWeb(debug, default_dict) {
|
||||
/**
|
||||
* @param {boolean} debug
|
||||
* @param {Object} default_dict
|
||||
* @param {boolean} [enableTranslation=true] if true (this is the default),
|
||||
* the rendering will translate all strings that are not marked with
|
||||
* t-translation=off. This is useful for the kanban view, which uses a
|
||||
* template which is already translated by the server
|
||||
*/
|
||||
function QWeb(debug, default_dict, enableTranslation) {
|
||||
if (enableTranslation === undefined) {
|
||||
enableTranslation = true;
|
||||
}
|
||||
var qweb = new QWeb2.Engine();
|
||||
qweb.default_dict = _.extend({}, default_dict || {}, {
|
||||
'_' : _,
|
||||
@@ -16,7 +27,7 @@ function QWeb(debug, default_dict) {
|
||||
'csrf_token': odoo.csrf_token,
|
||||
});
|
||||
qweb.debug = debug;
|
||||
qweb.preprocess_node = preprocess_node;
|
||||
qweb.preprocess_node = enableTranslation ? preprocess_node : function () {};
|
||||
return qweb;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,14 +32,11 @@ data.dom_ready = dom_ready;
|
||||
var all_ready;
|
||||
data.ready = function () {
|
||||
if (!all_ready) {
|
||||
all_ready = $.when(dom_ready, ajax.loadXML()).then(function () {
|
||||
// TODO find a better way to find if we are in the backend or not
|
||||
// We don't load translation if we are in the backend since it's already done by the webclient
|
||||
if (!$(document).find('.o_web_client').length) {
|
||||
return load_translations();
|
||||
}
|
||||
});
|
||||
} else if(all_ready.state() === "resolved") { // can add async template
|
||||
all_ready = $.when(dom_ready, ajax.loadXML());
|
||||
if (!odoo._modules) {
|
||||
all_ready.then(load_translations);
|
||||
}
|
||||
} else { // can add async template
|
||||
all_ready = $.when(dom_ready, ajax.loadXML());
|
||||
}
|
||||
return all_ready;
|
||||
|
||||
@@ -19,6 +19,57 @@ var editor = eventHandler.modules.editor;
|
||||
var renderer = $.summernote.renderer;
|
||||
var options = $.summernote.options;
|
||||
|
||||
// Browser-unify execCommand
|
||||
var oldJustify = {};
|
||||
_.each(['Left', 'Right', 'Full', 'Center'], function (align) {
|
||||
oldJustify[align] = editor['justify' + align];
|
||||
editor['justify' + align] = function ($editable, value) {
|
||||
// Before calling the standard function, check all elements which have
|
||||
// an 'align' attribute and mark them with their value
|
||||
var $align = $editable.find('[align]');
|
||||
_.each($align, function (el) {
|
||||
var $el = $(el);
|
||||
$el.data('__align', $el.attr('align'));
|
||||
});
|
||||
|
||||
// Call the standard function
|
||||
oldJustify[align].apply(this, arguments);
|
||||
|
||||
// Then:
|
||||
|
||||
// Remove the text-align of elements which lost the 'align' attribute
|
||||
var $newAlign = $editable.find('[align]');
|
||||
$align.not($newAlign).css('text-align', '');
|
||||
|
||||
// Transform the 'align' attribute into the 'text-align' css
|
||||
// property for elements which received the 'align' attribute or whose
|
||||
// 'align' attribute changed
|
||||
_.each($newAlign, function (el) {
|
||||
var $el = $(el);
|
||||
|
||||
var oldAlignValue = $align.data('__align');
|
||||
var alignValue = $el.attr('align');
|
||||
if (oldAlignValue === alignValue) {
|
||||
// If the element already had an 'align' attribute and that it
|
||||
// did not changed, do nothing (compatibility)
|
||||
return;
|
||||
}
|
||||
|
||||
$el.removeAttr('align');
|
||||
$el.css('text-align', alignValue);
|
||||
|
||||
// Note the first step (removing the text-align of elemnts which
|
||||
// lost the 'align' attribute) is kinda the same as this one, but
|
||||
// this one handles the elements which have been edited with chrome
|
||||
// or with this new system
|
||||
$el.find('*').css('text-align', '');
|
||||
});
|
||||
|
||||
// Unmark the elements
|
||||
$align.removeData('__align');
|
||||
};
|
||||
});
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* Add method to Summernote*/
|
||||
|
||||
@@ -2319,26 +2370,6 @@ eventHandler.modules.popover.update = function ($popover, oStyle, isAirMode) {
|
||||
}
|
||||
};
|
||||
|
||||
// override summernote clipboard functionality
|
||||
eventHandler.modules.clipboard.attach = function(layoutInfo) {
|
||||
var $editable = layoutInfo.editable();
|
||||
$editable.on('paste', function(e) {
|
||||
var clipboardData = ((e.originalEvent || e).clipboardData || window.clipboardData);
|
||||
// Change nothing if pasting html (copy from text editor / web / ...) or
|
||||
// if clipboardData is not available (IE / ...)
|
||||
if (clipboardData && clipboardData.types && clipboardData.types.length === 1 && clipboardData.types[0] === "text/plain") {
|
||||
e.preventDefault();
|
||||
$editable.data('NoteHistory').recordUndo($editable); // FIXME
|
||||
var pastedText = clipboardData.getData("text/plain");
|
||||
// Try removing linebreaks which are not really linebreaks (in a PDF,
|
||||
// when a sentence goes over the next line, copying it considers it
|
||||
// a linebreak for example).
|
||||
var formattedText = pastedText.replace(/([\w-])\r?\n([\w-])/g, "$1 $2").trim();
|
||||
document.execCommand("insertText", false, formattedText);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var fn_attach = eventHandler.attach;
|
||||
|
||||
@@ -60,7 +60,7 @@ var KanbanView = View.extend({
|
||||
init: function () {
|
||||
this._super.apply(this, arguments);
|
||||
|
||||
this.qweb = new QWeb(session.debug, {_s: session.origin});
|
||||
this.qweb = new QWeb(session.debug, {_s: session.origin}, false);
|
||||
|
||||
this.limit = this.options.limit || parseInt(this.fields_view.arch.attrs.limit, 10) || 40;
|
||||
this.fields = this.fields_view.fields;
|
||||
|
||||
@@ -67,11 +67,18 @@ var PlannerDialog = Dialog.extend({
|
||||
* Fetch the planner's rendered template
|
||||
*/
|
||||
willStart: function() {
|
||||
var context = session.user_context;
|
||||
// fallback context for frontend
|
||||
if(_.isEmpty(context)) {
|
||||
context = {
|
||||
lang: (document.documentElement.getAttribute('lang')||'').replace('-', '_'),
|
||||
};
|
||||
}
|
||||
var def = (new Model('web.planner')).call('render', [
|
||||
this.planner.view_id[0],
|
||||
this.planner.planner_application
|
||||
], {
|
||||
context: session.user_context
|
||||
context: context
|
||||
}).then((function (template) {
|
||||
this.$template = $(template);
|
||||
}).bind(this));
|
||||
|
||||
@@ -168,7 +168,7 @@ odoo.define('website_sale.website_sale', function (require) {
|
||||
}
|
||||
else {
|
||||
$q.parents('li:first').addClass("hidden");
|
||||
$('a[href^="/shop/checkout"]').addClass("hidden");
|
||||
$('a[href*="/shop/checkout"]').addClass("hidden");
|
||||
}
|
||||
|
||||
$q.html(data.cart_quantity).hide().fadeIn(600);
|
||||
|
||||
@@ -12,3 +12,4 @@ List of contributors:
|
||||
|
||||
Laurent Destailleur ldestailleur@teclib.com https://github.com/eldy
|
||||
David Halgand dhalgand@teclib.com https://github.com/halgandd
|
||||
Guillaume Masson gmasson@teclib.com https://github.com/metaminux
|
||||
|
||||
@@ -280,6 +280,13 @@ class Users(models.Model):
|
||||
if any(user.company_ids and user.company_id not in user.company_ids for user in self):
|
||||
raise ValidationError(_('The chosen company is not in the allowed companies for this user'))
|
||||
|
||||
@api.multi
|
||||
@api.constrains('action_id')
|
||||
def _check_action_id(self):
|
||||
action_open_website = self.env.ref('base.action_open_website', raise_if_not_found=False)
|
||||
if action_open_website and any(user.action_id.id == action_open_website.id for user in self):
|
||||
raise ValidationError(_('The "App Switcher" action cannot be selected as home action.'))
|
||||
|
||||
@api.multi
|
||||
def read(self, fields=None, load='_classic_read'):
|
||||
if fields and self == self.env.user:
|
||||
|
||||
Reference in New Issue
Block a user