You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

226 lines
8.5 KiB

9 years ago
  1. # -*- coding: utf-8 -*-
  2. # © 2014-2015 ACSONE SA/NV (<http://acsone.eu>)
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  4. import datetime
  5. import time
  6. from odoo import fields
  7. import odoo.tests.common as common
  8. from odoo.tools.safe_eval import safe_eval
  9. from ..models.aep import AccountingExpressionProcessor as AEP
  10. from ..models.accounting_none import AccountingNone
  11. class TestAEP(common.TransactionCase):
  12. def setUp(self):
  13. super(TestAEP, self).setUp()
  14. self.res_company = self.env['res.company']
  15. self.account_model = self.env['account.account']
  16. self.move_model = self.env['account.move']
  17. self.journal_model = self.env['account.journal']
  18. self.curr_year = datetime.date.today().year
  19. self.prev_year = self.curr_year - 1
  20. # create company
  21. self.company = self.res_company.create({
  22. 'name': 'AEP Company'})
  23. # create receivable bs account
  24. type_ar = self.browse_ref('account.data_account_type_receivable')
  25. self.account_ar = self.account_model.create({
  26. 'company_id': self.company.id,
  27. 'code': '400AR',
  28. 'name': 'Receivable',
  29. 'user_type_id': type_ar.id,
  30. 'reconcile': True})
  31. # create income pl account
  32. type_in = self.browse_ref('account.data_account_type_revenue')
  33. self.account_in = self.account_model.create({
  34. 'company_id': self.company.id,
  35. 'code': '700IN',
  36. 'name': 'Income',
  37. 'user_type_id': type_in.id})
  38. # create journal
  39. self.journal = self.journal_model.create({
  40. 'company_id': self.company.id,
  41. 'name': 'Sale journal',
  42. 'code': 'VEN',
  43. 'type': 'sale'})
  44. # create move in december last year
  45. self._create_move(
  46. date=datetime.date(self.prev_year, 12, 1),
  47. amount=100,
  48. debit_acc=self.account_ar,
  49. credit_acc=self.account_in)
  50. # create move in january this year
  51. self._create_move(
  52. date=datetime.date(self.curr_year, 1, 1),
  53. amount=300,
  54. debit_acc=self.account_ar,
  55. credit_acc=self.account_in)
  56. # create move in february this year
  57. self._create_move(
  58. date=datetime.date(self.curr_year, 3, 1),
  59. amount=500,
  60. debit_acc=self.account_ar,
  61. credit_acc=self.account_in)
  62. # create the AEP, and prepare the expressions we'll need
  63. self.aep = AEP(self.company)
  64. self.aep.parse_expr("bali[]")
  65. self.aep.parse_expr("bale[]")
  66. self.aep.parse_expr("balp[]")
  67. self.aep.parse_expr("balu[]")
  68. self.aep.parse_expr("bali[700IN]")
  69. self.aep.parse_expr("bale[700IN]")
  70. self.aep.parse_expr("balp[700IN]")
  71. self.aep.parse_expr("bali[400AR]")
  72. self.aep.parse_expr("bale[400AR]")
  73. self.aep.parse_expr("balp[400AR]")
  74. self.aep.parse_expr("debp[400A%]")
  75. self.aep.parse_expr("crdp[700I%]")
  76. self.aep.parse_expr("bal_700IN") # deprecated
  77. self.aep.parse_expr("bals[700IN]") # deprecated
  78. self.aep.done_parsing()
  79. def _create_move(self, date, amount, debit_acc, credit_acc):
  80. move = self.move_model.create({
  81. 'journal_id': self.journal.id,
  82. 'date': fields.Date.to_string(date),
  83. 'line_ids': [(0, 0, {
  84. 'name': '/',
  85. 'debit': amount,
  86. 'account_id': debit_acc.id,
  87. }), (0, 0, {
  88. 'name': '/',
  89. 'credit': amount,
  90. 'account_id': credit_acc.id,
  91. })]})
  92. move.post()
  93. return move
  94. def _do_queries(self, date_from, date_to):
  95. self.aep.do_queries(
  96. date_from=fields.Date.to_string(date_from),
  97. date_to=fields.Date.to_string(date_to),
  98. target_move='posted')
  99. def _eval(self, expr):
  100. eval_dict = {'AccountingNone': AccountingNone}
  101. return safe_eval(self.aep.replace_expr(expr), eval_dict)
  102. def _eval_by_account_id(self, expr):
  103. res = {}
  104. eval_dict = {'AccountingNone': AccountingNone}
  105. for account_id, replaced_exprs in \
  106. self.aep.replace_exprs_by_account_id([expr]):
  107. res[account_id] = safe_eval(replaced_exprs[0], eval_dict)
  108. return res
  109. def test_sanity_check(self):
  110. self.assertEquals(self.company.fiscalyear_last_day, 31)
  111. self.assertEquals(self.company.fiscalyear_last_month, 12)
  112. def test_aep_basic(self):
  113. # let's query for december
  114. self._do_queries(
  115. datetime.date(self.prev_year, 12, 1),
  116. datetime.date(self.prev_year, 12, 31))
  117. # initial balance must be None
  118. self.assertIs(self._eval('bali[400AR]'), AccountingNone)
  119. self.assertIs(self._eval('bali[700IN]'), AccountingNone)
  120. # check variation
  121. self.assertEquals(self._eval('balp[400AR]'), 100)
  122. self.assertEquals(self._eval('balp[700IN]'), -100)
  123. # check ending balance
  124. self.assertEquals(self._eval('bale[400AR]'), 100)
  125. self.assertEquals(self._eval('bale[700IN]'), -100)
  126. # let's query for January
  127. self._do_queries(
  128. datetime.date(self.curr_year, 1, 1),
  129. datetime.date(self.curr_year, 1, 31))
  130. # initial balance is None for income account (it's not carried over)
  131. self.assertEquals(self._eval('bali[400AR]'), 100)
  132. self.assertIs(self._eval('bali[700IN]'), AccountingNone)
  133. # check variation
  134. self.assertEquals(self._eval('balp[400AR]'), 300)
  135. self.assertEquals(self._eval('balp[700IN]'), -300)
  136. # check ending balance
  137. self.assertEquals(self._eval('bale[400AR]'), 400)
  138. self.assertEquals(self._eval('bale[700IN]'), -300)
  139. # let's query for March
  140. self._do_queries(
  141. datetime.date(self.curr_year, 3, 1),
  142. datetime.date(self.curr_year, 3, 31))
  143. # initial balance is the ending balance fo January
  144. self.assertEquals(self._eval('bali[400AR]'), 400)
  145. self.assertEquals(self._eval('bali[700IN]'), -300)
  146. # check variation
  147. self.assertEquals(self._eval('balp[400AR]'), 500)
  148. self.assertEquals(self._eval('balp[700IN]'), -500)
  149. # check ending balance
  150. self.assertEquals(self._eval('bale[400AR]'), 900)
  151. self.assertEquals(self._eval('bale[700IN]'), -800)
  152. # check some variant expressions, for coverage
  153. self.assertEquals(self._eval('crdp[700I%]'), 500)
  154. self.assertEquals(self._eval('debp[400A%]'), 500)
  155. self.assertEquals(self._eval('bal_700IN'), -500)
  156. self.assertEquals(self._eval('bals[700IN]'), -800)
  157. # unallocated p&l from previous year
  158. self.assertEquals(self._eval('balu[]'), -100)
  159. # TODO allocate profits, and then...
  160. def test_aep_by_account(self):
  161. self._do_queries(
  162. datetime.date(self.curr_year, 3, 1),
  163. datetime.date(self.curr_year, 3, 31))
  164. variation = self._eval_by_account_id('balp[]')
  165. self.assertEquals(variation, {
  166. self.account_ar.id: 500,
  167. self.account_in.id: -500,
  168. })
  169. variation = self._eval_by_account_id('balp[700IN]')
  170. self.assertEquals(variation, {
  171. self.account_in.id: -500,
  172. })
  173. end = self._eval_by_account_id('bale[]')
  174. self.assertEquals(end, {
  175. self.account_ar.id: 900,
  176. self.account_in.id: -800,
  177. })
  178. def test_aep_convenience_methods(self):
  179. initial = AEP.get_balances_initial(
  180. self.company,
  181. time.strftime('%Y') + '-03-01',
  182. 'posted')
  183. self.assertEquals(initial, {
  184. self.account_ar.id: (400, 0),
  185. self.account_in.id: (0, 300),
  186. })
  187. variation = AEP.get_balances_variation(
  188. self.company,
  189. time.strftime('%Y') + '-03-01',
  190. time.strftime('%Y') + '-03-31',
  191. 'posted')
  192. self.assertEquals(variation, {
  193. self.account_ar.id: (500, 0),
  194. self.account_in.id: (0, 500),
  195. })
  196. end = AEP.get_balances_end(
  197. self.company,
  198. time.strftime('%Y') + '-03-31',
  199. 'posted')
  200. self.assertEquals(end, {
  201. self.account_ar.id: (900, 0),
  202. self.account_in.id: (0, 800),
  203. })
  204. unallocated = AEP.get_unallocated_pl(
  205. self.company,
  206. time.strftime('%Y') + '-03-15',
  207. 'posted')
  208. self.assertEquals(unallocated, (0, 100))