GoodERP
Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

262 lines
12KB

  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. import calendar
  5. class CreateBalanceSheetWizard(models.TransientModel):
  6. """创建资产负债 和利润表的 wizard"""
  7. _name = "create.balance.sheet.wizard"
  8. _description = '资产负债表和利润表的向导'
  9. company_id = fields.Many2one(
  10. 'res.company',
  11. string='公司',
  12. change_default=True,
  13. default=lambda self: self.env.company)
  14. @api.model
  15. def _default_period_domain(self):
  16. """
  17. 用来设定期间的 可选的范围(这个是一个范围)
  18. :return: domain条件
  19. """
  20. period_domain_setting = self.env['ir.default']._get(
  21. 'finance.config.settings', 'defaul_period_domain')
  22. return [('is_closed', '!=', False)] \
  23. if period_domain_setting == 'cannot' else []
  24. @api.model
  25. def _default_period_id(self):
  26. return self._default_period_id_impl()
  27. def _default_period_id_impl(self):
  28. """
  29. 默认是当前会计期间
  30. :return: 当前会计期间的对象
  31. """
  32. return self.env['finance.period'].get_date_now_period_id()
  33. period_id = fields.Many2one(
  34. 'finance.period',
  35. string='会计期间',
  36. domain=_default_period_domain,
  37. default=_default_period_id, help='用来设定报表的期间')
  38. def compute_balance(self, parameter_str, period_id, compute_field_list):
  39. """根据所填写的 科目的code 和计算的字段 进行计算对应的资产值"""
  40. if parameter_str:
  41. parameter_str_list = parameter_str.split('~')
  42. subject_vals = []
  43. if len(parameter_str_list) == 1:
  44. subject_ids = self.env['finance.account'].search(
  45. [('code', '=', parameter_str_list[0]),
  46. ('account_type', '!=', 'view')])
  47. else:
  48. subject_ids = self.env['finance.account'].search(
  49. [('code', '>=', parameter_str_list[0]),
  50. ('code', '<=', parameter_str_list[1]),
  51. ('account_type', '!=', 'view')])
  52. trial_balances = self.env['trial.balance'].search(
  53. [('subject_name_id', 'in', [
  54. subject.id for subject in subject_ids]),
  55. ('period_id', '=', period_id.id)])
  56. for trial_balance in trial_balances:
  57. # 根据参数code 对应的科目的 方向 进行不同的操作
  58. # 解决:累计折旧 余额记贷方
  59. if trial_balance.subject_name_id.costs_types == 'assets' \
  60. or trial_balance.subject_name_id.costs_types == 'cost':
  61. subject_vals.append(
  62. trial_balance[compute_field_list[0]]
  63. - trial_balance[compute_field_list[1]])
  64. elif trial_balance.subject_name_id.costs_types == 'debt' or \
  65. trial_balance.subject_name_id.costs_types == 'equity':
  66. subject_vals.append(
  67. trial_balance[compute_field_list[1]]
  68. - trial_balance[compute_field_list[0]])
  69. return sum(subject_vals)
  70. def deal_with_balance_formula(self, balance_formula,
  71. period_id, year_begain_field):
  72. if balance_formula:
  73. return_vals = sum([self.compute_balance(
  74. one_formula, period_id, year_begain_field)
  75. for one_formula in balance_formula.split(';')])
  76. else:
  77. return_vals = 0
  78. return return_vals
  79. def balance_sheet_create(self, balance_sheet_obj,
  80. year_begain_field, current_period_field):
  81. balance_sheet_obj.write(
  82. {'beginning_balance': self.deal_with_balance_formula(
  83. balance_sheet_obj.balance_formula,
  84. self.period_id,
  85. year_begain_field),
  86. 'ending_balance': self.deal_with_balance_formula(
  87. balance_sheet_obj.balance_formula,
  88. self.period_id,
  89. current_period_field),
  90. 'beginning_balance_two': self.deal_with_balance_formula(
  91. balance_sheet_obj.balance_two_formula,
  92. self.period_id, year_begain_field),
  93. 'ending_balance_two': self.deal_with_balance_formula(
  94. balance_sheet_obj.balance_two_formula,
  95. self.period_id, current_period_field)})
  96. def create_balance_sheet(self):
  97. """ 资产负债表的创建 """
  98. balance_wizard = self.env['create.trial.balance.wizard'].create(
  99. {'period_id': self.period_id.id})
  100. balance_wizard.create_trial_balance()
  101. view_id = self.env.ref('finance.balance_sheet_list_wizard').id
  102. balance_sheet_objs = self.env['balance.sheet'].search([])
  103. year_begain_field = ['year_init_debit', 'year_init_credit']
  104. current_period_field = [
  105. 'ending_balance_debit', 'ending_balance_credit']
  106. for balance_sheet_obj in balance_sheet_objs:
  107. self.balance_sheet_create(
  108. balance_sheet_obj, year_begain_field, current_period_field)
  109. force_company = self._context.get('force_company')
  110. if not force_company:
  111. force_company = self.env.user.company_id.id
  112. company_row = self.env['res.company'].browse(force_company)
  113. days = calendar.monthrange(
  114. int(self.period_id.year), int(self.period_id.month))[1]
  115. # TODO 格子不对
  116. attachment_information = self.env._(
  117. "编制单位:%s,%s年%s月%s日,单位:元",
  118. company_row.name,
  119. self.period_id.year,
  120. self.period_id.month,
  121. str(days),
  122. )
  123. domain = [
  124. ('id', 'in', [balance_sheet_obj.id
  125. for balance_sheet_obj in balance_sheet_objs])]
  126. action_name = _("资产负债表: %s") % self.period_id.name
  127. return { # 返回生成资产负债表的数据的列表
  128. 'type': 'ir.actions.act_window',
  129. 'name': action_name,
  130. 'view_mode': 'list',
  131. 'res_model': 'balance.sheet',
  132. 'target': 'main',
  133. 'view_id': False,
  134. 'views': [(view_id, 'list')],
  135. 'context': {'period_id': self.period_id.id,
  136. 'attachment_information': attachment_information},
  137. 'domain': domain,
  138. 'limit': 65535,
  139. }
  140. def deal_with_profit_formula(self, occurrence_balance_formula,
  141. period_id, year_begain_field):
  142. if occurrence_balance_formula:
  143. return_vals = sum(
  144. [self.compute_profit(
  145. balance_formula, period_id, year_begain_field)
  146. for balance_formula in
  147. occurrence_balance_formula.split(";")
  148. ])
  149. else:
  150. return_vals = 0
  151. return return_vals
  152. def create_profit_statement(self):
  153. """生成利润表"""
  154. balance_wizard = self.env['create.trial.balance.wizard'].create(
  155. {'period_id': self.period_id.id})
  156. balance_wizard.create_trial_balance()
  157. view_id = self.env.ref('finance.profit_statement_list').id
  158. balance_sheet_objs = self.env['profit.statement'].search([])
  159. year_begain_field = ['cumulative_occurrence_debit',
  160. 'cumulative_occurrence_credit']
  161. current_period_field = [
  162. 'current_occurrence_debit', 'current_occurrence_credit']
  163. for balance_sheet_obj in balance_sheet_objs:
  164. balance_sheet_obj.write(
  165. {'cumulative_occurrence_balance':
  166. self.deal_with_profit_formula(
  167. balance_sheet_obj.occurrence_balance_formula,
  168. self.period_id, year_begain_field),
  169. 'current_occurrence_balance': self.compute_profit(
  170. balance_sheet_obj.occurrence_balance_formula,
  171. self.period_id,
  172. current_period_field)})
  173. force_company = self._context.get('force_company')
  174. if not force_company:
  175. force_company = self.env.user.company_id.id
  176. company_row = self.env['res.company'].browse(force_company)
  177. days = calendar.monthrange(
  178. int(self.period_id.year), int(self.period_id.month))[1]
  179. attachment_information = '编制单位:' + company_row.name + ',' \
  180. + self.period_id.year \
  181. + '年' + self.period_id.month + '月' \
  182. + ',' + '单位:元'
  183. domain = [
  184. ('id', 'in', [
  185. balance_sheet_obj.id
  186. for balance_sheet_obj in balance_sheet_objs])]
  187. # 使用 %s 占位符,并将变量作为参数传入翻译函数
  188. action_name = self.env._('利润表:%s', self.period_id.name)
  189. return { # 返回生成利润表的数据的列表
  190. 'type': 'ir.actions.act_window',
  191. 'name': action_name,
  192. 'view_mode': 'list',
  193. 'res_model': 'profit.statement',
  194. 'target': 'main',
  195. 'view_id': False,
  196. 'views': [(view_id, 'list')],
  197. 'context': {'period_id': self.period_id.id,
  198. 'attachment_information': attachment_information},
  199. 'domain': domain,
  200. 'limit': 65535,
  201. }
  202. def compute_profit(self, parameter_str, period_id, compute_field_list):
  203. """ 根据传进来的 的科目的code 进行利润表的计算 """
  204. if parameter_str:
  205. parameter_str_list = parameter_str.split('~')
  206. subject_vals_in = []
  207. subject_vals_out = []
  208. total_sum = 0
  209. sign_in = False
  210. sign_out = False
  211. if len(parameter_str_list) == 1:
  212. subject_ids = self.env['finance.account'].search(
  213. [('code', '=', parameter_str_list[0]),
  214. ('account_type', '!=', 'view')])
  215. else:
  216. subject_ids = self.env['finance.account'].search(
  217. [('code', '>=', parameter_str_list[0]),
  218. ('code', '<=', parameter_str_list[1]),
  219. ('account_type', '!=', 'view')])
  220. if subject_ids: # 本行计算科目借贷方向
  221. for line in subject_ids:
  222. if line.balance_directions == 'in':
  223. sign_in = True
  224. if line.balance_directions == 'out':
  225. sign_out = True
  226. trial_balances = self.env['trial.balance'].search([
  227. ('subject_name_id', 'in', [
  228. subject.id for subject in subject_ids]),
  229. ('period_id', '=', period_id.id)])
  230. for trial_balance in trial_balances:
  231. if trial_balance.subject_name_id.balance_directions == 'in':
  232. subject_vals_in.append(
  233. trial_balance[compute_field_list[0]])
  234. elif trial_balance.subject_name_id.balance_directions == 'out':
  235. subject_vals_out.append(
  236. trial_balance[compute_field_list[1]])
  237. if sign_out and sign_in: # 方向有借且有贷
  238. total_sum = sum(subject_vals_out) - sum(subject_vals_in)
  239. else:
  240. if subject_vals_in:
  241. total_sum = sum(subject_vals_in)
  242. else:
  243. total_sum = sum(subject_vals_out)
  244. return total_sum
上海开阖软件有限公司 沪ICP备12045867号-1