##############################################################################
import time
-from datetime import datetime, timedelta
+from datetime import datetime
from dateutil.relativedelta import relativedelta
from operator import itemgetter
import netsvc
+import pooler
from osv import fields, osv
import decimal_precision as dp
from tools.translate import _
if amt:
next_date = (datetime.strptime(date_ref, '%Y-%m-%d') + relativedelta(days=line.days))
if line.days2 < 0:
- nyear = next_date.strftime("%Y")
- nmonth = str(int(next_date.strftime("%m"))% 12+1)
- nday = "1"
-
- ndate = "%s-%s-%s" % (nyear, nmonth, nday)
- nseconds = time.mktime(time.strptime(ndate, '%Y-%m-%d'))
- next_month = datetime.fromtimestamp(nseconds)
-
- delta = timedelta(seconds=1)
- next_date = next_month - delta
- next_date = next_date + relativedelta(days=line.days2)
+ next_first_date = next_date + relativedelta(day=1,months=1) #Getting 1st of next month
+ next_date = next_first_date + relativedelta(days=line.days2)
if line.days2 > 0:
next_date += relativedelta(day=line.days2, months=1)
result.append( (next_date.strftime('%Y-%m-%d'), amt) )
if not ids:
ids = self.search(cr, user, [('name', operator, name)]+ args, limit=limit)
if not ids and len(name.split()) >= 2:
- ids = self.search(cr, user, [('code', operator, name.split()[0]), ('name', operator, name.split()[1])]+ args, limit=limit)
+ #Separating code and name of account for searching
+ operand1,operand2 = name.split(' ',1) #name can contain spaces e.g. OpenERP S.A.
+ ids = self.search(cr, user, [('code', operator, operand1), ('name', operator, operand2)]+ args, limit=limit)
else:
ids = self.search(cr, user, args, context=context, limit=limit)
return self.name_get(cr, user, ids, context=context)
_columns = {
'name': fields.char('Journal Name', size=64, required=True, translate=True),
'code': fields.char('Code', size=16, required=True, help="The code will be used to generate the numbers of the journal entries of this journal."),
- 'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'), ('cash', 'Cash'), ('bank', 'Bank and Cheques'), ('general', 'General'), ('situation', 'Situation')], 'Type', size=32, required=True,
+ 'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'), ('cash', 'Cash'), ('bank', 'Bank and Cheques'), ('general', 'General'), ('situation', 'Opening/Closing Situation')], 'Type', size=32, required=True,
help="Select 'Sale' for Sale journal to be used at the time of making invoice."\
" Select 'Purchase' for Purchase Journal to be used at the time of approving purchase order."\
" Select 'Cash' to be used at the time of making payment."\
- " Select 'General' to be used at the time of stock input/output."\
- " Select 'Situation' to be used at the time of making vouchers."),
+ " Select 'General' for miscellaneous operations."\
+ " Select 'Opening/Closing Situation' to be used at the time of new fiscal year creation or end of year entries generation."),
'refund_journal': fields.boolean('Refund Journal', help='Fill this if the journal is to be used for refunds of invoices.'),
'type_control_ids': fields.many2many('account.account.type', 'account_journal_type_rel', 'journal_id','type_id', 'Type Controls', domain=[('code','<>','view'), ('code', '<>', 'closed')]),
'account_control_ids': fields.many2many('account.account', 'account_account_type_rel', 'journal_id','account_id', 'Account', domain=[('type','<>','view'), ('type', '<>', 'closed')]),
'user_id': lambda self,cr,uid,context: uid,
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
}
+ _sql_constraints = [
+ ('code_company_uniq', 'unique (code, company_id)', 'The code of the journal must be unique per company !'),
+ ('name_company_uniq', 'unique (name, company_id)', 'The name of the journal must be unique per company !'),
+ ]
+
+ _order = 'code'
+
+ def copy(self, cr, uid, id, default={}, context=None, done_list=[], local=False):
+ journal = self.browse(cr, uid, id, context=context)
+ if not default:
+ default = {}
+ default = default.copy()
+ default['code'] = (journal['code'] or '') + '(copy)'
+ default['name'] = (journal['name'] or '') + '(copy)'
+ return super(account_journal, self).copy(cr, uid, id, default, context=context)
def write(self, cr, uid, ids, vals, context=None):
if 'company_id' in vals:
help='All manually created new journal entry are usually in the state \'Unposted\', but you can set the option to skip that state on the related journal. In that case, they will be behave as journal entries automatically created by the system on document validation (invoices, bank statements...) and will be created in \'Posted\' state.'),
'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}),
'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'),
- 'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner"),
+ 'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True),
'amount': fields.function(_amount_compute, method=True, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount),
'date': fields.date('Date', required=True, states={'posted':[('readonly',True)]}),
'narration':fields.text('Narration'),
'name': '/',
'state': 'draft',
'period_id': _get_period,
- 'date': time.strftime('%Y-%m-%d'),
+ 'date': lambda *a: time.strftime('%Y-%m-%d'),
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
}
#
# TODO: Check if period is closed !
#
- def create(self, cr, uid, vals, context={}):
+ def create(self, cr, uid, vals, context=None):
+ context = context or {}
if 'line_id' in vals and context.get('copy'):
for l in vals['line_id']:
if not l[0]:
return result
def copy(self, cr, uid, id, default={}, context={}):
+ context = context or {}
default.update({
'state':'draft',
'name':'/',
})
return super(account_move, self).copy(cr, uid, id, default, context)
- def unlink(self, cr, uid, ids, context={}, check=True):
+ def unlink(self, cr, uid, ids, context=None, check=True):
+ context = context or {}
toremove = []
obj_move_line = self.pool.get('account.move.line')
for move in self.browse(cr, uid, ids, context):
if line.account_id.currency_id and line.currency_id:
if line.account_id.currency_id.id != line.currency_id.id and (line.account_id.currency_id.id != line.account_id.company_id.currency_id.id):
- raise osv.except_osv(_('Error'), _("""Couldn't create move with currency different from the secondary currency of the account "%s - %s". Clear the secondary currency field of the account definition if you want to accept all currencies.""" % (line.account_id.code, line.account_id.name)))
+ raise osv.except_osv(_('Error'), _("""Couldn't create move with currency different from the secondary currency of the account "%s - %s". Clear the secondary currency field of the account definition if you want to accept all currencies.""") % (line.account_id.code, line.account_id.name))
if abs(amount) < 10 ** -4:
# If the move is balanced
'notprintable':fields.boolean("Not Printable in Invoice", help="Check this box if you don't want any VAT related to this Tax Code to appear on invoices"),
}
-
def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80):
if not args:
args = []
_constraints = [
(_check_recursion, 'Error ! You can not create recursive accounts.', ['parent_id'])
]
- _order = 'code,name'
+ _order = 'code'
account_tax_code()
class account_tax(osv.osv):
return result in the context
Ex: result=round(price_unit*0.21,4)
"""
+
+ def get_precision_tax():
+ def change_digit_tax(cr):
+ res = pooler.get_pool(cr.dbname).get('decimal.precision').precision_get(cr, 1, 'Account')
+ return (16, res+2)
+ return change_digit_tax
+
_name = 'account.tax'
_description = 'Tax'
_columns = {
'name': fields.char('Tax Name', size=64, required=True, translate=True, help="This name will be displayed on reports"),
'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the tax lines from the lowest sequences to the higher ones. The order is important if you have a tax with several tax children. In this case, the evaluation order is important."),
- 'amount': fields.float('Amount', required=True, digits_compute=dp.get_precision('Account'), help="For taxes of type percentage, enter % ratio between 0-1."),
+ 'amount': fields.float('Amount', required=True, digits_compute=get_precision_tax(), help="For taxes of type percentage, enter % ratio between 0-1."),
'active': fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the tax without removing it."),
'type': fields.selection( [('percent','Percentage'), ('fixed','Fixed Amount'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True,
help="The computation method for the tax amount."),
date_maturity = time.strftime('%Y-%m-%d')
if line.date_maturity == 'partner':
if not line.partner_id:
- raise osv.except_osv(_('Error !'), _("Maturity date of entry line generated by model line '%s' of model '%s' is based on partner payment term! \
- \nPlease define partner on it!"%(line.name, model.name)))
+ raise osv.except_osv(_('Error !'), _("Maturity date of entry line generated by model line '%s' of model '%s' is based on partner payment term!" \
+ "\nPlease define partner on it!")%(line.name, model.name))
if line.partner_id.property_payment_term:
payment_term_id = line.partner_id.property_payment_term.id
pterm_list = pt_obj.compute(cr, uid, payment_term_id, value=1, date_ref=date_maturity)
'lines_id': fields.one2many('account.subscription.line', 'subscription_id', 'Subscription Lines')
}
_defaults = {
- 'date_start': time.strftime('%Y-%m-%d'),
+ 'date_start': lambda *a: time.strftime('%Y-%m-%d'),
'period_type': 'month',
'period_total': 12,
'period_nbr': 1,
'bank_accounts_id': fields.one2many('account.bank.accounts.wizard', 'bank_account_id', 'Bank Accounts', required=True),
'code_digits':fields.integer('# of Digits', required=True, help="No. of Digits to use for account code"),
'seq_journal':fields.boolean('Separated Journal Sequences', help="Check this box if you want to use a different sequence for each created journal. Otherwise, all will use the same sequence."),
+ "sale_tax": fields.many2one("account.tax.template", "Default Sale Tax"),
+ "purchase_tax": fields.many2one("account.tax.template", "Default Purchase Tax"),
}
+ def onchange_chart_template_id(self, cr, uid, ids, chart_template_id=False, context=None):
+ res = {}
+ res['value'] = {}
+ res['value']["sale_tax"] = False
+ res['value']["purchase_tax"] = False
+ if chart_template_id:
+ sale_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
+ , "=", chart_template_id), ('type_tax_use', 'in', ('sale','all'))], order="sequence")
+ purchase_tax_ids = self.pool.get('account.tax.template').search(cr, uid, [("chart_template_id"
+ , "=", chart_template_id), ('type_tax_use', 'in', ('purchase','all'))], order="sequence")
+ res['value']["sale_tax"] = sale_tax_ids and sale_tax_ids[0] or False
+ res['value']["purchase_tax"] = purchase_tax_ids and purchase_tax_ids[0] or False
+ return res
def _get_chart(self, cr, uid, context={}):
ids = self.pool.get('account.chart.template').search(cr, uid, [], context=context)
tax_code_template_ref[tax_code_template.id] = new_tax_code
#create all the tax
+ tax_template_to_tax = {}
for tax in obj_multi.chart_template_id.tax_template_ids:
#create it
vals_tax = {
'type_tax_use': tax.type_tax_use
}
new_tax = obj_acc_tax.create(cr, uid, vals_tax)
+ tax_template_to_tax[tax.id] = new_tax
#as the accounts have not been created yet, we have to wait before filling these fields
todo_dict[new_tax] = {
'account_collected_id': tax.account_collected_id and tax.account_collected_id.id or False,
if obj_multi.seq_journal:
seq_id_sale = obj_sequence.search(cr, uid, [('name','=','Sale Journal')])[0]
seq_id_purchase = obj_sequence.search(cr, uid, [('name','=','Purchase Journal')])[0]
+ seq_id_sale_refund = obj_sequence.search(cr, uid, [('name','=','Sales Refund Journal')])
+ if seq_id_sale_refund:
+ seq_id_sale_refund = seq_id_sale_refund[0]
+ seq_id_purchase_refund = obj_sequence.search(cr, uid, [('name','=','Purchase Refund Journal')])
+ if seq_id_purchase_refund:
+ seq_id_purchase_refund = seq_id_purchase_refund[0]
else:
seq_id_sale = seq_id
seq_id_purchase = seq_id
+ seq_id_sale_refund = seq_id
+ seq_id_purchase_refund = seq_id
vals_journal['view_id'] = view_id
obj_journal.create(cr,uid,vals_journal)
+ # Creating Journals Sales Refund and Purchase Refund
+ vals_journal = {}
+ data_id = obj_data.search(cr, uid, [('model', '=', 'account.journal.view'), ('name', '=', 'account_sp_refund_journal_view')], context=context)
+ data = obj_data.browse(cr, uid, data_id[0], context=context)
+ view_id = data.res_id
+
+ #Sales Refund Journal
+ vals_journal = {
+ 'view_id': view_id,
+ 'name': _('Sales Refund Journal'),
+ 'type': 'sale_refund',
+ 'refund_journal': True,
+ 'code': _('SCNJ'),
+ 'sequence_id': seq_id_sale_refund,
+ 'analytic_journal_id': analitical_journal_sale,
+ 'company_id': company_id
+ }
+
+ if obj_multi.chart_template_id.property_account_receivable:
+ vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
+ vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
+
+
+# if obj_multi.property_account_receivable:
+# vals_journal.update({
+# 'default_credit_account_id': acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id],
+# 'default_debit_account_id': acc_template_ref[obj_multi.chart_template_id.property_account_income_categ.id]
+# })
+ obj_journal.create(cr, uid, vals_journal, context=context)
+
+ # Purchase Refund Journal
+ vals_journal = {
+ 'view_id': view_id,
+ 'name': _('Purchase Refund Journal'),
+ 'type': 'purchase_refund',
+ 'refund_journal': True,
+ 'code': _('ECNJ'),
+ 'sequence_id': seq_id_purchase_refund,
+ 'analytic_journal_id': analitical_journal_purchase,
+ 'company_id': company_id
+ }
+
+ if obj_multi.chart_template_id.property_account_payable:
+ vals_journal['default_credit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
+ vals_journal['default_debit_account_id'] = acc_template_ref[obj_multi.chart_template_id.property_account_expense_categ.id]
+
+
+# if obj_multi.property_account_payable:
+# vals_journal.update({
+# 'default_credit_account_id': acc_template_ref[obj_multi.property_account_expense_categ.id],
+# 'default_debit_account_id': acc_template_ref[obj_multi.property_account_expense_categ.id]
+# })
+ obj_journal.create(cr, uid, vals_journal, context=context)
+
# Bank Journals
data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')])
data = obj_data.browse(cr, uid, data_id[0])
}
obj_ac_fp.create(cr, uid, vals_acc)
+ ir_values = self.pool.get('ir.values')
+ if obj_multi.sale_tax:
+ ir_values.set(cr, uid, key='default', key2=False, name="taxes_id", company=obj_multi.company_id.id,
+ models =[('product.product',False)], value=[tax_template_to_tax[obj_multi.sale_tax.id]])
+ if obj_multi.purchase_tax:
+ ir_values.set(cr, uid, key='default', key2=False, name="supplier_taxes_id", company=obj_multi.company_id.id,
+ models =[('product.product',False)], value=[tax_template_to_tax[obj_multi.purchase_tax.id]])
+
wizard_multi_charts_accounts()
class account_bank_accounts_wizard(osv.osv_memory):
- _name='account.bank.accounts.wizard'
+ _name = 'account.bank.accounts.wizard'
_columns = {
- 'acc_name':fields.char('Account Name.', size=64, required=True),
- 'bank_account_id':fields.many2one('wizard.multi.charts.accounts', 'Bank Account', required=True),
- 'currency_id':fields.many2one('res.currency', 'Currency'),
- 'account_type':fields.selection([('cash','Cash'),('check','Check'),('bank','Bank')], 'Type', size=32),
+ 'acc_name': fields.char('Account Name.', size=64, required=True),
+ 'bank_account_id': fields.many2one('wizard.multi.charts.accounts', 'Bank Account', required=True),
+ 'currency_id': fields.many2one('res.currency', 'Currency'),
+ 'account_type': fields.selection([('cash','Cash'),('check','Check'),('bank','Bank')], 'Type', size=32),
}
_defaults = {
'currency_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.currency_id.id,
- }
+ }
account_bank_accounts_wizard()