GoodERP
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

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