GoodERP
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.

1236 lines
54KB

  1. # Copyright 2016 上海开阖软件有限公司 (http://www.osbzr.com)
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo import models, fields, api
  4. from odoo.exceptions import UserError
  5. from math import fabs
  6. import copy
  7. from odoo.tools.translate import _
  8. class TrialBalance(models.Model):
  9. """科目余额表"""
  10. _name = "trial.balance"
  11. _order = 'subject_code'
  12. _description = '科目余额表'
  13. @api.depends('cumulative_occurrence_debit',
  14. 'cumulative_occurrence_credit',
  15. 'ending_balance_debit',
  16. 'ending_balance_credit',
  17. 'subject_name_id')
  18. def _get_year_init(self):
  19. for tb in self:
  20. if tb.subject_name_id.costs_types in ('in', 'out'):
  21. tb.year_init_debit = tb.year_init_credit = 0
  22. continue
  23. if tb.subject_name_id.balance_directions == 'in':
  24. # 年初借 = 期末借 - 期末贷 - 本年借 + 本年贷
  25. tb.year_init_debit = (
  26. tb.ending_balance_debit
  27. - tb.ending_balance_credit
  28. - tb.cumulative_occurrence_debit
  29. + tb.cumulative_occurrence_credit)
  30. tb.year_init_credit = 0
  31. else:
  32. # 年初贷 = 期末贷 - 期末借 - 本年贷 + 本年借
  33. tb.year_init_credit = (
  34. tb.ending_balance_credit
  35. - tb.ending_balance_debit
  36. - tb.cumulative_occurrence_credit
  37. + tb.cumulative_occurrence_debit)
  38. tb.year_init_debit = 0
  39. period_id = fields.Many2one('finance.period', string='会计期间')
  40. subject_code = fields.Char('科目编码')
  41. subject_name = fields.Char('科目名称')
  42. subject_name_id = fields.Many2one(
  43. 'finance.account', string='科目', ondelete='cascade')
  44. account_type = fields.Selection(
  45. string='科目类型', related='subject_name_id.account_type')
  46. level = fields.Integer(
  47. string='科目级次', related='subject_name_id.level', store=True)
  48. year_init_debit = fields.Float(
  49. '年初余额(借方)', digits='Amount', default=0, compute=_get_year_init)
  50. year_init_credit = fields.Float(
  51. '年初余额(贷方)', digits='Amount', default=0, compute=_get_year_init)
  52. initial_balance_debit = fields.Float(
  53. '期初余额(借方)', digits='Amount', default=0)
  54. initial_balance_credit = fields.Float(
  55. '期初余额(贷方)', digits='Amount', default=0)
  56. current_occurrence_debit = fields.Float(
  57. '本期发生额(借方)', digits='Amount', default=0)
  58. current_occurrence_credit = fields.Float(
  59. '本期发生额(贷方)', digits='Amount', default=0)
  60. ending_balance_debit = fields.Float(
  61. '期末余额(借方)', digits='Amount', default=0)
  62. ending_balance_credit = fields.Float(
  63. '期末余额(贷方)', digits='Amount', default=0)
  64. cumulative_occurrence_debit = fields.Float(
  65. '本年累计发生额(借方)', digits='Amount', default=0)
  66. cumulative_occurrence_credit = fields.Float(
  67. '本年累计发生额(贷方)', digits='Amount', default=0)
  68. def button_change_number(self):
  69. self.ensure_one()
  70. view = self.env.ref('finance.change_cumulative_occurrence_wizard_form')
  71. return {
  72. 'name': '调整累计数',
  73. 'type': 'ir.actions.act_window',
  74. 'view_mode': 'form',
  75. 'res_model': 'change.cumulative.occurrence.wizard',
  76. 'views': [(view.id, 'form')],
  77. 'view_id': view.id,
  78. 'target': 'new',
  79. 'context': dict(
  80. self.env.context,
  81. active_id=self.id,
  82. active_ids=[self.id]
  83. ),
  84. }
  85. @api.model
  86. def check_trial_balance(self, period_id):
  87. res = {}
  88. trial_balance_items = self.env['trial.balance'].search(
  89. [('period_id', '=', period_id.id),
  90. ('account_type', '=', 'normal')])
  91. field_list = [
  92. "total_year_init_debit",
  93. "total_year_init_credit",
  94. "total_initial_balance_debit",
  95. "total_initial_balance_credit",
  96. "total_current_occurrence_debit",
  97. "total_current_occurrence_credit",
  98. "total_ending_balance_debit",
  99. "total_ending_balance_credit",
  100. "total_cumulative_occurrence_debit",
  101. "total_cumulative_occurrence_credit"
  102. ]
  103. for field in field_list:
  104. res.update({field: sum(trial_balance_items.mapped(field[6:]))})
  105. if period_id == period_id.get_init_period():
  106. diff_year_init = res.get(
  107. 'total_year_init_debit', 0) - res.get(
  108. 'total_year_init_credit', 0)
  109. diff_cumulative_occurrence = res.get(
  110. 'total_cumulative_occurrence_debit', 0) - res.get(
  111. 'total_cumulative_occurrence_credit', 0)
  112. diff_ending_balance = res.get(
  113. 'total_ending_balance_debit', 0) - res.get(
  114. 'total_ending_balance_credit', 0)
  115. if diff_year_init != 0:
  116. raise UserError('期间:%s 借贷不平\n\n差异金额:%s' %
  117. (period_id.name, diff_year_init))
  118. if diff_cumulative_occurrence != 0:
  119. raise UserError('期间:%s 借贷不平\n\n差异金额:%s' %
  120. (period_id.name, diff_cumulative_occurrence))
  121. if diff_ending_balance != 0:
  122. raise UserError('期间:%s 借贷不平\n\n差异金额:%s' %
  123. (period_id.name, diff_ending_balance))
  124. else:
  125. diff_initial_balance = res.get(
  126. 'total_initial_balance_debit', 0) - res.get(
  127. 'total_initial_balance_credit', 0)
  128. diff_current_occurrence = res.get(
  129. 'total_current_occurrence_debit', 0) - res.get(
  130. 'total_current_occurrence_credit', 0)
  131. diff_ending_balance = res.get(
  132. 'total_ending_balance_debit', 0) - res.get(
  133. 'total_ending_balance_credit', 0)
  134. if diff_initial_balance != 0:
  135. raise UserError('期间:%s 借贷不平\n\n差异金额:%s' %
  136. (period_id.name, diff_initial_balance))
  137. if diff_current_occurrence != 0:
  138. raise UserError('期间:%s 借贷不平\n\n差异金额:%s' %
  139. (period_id.name, diff_current_occurrence))
  140. if diff_ending_balance != 0:
  141. raise UserError('期间:%s 借贷不平\n\n差异金额:%s' %
  142. (period_id.name, diff_ending_balance))
  143. return True
  144. class CheckTrialBalanceWizard(models.TransientModel):
  145. """ 检查试算平衡
  146. """
  147. _name = 'check.trial.balance.wizard'
  148. _description = '检查试算平衡'
  149. @api.model
  150. def default_get(self, fields):
  151. res = super(CheckTrialBalanceWizard, self).default_get(fields)
  152. active_id = self.env.context.get('active_id', False)
  153. trial_balance_item = self.env['trial.balance'].browse(active_id)
  154. period_id = trial_balance_item.period_id
  155. is_init_period = False
  156. if period_id == period_id.get_init_period():
  157. is_init_period = True
  158. trial_balance_items = self.env['trial.balance'].search(
  159. [('period_id', '=', period_id.id),
  160. ('account_type', '=', 'normal')])
  161. field_list = [
  162. "total_year_init_debit",
  163. "total_year_init_credit",
  164. "total_initial_balance_debit",
  165. "total_initial_balance_credit",
  166. "total_current_occurrence_debit",
  167. "total_current_occurrence_credit",
  168. "total_ending_balance_debit",
  169. "total_ending_balance_credit",
  170. "total_cumulative_occurrence_debit",
  171. "total_cumulative_occurrence_credit"
  172. ]
  173. for field in field_list:
  174. res.update({field: sum(trial_balance_items.mapped(field[6:]))})
  175. res.update({'period_id': period_id.id,
  176. 'is_init_period': is_init_period})
  177. if is_init_period:
  178. diff_year_init = res.get('total_year_init_debit', 0) - res.get(
  179. 'total_year_init_credit', 0)
  180. diff_cumulative_occurrence = res.get(
  181. 'total_cumulative_occurrence_debit', 0) - res.get(
  182. 'total_cumulative_occurrence_credit', 0)
  183. diff_ending_balance = res.get(
  184. 'total_ending_balance_debit', 0) - res.get(
  185. 'total_ending_balance_credit', 0)
  186. if diff_year_init != 0:
  187. res.update({'is_balance': False, 'result': '2',
  188. 'diff': diff_year_init})
  189. if diff_cumulative_occurrence != 0:
  190. res.update({'is_balance': False, 'result': '2',
  191. 'diff': diff_cumulative_occurrence})
  192. if diff_ending_balance != 0:
  193. res.update({'is_balance': False, 'result': '2',
  194. 'diff': diff_ending_balance})
  195. if not (diff_year_init
  196. or diff_cumulative_occurrence
  197. or diff_ending_balance):
  198. res.update({'is_balance': True, 'result': '1'})
  199. else:
  200. diff_initial_balance = res.get(
  201. 'total_initial_balance_debit', 0) - res.get(
  202. 'total_initial_balance_credit', 0)
  203. diff_current_occurrence = res.get(
  204. 'total_current_occurrence_debit', 0) - res.get(
  205. 'total_current_occurrence_credit', 0)
  206. diff_ending_balance = res.get(
  207. 'total_ending_balance_debit', 0) - res.get(
  208. 'total_ending_balance_credit', 0)
  209. if diff_initial_balance != 0:
  210. res.update({'is_balance': False, 'result': '2',
  211. 'diff': diff_initial_balance})
  212. if diff_current_occurrence != 0:
  213. res.update({'is_balance': False, 'result': '2',
  214. 'diff': diff_current_occurrence})
  215. if diff_ending_balance != 0:
  216. res.update({'is_balance': False, 'result': '2',
  217. 'diff': diff_ending_balance})
  218. if not (diff_initial_balance
  219. or diff_current_occurrence
  220. or diff_ending_balance):
  221. res.update({'is_balance': True, 'result': '1'})
  222. return res
  223. period_id = fields.Many2one(
  224. 'finance.period', string='会计期间', help='检查试算平衡的期间')
  225. is_init_period = fields.Boolean(
  226. string='Is Init Period',
  227. )
  228. total_year_init_debit = fields.Float(
  229. '年初余额(借方)', digits='Amount', default=0)
  230. total_year_init_credit = fields.Float(
  231. '年初余额(贷方)', digits='Amount', default=0)
  232. total_initial_balance_debit = fields.Float(
  233. '期初余额(借方)', digits='Amount', default=0)
  234. total_initial_balance_credit = fields.Float(
  235. '期初余额(贷方)', digits='Amount', default=0)
  236. total_current_occurrence_debit = fields.Float(
  237. '本期发生额(借方)', digits='Amount', default=0)
  238. total_current_occurrence_credit = fields.Float(
  239. '本期发生额(贷方)', digits='Amount', default=0)
  240. total_ending_balance_debit = fields.Float(
  241. '期末余额(借方)', digits='Amount', default=0)
  242. total_ending_balance_credit = fields.Float(
  243. '期末余额(贷方)', digits='Amount', default=0)
  244. total_cumulative_occurrence_debit = fields.Float(
  245. '本年累计发生额(借方)', digits='Amount', default=0)
  246. total_cumulative_occurrence_credit = fields.Float(
  247. '本年累计发生额(贷方)', digits='Amount', default=0)
  248. result = fields.Selection(
  249. string='借贷平衡情况',
  250. selection=[('1', '借贷平衡'), ('2', '借贷不平')]
  251. )
  252. is_balance = fields.Boolean(
  253. string='Is Balance',
  254. )
  255. diff = fields.Float(
  256. string='差异金额',
  257. )
  258. company_id = fields.Many2one(
  259. 'res.company',
  260. string='公司',
  261. change_default=True,
  262. default=lambda self: self.env.company)
  263. class ChangeCumulativeOccurrenceWizard(models.TransientModel):
  264. """ The summary line for a class docstring should fit on one line.
  265. """
  266. _name = 'change.cumulative.occurrence.wizard'
  267. _description = 'Change Cumulative Occurrence Wizard'
  268. old_cumulative_occurrence_debit = fields.Float(
  269. '原本年累计发生额(借方)', digits='Amount')
  270. cumulative_occurrence_debit = fields.Float(
  271. '本年累计发生额(借方)', digits='Amount')
  272. old_cumulative_occurrence_credit = fields.Float(
  273. '原本年累计发生额(贷方)', digits='Amount')
  274. cumulative_occurrence_credit = fields.Float(
  275. '本年累计发生额(贷方)', digits='Amount')
  276. cumulative_occurrence = fields.Float('本年累计实际发生额', digits='Amount')
  277. account_id = fields.Many2one(
  278. string='科目',
  279. comodel_name='finance.account',
  280. ondelete='set null',
  281. )
  282. costs_types = fields.Selection(
  283. string='科目类型',
  284. related='account_id.user_type.costs_types',
  285. )
  286. trial_balance_id = fields.Many2one(
  287. string='Trial Balance',
  288. comodel_name='trial.balance',
  289. ondelete='set null',
  290. )
  291. @api.model
  292. def default_get(self, fields):
  293. if len(self.env.context.get('active_ids', False)) > 1:
  294. raise UserError('一次只能调整一行')
  295. res = super(ChangeCumulativeOccurrenceWizard, self).default_get(fields)
  296. active_id = self.env.context.get('active_id', False)
  297. if active_id:
  298. trial_balance_item = self.env['trial.balance'].browse(active_id)
  299. if trial_balance_item.subject_name_id.account_type == 'view':
  300. raise UserError('只能调整末级科目相关的行')
  301. res.update({
  302. 'cumulative_occurrence_debit':
  303. trial_balance_item.cumulative_occurrence_debit,
  304. 'cumulative_occurrence_credit':
  305. trial_balance_item.cumulative_occurrence_credit,
  306. 'old_cumulative_occurrence_debit':
  307. trial_balance_item.cumulative_occurrence_debit,
  308. 'old_cumulative_occurrence_credit':
  309. trial_balance_item.cumulative_occurrence_credit,
  310. 'trial_balance_id': active_id,
  311. 'account_id': trial_balance_item.subject_name_id.id
  312. })
  313. return res
  314. def update_cumulative_occurrence(self):
  315. parent_accounts = []
  316. account = self.trial_balance_id.subject_name_id
  317. while account:
  318. parent_accounts.append(account)
  319. account = account.parent_id
  320. diff_cumulative_occurrence_debit = 0
  321. diff_cumulative_occurrence_credit = 0
  322. if self.costs_types in ('in', 'out'):
  323. diff_cumulative_occurrence_debit = self.cumulative_occurrence - \
  324. self.old_cumulative_occurrence_debit
  325. diff_cumulative_occurrence_credit = self.cumulative_occurrence - \
  326. self.old_cumulative_occurrence_credit
  327. else:
  328. diff_cumulative_occurrence_debit = (
  329. self.cumulative_occurrence_debit
  330. - self.old_cumulative_occurrence_debit)
  331. diff_cumulative_occurrence_credit = (
  332. self.cumulative_occurrence_credit
  333. - self.old_cumulative_occurrence_credit)
  334. for account in parent_accounts:
  335. trial_balance_ids = self.env['trial.balance'].search(
  336. [('subject_name_id', '=', account.id),
  337. ('period_id', '=', self.trial_balance_id.period_id.id)])
  338. for trial_balance_id in trial_balance_ids:
  339. trial_balance_id.write(
  340. {'cumulative_occurrence_debit':
  341. (trial_balance_id.cumulative_occurrence_debit
  342. + diff_cumulative_occurrence_debit)})
  343. trial_balance_id.write(
  344. {'cumulative_occurrence_credit':
  345. (trial_balance_id.cumulative_occurrence_credit
  346. + diff_cumulative_occurrence_credit)})
  347. view = self.env.ref('finance.init_balance_list')
  348. return {
  349. 'type': 'ir.actions.act_window',
  350. 'name': '科目余额表:' + self.trial_balance_id.period_id.name,
  351. 'view_mode': 'list',
  352. 'res_model': 'trial.balance',
  353. 'target': 'main',
  354. 'view_id': False,
  355. 'views': [(view.id, 'list')],
  356. 'domain': [('period_id', '=', self.trial_balance_id.period_id.id)]
  357. }
  358. class CreateTrialBalanceWizard(models.TransientModel):
  359. """根据输入的期间 生成科目余额表的 向导 """
  360. _name = "create.trial.balance.wizard"
  361. _description = '科目余额表的创建向导'
  362. @api.model
  363. def _default_period_id(self):
  364. return self._default_period_id_impl()
  365. @api.model
  366. def _default_period_id_impl(self):
  367. """
  368. 默认是当前会计期间
  369. :return: 当前会计期间的对象
  370. """
  371. return self.env['finance.period'].get_date_now_period_id()
  372. period_id = fields.Many2one(
  373. 'finance.period',
  374. default=_default_period_id,
  375. string='会计期间',
  376. help='限定生成期间的范围')
  377. has_transaction = fields.Boolean(
  378. string='有发生额',
  379. )
  380. has_balance = fields.Boolean(
  381. string='有余额',
  382. )
  383. company_id = fields.Many2one(
  384. 'res.company',
  385. string='公司',
  386. change_default=True,
  387. default=lambda self: self.env.company)
  388. def compute_last_period_id(self, period_id):
  389. """取得参数区间的上个期间"""
  390. if int(period_id.month) == 1:
  391. year = int(period_id.year) - 1
  392. month = 12
  393. else:
  394. year = period_id.year
  395. month = int(period_id.month) - 1
  396. return self.env['finance.period'].search([
  397. ('year', '=', str(year)),
  398. ('month', '=', str(month))])
  399. def compute_next_period_id(self, period_id):
  400. """取得输入期间的下一个期间"""
  401. if int(period_id.month) == 12:
  402. year = int(period_id.year) + 1
  403. month = 1
  404. else:
  405. year = period_id.year
  406. month = int(period_id.month) + 1
  407. return self.env['finance.period'].search([
  408. ('year', '=', str(year)),
  409. ('month', '=', str(month))])
  410. def get_period_balance(self, period_id):
  411. """取出本期发生额
  412. 返回结果是 科目 借 贷
  413. """
  414. # sql = '''select vol.account_id as account_id,
  415. # sum(vol.debit) as debit,
  416. # sum(vol.credit) as credit
  417. # from voucher as vo
  418. # left join voucher_line as vol
  419. # on vo.id = vol.voucher_id
  420. # where vo.period_id=%s
  421. # group by vol.account_id'''
  422. # self.env.cr.execute(sql, (period_id,))
  423. # return self.env.cr.dictfetchall()
  424. self.ensure_one()
  425. data = []
  426. for account in self.env['finance.account'].search([]):
  427. account_balance = account.get_balance(period_id)
  428. data.append({
  429. 'account_id': account.id,
  430. 'debit': account_balance.get('debit'),
  431. 'credit': account_balance.get('credit'),
  432. 'balance': account_balance.get('balance')
  433. })
  434. return data
  435. def create_trial_balance(self):
  436. """ \
  437. 生成科目余额表 \
  438. 1.如果所选区间已经关闭则直接调出已有的科目余额表记录
  439. 2.判断如果所选的区间的 前一个期间没有关闭则报错
  440. 3.如果上一个区间不存在则报错
  441. """
  442. trial_balance_objs = self.env['trial.balance'].search(
  443. [('period_id', '=', self.period_id.id)])
  444. trial_balance_ids = [
  445. trial_balance_row.id for trial_balance_row in trial_balance_objs]
  446. if not self.period_id.is_closed:
  447. trial_balance_objs.unlink()
  448. last_period = self.compute_last_period_id(self.period_id)
  449. if last_period:
  450. if not last_period.is_closed:
  451. raise UserError('期间%s未结账,无法取到%s期期初余额' %
  452. (last_period.name, self.period_id.name))
  453. period_id = self.period_id.id
  454. current_occurrence_dic_list = self.get_period_balance(period_id)
  455. trial_balance_dict = {}
  456. """把本期发生额的数量填写到 准备好的dict 中 """
  457. for current_occurrence in current_occurrence_dic_list:
  458. account = self.env['finance.account'].browse(
  459. current_occurrence.get('account_id'))
  460. ending_balance_debit = ending_balance_credit = 0
  461. this_debit = current_occurrence.get('debit', 0) or 0
  462. this_credit = current_occurrence.get('credit', 0) or 0
  463. if account.balance_directions == 'in':
  464. ending_balance_debit = this_debit - this_credit
  465. else:
  466. ending_balance_credit = this_credit - this_debit
  467. account_dict = {'period_id': period_id,
  468. 'current_occurrence_debit': this_debit,
  469. 'current_occurrence_credit': this_credit,
  470. 'subject_code': account.code,
  471. 'initial_balance_credit': 0,
  472. 'initial_balance_debit': 0,
  473. 'ending_balance_debit': ending_balance_debit,
  474. 'ending_balance_credit': ending_balance_credit,
  475. 'cumulative_occurrence_debit': this_debit,
  476. 'cumulative_occurrence_credit': this_credit,
  477. 'subject_name_id': account.id}
  478. trial_balance_dict[account.id] = account_dict
  479. trial_balance_dict.update(self.construct_trial_balance_dict(
  480. trial_balance_dict, last_period))
  481. trial_balance_ids = [
  482. self.env['trial.balance'].create(vals).id
  483. for (key, vals) in list(trial_balance_dict.items())]
  484. else:
  485. # 更新 科目余额表, 将新出现的 科目加入到 科目余额表
  486. trial_balance_dict = {}
  487. period_id = self.period_id.id
  488. last_period = self.compute_last_period_id(self.period_id)
  489. current_occurrence_dic_list = self.get_period_balance(period_id)
  490. exist_trial_balanace_accounts = self.env['trial.balance'].search(
  491. [('period_id', '=', period_id)]).mapped('subject_name_id')
  492. for current_occurrence in current_occurrence_dic_list:
  493. account = self.env['finance.account'].browse(
  494. current_occurrence.get('account_id'))
  495. if account not in exist_trial_balanace_accounts:
  496. trial_balance_dict[account.id] = \
  497. self._prepare_account_dict(
  498. current_occurrence,
  499. period_id)
  500. trial_balance_dict.update(self.construct_trial_balance_dict(
  501. trial_balance_dict, last_period))
  502. for (key, vals) in list(trial_balance_dict.items()):
  503. if key not in exist_trial_balanace_accounts.ids:
  504. trial_balance_ids.extend(
  505. self.env['trial.balance'].create(vals).ids)
  506. # 对 科目余额表 上下级 数据重新计算
  507. for trial_item in self.env['trial.balance'].search([
  508. ('account_type', '=', 'view'),
  509. ('period_id', '=', self.period_id.id)],
  510. order='level desc'):
  511. parent_account_id = trial_item.subject_name_id
  512. child_account_ids = self.env['finance.account'].search(
  513. [('id', 'child_of', parent_account_id.id),
  514. ('account_type', '=', 'normal')])
  515. child_trial_items = self.env['trial.balance'].search(
  516. [('subject_name_id', 'in', child_account_ids.ids),
  517. ('period_id', '=', self.period_id.id)])
  518. trial_item.write(
  519. {
  520. "year_init_debit": sum(
  521. child_trial_items.mapped("year_init_debit")),
  522. "year_init_credit": sum(
  523. child_trial_items.mapped("year_init_credit")),
  524. "initial_balance_debit": sum(
  525. child_trial_items.mapped("initial_balance_debit")),
  526. "initial_balance_credit": sum(
  527. child_trial_items.mapped("initial_balance_credit")),
  528. "current_occurrence_debit": sum(
  529. child_trial_items.mapped("current_occurrence_debit")),
  530. "current_occurrence_credit": sum(
  531. child_trial_items.mapped("current_occurrence_credit")),
  532. "ending_balance_debit": sum(
  533. child_trial_items.mapped("ending_balance_debit")),
  534. "ending_balance_credit": sum(
  535. child_trial_items.mapped("ending_balance_credit")),
  536. "cumulative_occurrence_debit": sum(
  537. child_trial_items.mapped("cumulative_occurrence_debit")
  538. ),
  539. "cumulative_occurrence_credit": sum(
  540. child_trial_items.mapped(
  541. "cumulative_occurrence_credit")),
  542. }
  543. )
  544. view_id = self.env.ref('finance.trial_balance_list').id
  545. if self.period_id == self.period_id.get_init_period():
  546. view_id = self.env.ref('finance.init_balance_list').id
  547. context = {}
  548. if self.has_balance and not self.has_transaction:
  549. context.update({'search_default_has_balance': 1})
  550. elif not self.has_balance and self.has_transaction:
  551. context.update({'search_default_has_transaction': 1})
  552. elif self.has_balance and self.has_transaction:
  553. context.update({'search_default_has_balance': 1,
  554. 'search_default_has_transaction': 1})
  555. # 引入 from odoo import _ 后使用 _(), 使用 %s 占位符,让翻译人员能够翻译完整的句子结构
  556. action_name = _("科目余额表: %s") % self.period_id.name
  557. return {
  558. 'type': 'ir.actions.act_window',
  559. 'name': action_name,
  560. 'view_mode': 'list',
  561. 'res_model': 'trial.balance',
  562. 'target': 'main',
  563. 'view_id': False,
  564. 'context': context,
  565. 'views': [(view_id, 'list')],
  566. 'domain': [('id', 'in', trial_balance_ids)]
  567. }
  568. def _prepare_account_dict(self, current_occurrence, period_id):
  569. account = self.env['finance.account'].browse(
  570. current_occurrence.get('account_id'))
  571. ending_balance_debit = ending_balance_credit = 0
  572. this_debit = current_occurrence.get('debit', 0) or 0
  573. this_credit = current_occurrence.get('credit', 0) or 0
  574. if account.balance_directions == 'in':
  575. ending_balance_debit = this_debit - this_credit
  576. else:
  577. ending_balance_credit = this_credit - this_debit
  578. account_dict = {
  579. 'period_id': period_id,
  580. 'current_occurrence_debit': this_debit,
  581. 'current_occurrence_credit': this_credit,
  582. 'subject_code': account.code,
  583. 'initial_balance_credit': 0,
  584. 'initial_balance_debit': 0,
  585. 'ending_balance_debit': ending_balance_debit,
  586. 'ending_balance_credit': ending_balance_credit,
  587. 'cumulative_occurrence_debit': this_debit,
  588. 'cumulative_occurrence_credit': this_credit,
  589. 'subject_name_id': account.id
  590. }
  591. return account_dict
  592. def compute_trial_balance_data(self, trial_balance, last_period,
  593. subject_name_id, trial_balance_dict):
  594. ''' 获得 科目余额表 数据 '''
  595. initial_balance_credit = trial_balance.ending_balance_credit or 0
  596. initial_balance_debit = trial_balance.ending_balance_debit or 0
  597. this_debit = this_credit = ending_balance_credit = 0
  598. if subject_name_id in trial_balance_dict: # 本月有发生额
  599. this_debit = trial_balance_dict[subject_name_id].get(
  600. 'current_occurrence_debit', 0) or 0
  601. this_credit = trial_balance_dict[subject_name_id].get(
  602. 'current_occurrence_credit', 0) or 0
  603. ending_balance_debit = initial_balance_debit + \
  604. this_debit - initial_balance_credit - this_credit
  605. if ending_balance_debit < 0:
  606. ending_balance_credit -= ending_balance_debit
  607. ending_balance_debit = 0
  608. else:
  609. ending_balance_credit = initial_balance_credit
  610. ending_balance_debit = initial_balance_debit
  611. # 本年累计发生额
  612. if self.period_id.year == last_period.year:
  613. cumulative_occurrence_credit = this_credit + \
  614. trial_balance.cumulative_occurrence_credit
  615. cumulative_occurrence_debit = this_debit + \
  616. trial_balance.cumulative_occurrence_debit
  617. else:
  618. cumulative_occurrence_credit = this_credit
  619. cumulative_occurrence_debit = this_debit
  620. return_vals = [initial_balance_credit,
  621. initial_balance_debit,
  622. ending_balance_credit,
  623. ending_balance_debit,
  624. this_debit,
  625. this_credit,
  626. cumulative_occurrence_credit,
  627. cumulative_occurrence_debit]
  628. return return_vals
  629. def construct_trial_balance_dict(self, trial_balance_dict, last_period):
  630. """ 结合上一期间的 数据 填写 trial_balance_dict(余额表 记录生成dict) """
  631. currency_dict = copy.deepcopy(trial_balance_dict)
  632. for trial_balance in self.env['trial.balance'].search(
  633. [('period_id', '=', last_period.id)]):
  634. subject_name_id = trial_balance.subject_name_id.id
  635. [initial_balance_credit, initial_balance_debit,
  636. ending_balance_credit, ending_balance_debit, this_debit,
  637. this_credit, cumulative_occurrence_credit,
  638. cumulative_occurrence_debit] = \
  639. self.compute_trial_balance_data(
  640. trial_balance, last_period, subject_name_id, currency_dict)
  641. subject_code = trial_balance.subject_code
  642. currency_dict[trial_balance.subject_name_id.id] = {
  643. 'initial_balance_credit': initial_balance_credit,
  644. 'initial_balance_debit': initial_balance_debit,
  645. 'ending_balance_credit': ending_balance_credit,
  646. 'ending_balance_debit': ending_balance_debit,
  647. 'current_occurrence_debit': this_debit,
  648. 'current_occurrence_credit': this_credit,
  649. 'cumulative_occurrence_credit': cumulative_occurrence_credit,
  650. 'cumulative_occurrence_debit': cumulative_occurrence_debit,
  651. 'subject_code': subject_code,
  652. 'period_id': self.period_id.id,
  653. 'subject_name_id': subject_name_id
  654. }
  655. return currency_dict
  656. class CreateVouchersSummaryWizard(models.TransientModel):
  657. """创建 明细账或者总账的向导 """
  658. _name = "create.vouchers.summary.wizard"
  659. _description = '明细账或总账创建向导'
  660. @api.model
  661. def _default_end_period_id(self):
  662. """
  663. 默认是当前会计期间
  664. :return: 当前会计期间的对象
  665. """
  666. return self.env['finance.period'].get_date_now_period_id()
  667. @api.model
  668. def _default_begin_period_id(self):
  669. """
  670. 默认是当前会计期间
  671. :return: 当前会计期间的对象
  672. """
  673. return self.env['finance.period'].get_year_fist_period_id()
  674. @api.model
  675. def _default_subject_name_id(self):
  676. return self.env['finance.account'].get_smallest_code_account()
  677. @api.model
  678. def _default_subject_name_end_id(self):
  679. return self.env['finance.account'].get_max_code_account()
  680. period_begin_id = fields.Many2one(
  681. 'finance.period',
  682. string='开始期间',
  683. default=_default_begin_period_id,
  684. help='默认是本年第一个期间')
  685. period_end_id = fields.Many2one(
  686. 'finance.period',
  687. string='结束期间',
  688. default=_default_end_period_id,
  689. help='默认是当前期间')
  690. subject_name_id = fields.Many2one(
  691. 'finance.account',
  692. string='会计科目 从',
  693. default=_default_subject_name_id,
  694. help='默认是所有科目的最小code')
  695. subject_name_end_id = fields.Many2one(
  696. 'finance.account',
  697. string='到',
  698. default=_default_subject_name_end_id,
  699. help='默认是所有科目的最大code')
  700. no_occurred = fields.Boolean(
  701. '有发生额', default=True, help='无发生额的科目不显示明细账,默认为不显示')
  702. no_balance = fields.Boolean(
  703. '有余额', default=True, help='无余额的科目不显示明细账,默认为不显示')
  704. company_id = fields.Many2one(
  705. 'res.company',
  706. string='公司',
  707. change_default=True,
  708. default=lambda self: self.env.company)
  709. @api.onchange('period_begin_id', 'period_end_id')
  710. def onchange_period(self):
  711. '''结束期间大于起始期间报错'''
  712. if self.env['finance.period'].period_compare(
  713. self.period_end_id, self.period_begin_id) < 0:
  714. self.period_end_id = self.period_begin_id
  715. return {'warning': {
  716. 'title': '错误',
  717. 'message':
  718. '结束期间必须大于等于开始期间!\n开始期间为:%s 结束期间为:%s' %
  719. (self.period_begin_id.name, self.period_end_id.name),
  720. }}
  721. def get_initial_balance(self, period, account_row):
  722. """取得期初余额"""
  723. vals_dict = {}
  724. if period:
  725. period_id = period.id
  726. else:
  727. period_id = False
  728. initial_balance_credit = 0
  729. initial_balance_debit = 0
  730. trial_balance_obj = self.env['trial.balance'].search(
  731. [('period_id', '=', period_id),
  732. ('subject_name_id', '=', account_row.id)])
  733. if trial_balance_obj:
  734. initial_balance_credit = trial_balance_obj.ending_balance_credit
  735. initial_balance_debit = trial_balance_obj.ending_balance_debit
  736. direction_tuple = self.judgment_lending(
  737. 0, initial_balance_credit, initial_balance_debit)
  738. vals_dict.update({
  739. 'date': False,
  740. 'direction': direction_tuple[0],
  741. 'balance': fabs(direction_tuple[1]),
  742. 'summary':
  743. account_row.code + ' ' + account_row.name + ":" + '期初余额'})
  744. return vals_dict
  745. def judgment_lending(self, balance, balance_credit, balance_debit):
  746. """根据明细账的借贷 金额 判断出本条记录的余额 及方向,balance 为上一条记录余额
  747. 传入参数 余额 ,贷方,借方
  748. :return:返回一个tuple (借贷平借贷方向 ,余额)
  749. """
  750. balance += balance_debit - balance_credit
  751. if balance > 0:
  752. direction = '借'
  753. elif balance < 0:
  754. direction = '贷'
  755. else:
  756. direction = '平'
  757. return (direction, balance)
  758. def get_year_balance(self, period, subject_name):
  759. """根据期间和科目名称 计算出本期合计 和本年累计 (已经关闭的期间)
  760. :param period 期间 subject_name 科目object
  761. return: [本期合计dict,本年合计dict ]
  762. """
  763. vals_dict = {}
  764. trial_balance_obj = self.env['trial.balance'].search(
  765. [('period_id', '=', period.id),
  766. ('subject_name_id', '=', subject_name.id)])
  767. if trial_balance_obj:
  768. cumulative_occurrence_credit = \
  769. trial_balance_obj.cumulative_occurrence_credit
  770. cumulative_occurrence_debit = \
  771. trial_balance_obj.cumulative_occurrence_debit
  772. current_occurrence_credit = \
  773. trial_balance_obj.current_occurrence_credit
  774. current_occurrence_debit = \
  775. trial_balance_obj.current_occurrence_debit
  776. ending_balance_debit = trial_balance_obj.ending_balance_debit
  777. ending_balance_credit = trial_balance_obj.ending_balance_credit
  778. else:
  779. cumulative_occurrence_credit = 0
  780. cumulative_occurrence_debit = 0
  781. current_occurrence_credit = 0
  782. current_occurrence_debit = 0
  783. ending_balance_debit = 0
  784. ending_balance_credit = 0
  785. direction_tuple_period = self.judgment_lending(
  786. 0, ending_balance_credit, ending_balance_debit)
  787. period_vals = {
  788. 'date': False,
  789. 'direction': direction_tuple_period[0],
  790. 'period_id': period.id,
  791. 'credit': current_occurrence_credit,
  792. 'debit': current_occurrence_debit,
  793. 'balance': fabs(direction_tuple_period[1]),
  794. 'summary': subject_name.code + ' ' +
  795. subject_name.name + ":" + '本期合计'}
  796. vals_dict.update({
  797. 'date': False,
  798. 'direction': direction_tuple_period[0],
  799. 'balance': fabs(direction_tuple_period[1]),
  800. 'period_id': False,
  801. 'debit': cumulative_occurrence_debit,
  802. 'credit': cumulative_occurrence_credit,
  803. 'summary': subject_name.code + ' ' +
  804. subject_name.name + ":" + '本年累计'})
  805. return [period_vals, vals_dict]
  806. def get_current_occurrence_amount(self, period, subject_name):
  807. """计算出 本期的科目的 voucher_line的明细记录 """
  808. child_ids = self.env['finance.account'].search(
  809. [('id', 'child_of', subject_name.id)])
  810. account_ids = tuple(child_ids.ids)
  811. sql = '''
  812. select vo.date as date,
  813. vo.id as voucher_id,
  814. COALESCE(vol.debit,0) as debit,
  815. vol.name as summary,
  816. COALESCE(vol.credit,0) as credit
  817. from voucher as vo left join voucher_line as vol
  818. on vo.id = vol.voucher_id
  819. where vo.state='done'
  820. and vo.period_id=%s
  821. and vol.account_id = %s
  822. order by vo.name
  823. '''
  824. self.env.cr.execute(sql, (period.id, subject_name.id))
  825. sql_results = self.env.cr.dictfetchall()
  826. last_period = self.env[
  827. 'create.trial.balance.wizard'].compute_last_period_id(period)
  828. local_last_period = last_period
  829. initial_balance = self.get_initial_balance(
  830. local_last_period, subject_name)
  831. balance = 0 # 上一条记录余额
  832. for i in range(len(sql_results)):
  833. if i == 0:
  834. balance = initial_balance['balance']
  835. if initial_balance['direction'] == '贷':
  836. balance = -balance
  837. else:
  838. balance += sql_results[i - 1]['debit'] - \
  839. sql_results[i - 1]['credit']
  840. direction_tuple = self.judgment_lending(
  841. balance, sql_results[i]['credit'], sql_results[i]['debit'])
  842. sql_results[i].update({'direction': direction_tuple[0],
  843. 'balance': fabs(direction_tuple[1]),
  844. 'period_id': period.id}
  845. )
  846. return sql_results
  847. def get_unclose_year_balance(self, initial_balance_new,
  848. period, subject_name):
  849. """取得没有关闭的期间的 本期合计和 本年累计"""
  850. current_occurrence = {}
  851. child_ids = self.env['finance.account'].search(
  852. [('id', 'child_of', subject_name.id)])
  853. account_ids = tuple(child_ids.ids)
  854. sql = '''
  855. select sum(COALESCE(vol.debit,0)) as debit,
  856. sum(COALESCE(vol.credit,0)) as credit
  857. from voucher as vo left join voucher_line as vol
  858. on vo.id = vol.voucher_id where vo.state='done'
  859. and vo.period_id=%s and vol.account_id in %s
  860. group by vol.account_id'''
  861. self.env.cr.execute(sql, (period.id, account_ids))
  862. sql_results = self.env.cr.dictfetchall()
  863. current_credit = 0
  864. current_debit = 0
  865. if sql_results:
  866. current_credit = sum(row.get('credit', 0) for row in sql_results)
  867. current_debit = sum(row.get('debit', 0) for row in sql_results)
  868. # 本年累计
  869. # 查找累计区间,作本年累计
  870. year_balance_debit = year_balance_credit = 0
  871. compute_periods = self.env['finance.period'].search(
  872. [('year', '=', str(period.year)),
  873. ('month', '<=', str(period.month))])
  874. init_period_id = False
  875. for line_period in compute_periods:
  876. if line_period == line_period.get_init_period():
  877. init_period_id = line_period
  878. sql = '''
  879. select sum(COALESCE(vol.debit,0)) as debit,
  880. sum(COALESCE(vol.credit,0)) as credit
  881. from voucher as vo left join voucher_line as vol
  882. on vo.id = vol.voucher_id where vo.state='done'
  883. and vo.period_id=%s and vol.account_id in %s
  884. group by vol.account_id'''
  885. self.env.cr.execute(sql, (line_period.id, account_ids))
  886. sql_results = self.env.cr.dictfetchall()
  887. if sql_results:
  888. year_balance_debit = year_balance_debit + \
  889. sum(row.get('debit', 0) for row in sql_results)
  890. year_balance_credit = year_balance_credit + \
  891. sum(row.get('credit', 0) for row in sql_results)
  892. if init_period_id:
  893. trial_balance_init_period = self.env['trial.balance'].search(
  894. [('subject_name_id', '=', subject_name.id),
  895. ('period_id', '=', init_period_id.id)])
  896. year_balance_debit -= sum(
  897. trial_balance_init_period.mapped('year_init_debit'))
  898. year_balance_credit -= sum(
  899. trial_balance_init_period.mapped('year_init_credit'))
  900. direction_tuple_current = self.judgment_lending(
  901. initial_balance_new.get('balance', 0)
  902. if initial_balance_new['direction'] == '借'
  903. else -initial_balance_new.get('balance', 0),
  904. current_credit, current_debit)
  905. current_occurrence.update({
  906. 'date': False,
  907. 'direction': direction_tuple_current[0],
  908. 'balance': fabs(direction_tuple_current[1]),
  909. 'debit': current_debit,
  910. 'credit': current_credit,
  911. 'period_id': period.id,
  912. 'summary': subject_name.code + ' ' +
  913. subject_name.name + ":" + '本期合计'
  914. })
  915. initial_balance_new.update({
  916. 'date': False,
  917. 'direction': direction_tuple_current[0],
  918. 'balance': abs(direction_tuple_current[1]),
  919. 'debit': year_balance_debit,
  920. 'credit': year_balance_credit,
  921. 'period_id': False,
  922. 'summary': subject_name.code + ' ' +
  923. subject_name.name + ":" + '本年累计'
  924. })
  925. return [current_occurrence, initial_balance_new]
  926. def create_vouchers_summary(self):
  927. """创建出根据所选期间范围内的 明细帐记录"""
  928. last_period = self.env[
  929. 'create.trial.balance.wizard'].compute_last_period_id(
  930. self.period_begin_id)
  931. if last_period:
  932. if not last_period.is_closed:
  933. raise UserError('期间%s未结账,无法取到%s期初余额' %
  934. (last_period.name, self.period_begin_id.name))
  935. vouchers_summary_ids = []
  936. subject_ids = self.env['finance.account'].search(
  937. [('code', '>=', self.subject_name_id.code),
  938. ('code', '<=', self.subject_name_end_id.code)])
  939. account_ids = []
  940. for subject_id in subject_ids:
  941. child_subject_ids = self.env['finance.account'].search(
  942. [('id', 'child_of', subject_id.id)])
  943. account_ids.extend(child_subject_ids)
  944. new_account_ids = []
  945. for account in account_ids:
  946. if account not in new_account_ids:
  947. new_account_ids.append(account)
  948. for account_line in new_account_ids:
  949. local_last_period = last_period
  950. local_currcy_period = self.period_begin_id
  951. break_flag = True
  952. init = 1
  953. while break_flag:
  954. create_vals = []
  955. initial_balance = self.get_initial_balance(
  956. local_last_period, account_line) # 取上期间期初余额
  957. if init:
  958. create_vals.append(initial_balance) # 期初
  959. init = 0
  960. occurrence_amount = self.get_current_occurrence_amount(
  961. local_currcy_period, account_line) # 本期明细
  962. create_vals += occurrence_amount
  963. if local_currcy_period.is_closed:
  964. cumulative_year_occurrence = self.get_year_balance(
  965. local_currcy_period, account_line) # 本期合计 本年累计
  966. else:
  967. cumulative_year_occurrence = self.get_unclose_year_balance(
  968. copy.deepcopy(initial_balance),
  969. local_currcy_period, account_line)
  970. create_vals += cumulative_year_occurrence
  971. if local_currcy_period.id == self.period_end_id.id:
  972. break_flag = False
  973. local_last_period = local_currcy_period
  974. local_currcy_period = self.env[
  975. 'create.trial.balance.wizard'].compute_next_period_id(
  976. local_currcy_period)
  977. if not local_currcy_period: # 无下一期间,退出循环。
  978. break_flag = False
  979. # # 无发生额不显示
  980. # if self.no_occurred and len(occurrence_amount) == 0:
  981. # continue
  982. # 无余额不显示
  983. if cumulative_year_occurrence[0].get('credit') == 0 \
  984. and cumulative_year_occurrence[0].get('debit') == 0 \
  985. and cumulative_year_occurrence[0].get('balance') == 0:
  986. continue
  987. for vals in create_vals: # create_vals 值顺序为:期初余额 本期明细 本期本年累计
  988. vouchers_summary_ids.append(
  989. (self.env['vouchers.summary'].create(vals)).id)
  990. view_id = self.env.ref('finance.vouchers_summary_list').id
  991. title = self.period_begin_id.name
  992. if self.period_end_id != self.period_begin_id:
  993. title += '-'
  994. title += self.period_end_id.name
  995. title += '_'
  996. title += self.subject_name_id.name
  997. if self.subject_name_end_id != self.subject_name_id:
  998. title += '-'
  999. title += self.subject_name_end_id.name
  1000. return {
  1001. 'type': 'ir.actions.act_window',
  1002. 'name': '明细账 : %s' % title,
  1003. 'view_mode': 'list',
  1004. 'res_model': 'vouchers.summary',
  1005. 'target': 'main',
  1006. 'view_id': False,
  1007. 'views': [(view_id, 'list')],
  1008. 'domain': [('id', 'in', vouchers_summary_ids)],
  1009. 'limit': 65535,
  1010. }
  1011. def create_general_ledger_account(self):
  1012. """创建总账"""
  1013. last_period = self.env[
  1014. 'create.trial.balance.wizard'].compute_last_period_id(
  1015. self.period_begin_id)
  1016. if last_period and not last_period.is_closed:
  1017. raise UserError(
  1018. '期间%s未结账,无法取到%s期初余额' %
  1019. (last_period.name, self.period_begin_id.name))
  1020. vouchers_summary_ids = []
  1021. subject_ids = self.env['finance.account'].search(
  1022. [('code', '>=', self.subject_name_id.code),
  1023. ('code', '<=', self.subject_name_end_id.code)])
  1024. account_ids = []
  1025. for subject_id in subject_ids:
  1026. child_subject_ids = self.env['finance.account'].search(
  1027. [('id', 'child_of', subject_id.id)])
  1028. account_ids.extend(child_subject_ids)
  1029. new_account_ids = []
  1030. for account in account_ids:
  1031. if account not in new_account_ids:
  1032. new_account_ids.append(account)
  1033. for account_line in new_account_ids:
  1034. local_last_period = last_period
  1035. local_currcy_period = self.period_begin_id
  1036. break_flag = True
  1037. while break_flag:
  1038. create_vals = []
  1039. initial_balance = self.get_initial_balance(
  1040. local_last_period, account_line)
  1041. create_vals.append(initial_balance)
  1042. if local_currcy_period.is_closed:
  1043. cumulative_year_occurrence = self.get_year_balance(
  1044. local_currcy_period, account_line)
  1045. else:
  1046. cumulative_year_occurrence = self.get_unclose_year_balance(
  1047. copy.deepcopy(initial_balance),
  1048. local_currcy_period, account_line)
  1049. create_vals += cumulative_year_occurrence
  1050. if local_currcy_period.id == self.period_end_id.id:
  1051. break_flag = False
  1052. local_last_period = local_currcy_period
  1053. local_currcy_period = self.env[
  1054. 'create.trial.balance.wizard'].compute_next_period_id(
  1055. local_currcy_period)
  1056. if not local_currcy_period: # 无下一期间,退出循环。
  1057. break_flag = False
  1058. # 无余额不显示
  1059. if self.no_balance \
  1060. and cumulative_year_occurrence[0].get('credit') == 0 \
  1061. and cumulative_year_occurrence[0].get('debit') == 0 \
  1062. and cumulative_year_occurrence[1].get('credit') == 0 \
  1063. and cumulative_year_occurrence[1].get('debit') == 0:
  1064. continue
  1065. for vals in create_vals:
  1066. del vals['date']
  1067. vouchers_summary_ids.append(
  1068. (self.env['general.ledger.account'].create(vals)).id)
  1069. view_id = self.env.ref('finance.general_ledger_account_list').id
  1070. title = self.period_begin_id.name
  1071. if self.period_end_id != self.period_begin_id:
  1072. title += '-'
  1073. title += self.period_end_id.name
  1074. title += '_'
  1075. title += self.subject_name_id.name
  1076. if self.subject_name_end_id != self.subject_name_id:
  1077. title += '-'
  1078. title += self.subject_name_end_id.name
  1079. return {
  1080. 'type': 'ir.actions.act_window',
  1081. 'name': '总账 %s' % title,
  1082. 'view_mode': 'list',
  1083. 'res_model': 'general.ledger.account',
  1084. 'target': 'main',
  1085. 'view_id': False,
  1086. 'views': [(view_id, 'list')],
  1087. 'domain': [('id', 'in', vouchers_summary_ids)],
  1088. 'limit': 65535,
  1089. }
  1090. class VouchersSummary(models.TransientModel):
  1091. """明细帐"""
  1092. _name = 'vouchers.summary'
  1093. _description = '明细账'
  1094. date = fields.Date('日期', help='日期')
  1095. period_id = fields.Many2one('finance.period', string='会计期间', help='会计期间')
  1096. voucher_id = fields.Many2one('voucher', '凭证字号', help='凭证字号')
  1097. summary = fields.Char('摘要', help='从凭证中获取到对应的摘要')
  1098. direction = fields.Char('方向', help='会计术语,主要方向借、贷、平, 当借方金额大于贷方金额 方向为借\n\
  1099. ,当贷方金额大于借方金额 方向为贷\n 借贷相等时 方向为平')
  1100. debit = fields.Float('借方金额', digits='Amount', help='借方金额')
  1101. credit = fields.Float('贷方金额', digits='Amount', help='贷方金额')
  1102. balance = fields.Float('余额', digits='Amount', help='一般显示为正数,计算方式:当方向为借时 \
  1103. 余额= 借方金额-贷方金额, 当方向为贷时 余额= 贷方金额-借方金额')
  1104. def view_detail_voucher(self):
  1105. '''查看凭证明细按钮'''
  1106. view = self.env.ref('finance.voucher_form')
  1107. return {
  1108. 'name': self.env._('会计凭证明细'),
  1109. 'view_mode': 'form',
  1110. 'view_id': False,
  1111. 'views': [(view.id, 'form')],
  1112. 'res_model': 'voucher',
  1113. 'type': 'ir.actions.act_window',
  1114. 'res_id': self.voucher_id.id,
  1115. }
  1116. class GeneralLedgerAccount(models.TransientModel):
  1117. """总账"""
  1118. _name = 'general.ledger.account'
  1119. _description = '总账'
  1120. period_id = fields.Many2one(
  1121. 'finance.period', string='会计期间', help='记录本条记录的期间!')
  1122. summary = fields.Char('摘要', help='摘要')
  1123. direction = fields.Char('方向', help='会计术语,主要方向借、贷、平, 当借方金额大于贷方金额 方向为借\n\
  1124. ,当贷方金额大于借方金额 方向为贷\n 借贷相等时 方向为平')
  1125. debit = fields.Float('借方金额', digits='Amount', help='借方金额')
  1126. credit = fields.Float('贷方金额', digits='Amount', help='贷方金额')
  1127. balance = fields.Float('余额', digits='Amount', help='一般显示为正数,计算方式:当方向为借时\
  1128. 余额= 借方金额-贷方金额, 当方向为贷时 余额= 贷方金额-借方金额')
上海开阖软件有限公司 沪ICP备12045867号-1