[MERGE] account_*: reorganize files, finish migration and apply guidelines
This commit is contained in:
@@ -1,7 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import account_journal
|
||||
import account_journal_dashboard
|
||||
import account_payment
|
||||
|
||||
import models
|
||||
import wizard
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': 'Check Printing Base',
|
||||
'version': '1.0',
|
||||
@@ -10,13 +12,12 @@ It must be used as a dependency for modules that provide country-specific check
|
||||
The check settings are located in the accounting journals configuration page.
|
||||
""",
|
||||
'website': 'https://www.odoo.com/page/accounting',
|
||||
'depends' : ['account'],
|
||||
'depends': ['account'],
|
||||
'data': [
|
||||
'data/check_printing.xml',
|
||||
'views/account_journal_dashboard_view.xml',
|
||||
'views/account_journal_view.xml',
|
||||
'views/account_payment_view.xml',
|
||||
'wizard/print_pre_numbered_checks.xml'
|
||||
'data/account_check_printing_data.xml',
|
||||
'views/account_journal_views.xml',
|
||||
'views/account_payment_views.xml',
|
||||
'wizard/print_prenumbered_checks_views.xml'
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from openerp import models, api, _
|
||||
|
||||
class account_journal(models.Model):
|
||||
_inherit = "account.journal"
|
||||
|
||||
@api.multi
|
||||
def get_journal_dashboard_datas(self):
|
||||
domain_checks_to_print = [
|
||||
('journal_id', '=', self.id),
|
||||
('payment_method_id.code', '=', 'check_printing'),
|
||||
('state','=','posted')
|
||||
]
|
||||
return dict(
|
||||
super(account_journal, self).get_journal_dashboard_datas(),
|
||||
num_checks_to_print=len(self.env['account.payment'].search(domain_checks_to_print))
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def action_checks_to_print(self):
|
||||
return {
|
||||
'name': _('Checks to Print'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'list,form,graph',
|
||||
'res_model': 'account.payment',
|
||||
'context': dict(
|
||||
self.env.context,
|
||||
search_default_checks_to_send=1,
|
||||
journal_id=self.id,
|
||||
default_journal_id=self.id,
|
||||
default_payment_type='outbound',
|
||||
default_payment_method_id=self.env.ref('account_check_printing.account_payment_method_check').id,
|
||||
),
|
||||
}
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<record id="account_payment_method_check" model="account.payment.method">
|
||||
@@ -30,4 +30,4 @@
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -0,0 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import account_journal
|
||||
import account_payment
|
||||
+32
-2
@@ -1,7 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.exceptions import ValidationError
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
class AccountJournal(models.Model):
|
||||
_inherit = "account.journal"
|
||||
@@ -76,3 +77,32 @@ class AccountJournal(models.Model):
|
||||
bank_journal.write({
|
||||
'outbound_payment_method_ids': [(4, check_printing.id, None)],
|
||||
})
|
||||
|
||||
@api.multi
|
||||
def get_journal_dashboard_datas(self):
|
||||
domain_checks_to_print = [
|
||||
('journal_id', '=', self.id),
|
||||
('payment_method_id.code', '=', 'check_printing'),
|
||||
('state', '=', 'posted')
|
||||
]
|
||||
return dict(
|
||||
super(AccountJournal, self).get_journal_dashboard_datas(),
|
||||
num_checks_to_print=len(self.env['account.payment'].search(domain_checks_to_print))
|
||||
)
|
||||
|
||||
@api.multi
|
||||
def action_checks_to_print(self):
|
||||
return {
|
||||
'name': _('Checks to Print'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_mode': 'list,form,graph',
|
||||
'res_model': 'account.payment',
|
||||
'context': dict(
|
||||
self.env.context,
|
||||
search_default_checks_to_send=1,
|
||||
journal_id=self.id,
|
||||
default_journal_id=self.id,
|
||||
default_payment_type='outbound',
|
||||
default_payment_method_id=self.env.ref('account_check_printing.account_payment_method_check').id,
|
||||
),
|
||||
}
|
||||
+18
-16
@@ -1,12 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import math
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.tools import amount_to_text_en, float_round
|
||||
from openerp.exceptions import UserError, ValidationError
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.tools import amount_to_text_en, float_round
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
class account_register_payments(models.TransientModel):
|
||||
|
||||
class AccountRegisterPayments(models.TransientModel):
|
||||
_inherit = "account.register.payments"
|
||||
|
||||
check_amount_in_words = fields.Char(string="Amount in Words")
|
||||
@@ -18,15 +20,15 @@ class account_register_payments(models.TransientModel):
|
||||
|
||||
@api.onchange('journal_id')
|
||||
def _onchange_journal_id(self):
|
||||
if hasattr(super(account_register_payments, self), '_onchange_journal_id'):
|
||||
super(account_register_payments, self)._onchange_journal_id()
|
||||
if hasattr(super(AccountRegisterPayments, self), '_onchange_journal_id'):
|
||||
super(AccountRegisterPayments, self)._onchange_journal_id()
|
||||
if self.journal_id.check_manual_sequencing:
|
||||
self.check_number = self.journal_id.check_sequence_id.number_next_actual
|
||||
|
||||
@api.onchange('amount')
|
||||
def _onchange_amount(self):
|
||||
if hasattr(super(account_register_payments, self), '_onchange_amount'):
|
||||
super(account_register_payments, self)._onchange_amount()
|
||||
if hasattr(super(AccountRegisterPayments, self), '_onchange_amount'):
|
||||
super(AccountRegisterPayments, self)._onchange_amount()
|
||||
# TODO: merge, refactor and complete the amount_to_text and amount_to_text_en classes
|
||||
check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(self.amount), lang='en', currency='')
|
||||
check_amount_in_words = check_amount_in_words.replace(' and Zero Cent', '') # Ugh
|
||||
@@ -36,7 +38,7 @@ class account_register_payments(models.TransientModel):
|
||||
self.check_amount_in_words = check_amount_in_words
|
||||
|
||||
def get_payment_vals(self):
|
||||
res = super(account_register_payments, self).get_payment_vals()
|
||||
res = super(AccountRegisterPayments, self).get_payment_vals()
|
||||
if self.payment_method_id == self.env.ref('account_check_printing.account_payment_method_check'):
|
||||
res.update({
|
||||
'check_amount_in_words': self.check_amount_in_words,
|
||||
@@ -45,7 +47,7 @@ class account_register_payments(models.TransientModel):
|
||||
return res
|
||||
|
||||
|
||||
class account_payment(models.Model):
|
||||
class AccountPayment(models.Model):
|
||||
_inherit = "account.payment"
|
||||
|
||||
check_amount_in_words = fields.Char(string="Amount in Words")
|
||||
@@ -56,15 +58,15 @@ class account_payment(models.Model):
|
||||
|
||||
@api.onchange('journal_id')
|
||||
def _onchange_journal_id(self):
|
||||
if hasattr(super(account_payment, self), '_onchange_journal_id'):
|
||||
super(account_payment, self)._onchange_journal_id()
|
||||
if hasattr(super(AccountPayment, self), '_onchange_journal_id'):
|
||||
super(AccountPayment, self)._onchange_journal_id()
|
||||
if self.journal_id.check_manual_sequencing:
|
||||
self.check_number = self.journal_id.check_sequence_id.number_next_actual
|
||||
|
||||
@api.onchange('amount')
|
||||
def _onchange_amount(self):
|
||||
if hasattr(super(account_payment, self), '_onchange_amount'):
|
||||
super(account_payment, self)._onchange_amount()
|
||||
if hasattr(super(AccountPayment, self), '_onchange_amount'):
|
||||
super(AccountPayment, self)._onchange_amount()
|
||||
check_amount_in_words = amount_to_text_en.amount_to_text(math.floor(self.amount), lang='en', currency='')
|
||||
check_amount_in_words = check_amount_in_words.replace(' and Zero Cent', '') # Ugh
|
||||
decimals = self.amount % 1
|
||||
@@ -73,7 +75,7 @@ class account_payment(models.Model):
|
||||
self.check_amount_in_words = check_amount_in_words
|
||||
|
||||
def _check_communication(self, payment_method_id, communication):
|
||||
super(account_payment, self)._check_communication(payment_method_id, communication)
|
||||
super(AccountPayment, self)._check_communication(payment_method_id, communication)
|
||||
if payment_method_id == self.env.ref('account_check_printing.account_payment_method_check').id:
|
||||
if not communication:
|
||||
return
|
||||
@@ -86,7 +88,7 @@ class account_payment(models.Model):
|
||||
and vals.get('check_manual_sequencing'):
|
||||
sequence = self.env['account.journal'].browse(vals['journal_id']).check_sequence_id
|
||||
vals.update({'check_number': sequence.next_by_id()})
|
||||
return super(account_payment, self.sudo()).create(vals)
|
||||
return super(AccountPayment, self.sudo()).create(vals)
|
||||
|
||||
@api.multi
|
||||
def print_checks(self):
|
||||
@@ -1,20 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_account_journal_form_inherited" model="ir.ui.view">
|
||||
<field name="name">account.journal.form.inherited</field>
|
||||
<field name="model">account.journal</field>
|
||||
<field name="inherit_id" ref="account.view_account_journal_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@name='advanced_settings']/group" position="inside">
|
||||
<group string="Check Printing" attrs="{'invisible': [('check_printing_payment_method_selected', '=', False)]}">
|
||||
<field name="check_printing_payment_method_selected" invisible="1"/>
|
||||
<field name="check_sequence_id" invisible="1"/>
|
||||
<field name="check_manual_sequencing"/>
|
||||
<field name="check_next_number" attrs="{'invisible': [('check_manual_sequencing', '=', False)]}"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
+19
-4
@@ -1,5 +1,5 @@
|
||||
<openerp>
|
||||
<data>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="account_journal_dashboard_kanban_view_inherited" model="ir.ui.view">
|
||||
<field name="name">account.journal.dashboard.kanban.inherited</field>
|
||||
<field name="model">account.journal</field>
|
||||
@@ -20,5 +20,20 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
<record id="view_account_journal_form_inherited" model="ir.ui.view">
|
||||
<field name="name">account.journal.form.inherited</field>
|
||||
<field name="model">account.journal</field>
|
||||
<field name="inherit_id" ref="account.view_account_journal_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[@name='advanced_settings']/group" position="inside">
|
||||
<group string="Check Printing" attrs="{'invisible': [('check_printing_payment_method_selected', '=', False)]}">
|
||||
<field name="check_printing_payment_method_selected" invisible="1"/>
|
||||
<field name="check_sequence_id" invisible="1"/>
|
||||
<field name="check_manual_sequencing"/>
|
||||
<field name="check_next_number" attrs="{'invisible': [('check_manual_sequencing', '=', False)]}"/>
|
||||
</group>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
+2
-4
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<record id="view_account_payment_form_inherited" model="ir.ui.view">
|
||||
<field name="name">account.payment.form.inherited</field>
|
||||
<field name="model">account.payment</field>
|
||||
@@ -61,5 +60,4 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,3 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import print_pre_numbered_checks
|
||||
import print_prenumbered_checks
|
||||
|
||||
+4
-2
@@ -1,8 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import api, fields, models
|
||||
from odoo import api, fields, models
|
||||
|
||||
class print_pre_numbered_checks(models.TransientModel):
|
||||
|
||||
class PrintPreNumberedChecks(models.TransientModel):
|
||||
_name = 'print.prenumbered.checks'
|
||||
_description = 'Print Pre-numbered Checks'
|
||||
|
||||
+2
-4
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" ?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
|
||||
<record id="print_pre_numbered_checks_view" model="ir.ui.view">
|
||||
<field name="name">Print Pre-numbered Checks</field>
|
||||
@@ -21,5 +20,4 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import tax_cash_basis
|
||||
import models
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name' : 'Account Tax Cash Basis',
|
||||
'version' : '1.1',
|
||||
@@ -13,7 +14,8 @@
|
||||
'website': 'https://www.odoo.com/page/accounting',
|
||||
'depends' : ['account'],
|
||||
'data': [
|
||||
'views/tax_cash_basis_view.xml',
|
||||
'views/account_tax_views.xml',
|
||||
'views/account_config_setting_views.xml',
|
||||
],
|
||||
'installable': True,
|
||||
'auto_install': False,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import account_config_settings
|
||||
import account_move
|
||||
import account_partial_reconcile
|
||||
import account_tax
|
||||
import res_company
|
||||
@@ -0,0 +1,13 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class AccountConfigSettings(models.TransientModel):
|
||||
_inherit = 'account.config.settings'
|
||||
|
||||
tax_cash_basis_journal_id = fields.Many2one(
|
||||
'account.journal',
|
||||
related='company_id.tax_cash_basis_journal_id',
|
||||
string="Tax Cash Basis Journal",)
|
||||
@@ -0,0 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class AccountMoveCashBasis(models.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
tax_cash_basis_rec_id = fields.Many2one(
|
||||
'account.partial.reconcile',
|
||||
string='Tax Cash Basis Entry of',
|
||||
help="Technical field used to keep track of the tax cash basis reconciliation."
|
||||
"This is needed when cancelling the source: it will post the inverse journal entry to cancel that part too.")
|
||||
+16
-43
@@ -1,64 +1,37 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.exceptions import UserError
|
||||
|
||||
class AccountTaxCashBasis(models.Model):
|
||||
_inherit = 'account.tax'
|
||||
|
||||
use_cash_basis = fields.Boolean('Use Cash Basis', help='Select this if the tax should use cash basis, which will \
|
||||
create an entry for this tax on a given account during reconciliation')
|
||||
cash_basis_account = fields.Many2one('account.account', string='Tax Received Account', domain=[('deprecated', '=', False)], help='Account use when \
|
||||
creating entry for tax cash basis')
|
||||
|
||||
|
||||
class AccountMoveCashBasis(models.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
tax_cash_basis_rec_id = fields.Many2one('account.partial.reconcile', string='Tax Cash Basis Entry of', help="Technical field used to keep track of the tax cash basis reconciliation. This is needed when cancelling the source: it will post the inverse journal entry to cancel that part too.")
|
||||
|
||||
|
||||
class AccountConfigSettings(models.TransientModel):
|
||||
_inherit = 'account.config.settings'
|
||||
|
||||
tax_cash_basis_journal_id = fields.Many2one('account.journal',
|
||||
related='company_id.tax_cash_basis_journal_id',
|
||||
string="Tax Cash Basis Journal",)
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
tax_cash_basis_journal_id = fields.Many2one('account.journal', string="Tax Cash Basis Journal")
|
||||
from odoo import api, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountPartialReconcileCashBasis(models.Model):
|
||||
_inherit = 'account.partial.reconcile'
|
||||
|
||||
def create_tax_cash_basis_entry(self, value_before_reconciliation):
|
||||
#Search in account_move if we have any taxes account move lines
|
||||
# Search in account_move if we have any taxes account move lines
|
||||
tax_group = {}
|
||||
total_by_cash_basis_account = {}
|
||||
for move in (self.debit_move_id.move_id, self.credit_move_id.move_id):
|
||||
for line in move.line_ids:
|
||||
if line.tax_line_id and line.tax_line_id.use_cash_basis:
|
||||
#amount to write is the current cash_basis amount minus the one before the reconciliation
|
||||
# amount to write is the current cash_basis amount minus the one before the reconciliation
|
||||
matched_percentage = value_before_reconciliation[move.id]
|
||||
amount = (line.credit_cash_basis - line.debit_cash_basis) - (line.credit - line.debit) * matched_percentage
|
||||
#group by line account
|
||||
# group by line account
|
||||
acc = line.account_id.id
|
||||
if tax_group.get(acc, False):
|
||||
tax_group[acc] += amount
|
||||
else:
|
||||
tax_group[acc] = amount
|
||||
#Group by cash basis account
|
||||
# Group by cash basis account
|
||||
acc = line.tax_line_id.cash_basis_account.id
|
||||
if total_by_cash_basis_account.get(acc, False):
|
||||
total_by_cash_basis_account[acc] += amount
|
||||
else:
|
||||
total_by_cash_basis_account[acc] = amount
|
||||
line_to_create = []
|
||||
for k,v in tax_group.items():
|
||||
for k, v in tax_group.items():
|
||||
line_to_create.append((0, 0, {
|
||||
'name': '/',
|
||||
'debit': v if v > 0 else 0.0,
|
||||
@@ -66,8 +39,8 @@ class AccountPartialReconcileCashBasis(models.Model):
|
||||
'account_id': k,
|
||||
}))
|
||||
|
||||
#Create counterpart vals
|
||||
for k,v in total_by_cash_basis_account.items():
|
||||
# Create counterpart vals
|
||||
for k, v in total_by_cash_basis_account.items():
|
||||
line_to_create.append((0, 0, {
|
||||
'name': '/',
|
||||
'debit': abs(v) if v < 0 else 0.0,
|
||||
@@ -75,9 +48,9 @@ class AccountPartialReconcileCashBasis(models.Model):
|
||||
'account_id': k,
|
||||
}))
|
||||
|
||||
#Create move
|
||||
# Create move
|
||||
if len(line_to_create) > 0:
|
||||
#Check if company_journal for cash basis is set if not, raise exception
|
||||
# Check if company_journal for cash basis is set if not, raise exception
|
||||
if not self.company_id.tax_cash_basis_journal_id:
|
||||
raise UserError(_('There is no tax cash basis journal defined ' \
|
||||
'for this company: "%s" \nConfigure it in Accounting/Configuration/Settings') % \
|
||||
@@ -86,7 +59,7 @@ class AccountPartialReconcileCashBasis(models.Model):
|
||||
'journal_id': self.company_id.tax_cash_basis_journal_id.id,
|
||||
'line_ids': line_to_create,
|
||||
'tax_cash_basis_rec_id': self.id})
|
||||
#post move
|
||||
# post move
|
||||
move.post()
|
||||
|
||||
@api.model
|
||||
@@ -96,15 +69,15 @@ class AccountPartialReconcileCashBasis(models.Model):
|
||||
aml.append(vals['debit_move_id'])
|
||||
if vals.get('credit_move_id', False):
|
||||
aml.append(vals['credit_move_id'])
|
||||
#Get value of matched percentage from both move before reconciliating
|
||||
# Get value of matched percentage from both move before reconciliating
|
||||
lines = self.env['account.move.line'].browse(aml)
|
||||
value_before_reconciliation = {}
|
||||
for line in lines:
|
||||
if not value_before_reconciliation.get(line.move_id.id, False):
|
||||
value_before_reconciliation[line.move_id.id] = line.move_id.matched_percentage
|
||||
#Reconcile
|
||||
# Reconcile
|
||||
res = super(AccountPartialReconcileCashBasis, self).create(vals)
|
||||
#eventually create a tax cash basis entry
|
||||
# eventually create a tax cash basis entry
|
||||
res.create_tax_cash_basis_entry(value_before_reconciliation)
|
||||
return res
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class AccountTax(models.Model):
|
||||
_inherit = 'account.tax'
|
||||
|
||||
use_cash_basis = fields.Boolean(
|
||||
'Use Cash Basis',
|
||||
help="Select this if the tax should use cash basis,"
|
||||
"which will create an entry for this tax on a given account during reconciliation")
|
||||
cash_basis_account = fields.Many2one(
|
||||
'account.account',
|
||||
string='Tax Received Account',
|
||||
domain=[('deprecated', '=', False)],
|
||||
help='Account use when creating entry for tax cash basis')
|
||||
@@ -0,0 +1,10 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class ResCompany(models.Model):
|
||||
_inherit = 'res.company'
|
||||
|
||||
tax_cash_basis_journal_id = fields.Many2one('account.journal', string="Tax Cash Basis Journal")
|
||||
@@ -0,0 +1,16 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="view_account_config_cash_basis_inherit_form">
|
||||
<field name="name">view.account.config.cash.basis.form.inherit</field>
|
||||
<field name="inherit_id" ref="account.view_account_config_settings"/>
|
||||
<field name="model">account.config.settings</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//p[@id='journal_config_message']" position="replace">
|
||||
<div>
|
||||
<label for="tax_cash_basis_journal_id"/>
|
||||
<field name="tax_cash_basis_journal_id" class="oe_inline"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_tax_form_cash_basis_inherit" model="ir.ui.view">
|
||||
<field name="name">tax.form.cash.basis.inherit</field>
|
||||
<field name="model">account.tax</field>
|
||||
<field name="inherit_id" ref="account.view_tax_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='advanced_booleans']" position="inside">
|
||||
<field name="use_cash_basis" attrs="{'invisible':[('amount_type','=', 'group')]}"/>
|
||||
<field name="cash_basis_account" attrs="{'invisible': [('use_cash_basis', '=', False)], 'required': [('use_cash_basis', '=', True)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -1,32 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
|
||||
<record id="view_tax_form_cash_basis_inherit" model="ir.ui.view">
|
||||
<field name="name">tax.form.cash.basis.inherit</field>
|
||||
<field name="model">account.tax</field>
|
||||
<field name="inherit_id" ref="account.view_tax_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//group[@name='advanced_booleans']" position="inside">
|
||||
<field name="use_cash_basis" attrs="{'invisible':[('amount_type','=', 'group')]}"/>
|
||||
<field name="cash_basis_account" attrs="{'invisible': [('use_cash_basis', '=', False)], 'required': [('use_cash_basis', '=', True)]}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_account_config_cash_basis_inherit_form">
|
||||
<field name="name">view.account.config.cash.basis.form.inherit</field>
|
||||
<field name="inherit_id" ref="account.view_account_config_settings"/>
|
||||
<field name="model">account.config.settings</field>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//p[@id='journal_config_message']" position="replace">
|
||||
<div>
|
||||
<label for="tax_cash_basis_journal_id"/>
|
||||
<field name="tax_cash_basis_journal_id" class="oe_inline"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,2 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import account_tax_python
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import models
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
{
|
||||
'name': "Define Taxes as Python Code",
|
||||
'summary': """
|
||||
@@ -14,6 +16,6 @@
|
||||
'version': '1.0',
|
||||
'depends': ['account'],
|
||||
'data': [
|
||||
'account_tax_python.xml',
|
||||
'views/account_tax_views.xml',
|
||||
],
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import account_tax
|
||||
+6
-4
@@ -1,7 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import models, fields, api
|
||||
from odoo.tools.safe_eval import safe_eval
|
||||
|
||||
from openerp import models, fields, api
|
||||
from openerp.tools.safe_eval import safe_eval
|
||||
|
||||
class AccountTaxPython(models.Model):
|
||||
_inherit = "account.tax"
|
||||
@@ -24,7 +26,6 @@ class AccountTaxPython(models.Model):
|
||||
":param product: product.product recordset singleton or None\n"
|
||||
":param partner: res.partner recordset singleton or None")
|
||||
|
||||
|
||||
def _compute_amount(self, base_amount, price_unit, quantity=1.0, product=None, partner=None):
|
||||
self.ensure_one()
|
||||
if self.amount_type == 'code':
|
||||
@@ -39,7 +40,7 @@ class AccountTaxPython(models.Model):
|
||||
taxes = self.env['account.tax']
|
||||
company = self.env.user.company_id
|
||||
for tax in self:
|
||||
localdict = {'price_unit':price_unit, 'quantity': quantity, 'product':product, 'partner':partner, 'company': company}
|
||||
localdict = {'price_unit': price_unit, 'quantity': quantity, 'product': product, 'partner': partner, 'company': company}
|
||||
safe_eval(tax.python_applicable, localdict, mode="exec", nocopy=True)
|
||||
if localdict.get('result', False):
|
||||
taxes += tax
|
||||
@@ -54,6 +55,7 @@ class AccountTaxPython(models.Model):
|
||||
recs = self.browse(cr, uid, ids, context=context)
|
||||
return AccountTaxPython.compute_all(recs, price_unit, currency, quantity, product, partner)
|
||||
|
||||
|
||||
class AccountTaxTemplatePython(models.Model):
|
||||
_inherit = 'account.tax.template'
|
||||
|
||||
+2
-4
@@ -1,6 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<record id="view_tax_form_inherited" model="ir.ui.view">
|
||||
<field name="name">account.tax.form.inherited</field>
|
||||
<field name="model">account.tax</field>
|
||||
@@ -18,5 +17,4 @@
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -1,4 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import account_test
|
||||
|
||||
import models
|
||||
import report
|
||||
|
||||
@@ -21,10 +21,10 @@ and print the report from Print button in header area.
|
||||
'depends': ['account'],
|
||||
'data': [
|
||||
'security/ir.model.access.csv',
|
||||
'account_test_view.xml',
|
||||
'account_test_report.xml',
|
||||
'account_test_data.xml',
|
||||
'views/report_accounttest.xml',
|
||||
'views/accounting_assert_test_views.xml',
|
||||
'report/accounting_assert_test_reports.xml',
|
||||
'data/accounting_assert_test_data.xml',
|
||||
'report/report_account_test_templates.xml',
|
||||
],
|
||||
'active': False,
|
||||
'installable': True
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import accounting_assert_test
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp import fields, models
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import fields, models
|
||||
|
||||
CODE_EXEC_DEFAULT = '''\
|
||||
res = []
|
||||
@@ -1,2 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import account_test_report
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import report_account_test
|
||||
|
||||
+4
-2
@@ -1,7 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import datetime
|
||||
from openerp import api, models, _
|
||||
from openerp.tools.safe_eval import safe_eval as eval
|
||||
from odoo import api, models, _
|
||||
from odoo.tools.safe_eval import safe_eval as eval
|
||||
#
|
||||
# Use period and Journal for selection or resources
|
||||
#
|
||||
@@ -1,4 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import account_voucher
|
||||
import models
|
||||
|
||||
@@ -30,10 +30,9 @@ This module manages:
|
||||
'demo' : [],
|
||||
'data' : [
|
||||
'security/ir.model.access.csv',
|
||||
'account_voucher_view.xml',
|
||||
'voucher_sales_purchase_view.xml',
|
||||
'views/account_voucher_views.xml',
|
||||
'security/account_voucher_security.xml',
|
||||
'account_voucher_data.xml',
|
||||
'data/account_voucher_data.xml',
|
||||
],
|
||||
'test' : [
|
||||
'test/account_voucher_users.yml',
|
||||
|
||||
@@ -1,173 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="view_voucher_tree">
|
||||
<field name="name">account.voucher.tree</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-info="state == 'draft'" decoration-muted="state == 'cancel'" string="Voucher Entries">
|
||||
<field name="date"/>
|
||||
<field name="number"/>
|
||||
<field name="partner_id" string="Customer"/>
|
||||
<field name="voucher_type" invisible="context.get('visible', True)"/>
|
||||
<field name="amount" sum="Total Amount"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_voucher_tree_purchase">
|
||||
<field name="name">account.voucher.tree.supplier</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-info="state == 'draft'" decoration-muted="state == 'cancel'" string="Voucher Entries" create="0" edit="0">
|
||||
<field name="date"/>
|
||||
<field name="number"/>
|
||||
<field name="reference"/>
|
||||
<field name="partner_id" string="Vendor"/>
|
||||
<field name="voucher_type" invisible="context.get('visible', True)"/>
|
||||
<field name="amount" sum="Total Amount"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_voucher_kanban">
|
||||
<field name="name">account.voucher.kanban</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_mobile">
|
||||
<field name="number"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="amount"/>
|
||||
<field name="date"/>
|
||||
<field name="state"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<strong><span><t t-esc="record.partner_id.value"/></span></strong>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<strong><span class="pull-right text-right"><t t-esc="record.amount.value"/></span></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6 text-muted">
|
||||
<span><t t-esc="record.number.value"/> <t t-esc="record.date.value"/></span>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<span class="pull-right text-right">
|
||||
<field name="state" widget="kanban_label_selection" options="{'classes': {'draft': 'default', 'cancel': 'default', 'none': 'danger', 'proforma': 'warning',
|
||||
'posted': 'success'}}"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_voucher_line_form">
|
||||
<field name="name">account.voucher.line.form</field>
|
||||
<field name="model">account.voucher.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Voucher Lines">
|
||||
<group>
|
||||
<group>
|
||||
<field name="product_id"/>
|
||||
<field name="quantity" class="oe_inline"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="price_subtotal"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="account_id"/>
|
||||
<field name="tax_ids" widget="many2many_tags"/>
|
||||
<field name="account_analytic_id" domain="[('company_id', '=', company_id)]" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<label for="name"/>
|
||||
<field name="name"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_voucher_line_tree">
|
||||
<field name="name">account.voucher.line.tree</field>
|
||||
<field name="model">account.voucher.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Voucher Lines" editable="bottom">
|
||||
<field name="product_id"
|
||||
on_change="product_id_change(product_id, parent.partner_id, price_unit, company_id, parent.currency_id, parent.voucher_type)" />
|
||||
<field name="name"/>
|
||||
<field name="account_id"/>
|
||||
<field name="account_analytic_id" domain="[('company_id', '=', company_id)]" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="quantity"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="tax_ids" widget="many2many_tags"/>
|
||||
<field name="price_subtotal"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_voucher_filter" model="ir.ui.view">
|
||||
<field name="name">account.voucher.select</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="priority">1</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Vouchers">
|
||||
<field name="number" string="Voucher"/>
|
||||
<field name="date"/>
|
||||
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Vouchers"/>
|
||||
<filter string="Posted" domain="[('state','=','posted')]" help="Posted Vouchers"/>
|
||||
<separator/>
|
||||
<filter string="To Review" domain="[('state','=','posted')]" help="To Review"/>
|
||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
||||
<field name="journal_id" widget="selection" context="{'journal_id': self, 'set_visible':False}" /> <!-- Keep widget=selection on this field to pass numeric `self` value, which is not the case for regular m2o widgets! -->
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Journal" domain="[]" context="{'group_by':'journal_id'}"/>
|
||||
<filter string="Date" domain="[]" context="{'group_by':'date','visible':True}"/>
|
||||
<filter string="Status" domain="[]" context="{'group_by':'state'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="account_cash_statement_graph" model="ir.ui.view">
|
||||
<field name="name">account.voucher.graph</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Voucher Statistics" type="bar">
|
||||
<field name="date"/>
|
||||
<field name="amount" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window
|
||||
id="act_journal_voucher_open"
|
||||
name="Voucher Entries"
|
||||
context="{'search_default_journal_id': active_id, 'default_journal_id': active_id}"
|
||||
res_model="account.voucher"
|
||||
src_model="account.journal"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_review_voucher_list">
|
||||
<field name="name">Vouchers Entries</field>
|
||||
<field name="res_model">account.voucher</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" eval="view_voucher_tree"/>
|
||||
<field name="domain">[('state','=','posted')]</field>
|
||||
<field name="context">{'state':'posted', 'voucher_type': voucher_type}</field>
|
||||
<field name="search_view_id" ref="view_voucher_filter"/>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
|
||||
<!-- notify all employees of module installation -->
|
||||
@@ -22,4 +22,4 @@
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import account_voucher
|
||||
+80
-67
@@ -2,12 +2,78 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
|
||||
from openerp import fields, models, api, _
|
||||
import openerp.addons.decimal_precision as dp
|
||||
from openerp.exceptions import UserError
|
||||
from odoo import fields, models, api, _
|
||||
import odoo.addons.decimal_precision as dp
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class AccountVoucher(models.Model):
|
||||
_name = 'account.voucher'
|
||||
_description = 'Accounting Voucher'
|
||||
_inherit = ['mail.thread']
|
||||
_order = "date desc, id desc"
|
||||
|
||||
@api.model
|
||||
def _default_journal(self):
|
||||
voucher_type = self._context.get('voucher_type', 'sale')
|
||||
company_id = self._context.get('company_id', self.env.user.company_id.id)
|
||||
domain = [
|
||||
('type', '=', voucher_type),
|
||||
('company_id', '=', company_id),
|
||||
]
|
||||
return self.env['account.journal'].search(domain, limit=1)
|
||||
|
||||
voucher_type = fields.Selection([
|
||||
('sale', 'Sale'),
|
||||
('purchase', 'Purchase')
|
||||
], string='Type', readonly=True, states={'draft': [('readonly', False)]}, oldname="type")
|
||||
name = fields.Char('Payment Reference',
|
||||
readonly=True, states={'draft': [('readonly', False)]}, default='')
|
||||
date = fields.Date("Bill Date", readonly=True,
|
||||
select=True, states={'draft': [('readonly', False)]},
|
||||
copy=False, default=fields.Date.context_today)
|
||||
account_date = fields.Date("Accounting Date",
|
||||
readonly=True, select=True, states={'draft': [('readonly', False)]},
|
||||
help="Effective date for accounting entries", copy=False, default=fields.Date.context_today)
|
||||
journal_id = fields.Many2one('account.journal', 'Journal',
|
||||
required=True, readonly=True, states={'draft': [('readonly', False)]}, default=_default_journal)
|
||||
account_id = fields.Many2one('account.account', 'Account',
|
||||
required=True, readonly=True, states={'draft': [('readonly', False)]},
|
||||
domain="[('deprecated', '=', False), ('internal_type','=', (pay_now == 'pay_now' and 'liquidity' or voucher_type == 'purchase' and 'payable' or 'receivable'))]")
|
||||
line_ids = fields.One2many('account.voucher.line', 'voucher_id', 'Voucher Lines',
|
||||
readonly=True, copy=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
narration = fields.Text('Notes', readonly=True, states={'draft': [('readonly', False)]})
|
||||
currency_id = fields.Many2one('res.currency', compute='_get_journal_currency',
|
||||
string='Currency', readonly=True, required=True, default=lambda self: self._get_currency())
|
||||
company_id = fields.Many2one('res.company', 'Company',
|
||||
required=True, readonly=True, states={'draft': [('readonly', False)]},
|
||||
related='journal_id.company_id', default=lambda self: self._get_company())
|
||||
state = fields.Selection([
|
||||
('draft', 'Draft'),
|
||||
('cancel', 'Cancelled'),
|
||||
('proforma', 'Pro-forma'),
|
||||
('posted', 'Posted')
|
||||
], 'Status', readonly=True, track_visibility='onchange', copy=False, default='draft',
|
||||
help=" * The 'Draft' status is used when a user is encoding a new and unconfirmed Voucher.\n"
|
||||
" * The 'Pro-forma' status is used when the voucher does not have a voucher number.\n"
|
||||
" * The 'Posted' status is used when user create voucher,a voucher number is generated and voucher entries are created in account.\n"
|
||||
" * The 'Cancelled' status is used when user cancel voucher.")
|
||||
reference = fields.Char('Bill Reference', readonly=True, states={'draft': [('readonly', False)]},
|
||||
help="The partner reference of this document.", copy=False)
|
||||
amount = fields.Monetary(string='Total', store=True, readonly=True, compute='_compute_total')
|
||||
tax_amount = fields.Monetary(readonly=True, store=True, compute='_compute_total')
|
||||
tax_correction = fields.Monetary(readonly=True, states={'draft': [('readonly', False)]},
|
||||
help='In case we have a rounding problem in the tax, use this field to correct it')
|
||||
number = fields.Char(readonly=True, copy=False)
|
||||
move_id = fields.Many2one('account.move', 'Journal Entry', copy=False)
|
||||
partner_id = fields.Many2one('res.partner', 'Partner', change_default=1, readonly=True, states={'draft': [('readonly', False)]})
|
||||
paid = fields.Boolean(compute='_check_paid', help="The Voucher has been totally paid.")
|
||||
pay_now = fields.Selection([
|
||||
('pay_now', 'Pay Directly'),
|
||||
('pay_later', 'Pay Later'),
|
||||
], 'Payment', select=True, readonly=True, states={'draft': [('readonly', False)]}, default='pay_later')
|
||||
date_due = fields.Date('Due Date', readonly=True, select=True, states={'draft': [('readonly', False)]})
|
||||
|
||||
@api.one
|
||||
@api.depends('move_id.line_ids.reconciled', 'move_id.line_ids.account_id.internal_type')
|
||||
@@ -35,16 +101,6 @@ class AccountVoucher(models.Model):
|
||||
def _get_journal_currency(self):
|
||||
self.currency_id = self.journal_id.currency_id.id or self.company_id.currency_id.id
|
||||
|
||||
@api.model
|
||||
def _default_journal(self):
|
||||
voucher_type = self._context.get('voucher_type', 'sale')
|
||||
company_id = self._context.get('company_id', self.env.user.company_id.id)
|
||||
domain = [
|
||||
('type', '=', voucher_type),
|
||||
('company_id', '=', company_id),
|
||||
]
|
||||
return self.env['account.journal'].search(domain, limit=1)
|
||||
|
||||
@api.multi
|
||||
@api.depends('tax_correction', 'line_ids.price_subtotal')
|
||||
def _compute_total(self):
|
||||
@@ -63,50 +119,6 @@ class AccountVoucher(models.Model):
|
||||
def _get_account(self):
|
||||
self.account_id = self.account_pay_now_id if self.pay_now == 'pay_now' else self.account_pay_later_id
|
||||
|
||||
_name = 'account.voucher'
|
||||
_description = 'Accounting Voucher'
|
||||
_inherit = ['mail.thread']
|
||||
_order = "date desc, id desc"
|
||||
|
||||
voucher_type = fields.Selection([('sale', 'Sale'), ('purchase', 'Purchase')], string='Type', readonly=True, states={'draft': [('readonly', False)]}, oldname="type")
|
||||
name = fields.Char('Payment Reference', readonly=True, states={'draft': [('readonly', False)]}, default='')
|
||||
date = fields.Date("Bill Date", readonly=True, select=True, states={'draft': [('readonly', False)]},
|
||||
copy=False, default=fields.Date.context_today)
|
||||
account_date = fields.Date("Accounting Date", readonly=True, select=True, states={'draft': [('readonly', False)]},
|
||||
help="Effective date for accounting entries", copy=False, default=fields.Date.context_today)
|
||||
journal_id = fields.Many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft': [('readonly', False)]}, default=_default_journal)
|
||||
account_id = fields.Many2one('account.account', 'Account', required=True, readonly=True, states={'draft': [('readonly', False)]}, domain="[('deprecated', '=', False), ('internal_type','=', (pay_now == 'pay_now' and 'liquidity' or voucher_type == 'purchase' and 'payable' or 'receivable'))]")
|
||||
line_ids = fields.One2many('account.voucher.line', 'voucher_id', 'Voucher Lines',
|
||||
readonly=True, copy=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
narration = fields.Text('Notes', readonly=True, states={'draft': [('readonly', False)]})
|
||||
currency_id = fields.Many2one('res.currency', compute='_get_journal_currency', string='Currency', readonly=True, required=True, default=lambda self: self._get_currency())
|
||||
company_id = fields.Many2one('res.company', 'Company', required=True, readonly=True, states={'draft': [('readonly', False)]}, related='journal_id.company_id', default=lambda self: self._get_company())
|
||||
state = fields.Selection(
|
||||
[('draft', 'Draft'),
|
||||
('cancel', 'Cancelled'),
|
||||
('proforma', 'Pro-forma'),
|
||||
('posted', 'Posted')
|
||||
], 'Status', readonly=True, track_visibility='onchange', copy=False, default='draft',
|
||||
help=" * The 'Draft' status is used when a user is encoding a new and unconfirmed Voucher.\n"
|
||||
" * The 'Pro-forma' status is used when the voucher does not have a voucher number.\n"
|
||||
" * The 'Posted' status is used when user create voucher,a voucher number is generated and voucher entries are created in account.\n"
|
||||
" * The 'Cancelled' status is used when user cancel voucher.")
|
||||
reference = fields.Char('Bill Reference', readonly=True, states={'draft': [('readonly', False)]},
|
||||
help="The partner reference of this document.", copy=False)
|
||||
amount = fields.Monetary(string='Total', store=True, readonly=True, compute='_compute_total')
|
||||
tax_amount = fields.Monetary(readonly=True, store=True, compute='_compute_total')
|
||||
tax_correction = fields.Monetary(readonly=True, states={'draft': [('readonly', False)]}, help='In case we have a rounding problem in the tax, use this field to correct it')
|
||||
number = fields.Char(readonly=True, copy=False)
|
||||
move_id = fields.Many2one('account.move', 'Journal Entry', copy=False)
|
||||
partner_id = fields.Many2one('res.partner', 'Partner', change_default=1, readonly=True, states={'draft': [('readonly', False)]})
|
||||
paid = fields.Boolean(compute='_check_paid', help="The Voucher has been totally paid.")
|
||||
pay_now = fields.Selection([
|
||||
('pay_now', 'Pay Directly'),
|
||||
('pay_later', 'Pay Later'),
|
||||
], 'Payment', select=True, readonly=True, states={'draft': [('readonly', False)]}, default='pay_later')
|
||||
date_due = fields.Date('Due Date', readonly=True, select=True, states={'draft': [('readonly', False)]})
|
||||
|
||||
@api.onchange('date')
|
||||
def onchange_date(self):
|
||||
self.account_date = self.date
|
||||
@@ -235,7 +247,8 @@ class AccountVoucher(models.Model):
|
||||
if not line.price_subtotal:
|
||||
continue
|
||||
# convert the amount set on the voucher line into the currency of the voucher's company
|
||||
# this calls res_curreny.compute() with the right context, so that it will take either the rate on the voucher if it is relevant or will use the default behaviour
|
||||
# this calls res_curreny.compute() with the right context,
|
||||
# so that it will take either the rate on the voucher if it is relevant or will use the default behaviour
|
||||
amount = self._convert_amount(line.price_unit*line.quantity)
|
||||
move_line = {
|
||||
'journal_id': self.journal_id.id,
|
||||
@@ -307,18 +320,10 @@ class AccountVoucher(models.Model):
|
||||
return super(AccountVoucher, self)._track_subtype(init_values)
|
||||
|
||||
|
||||
class account_voucher_line(models.Model):
|
||||
class AccountVoucherLine(models.Model):
|
||||
_name = 'account.voucher.line'
|
||||
_description = 'Voucher Lines'
|
||||
|
||||
@api.one
|
||||
@api.depends('price_unit', 'tax_ids', 'quantity', 'product_id', 'voucher_id.currency_id')
|
||||
def _compute_subtotal(self):
|
||||
self.price_subtotal = self.quantity * self.price_unit
|
||||
if self.tax_ids:
|
||||
taxes = self.tax_ids.compute_all(self.price_unit, self.voucher_id.currency_id, self.quantity, product=self.product_id, partner=self.voucher_id.partner_id)
|
||||
self.price_subtotal = taxes['total_excluded']
|
||||
|
||||
name = fields.Text(string='Description', required=True)
|
||||
sequence = fields.Integer(default=10,
|
||||
help="Gives the sequence of this line when displaying the voucher.")
|
||||
@@ -338,6 +343,14 @@ class account_voucher_line(models.Model):
|
||||
tax_ids = fields.Many2many('account.tax', string='Tax', help="Only for tax excluded from price")
|
||||
currency_id = fields.Many2one('res.currency', related='voucher_id.currency_id')
|
||||
|
||||
@api.one
|
||||
@api.depends('price_unit', 'tax_ids', 'quantity', 'product_id', 'voucher_id.currency_id')
|
||||
def _compute_subtotal(self):
|
||||
self.price_subtotal = self.quantity * self.price_unit
|
||||
if self.tax_ids:
|
||||
taxes = self.tax_ids.compute_all(self.price_unit, self.voucher_id.currency_id, self.quantity, product=self.product_id, partner=self.voucher_id.partner_id)
|
||||
self.price_subtotal = taxes['total_excluded']
|
||||
|
||||
def _get_account(self, product, fpos, type):
|
||||
accounts = product.product_tmpl_id.get_product_accounts(fpos)
|
||||
if type == 'sale':
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="voucher_comp_rule" model="ir.rule">
|
||||
<field name="name">Voucher multi-company</field>
|
||||
@@ -14,4 +14,4 @@
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
uid: 'res_users_account_voucher_user'
|
||||
|
||||
-
|
||||
In order to check account voucher module in OpenERP I create a customer voucher
|
||||
In order to check account voucher module in Odoo I create a customer voucher
|
||||
-
|
||||
!record {model: account.voucher, id: account_voucher_voucherforaxelor0, view: view_sale_receipt_form}:
|
||||
voucher_type: sale
|
||||
|
||||
+170
-5
@@ -1,6 +1,173 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
<record model="ir.ui.view" id="view_voucher_tree">
|
||||
<field name="name">account.voucher.tree</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-info="state == 'draft'" decoration-muted="state == 'cancel'" string="Voucher Entries">
|
||||
<field name="date"/>
|
||||
<field name="number"/>
|
||||
<field name="partner_id" string="Customer"/>
|
||||
<field name="voucher_type" invisible="context.get('visible', True)"/>
|
||||
<field name="amount" sum="Total Amount"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_voucher_tree_purchase">
|
||||
<field name="name">account.voucher.tree.supplier</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-info="state == 'draft'" decoration-muted="state == 'cancel'" string="Voucher Entries" create="0" edit="0">
|
||||
<field name="date"/>
|
||||
<field name="number"/>
|
||||
<field name="reference"/>
|
||||
<field name="partner_id" string="Vendor"/>
|
||||
<field name="voucher_type" invisible="context.get('visible', True)"/>
|
||||
<field name="amount" sum="Total Amount"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_voucher_kanban">
|
||||
<field name="name">account.voucher.kanban</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="arch" type="xml">
|
||||
<kanban class="o_kanban_mobile">
|
||||
<field name="number"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="amount"/>
|
||||
<field name="date"/>
|
||||
<field name="state"/>
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
|
||||
<div class="row">
|
||||
<div class="col-xs-6">
|
||||
<strong><span><t t-esc="record.partner_id.value"/></span></strong>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<strong><span class="pull-right text-right"><t t-esc="record.amount.value"/></span></strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-6 text-muted">
|
||||
<span><t t-esc="record.number.value"/> <t t-esc="record.date.value"/></span>
|
||||
</div>
|
||||
<div class="col-xs-6">
|
||||
<span class="pull-right text-right">
|
||||
<field name="state" widget="kanban_label_selection" options="{'classes': {'draft': 'default', 'cancel': 'default', 'none': 'danger', 'proforma': 'warning',
|
||||
'posted': 'success'}}"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
</kanban>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_voucher_line_form">
|
||||
<field name="name">account.voucher.line.form</field>
|
||||
<field name="model">account.voucher.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Voucher Lines">
|
||||
<group>
|
||||
<group>
|
||||
<field name="product_id"/>
|
||||
<field name="quantity" class="oe_inline"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="price_subtotal"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="account_id"/>
|
||||
<field name="tax_ids" widget="many2many_tags"/>
|
||||
<field name="account_analytic_id" domain="[('company_id', '=', company_id)]" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="company_id" groups="base.group_multi_company" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<label for="name"/>
|
||||
<field name="name"/>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_voucher_line_tree">
|
||||
<field name="name">account.voucher.line.tree</field>
|
||||
<field name="model">account.voucher.line</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Voucher Lines" editable="bottom">
|
||||
<field name="product_id"
|
||||
on_change="product_id_change(product_id, parent.partner_id, price_unit, company_id, parent.currency_id, parent.voucher_type)" />
|
||||
<field name="name"/>
|
||||
<field name="account_id"/>
|
||||
<field name="account_analytic_id" domain="[('company_id', '=', company_id)]" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="quantity"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="tax_ids" widget="many2many_tags"/>
|
||||
<field name="price_subtotal"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="company_id" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_voucher_filter" model="ir.ui.view">
|
||||
<field name="name">account.voucher.select</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="priority">1</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Search Vouchers">
|
||||
<field name="number" string="Voucher"/>
|
||||
<field name="date"/>
|
||||
<filter string="Draft" domain="[('state','=','draft')]" help="Draft Vouchers"/>
|
||||
<filter string="Posted" domain="[('state','=','posted')]" help="Posted Vouchers"/>
|
||||
<separator/>
|
||||
<filter string="To Review" domain="[('state','=','posted')]" help="To Review"/>
|
||||
<field name="partner_id" filter_domain="[('partner_id', 'child_of', self)]"/>
|
||||
<field name="journal_id" widget="selection" context="{'journal_id': self, 'set_visible':False}" /> <!-- Keep widget=selection on this field to pass numeric `self` value, which is not the case for regular m2o widgets! -->
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Journal" domain="[]" context="{'group_by':'journal_id'}"/>
|
||||
<filter string="Date" domain="[]" context="{'group_by':'date','visible':True}"/>
|
||||
<filter string="Status" domain="[]" context="{'group_by':'state'}"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="account_cash_statement_graph" model="ir.ui.view">
|
||||
<field name="name">account.voucher.graph</field>
|
||||
<field name="model">account.voucher</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Voucher Statistics" type="bar">
|
||||
<field name="date"/>
|
||||
<field name="amount" operator="+"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<act_window
|
||||
id="act_journal_voucher_open"
|
||||
name="Voucher Entries"
|
||||
context="{'search_default_journal_id': active_id, 'default_journal_id': active_id}"
|
||||
res_model="account.voucher"
|
||||
src_model="account.journal"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_review_voucher_list">
|
||||
<field name="name">Vouchers Entries</field>
|
||||
<field name="res_model">account.voucher</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" eval="view_voucher_tree"/>
|
||||
<field name="domain">[('state','=','posted')]</field>
|
||||
<field name="context">{'state':'posted', 'voucher_type': voucher_type}</field>
|
||||
<field name="search_view_id" ref="view_voucher_filter"/>
|
||||
</record>
|
||||
|
||||
<record id="view_voucher_filter_vendor" model="ir.ui.view">
|
||||
<field name="name">account.voucher.purchase.select</field>
|
||||
<field name="model">account.voucher</field>
|
||||
@@ -268,6 +435,4 @@
|
||||
|
||||
<menuitem id="menu_action_purchase_receipt"
|
||||
action="action_purchase_receipt" parent="account.menu_finance_payables" sequence="4"/>
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user