GoodERP
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

298 Zeilen
15KB

  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. from odoo.exceptions import UserError
  5. class MoneyInvoice(models.Model):
  6. _inherit = 'money.invoice'
  7. voucher_id = fields.Many2one(
  8. 'voucher',
  9. '对应凭证',
  10. readonly=True,
  11. ondelete='restrict',
  12. copy=False,
  13. help='结算单确认时生成的对应凭证')
  14. cogs_voucher_id = fields.Many2one(
  15. 'voucher',
  16. '成本凭证',
  17. readonly=True,
  18. ondelete='set null',
  19. copy=False,
  20. help='结算单确认时生成的成本凭证')
  21. def money_invoice_draft(self):
  22. """
  23. 撤销确认结算单时,撤销确认凭证
  24. """
  25. res = super(MoneyInvoice, self).money_invoice_draft()
  26. for invoice in self:
  27. voucher, invoice.voucher_id = invoice.voucher_id, False
  28. if voucher.state == 'done':
  29. voucher.voucher_draft()
  30. # 始初化单反审核只删除明细行:生成初始化凭证时,不生成往来单位对方的科目,所以要删除相关明细行
  31. if invoice.is_init:
  32. vouch_obj = self.env['voucher'].search(
  33. [('id', '=', voucher.id)])
  34. vouch_obj_lines = self.env['voucher.line'].search([
  35. ('voucher_id', '=', vouch_obj.id),
  36. ('partner_id', '=', invoice.partner_id.id),
  37. ('init_obj', '=', 'money_invoice'), ])
  38. for vouch_obj_line in vouch_obj_lines:
  39. vouch_obj_line.unlink()
  40. else: # 非初始化单反审核时删除凭证
  41. voucher.unlink()
  42. # 删除发出成本凭证
  43. cogs_voucher = self.env['voucher'].search(
  44. [('ref', '=', '%s,%s' % (self._name, invoice.id))])
  45. if cogs_voucher:
  46. if cogs_voucher.state == 'done':
  47. cogs_voucher.voucher_draft()
  48. cogs_voucher.unlink()
  49. return res
  50. def money_invoice_done(self):
  51. """
  52. 确认结算单时,创建凭证并确认
  53. """
  54. res = super(MoneyInvoice, self).money_invoice_done()
  55. vals = {}
  56. # 初始化单的话,先找是否有初始化凭证,没有则新建一个
  57. for invoice in self:
  58. if invoice.is_init:
  59. vouch_obj = self.env['voucher'].search(
  60. [('is_init', '=', True)])
  61. if not vouch_obj:
  62. vouch_obj = self.env['voucher'].create(
  63. {'date': invoice.date,
  64. 'is_init': True,
  65. 'ref': '%s,%s' % (self._name, self.id)})
  66. invoice.write({'voucher_id': vouch_obj.id})
  67. else:
  68. vouch_obj = self.env['voucher'].create({
  69. 'date': invoice.invoice_date or
  70. (not self.env.company.draft_invoice and invoice.date) or
  71. fields.Date.context_today(self),
  72. 'ref': '%s,%s' % (self._name, self.id)})
  73. invoice.write({'voucher_id': vouch_obj.id})
  74. if not invoice.category_id.account_id:
  75. raise UserError('请配置%s的会计科目' % (invoice.category_id.name))
  76. partner_cat = invoice.category_id.type == 'income' \
  77. and invoice.partner_id.c_category_id \
  78. or invoice.partner_id.s_category_id
  79. partner_account_id = partner_cat.account_id.id
  80. if not partner_account_id:
  81. raise UserError('请配置%s的会计科目' % (partner_cat.name))
  82. if invoice.category_id.type == 'income':
  83. vals.update({
  84. 'vouch_obj_id': vouch_obj.id,
  85. 'partner_credit': invoice.partner_id.id,
  86. 'name': invoice.name,
  87. 'string': invoice.note or '',
  88. 'amount': invoice.amount,
  89. 'credit_account_id': invoice.category_id.account_id.id,
  90. 'partner_debit': invoice.partner_id.id,
  91. 'debit_account_id': partner_account_id,
  92. 'sell_tax_amount': invoice.tax_amount or 0,
  93. 'credit_auxiliary_id': invoice.auxiliary_id.id,
  94. 'currency_id': invoice.currency_id.id or '',
  95. 'rate_silent': self.env['res.currency'].get_rate_silent(
  96. self.date, invoice.currency_id.id) or 0,
  97. })
  98. # 找到发票对应发货单的凭证,复制修改, 结转主营业务成本
  99. send_voucher = False
  100. if self.env['ir.module.module'].sudo().search(
  101. [('name', '=', 'sell'), ('state', '=', 'installed')]):
  102. delivery = self.env['sell.delivery'].search(
  103. [('name', '=', invoice.name)])
  104. send_voucher = delivery.voucher_id
  105. # 该公司不是月末一次性结转发出成本
  106. if send_voucher:
  107. cost_voucher_data = send_voucher.copy_data()
  108. out_account_id = self.env.ref(
  109. 'finance.categ_sell_goods').account_id.id
  110. cogs_account_id = self.env.company.cogs_account.id
  111. # 如果发货单没有直接结转成本
  112. if out_account_id != cogs_account_id:
  113. for vl in cost_voucher_data[0]['line_ids']:
  114. if vl[2]['account_id'] != out_account_id:
  115. vl[2].update({'account_id': cogs_account_id})
  116. vl[2].update({
  117. 'debit': vl[2]['credit'],
  118. 'credit': vl[2]['debit'],
  119. 'voucher_id': False})
  120. cost_voucher_data[0].update(
  121. {'ref': '%s,%s' % (self._name, self.id)})
  122. voucher_date = invoice.invoice_date or (not self.env.company.draft_invoice and invoice.date) or None
  123. if voucher_date:
  124. cost_voucher_data[0].update({'date': voucher_date})
  125. cogs_voucher = self.env['voucher'].create(
  126. cost_voucher_data)
  127. cogs_voucher.voucher_done()
  128. invoice.cogs_voucher_id = cogs_voucher.id
  129. else:
  130. vals.update({
  131. 'vouch_obj_id': vouch_obj.id,
  132. 'name': invoice.name,
  133. 'string': invoice.note or '',
  134. 'amount': invoice.amount,
  135. 'credit_account_id': partner_account_id,
  136. 'debit_account_id': invoice.category_id.account_id.id,
  137. 'partner_debit': invoice.partner_id.id,
  138. 'partner_credit': invoice.partner_id.id,
  139. 'buy_tax_amount': invoice.tax_amount or 0,
  140. 'debit_auxiliary_id': invoice.auxiliary_id.id,
  141. 'currency_id': invoice.currency_id.id or '',
  142. 'rate_silent': self.env['res.currency'].get_rate_silent(
  143. self.date, invoice.currency_id.id) or 0,
  144. })
  145. if invoice.is_init:
  146. vals.update({'init_obj': 'money_invoice', })
  147. invoice.create_voucher_line(vals)
  148. # 删除初始非需要的凭证明细行,不确认凭证
  149. if invoice.is_init:
  150. vouch_line_ids = self.env['voucher.line'].search([
  151. ('account_id', '=', invoice.category_id.account_id.id),
  152. ('init_obj', '=', 'money_invoice')])
  153. # 删除凭证明细行之前先确保凭证是草稿状态
  154. if invoice.voucher_id.state == 'done':
  155. invoice.voucher_id.voucher_draft()
  156. for vouch_line_id in vouch_line_ids:
  157. vouch_line_id.unlink()
  158. else:
  159. vouch_obj.voucher_done()
  160. return res
  161. def create_voucher_line(self, vals):
  162. currency_debit = 0
  163. currency_credit = 0
  164. if not vals.get('currency_id') or vals.get('currency_id') == self.env.user.company_id.currency_id.id or\
  165. not vals.get('rate_silent'):
  166. debit = credit = vals.get('amount')
  167. else:
  168. # 外币免税
  169. # if vals.get('buy_tax_amount') or vals.get('sell_tax_amount'):
  170. # raise UserError('外贸免税!')
  171. # 如果是外币
  172. debit = credit = vals.get('amount') * vals.get('rate_silent')
  173. currency_debit = vals.get('amount')
  174. currency_credit = vals.get('amount')
  175. # 把税从金额中减去
  176. if not vals.get('currency_id') or vals.get('currency_id') == self.env.user.company_id.currency_id.id or\
  177. not vals.get('rate_silent'):
  178. # 如果是本位币
  179. if vals.get('buy_tax_amount'): # 如果传入了进项税
  180. debit = vals.get('amount') - vals.get('buy_tax_amount')
  181. if vals.get('sell_tax_amount'): # 如果传入了销项税
  182. credit = vals.get('amount') - vals.get('sell_tax_amount')
  183. else:
  184. #如果是外币
  185. if vals.get('buy_tax_amount'): # 如果传入了进项税
  186. currency_debit = vals.get('amount') - vals.get('buy_tax_amount')
  187. debit = (vals.get('amount') - vals.get('buy_tax_amount')) * vals.get('rate_silent')
  188. if vals.get('sell_tax_amount'): # 如果传入了销项税
  189. currency_credit = vals.get('amount') - vals.get('sell_tax_amount')
  190. credit = (vals.get('amount') - vals.get('sell_tax_amount')) * vals.get('rate_silent')
  191. # 借方行
  192. currency_id = vals.get(
  193. 'currency_id') or self.env.user.company_id.currency_id.id
  194. if currency_id != self.env.user.company_id.currency_id.id: # 结算单上是外币
  195. self.env['voucher.line'].create({
  196. 'name': "%s %s" % (vals.get('name'), vals.get('string')),
  197. 'account_id': vals.get('debit_account_id'),
  198. 'debit': debit,
  199. 'voucher_id': vals.get('vouch_obj_id'),
  200. 'partner_id': vals.get('partner_debit', ''),
  201. 'auxiliary_id': vals.get('debit_auxiliary_id', False),
  202. 'currency_id': vals.get('currency_id'),
  203. 'currency_amount': currency_debit,
  204. 'rate_silent': vals.get('rate_silent'),
  205. 'init_obj': vals.get('init_obj', False),
  206. })
  207. else: # 结算单上是本位币
  208. self.env['voucher.line'].create({
  209. 'name': "%s %s" % (vals.get('name'), vals.get('string')),
  210. 'account_id': vals.get('debit_account_id'),
  211. 'debit': debit,
  212. 'voucher_id': vals.get('vouch_obj_id'),
  213. 'partner_id': vals.get('partner_debit', ''),
  214. 'auxiliary_id': vals.get('debit_auxiliary_id', False),
  215. 'init_obj': vals.get('init_obj', False),
  216. })
  217. # 进项税行
  218. if vals.get('buy_tax_amount'):
  219. if not self.env.user.company_id.import_tax_account:
  220. raise UserError('请通过"配置-->高级配置-->公司"菜单来设置进项税科目')
  221. # 如果结算单是外币
  222. if currency_id != self.env.user.company_id.currency_id.id:
  223. self.env['voucher.line'].create({
  224. 'name': "%s %s" % (vals.get('name'), vals.get('string')),
  225. 'account_id': self.env.user.company_id.import_tax_account.id,
  226. 'debit': vals.get('buy_tax_amount') * vals.get('rate_silent'),
  227. 'voucher_id': vals.get('vouch_obj_id'),
  228. 'currency_amount': vals.get('buy_tax_amount'),
  229. 'rate_silent': vals.get('rate_silent'),
  230. 'currency_id': vals.get('currency_id'),
  231. })
  232. else:# 结算单上是本位币
  233. self.env['voucher.line'].create({
  234. 'name': "%s %s" % (vals.get('name'), vals.get('string')),
  235. 'account_id': self.env.user.company_id.import_tax_account.id,
  236. 'debit': vals.get('buy_tax_amount'),
  237. 'voucher_id': vals.get('vouch_obj_id'),
  238. })
  239. currency_id = vals.get(
  240. 'currency_id') or self.env.user.company_id.currency_id.id
  241. if currency_id != self.env.user.company_id.currency_id.id:
  242. # 如果是外币
  243. self.env['voucher.line'].create({
  244. 'name': "%s %s" % (vals.get('name'), vals.get('string')),
  245. 'partner_id': vals.get('partner_credit', ''),
  246. 'account_id': vals.get('credit_account_id'),
  247. 'credit': credit,
  248. 'voucher_id': vals.get('vouch_obj_id'),
  249. 'auxiliary_id': vals.get('credit_auxiliary_id', False),
  250. 'currency_amount': currency_credit,
  251. 'rate_silent': vals.get('rate_silent'),
  252. 'currency_id': vals.get('currency_id'),
  253. 'init_obj': vals.get('init_obj', False),
  254. })
  255. else:
  256. self.env['voucher.line'].create({
  257. 'name': "%s %s" % (vals.get('name'), vals.get('string')),
  258. 'partner_id': vals.get('partner_credit', ''),
  259. 'account_id': vals.get('credit_account_id'),
  260. 'credit': credit,
  261. 'voucher_id': vals.get('vouch_obj_id'),
  262. 'auxiliary_id': vals.get('credit_auxiliary_id', False),
  263. 'init_obj': vals.get('init_obj', False),
  264. })
  265. # 销项税行
  266. if vals.get('sell_tax_amount'):
  267. if not self.env.user.company_id.output_tax_account:
  268. raise UserError(
  269. '您还没有配置公司的销项税科目。\n请通过"配置-->高级配置-->公司"菜单来设置销项税科目!')
  270. if currency_id != self.env.user.company_id.currency_id.id:
  271. # 如果是外币,则销项税额要乘以汇率。
  272. self.env['voucher.line'].create({
  273. 'name': "%s %s" % (vals.get('name'), vals.get('string')),
  274. 'account_id': self.env.user.company_id.output_tax_account.id,
  275. 'credit': vals.get('sell_tax_amount') * vals.get('rate_silent') ,
  276. 'voucher_id': vals.get('vouch_obj_id'),
  277. 'currency_amount': vals.get('sell_tax_amount'),
  278. 'rate_silent': vals.get('rate_silent'),
  279. 'currency_id': vals.get('currency_id'),
  280. })
  281. else:
  282. #如果是本位币
  283. self.env['voucher.line'].create({
  284. 'name': "%s %s" % (vals.get('name'), vals.get('string')),
  285. 'account_id': self.env.user.company_id.output_tax_account.id,
  286. 'credit': vals.get('sell_tax_amount'),
  287. 'voucher_id': vals.get('vouch_obj_id'),
  288. })
  289. return True
上海开阖软件有限公司 沪ICP备12045867号-1