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.

257 lines
11KB

  1. # Copyright 2016 上海开阖软件有限公司 (http://www.osbzr.com)
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from datetime import datetime
  4. from odoo import fields, models, api
  5. from odoo.tools import float_is_zero
  6. from odoo.exceptions import UserError, ValidationError
  7. class Partner(models.Model):
  8. """查看业务伙伴对账单"""
  9. _inherit = 'partner'
  10. def _init_source_create(self, name, partner_id, category_id, is_init, date,
  11. currency_id,
  12. amount, reconciled, to_reconcile, date_due, state):
  13. if not float_is_zero(amount, 2):
  14. return self.env['money.invoice'].create({
  15. 'name': name,
  16. 'partner_id': partner_id,
  17. 'category_id': category_id,
  18. 'is_init': is_init,
  19. 'currency_id': currency_id,
  20. 'date': date,
  21. 'amount': amount,
  22. 'reconciled': reconciled,
  23. 'to_reconcile': to_reconcile,
  24. 'date_due': date_due,
  25. 'state': state,
  26. })
  27. def _set_receivable_init(self):
  28. self.ensure_one()
  29. # 如果有前期初值,删掉已前的单据
  30. money_invoice_id = self.env['money.invoice'].search([
  31. ('partner_id', '=', self.id),
  32. ('name', '=', '期初应收余额'),
  33. ('is_init', '=', True)])
  34. if money_invoice_id:
  35. if money_invoice_id.state == 'done':
  36. money_invoice_id.money_invoice_draft()
  37. money_invoice_id.unlink()
  38. if self.receivable_init:
  39. # 创建结算单
  40. categ = self.env.ref('money.core_category_sale')
  41. self._init_source_create(
  42. "期初应收余额", self.id, categ.id, True,
  43. self.env.user.company_id.start_date,
  44. self.c_category_id.account_id.currency_id.id,
  45. self.receivable_init, 0,
  46. self.receivable_init,
  47. self.env.user.company_id.start_date,
  48. 'draft')
  49. def _set_payable_init(self):
  50. self.ensure_one()
  51. # 如果有前期初值,删掉已前的单据
  52. money_invoice_id = self.env['money.invoice'].search([
  53. ('partner_id', '=', self.id),
  54. ('name', '=', '期初应付余额'),
  55. ('is_init', '=', True)])
  56. if money_invoice_id:
  57. money_invoice_id.money_invoice_draft()
  58. money_invoice_id.unlink()
  59. if self.payable_init:
  60. # 创建结算单
  61. categ = self.env.ref('money.core_category_purchase')
  62. self._init_source_create(
  63. "期初应付余额", self.id, categ.id, True,
  64. self.env.user.company_id.start_date,
  65. self.s_category_id.account_id.currency_id.id,
  66. self.payable_init, 0,
  67. self.payable_init,
  68. self.env.user.company_id.start_date, 'draft')
  69. receivable_init = fields.Float(u'应收期初',
  70. digits='Amount',
  71. copy=False,
  72. inverse=_set_receivable_init,
  73. help=u'客户的应收期初余额')
  74. payable_init = fields.Float(u'应付期初',
  75. digits='Amount',
  76. copy=False,
  77. inverse=_set_payable_init,
  78. help=u'供应商的应付期初余额')
  79. invoice_ids = fields.One2many(
  80. 'money.invoice', 'partner_id', '未清结算单',
  81. domain=[
  82. ('to_reconcile', '>', 0),
  83. ('state', '=', 'done'),
  84. ('date_due', '<=', datetime.today().date())])
  85. money_ids = fields.One2many(
  86. 'money.order', 'partner_id', '未清付款',
  87. domain=[('to_reconcile', '>', 0), ('state', '=', 'done')])
  88. amount_due = fields.Float('到期余额', compute='_compute_amount_due')
  89. def _compute_amount_due(self):
  90. for p in self:
  91. p.amount_due = 0
  92. p.amount_due += sum([i.to_reconcile for i in p.invoice_ids])
  93. p.amount_due -= sum([m.to_reconcile for m in p.money_ids])
  94. p.amount_due = round(p.amount_due, 2)
  95. def partner_statements(self):
  96. """
  97. 调用这个方法弹出 业务伙伴对账单向导
  98. :return:
  99. """
  100. self.ensure_one()
  101. ctx = {'default_partner_id': self.id}
  102. # 既是客户又是供应商的业务伙伴,根据是在客户还是供应商界面点击的 查看对账单 按钮,显示不同的明细
  103. if (self.c_category_id.type == 'customer'
  104. and self.env.context.get('is_customer_view')):
  105. view = self.env.ref('money.customer_statements_report_wizard_form')
  106. ctx.update({'default_customer': True})
  107. else:
  108. view = self.env.ref('money.partner_statements_report_wizard_form')
  109. ctx.update({'default_supplier': True})
  110. return {
  111. 'name': u'业务伙伴对账单向导',
  112. 'view_mode': 'form',
  113. 'view_id': False,
  114. 'views': [(view.id, 'form')],
  115. 'res_model': 'partner.statements.report.wizard',
  116. 'type': 'ir.actions.act_window',
  117. 'context': ctx,
  118. 'target': 'new',
  119. }
  120. def action_view_money_invoice(self):
  121. self.ensure_one()
  122. act = self.env.ref('money.action_view_money_invoice').read([])[0]
  123. act.update({'domain': [('partner_id', '=', self.id)]})
  124. act.update({'context': {'search_default_to_reconcile': '1'}})
  125. return act
  126. class BankAccount(models.Model):
  127. """查看账户对账单"""
  128. _inherit = 'bank.account'
  129. @api.onchange('init_currency_amount')
  130. def onchange_init_currency_amount(self):
  131. # 当账户的期初外币金额变动时,自动计算期初的本位币金额,并根据期初外币余额的变化修正外币余额的值。
  132. if self.currency_id:
  133. currency_rate = self.env['res.currency'].get_rate_silent(fields.Date.context_today(self),
  134. self.currency_id.id) or 1
  135. self.init_balance = self.init_currency_amount * currency_rate
  136. if self._origin:
  137. init_currency_amount_old_value = self._origin.init_currency_amount
  138. self.currency_amount = self.currency_amount + self.init_currency_amount - init_currency_amount_old_value
  139. else:
  140. self.currency_amount = self.init_currency_amount
  141. @api.depends('balance')
  142. def _compute_standard_balance(self):
  143. # 当外币账户余额变化时,自动计算本位币余额
  144. for res in self:
  145. if res.currency_id:
  146. currency_rate = res.env['res.currency'].get_rate_silent(fields.Date.context_today(res),
  147. res.currency_id.id) or 1
  148. res.standard_balance = res.balance * currency_rate
  149. res.currency_rate = currency_rate
  150. else:
  151. res.standard_balance = res.balance
  152. def _set_init_balance(self):
  153. """
  154. 如果 init_balance 字段里面有值则 进行 一系列的操作。
  155. :return:
  156. """
  157. self.ensure_one()
  158. start_date = self.env.user.company_id.start_date
  159. start_date_period_id = self.env['finance.period'].search_period(
  160. start_date)
  161. if self.init_balance and start_date_period_id.is_closed:
  162. raise UserError(u'初始化期间(%s)已结账!' % start_date_period_id.name)
  163. # 如果有前期初值,删掉已前的单据
  164. other_money_id = self.env['other.money.order'].search([
  165. ('bank_id', '=', self.id),
  166. ('is_init', '=', True)])
  167. if other_money_id:
  168. other_money_id.other_money_draft()
  169. other_money_id.unlink()
  170. if self.init_balance:
  171. # 资金期初 生成 其他收入
  172. money_get = self.with_context(
  173. type='other_get').env['other.money.order']
  174. # 如果账户是本位币账户
  175. if not self.currency_id:
  176. other_money_init = money_get.create({
  177. 'bank_id': self.id,
  178. 'date': self.env.user.company_id.start_date,
  179. 'is_init': True,
  180. 'line_ids': [(0, 0, {
  181. 'category_id': self.env.ref('money.core_category_init').id,
  182. 'amount': self.init_balance,
  183. 'tax_rate': 0,
  184. 'tax_amount': 0,
  185. })],
  186. 'state': 'draft',
  187. 'currency_amount': self.init_currency_amount,
  188. })
  189. # 如果账户是外币账户
  190. else:
  191. other_money_init = money_get.create({
  192. 'bank_id': self.id,
  193. 'date': self.env.user.company_id.start_date,
  194. 'is_init': True,
  195. 'line_ids': [(0, 0, {
  196. 'category_id': self.env.ref('money.core_category_init').id,
  197. 'amount': self.init_currency_amount,
  198. 'tax_rate': 0,
  199. 'tax_amount': 0,
  200. })],
  201. 'state': 'draft',
  202. 'currency_id': self.currency_id.id,
  203. })
  204. # 审核 其他收入单
  205. other_money_init.other_money_done()
  206. init_balance = fields.Float(u'期初',
  207. digits='Amount',
  208. inverse=_set_init_balance,
  209. help=u'资金的期初余额')
  210. init_currency_amount = fields.Float(u'期初外币金额',
  211. digits='Amount',
  212. inverse=_set_init_balance,
  213. help=u'外币资金的期初外币金额')
  214. standard_balance = fields.Float(u'本位币余额',
  215. digits='Amount',
  216. compute='_compute_standard_balance',
  217. store=True,
  218. help=u'本位币余额')
  219. currency_rate = fields.Float('汇率', digits='Price')
  220. def bank_statements(self):
  221. """
  222. 账户对账单向导 调用这个方法弹出 账户对账单向导
  223. :return:
  224. """
  225. self.ensure_one()
  226. view = self.env.ref('money.bank_statements_report_wizard_form')
  227. return {
  228. 'name': u'账户对账单向导',
  229. 'view_mode': 'form',
  230. 'view_id': False,
  231. 'views': [(view.id, 'form')],
  232. 'res_model': 'bank.statements.report.wizard',
  233. 'type': 'ir.actions.act_window',
  234. 'context': {'default_bank_id': self.id},
  235. 'target': 'new',
  236. }
上海开阖软件有限公司 沪ICP备12045867号-1