2012-03-07 12:43:01 +00:00
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
2012-03-09 10:38:12 +00:00
import time
import datetime
from dateutil . relativedelta import relativedelta
2012-03-07 12:43:01 +00:00
from operator import itemgetter
2012-03-09 10:38:12 +00:00
from os . path import join as opj
2012-03-07 12:43:01 +00:00
from tools . translate import _
2012-03-28 08:03:26 +00:00
from osv import osv , fields
2012-03-09 10:38:12 +00:00
import tools
2012-03-07 12:43:01 +00:00
class account_configuration ( osv . osv_memory ) :
2012-03-28 09:05:10 +00:00
_name = ' account.config.settings '
2012-03-07 12:43:01 +00:00
_inherit = ' res.config.settings '
2012-03-12 11:58:53 +00:00
2012-03-07 12:43:01 +00:00
def _get_charts ( self , cr , uid , context = None ) :
modules = self . pool . get ( ' ir.module.module ' )
# Looking for the module with the 'Account Charts' category
category_name , category_id = self . pool . get ( ' ir.model.data ' ) . get_object_reference ( cr , uid , ' base ' , ' module_category_localization_account_charts ' )
ids = modules . search ( cr , uid , [ ( ' category_id ' , ' = ' , category_id ) ] , context = context )
charts = list (
sorted ( ( ( m . name , m . shortdesc )
for m in modules . browse ( cr , uid , ids , context = context ) ) ,
key = itemgetter ( 1 ) ) )
charts . insert ( 0 , ( ' configurable ' , ' Generic Chart Of Accounts ' ) )
return charts
_columns = {
2012-03-28 09:36:17 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' , required = True ) ,
' has_default_company ' : fields . boolean ( ' Has default company ' , readonly = True ) ,
' currency_id ' : fields . related ( ' company_id ' , ' currency_id ' , type = ' many2one ' , relation = ' res.currency ' ,
string = ' Main currency ' , help = " Main currency of the company. " ) ,
' paypal_account ' : fields . related ( ' company_id ' , ' paypal_account ' , type = ' char ' , size = 128 ,
string = ' Paypal account ' , help = " Paypal username (usually email) for receiving online payments. " ) ,
' company_footer ' : fields . related ( ' company_id ' , ' rml_footer2 ' , type = ' char ' , size = 250 , readonly = True ,
string = ' Footer of reports ' , help = " Footer of reports based on your bank accounts. " ) ,
2012-03-28 08:03:26 +00:00
' charts ' : fields . selection ( _get_charts , ' Chart of Accounts ' , required = True ,
help = """ Installs localized accounting charts to match as closely as
possible the accounting needs of your company based on your country . """ ),
' date_start ' : fields . date ( ' Start Date ' , required = True ) ,
' date_stop ' : fields . date ( ' End Date ' , required = True ) ,
' period ' : fields . selection ( [ ( ' month ' , ' Monthly ' ) , ( ' 3months ' , ' 3 Monthly ' ) ] , ' Periods ' , required = True ) ,
' chart_template_id ' : fields . many2one ( ' account.chart.template ' , ' Chart Template ' ) ,
' fiscalyear_id ' : fields . many2one ( ' account.fiscalyear ' , ' Fiscal Year ' ) ,
2012-03-28 09:36:17 +00:00
' sale_journal_id ' : fields . many2one ( ' account.journal ' , ' Sale Journal ' ) ,
' sale_sequence_prefix ' : fields . related ( ' sale_journal_id ' , ' sequence_id ' , ' prefix ' , type = ' char ' , string = ' Invoice Sequence ' ) ,
' sale_sequence_next ' : fields . related ( ' sale_journal_id ' , ' sequence_id ' , ' number_next ' , type = ' integer ' , string = ' Invoice Sequence Next Number ' ) ,
' sale_refund_journal_id ' : fields . many2one ( ' account.journal ' , ' Sale Refund Journal ' ) ,
' sale_refund_sequence_prefix ' : fields . related ( ' sale_refund_journal_id ' , ' sequence_id ' , ' prefix ' , type = ' char ' , string = ' Refund Sequence ' ) ,
' sale_refund_sequence_next ' : fields . related ( ' sale_refund_journal_id ' , ' sequence_id ' , ' number_next ' , type = ' integer ' , string = ' Refund Sequence Next Number ' ) ,
' purchase_journal_id ' : fields . many2one ( ' account.journal ' , ' Purchase Journal ' ) ,
' purchase_sequence_prefix ' : fields . related ( ' purchase_journal_id ' , ' sequence_id ' , ' prefix ' , type = ' char ' , string = ' Supplier Invoice Sequence ' ) ,
' purchase_sequence_next ' : fields . related ( ' purchase_journal_id ' , ' sequence_id ' , ' number_next ' , type = ' integer ' , string = ' Supplier Invoice Sequence Next Number ' ) ,
' purchase_refund_journal_id ' : fields . many2one ( ' account.journal ' , ' Purchase Refund Journal ' ) ,
' purchase_refund_sequence_prefix ' : fields . related ( ' purchase_refund_journal_id ' , ' sequence_id ' , ' prefix ' , type = ' char ' , string = ' Supplier Refund Sequence ' ) ,
' purchase_refund_sequence_next ' : fields . related ( ' purchase_refund_journal_id ' , ' sequence_id ' , ' number_next ' , type = ' integer ' , string = ' Supplier Refund Sequence Next Number ' ) ,
2012-03-07 12:43:01 +00:00
2012-03-28 08:03:26 +00:00
' module_account_check_writing ' : fields . boolean ( ' Support check writings ' ,
help = """ This allows you to check writing and printing.
This installs the module account_check_writing . """ ),
' module_account_accountant ' : fields . boolean ( ' Accountant Features ' ,
help = """ This allows you to access all the accounting features, like the journal items and the chart of accounts.
This installs the module account_accountant . """ ),
' module_account_asset ' : fields . boolean ( ' Assets Management ' ,
help = """ This allows you to manage the assets owned by a company or a person.
It keeps track of the depreciation occurred on those assets , and creates account move for those depreciation lines .
This installs the module account_asset . """ ),
' module_account_budget ' : fields . boolean ( ' Budgets Management ' ,
help = """ This allows accountants to manage analytic and crossovered budgets.
Once the master budgets and the budgets are defined ,
the project managers can set the planned amount on each analytic account .
This installs the module account_budget . """ ),
' module_account_payment ' : fields . boolean ( ' Supplier Payment Orders ' ,
help = """ This allows you to create and manage your payment orders, with purposes to
* serve as base for an easy plug - in of various automated payment mechanisms , and
* provide a more efficient way to manage invoice payments .
This installs the module account_payment . """ ),
' module_account_voucher ' : fields . boolean ( ' Manage Customer Payments ' ,
help = """ This includes all the basic requirements of voucher entries for bank, cash, sales, purchase, expense, contra, etc.
This installs the module account_voucher . """ ),
' module_account_followup ' : fields . boolean ( ' Customer Follow-Ups ' ,
help = """ This allows to automate letters for unpaid invoices, with multi-level recalls.
This installs the module account_followup . """ ),
' module_account_analytic_plans ' : fields . boolean ( ' Support Multiple Analytic Plans ' ,
help = """ This allows to use several analytic plans, according to the general journal.
This installs the module account_analytic_plans . """ ),
' module_account_analytic_default ' : fields . boolean ( ' Rules for Analytic Assignation ' ,
help = """ Set default values for your analytic accounts.
Allows to automatically select analytic accounts based on criteria like product , partner , user , company , date .
This installs the module account_analytic_default . """ ),
' module_account_invoice_layout ' : fields . boolean ( ' Allow notes and subtotals ' ,
help = """ This provides some features to improve the layout of invoices.
It gives you the possibility to :
* order all the lines of an invoice
* add titles , comment lines , sub total lines
* draw horizontal lines and put page breaks .
This installs the module account_invoice_layout . """ ),
2012-03-07 12:43:01 +00:00
2012-03-28 08:03:26 +00:00
' group_analytic_account_for_sales ' : fields . boolean ( ' Analytic Accounting for Sales ' ,
implied_group = ' base.group_analytic_account_for_sales ' ,
help = " Allows you to specify an analytic account on sale orders. " ) ,
' group_analytic_account_for_purchase ' : fields . boolean ( ' Analytic Accounting for Purchases ' ,
implied_group = ' base.group_analytic_account_for_purchase ' ,
help = " Allows you to specify an analytic account on purchase orders. " ) ,
' group_dates_periods ' : fields . boolean ( ' Allow dates/periods ' ,
implied_group = ' base.group_dates_periods ' ,
help = " Allows you to keep the period same as your invoice date when you validate the invoice. " ) ,
' group_proforma_invoices ' : fields . boolean ( ' Allow Pro-forma Invoices ' ,
implied_group = ' base.group_proforma_invoices ' ,
help = " Allows you to put invoices in pro-forma state. " ) ,
2012-03-16 09:34:21 +00:00
2012-03-28 08:03:26 +00:00
' multi_charts_id ' : fields . many2one ( ' wizard.multi.charts.accounts ' , ' Multi charts accounts ' ) ,
' taxes_id ' : fields . many2one ( ' account.tax.template ' , ' Default Sale Tax ' , domain = " [( ' type_tax_use ' , ' = ' , ' sale ' )] " ) ,
' supplier_taxes_id ' : fields . many2one ( ' account.tax.template ' , ' Default Purchase Tax ' , domain = " [( ' type_tax_use ' , ' = ' , ' purchase ' )] " ) ,
' sale_tax_rate ' : fields . float ( ' Sales Tax( % ) ' ) ,
' purchase_tax_rate ' : fields . float ( ' Purchase Tax( % ) ' ) ,
' complete_tax_set ' : fields . boolean ( ' Complete Set of Taxes ' ) ,
2012-03-07 12:43:01 +00:00
}
2012-03-28 08:03:26 +00:00
2012-03-09 10:38:12 +00:00
def _default_company ( self , cr , uid , context = None ) :
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
2012-03-28 09:36:17 +00:00
return user . company_id . id
2012-03-09 10:38:12 +00:00
def _default_has_default_company ( self , cr , uid , context = None ) :
count = self . pool . get ( ' res.company ' ) . search_count ( cr , uid , [ ] , context = context )
return bool ( count == 1 )
2012-03-07 12:43:01 +00:00
_defaults = {
2012-03-28 09:36:17 +00:00
' company_id ' : _default_company ,
' has_default_company ' : _default_has_default_company ,
2012-03-28 08:03:26 +00:00
' date_start ' : lambda * a : time . strftime ( ' % Y-01-01 ' ) ,
' date_stop ' : lambda * a : time . strftime ( ' % Y-12-31 ' ) ,
' period ' : ' month ' ,
' charts ' : ' configurable ' ,
2012-03-07 12:43:01 +00:00
}
def _check_default_tax ( self , cr , uid , context = None ) :
ir_values_obj = self . pool . get ( ' ir.values ' )
taxes = { }
2012-03-13 10:05:58 +00:00
for tax in ir_values_obj . get ( cr , uid , ' default ' , False , [ ' product.template ' ] ) :
2012-03-07 12:43:01 +00:00
if tax [ 1 ] == ' taxes_id ' :
taxes . update ( { ' taxes_id ' : tax [ 2 ] } )
if tax [ 1 ] == ' supplier_taxes_id ' :
taxes . update ( { ' supplier_taxes_id ' : tax [ 2 ] } )
2012-03-12 11:45:47 +00:00
return taxes
2012-03-07 12:43:01 +00:00
2012-03-16 09:34:21 +00:00
def set_tax_defaults ( self , cr , uid , ids , context = None ) :
ir_values_obj = self . pool . get ( ' ir.values ' )
res = { }
wizard = self . browse ( cr , uid , ids ) [ 0 ]
if wizard . taxes_id . id :
ir_values_obj . set_default ( cr , uid , ' product.template ' , ' taxes_id ' , wizard . taxes_id . id )
if wizard . supplier_taxes_id . id :
ir_values_obj . set_default ( cr , uid , ' product.template ' , ' supplier_taxes_id ' , wizard . supplier_taxes_id . id )
return res
2012-03-07 12:43:01 +00:00
def default_get ( self , cr , uid , fields_list , context = None ) :
ir_values_obj = self . pool . get ( ' ir.values ' )
chart_template_obj = self . pool . get ( ' account.chart.template ' )
2012-03-09 10:38:12 +00:00
fiscalyear_obj = self . pool . get ( ' account.fiscalyear ' )
2012-03-09 12:50:12 +00:00
journal_obj = self . pool . get ( ' account.journal ' )
2012-03-07 12:43:01 +00:00
res = super ( account_configuration , self ) . default_get ( cr , uid , fields_list , context = context )
taxes = self . _check_default_tax ( cr , uid , context )
chart_template_ids = chart_template_obj . search ( cr , uid , [ ( ' visible ' , ' = ' , True ) ] , context = context )
2012-03-09 10:38:12 +00:00
fiscalyear_ids = fiscalyear_obj . search ( cr , uid , [ ( ' date_start ' , ' = ' , time . strftime ( ' % Y-01-01 ' ) ) , ( ' date_stop ' , ' = ' , time . strftime ( ' % Y-12-31 ' ) ) ] )
2012-03-09 07:38:20 +00:00
2012-03-07 12:43:01 +00:00
if chart_template_ids :
2012-03-16 13:08:45 +00:00
res . update ( { ' chart_template_id ' : chart_template_ids [ 0 ] } )
2012-03-16 09:34:21 +00:00
data = chart_template_obj . browse ( cr , uid , chart_template_ids [ 0 ] , context = context )
res . update ( { ' complete_tax_set ' : data . complete_tax_set } )
supplier_taxes_id = ir_values_obj . get_default ( cr , uid , ' product.template ' , ' supplier_taxes_id ' )
res . update ( { ' supplier_taxes_id ' : supplier_taxes_id } )
taxes_id = ir_values_obj . get_default ( cr , uid , ' product.template ' , ' taxes_id ' )
2012-03-16 13:08:45 +00:00
res . update ( { ' taxes_id ' : taxes_id } )
2012-03-16 09:34:21 +00:00
2012-03-09 10:38:12 +00:00
if fiscalyear_ids :
res . update ( { ' fiscalyear_id ' : fiscalyear_ids [ 0 ] } )
2012-03-07 12:43:01 +00:00
if taxes :
2012-03-16 09:34:21 +00:00
if chart_template_ids :
sale_tax_id = taxes . get ( ' taxes_id ' )
res . update ( { ' taxes_id ' : isinstance ( sale_tax_id , list ) and sale_tax_id [ 0 ] or sale_tax_id } )
purchase_tax_id = taxes . get ( ' supplier_taxes_id ' )
res . update ( { ' supplier_taxes_id ' : isinstance ( purchase_tax_id , list ) and purchase_tax_id [ 0 ] or purchase_tax_id } )
2012-03-13 10:05:58 +00:00
else :
2012-03-16 09:34:21 +00:00
res . update ( { ' sale_tax_rate ' : 15.0 , ' purchase_tax_rate ' : 15.0 } )
2012-03-07 12:43:01 +00:00
return res
2012-03-12 11:45:47 +00:00
2012-03-09 10:38:12 +00:00
def on_change_start_date ( self , cr , uid , id , start_date = False ) :
if start_date :
start_date = datetime . datetime . strptime ( start_date , " % Y- % m- %d " )
end_date = ( start_date + relativedelta ( months = 12 ) ) - relativedelta ( days = 1 )
return { ' value ' : { ' date_stop ' : end_date . strftime ( ' % Y- % m- %d ' ) } }
return { }
2012-03-09 12:50:12 +00:00
2012-03-28 09:36:17 +00:00
def onchange_company_id ( self , cr , uid , ids , company_id ) :
# change the value of all related fields
company = self . pool . get ( ' res.company ' ) . browse ( cr , uid , company_id )
values = {
' currency_id ' : company . currency_id . id ,
' paypal_account ' : company . paypal_account ,
' company_footer ' : company . rml_footer2 ,
}
2012-03-28 09:47:06 +00:00
for journal_type in ( ' sale ' , ' sale_refund ' , ' purchase ' , ' purchase_refund ' ) :
values . update ( {
journal_type + ' _journal_id ' : False ,
journal_type + ' _sequence_prefix ' : False ,
journal_type + ' _sequence_next ' : False ,
} )
2012-03-28 09:36:17 +00:00
journal_obj = self . pool . get ( ' account.journal ' )
journal_ids = journal_obj . search ( cr , uid , [ ( ' company_id ' , ' = ' , company_id ) ] )
for journal in journal_obj . browse ( cr , uid , journal_ids ) :
if journal . type in ( ' sale ' , ' sale_refund ' , ' purchase ' , ' purchase_refund ' ) :
values . update ( {
journal . type + ' _journal_id ' : journal . id ,
journal . type + ' _sequence_prefix ' : journal . sequence_id . prefix ,
journal . type + ' _sequence_next ' : journal . sequence_id . number_next ,
} )
return { ' value ' : values }
2012-03-16 09:34:21 +00:00
2012-03-13 09:32:32 +00:00
def install_chartofaccounts ( self , cr , uid , ids , context = None ) :
2012-03-09 10:38:12 +00:00
ir_module = self . pool . get ( ' ir.module.module ' )
2012-03-16 09:34:21 +00:00
multi_chart_obj = self . pool . get ( ' wizard.multi.charts.accounts ' )
chart_template_obj = self . pool . get ( ' account.chart.template ' )
tax_templ_obj = self . pool . get ( ' account.tax.template ' )
2012-03-09 10:38:12 +00:00
if context is None :
context = { }
for res in self . read ( cr , uid , ids , context = context ) :
2012-03-13 09:32:32 +00:00
chart = res . get ( ' charts ' )
if chart == ' configurable ' :
2012-03-09 10:38:12 +00:00
#load generic chart of account
fp = tools . file_open ( opj ( ' account ' , ' configurable_account_chart.xml ' ) )
tools . convert_xml_import ( cr , ' account ' , fp , { } , ' init ' , True , None )
fp . close ( )
2012-03-13 09:32:32 +00:00
elif chart . startswith ( ' l10n_ ' ) :
mod_ids = ir_module . search ( cr , uid , [ ( ' name ' , ' = ' , chart ) ] )
2012-03-09 10:38:12 +00:00
if mod_ids and ir_module . browse ( cr , uid , mod_ids [ 0 ] , context ) . state == ' uninstalled ' :
ir_module . button_immediate_install ( cr , uid , mod_ids , context )
2012-03-16 13:08:45 +00:00
chart_template_ids = chart_template_obj . search ( cr , uid , [ ( ' visible ' , ' = ' , True ) ] , context = context )
complete_tax_set = chart_template_obj . browse ( cr , uid , chart_template_ids [ 0 ] ) . complete_tax_set
if not complete_tax_set :
code_digits = multi_chart_obj . onchange_chart_template_id ( cr , uid , [ ] , chart_template_ids [ 0 ] , context = context ) [ ' value ' ] [ ' code_digits ' ]
object_id = multi_chart_obj . create ( cr , uid , { ' code_digits ' : code_digits , ' sale_tax_rate ' : res . get ( ' sale_tax_rate ' ) , ' purchase_tax_rate ' : res . get ( ' purchase_tax_rate ' ) } , context = context )
multi_chart_obj . execute ( cr , uid , [ object_id ] , context = context )
2012-03-16 09:34:21 +00:00
2012-03-09 10:38:12 +00:00
def configure_fiscalyear ( self , cr , uid , ids , context = None ) :
if context is None :
context = { }
fy_obj = self . pool . get ( ' account.fiscalyear ' )
for res in self . read ( cr , uid , ids , context = context ) :
if ' date_start ' in res and ' date_stop ' in res :
f_ids = fy_obj . search ( cr , uid , [ ( ' date_start ' , ' <= ' , res [ ' date_start ' ] ) , ( ' date_stop ' , ' >= ' , res [ ' date_stop ' ] ) , ( ' company_id ' , ' = ' , res [ ' company_id ' ] [ 0 ] ) ] , context = context )
if not f_ids :
name = code = res [ ' date_start ' ] [ : 4 ]
if int ( name ) != int ( res [ ' date_stop ' ] [ : 4 ] ) :
name = res [ ' date_start ' ] [ : 4 ] + ' - ' + res [ ' date_stop ' ] [ : 4 ]
code = res [ ' date_start ' ] [ 2 : 4 ] + ' - ' + res [ ' date_stop ' ] [ 2 : 4 ]
vals = {
' name ' : name ,
' code ' : code ,
' date_start ' : res [ ' date_start ' ] ,
' date_stop ' : res [ ' date_stop ' ] ,
' company_id ' : res [ ' company_id ' ] [ 0 ]
}
fiscal_id = fy_obj . create ( cr , uid , vals , context = context )
if res [ ' period ' ] == ' month ' :
fy_obj . create_period ( cr , uid , [ fiscal_id ] )
elif res [ ' period ' ] == ' 3months ' :
fy_obj . create_period3 ( cr , uid , [ fiscal_id ] )
2012-03-28 08:03:26 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: