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

346 行
17KB

  1. # Copyright 2016 上海开阖软件有限公司 (http://www.osbzr.com)
  2. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  3. from odoo.exceptions import UserError
  4. from odoo import fields, models, api
  5. from odoo.tools import float_compare
  6. class MoneyTransferOrder(models.Model):
  7. _name = 'money.transfer.order'
  8. _description = u'资金转账单'
  9. _inherit = ['mail.thread', 'mail.activity.mixin']
  10. _order = 'id desc'
  11. state = fields.Selection([
  12. ('draft', u'草稿'),
  13. ('done', u'已确认'),
  14. ('cancel', u'已作废'),
  15. ], string=u'状态', readonly=True,
  16. default='draft', copy=False, index=True,
  17. tracking=True,
  18. help=u'资金转账单状态标识,新建时状态为草稿;确认后状态为已确认')
  19. name = fields.Char(string=u'单据编号', copy=False, default='/',
  20. help=u'单据编号,创建时会自动生成')
  21. date = fields.Date(string=u'单据日期',
  22. default=lambda self: fields.Date.context_today(self),
  23. help=u'单据创建日期')
  24. note = fields.Text(string=u'备注', help=u'可以为该单据添加一些需要的标识信息')
  25. line_ids = fields.One2many('money.transfer.order.line', 'transfer_id',
  26. string=u'资金转账单行',
  27. help=u'资金转账单明细行')
  28. company_id = fields.Many2one(
  29. 'res.company',
  30. string=u'公司',
  31. change_default=True,
  32. default=lambda self: self.env.company)
  33. voucher_id = fields.Many2one('voucher',
  34. u'对应凭证',
  35. readonly=True,
  36. ondelete='restrict',
  37. help=u'资金转账单确认时生成的对应凭证',
  38. copy=False)
  39. transfer_amount = fields.Float(
  40. compute='_compute_transfer_amount', string='转账总金额')
  41. is_multi_currency = fields.Boolean('多币种', related='company_id.is_multi_currency')
  42. @api.depends('line_ids', 'line_ids.amount')
  43. def _compute_transfer_amount(self):
  44. for mto in self:
  45. mto.transfer_amount = sum([line.amount for line in mto.line_ids])
  46. def money_transfer_done(self):
  47. '''转账单的审核按钮'''
  48. self.ensure_one()
  49. if not self.line_ids:
  50. raise UserError('请先输入转账金额')
  51. decimal_amount = self.env.ref('core.decimal_amount')
  52. for line in self.line_ids:
  53. company_currency_id = self.env.user.company_id.currency_id.id
  54. out_currency_id = \
  55. line.out_bank_id.currency_id.id or company_currency_id
  56. in_currency_id = \
  57. line.in_bank_id.currency_id.id or company_currency_id
  58. if line.out_bank_id == line.in_bank_id:
  59. raise UserError('转出账户与转入账户不能相同')
  60. if line.amount <= 0:
  61. raise UserError('转账金额必须大于0。\n 转账金额:%s' % line.amount)
  62. if out_currency_id == company_currency_id: # 如果转出账户是公司本位币
  63. if float_compare(
  64. line.out_bank_id.balance,
  65. line.amount,
  66. decimal_amount.digits) == -1:
  67. raise UserError('转出账户余额不足。\n转出账户余额:%s 本次转出金额:%s' % (
  68. line.out_bank_id.balance, line.amount))
  69. else: # 转出账户余额充足
  70. line.out_bank_id.balance -= line.amount
  71. if in_currency_id == company_currency_id: # 如果转入账户是公司本位币
  72. line.in_bank_id.balance += line.amount
  73. else: # 如果转入账户是外币
  74. line.in_bank_id.balance += line.currency_amount
  75. else: # 如果转出账户是外币
  76. if float_compare(
  77. line.out_bank_id.balance,
  78. line.currency_amount,
  79. precision_digits=decimal_amount.digits) == -1:
  80. raise UserError(
  81. '转出账户余额不足。\n转出账户余额:%s 本次转出外币金额:%s'
  82. % (line.out_bank_id.balance, line.currency_amount))
  83. if in_currency_id == company_currency_id: # 如果转入账户是公司本位币
  84. line.in_bank_id.balance += line.amount
  85. line.out_bank_id.balance -= line.currency_amount
  86. elif (in_currency_id != company_currency_id
  87. and in_currency_id == out_currency_id):
  88. # 如果转入账户是外币,只支持同种外币互转
  89. line.in_bank_id.balance += line.currency_amount
  90. line.out_bank_id.balance -= line.currency_amount
  91. else:
  92. raise UserError('系统不支持外币转不同外币')
  93. # 创建凭证并审核
  94. voucher = self.create_voucher()
  95. return self.write({
  96. 'voucher_id': voucher.id,
  97. 'state': 'done',
  98. })
  99. def money_transfer_draft(self):
  100. '''转账单的反审核按钮,外币要考虑是转入还是转出'''
  101. self.ensure_one()
  102. decimal_amount = self.env.ref('core.decimal_amount')
  103. for line in self.line_ids:
  104. company_currency_id = self.env.user.company_id.currency_id.id
  105. out_currency_id = \
  106. line.out_bank_id.currency_id.id or company_currency_id
  107. in_currency_id = \
  108. line.in_bank_id.currency_id.id or company_currency_id
  109. if line.currency_amount > 0:
  110. if (in_currency_id != company_currency_id
  111. and out_currency_id == in_currency_id):
  112. # 转入和转出都是外币
  113. if float_compare(
  114. line.in_bank_id.balance,
  115. line.currency_amount,
  116. precision_digits=decimal_amount.digits) == -1:
  117. raise UserError(
  118. '转入账户余额不足。\n转入账户余额:%s 本次转出外币金额:%s'
  119. % (line.in_bank_id.balance, line.currency_amount))
  120. else: # 转入账户余额充足
  121. line.in_bank_id.balance -= line.currency_amount
  122. line.out_bank_id.balance += line.currency_amount
  123. elif (in_currency_id == company_currency_id
  124. and out_currency_id != company_currency_id):
  125. # 转入账户为本位币,转出是外币
  126. if float_compare(
  127. line.in_bank_id.balance,
  128. line.amount,
  129. precision_digits=decimal_amount.digits) == -1:
  130. raise UserError(
  131. '转入账户余额不足。\n转入账户余额:%s 本次转出金额:%s'
  132. % (line.in_bank_id.balance, line.amount))
  133. else:
  134. line.in_bank_id.balance -= line.amount
  135. line.out_bank_id.balance += line.currency_amount
  136. elif (in_currency_id != company_currency_id
  137. and out_currency_id == company_currency_id):
  138. # 转入账户为外币,转出是人民币
  139. if float_compare(
  140. line.in_bank_id.balance,
  141. line.currency_amount,
  142. precision_digits=decimal_amount.digits) == -1:
  143. raise UserError(
  144. '转入账户余额不足。\n转入账户余额:%s 本次转出金额:%s'
  145. % (line.in_bank_id.balance, line.currency_amount))
  146. else:
  147. line.in_bank_id.balance -= line.currency_amount
  148. line.out_bank_id.balance += line.amount
  149. else:
  150. raise UserError('系统不支持外币转不同外币')
  151. else: # 转入/转出账户都为本位币
  152. if float_compare(
  153. line.in_bank_id.balance,
  154. line.amount,
  155. precision_digits=decimal_amount.digits) == -1:
  156. raise UserError('转入账户余额不足。\n转入账户余额:%s 本次转出金额:%s'
  157. % (line.in_bank_id.balance, line.amount))
  158. else:
  159. line.in_bank_id.balance -= line.amount
  160. line.out_bank_id.balance += line.amount
  161. voucher = self.voucher_id
  162. self.write({
  163. 'voucher_id': False,
  164. 'state': 'draft',
  165. })
  166. # 反审核凭证并删除
  167. if voucher.state == 'done':
  168. voucher.voucher_draft()
  169. voucher.unlink()
  170. return True
  171. def create_voucher(self):
  172. """创建凭证并审核"""
  173. vouch_obj = self.env['voucher'].create(
  174. {'date': self.date, 'ref': '%s,%s' % (self._name, self.id)})
  175. vals = {}
  176. for line in self.line_ids:
  177. out_currency_id = (
  178. line.out_bank_id.currency_id.id
  179. or self.env.user.company_id.currency_id.id)
  180. in_currency_id = (
  181. line.in_bank_id.currency_id.id
  182. or self.env.user.company_id.currency_id.id)
  183. company_currency_id = self.env.user.company_id.currency_id.id
  184. if (out_currency_id != company_currency_id
  185. or in_currency_id != company_currency_id) \
  186. and not line.currency_amount:
  187. raise UserError('错误, 请请输入外币金额。')
  188. if (line.currency_amount
  189. and in_currency_id == company_currency_id
  190. and out_currency_id != company_currency_id):
  191. '''结汇'''
  192. '''借方行'''
  193. self.env['voucher.line'].create({
  194. 'name': "%s %s结汇至%s %s" % (
  195. self.name,
  196. line.out_bank_id.name,
  197. line.in_bank_id.name,
  198. self.note),
  199. 'account_id': line.in_bank_id.account_id.id,
  200. 'debit': line.amount,
  201. 'voucher_id': vouch_obj.id,
  202. 'partner_id': '',
  203. 'currency_id': '',
  204. 'currency_amount': line.currency_amount,
  205. 'rate_silent': line.amount / line.currency_amount
  206. })
  207. '''贷方行'''
  208. self.env['voucher.line'].create({
  209. 'name': "%s %s结汇至%s %s" % (
  210. self.name, line.out_bank_id.name,
  211. line.in_bank_id.name,
  212. self.note),
  213. 'account_id': line.out_bank_id.account_id.id,
  214. 'credit': line.amount,
  215. 'voucher_id': vouch_obj.id,
  216. 'partner_id': '',
  217. 'currency_id': out_currency_id,
  218. 'currency_amount': line.currency_amount,
  219. 'rate_silent': line.amount / line.currency_amount
  220. })
  221. elif (line.currency_amount
  222. and in_currency_id != company_currency_id
  223. and out_currency_id == company_currency_id):
  224. '''买汇'''
  225. '''借方行'''
  226. self.env['voucher.line'].create({
  227. 'name': u"%s %s买汇至%s %s" % (
  228. self.name,
  229. line.out_bank_id.name,
  230. line.in_bank_id.name,
  231. self.note),
  232. 'account_id': line.in_bank_id.account_id.id,
  233. 'debit': line.amount,
  234. 'voucher_id': vouch_obj.id,
  235. 'partner_id': '',
  236. 'currency_id': in_currency_id,
  237. 'currency_amount': line.currency_amount,
  238. 'rate_silent': line.amount / line.currency_amount
  239. })
  240. '''贷方行'''
  241. self.env['voucher.line'].create({
  242. 'name': u"%s %s买汇至%s %s" % (
  243. self.name,
  244. line.out_bank_id.name,
  245. line.in_bank_id.name,
  246. self.note),
  247. 'account_id': line.out_bank_id.account_id.id,
  248. 'credit': line.amount,
  249. 'voucher_id': vouch_obj.id,
  250. 'partner_id': '',
  251. 'currency_id': '',
  252. 'currency_amount': line.currency_amount,
  253. 'rate_silent': line.amount / line.currency_amount
  254. })
  255. elif (line.currency_amount
  256. and in_currency_id == out_currency_id
  257. and in_currency_id != company_currency_id):
  258. '''相同外币币别互转'''
  259. '''借方行'''
  260. rate_silent = self.env['res.currency'].get_rate_silent(
  261. self.date, in_currency_id)
  262. self.env['voucher.line'].create({
  263. 'name': u"%s %s外币互转至%s %s" % (
  264. self.name,
  265. line.out_bank_id.name,
  266. line.in_bank_id.name,
  267. self.note),
  268. 'account_id': line.in_bank_id.account_id.id,
  269. 'debit': line.currency_amount * rate_silent,
  270. 'voucher_id': vouch_obj.id,
  271. 'partner_id': '',
  272. 'currency_id': in_currency_id,
  273. 'currency_amount': line.currency_amount,
  274. 'rate_silent': rate_silent
  275. })
  276. '''贷方行'''
  277. self.env['voucher.line'].create({
  278. 'name': u"%s %s外币互转至%s %s" % (
  279. self.name, line.out_bank_id.name,
  280. line.in_bank_id.name, self.note),
  281. 'account_id': line.out_bank_id.account_id.id,
  282. 'credit': line.currency_amount * rate_silent,
  283. 'voucher_id': vouch_obj.id, 'partner_id': '',
  284. 'currency_id': out_currency_id,
  285. 'currency_amount': line.currency_amount,
  286. 'rate_silent': rate_silent
  287. })
  288. else:
  289. '''人民币间'''
  290. vals.update({
  291. 'vouch_obj_id': vouch_obj.id,
  292. 'name': self.name, 'string': self.note or '',
  293. 'amount': abs(line.amount),
  294. 'credit_account_id': line.out_bank_id.account_id.id,
  295. 'debit_account_id': line.in_bank_id.account_id.id,
  296. })
  297. self.env['money.invoice'].create_voucher_line(vals)
  298. vouch_obj.voucher_done()
  299. return vouch_obj
  300. class MoneyTransferOrderLine(models.Model):
  301. _name = 'money.transfer.order.line'
  302. _description = u'资金转账单明细'
  303. transfer_id = fields.Many2one('money.transfer.order',
  304. string=u'资金转账单', ondelete='cascade',
  305. help=u'资金转账单行对应的资金转账单')
  306. out_bank_id = fields.Many2one('bank.account', string=u'转出账户',
  307. required=True, ondelete='restrict',
  308. help=u'资金转账单行上的转出账户')
  309. in_bank_id = fields.Many2one('bank.account', string=u'转入账户',
  310. required=True, ondelete='restrict',
  311. help=u'资金转账单行上的转入账户')
  312. currency_amount = fields.Float(string=u'外币金额',
  313. digits='Amount',
  314. help=u'转出或转入的外币金额')
  315. amount = fields.Float(string=u'金额',
  316. digits='Amount',
  317. help=u'转出或转入的金额')
  318. mode_id = fields.Many2one('settle.mode', string=u'结算方式',
  319. ondelete='restrict',
  320. help=u'结算方式:支票、信用卡等')
  321. number = fields.Char(string=u'结算号', help=u'本次结算号')
  322. note = fields.Char(string=u'备注',
  323. help=u'可以为该单据添加一些需要的标识信息')
  324. company_id = fields.Many2one(
  325. 'res.company',
  326. string=u'公司',
  327. change_default=True,
  328. default=lambda self: self.env.company)
  329. is_multi_currency = fields.Boolean('多币种', related='company_id.is_multi_currency')
上海开阖软件有限公司 沪ICP备12045867号-1