GoodERP
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

1237 lines
53KB

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