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.

255 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 = '编制单位:' + company_row.name + ',' \
  117. + self.period_id.year \
  118. + '年' + self.period_id.month + '月' + \
  119. str(days) + '日' + ',' + '单位:元'
  120. domain = [
  121. ('id', 'in', [balance_sheet_obj.id
  122. for balance_sheet_obj in balance_sheet_objs])]
  123. return { # 返回生成资产负债表的数据的列表
  124. 'type': 'ir.actions.act_window',
  125. 'name': '资产负债表:' + self.period_id.name,
  126. 'view_mode': 'list',
  127. 'res_model': 'balance.sheet',
  128. 'target': 'main',
  129. 'view_id': False,
  130. 'views': [(view_id, 'list')],
  131. 'context': {'period_id': self.period_id.id,
  132. 'attachment_information': attachment_information},
  133. 'domain': domain,
  134. 'limit': 65535,
  135. }
  136. def deal_with_profit_formula(self, occurrence_balance_formula,
  137. period_id, year_begain_field):
  138. if occurrence_balance_formula:
  139. return_vals = sum(
  140. [self.compute_profit(
  141. balance_formula, period_id, year_begain_field)
  142. for balance_formula in
  143. occurrence_balance_formula.split(";")
  144. ])
  145. else:
  146. return_vals = 0
  147. return return_vals
  148. def create_profit_statement(self):
  149. """生成利润表"""
  150. balance_wizard = self.env['create.trial.balance.wizard'].create(
  151. {'period_id': self.period_id.id})
  152. balance_wizard.create_trial_balance()
  153. view_id = self.env.ref('finance.profit_statement_list').id
  154. balance_sheet_objs = self.env['profit.statement'].search([])
  155. year_begain_field = ['cumulative_occurrence_debit',
  156. 'cumulative_occurrence_credit']
  157. current_period_field = [
  158. 'current_occurrence_debit', 'current_occurrence_credit']
  159. for balance_sheet_obj in balance_sheet_objs:
  160. balance_sheet_obj.write(
  161. {'cumulative_occurrence_balance':
  162. self.deal_with_profit_formula(
  163. balance_sheet_obj.occurrence_balance_formula,
  164. self.period_id, year_begain_field),
  165. 'current_occurrence_balance': self.compute_profit(
  166. balance_sheet_obj.occurrence_balance_formula,
  167. self.period_id,
  168. current_period_field)})
  169. force_company = self._context.get('force_company')
  170. if not force_company:
  171. force_company = self.env.user.company_id.id
  172. company_row = self.env['res.company'].browse(force_company)
  173. days = calendar.monthrange(
  174. int(self.period_id.year), int(self.period_id.month))[1]
  175. attachment_information = '编制单位:' + company_row.name + ',' \
  176. + self.period_id.year \
  177. + '年' + self.period_id.month + '月' \
  178. + ',' + '单位:元'
  179. domain = [
  180. ('id', 'in', [
  181. balance_sheet_obj.id
  182. for balance_sheet_obj in balance_sheet_objs])]
  183. return { # 返回生成利润表的数据的列表
  184. 'type': 'ir.actions.act_window',
  185. 'name': '利润表:' + self.period_id.name,
  186. 'view_mode': 'list',
  187. 'res_model': 'profit.statement',
  188. 'target': 'main',
  189. 'view_id': False,
  190. 'views': [(view_id, 'list')],
  191. 'context': {'period_id': self.period_id.id,
  192. 'attachment_information': attachment_information},
  193. 'domain': domain,
  194. 'limit': 65535,
  195. }
  196. def compute_profit(self, parameter_str, period_id, compute_field_list):
  197. """ 根据传进来的 的科目的code 进行利润表的计算 """
  198. if parameter_str:
  199. parameter_str_list = parameter_str.split('~')
  200. subject_vals_in = []
  201. subject_vals_out = []
  202. total_sum = 0
  203. sign_in = False
  204. sign_out = False
  205. if len(parameter_str_list) == 1:
  206. subject_ids = self.env['finance.account'].search(
  207. [('code', '=', parameter_str_list[0]),
  208. ('account_type', '!=', 'view')])
  209. else:
  210. subject_ids = self.env['finance.account'].search(
  211. [('code', '>=', parameter_str_list[0]),
  212. ('code', '<=', parameter_str_list[1]),
  213. ('account_type', '!=', 'view')])
  214. if subject_ids: # 本行计算科目借贷方向
  215. for line in subject_ids:
  216. if line.balance_directions == 'in':
  217. sign_in = True
  218. if line.balance_directions == 'out':
  219. sign_out = True
  220. trial_balances = self.env['trial.balance'].search([
  221. ('subject_name_id', 'in', [
  222. subject.id for subject in subject_ids]),
  223. ('period_id', '=', period_id.id)])
  224. for trial_balance in trial_balances:
  225. if trial_balance.subject_name_id.balance_directions == 'in':
  226. subject_vals_in.append(
  227. trial_balance[compute_field_list[0]])
  228. elif trial_balance.subject_name_id.balance_directions == 'out':
  229. subject_vals_out.append(
  230. trial_balance[compute_field_list[1]])
  231. if sign_out and sign_in: # 方向有借且有贷
  232. total_sum = sum(subject_vals_out) - sum(subject_vals_in)
  233. else:
  234. if subject_vals_in:
  235. total_sum = sum(subject_vals_in)
  236. else:
  237. total_sum = sum(subject_vals_out)
  238. return total_sum
上海开阖软件有限公司 沪ICP备12045867号-1