|
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
# &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
|
|
|
# QQ:570165989
|
|
|
|
|
# Author:'wangshuai'
|
|
|
|
|
# Date:2020/11/25 0025
|
|
|
|
|
# &&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
|
|
|
|
|
import datetime
|
|
|
|
|
from datetime import date
|
|
|
|
|
from odoo import models, fields, api, _
|
|
|
|
|
from odoo.exceptions import ValidationError, MissingError, UserError
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AccountMove(models.Model):
|
|
|
|
|
_inherit = 'account.move'
|
|
|
|
|
_description = '记账凭证'
|
|
|
|
|
|
|
|
|
|
journal_id = fields.Many2one(
|
|
|
|
|
'account.journal',
|
|
|
|
|
string='Journal',
|
|
|
|
|
compute='_compute_journal_id', store=True, readonly=False, precompute=True,
|
|
|
|
|
required=True,
|
|
|
|
|
states={'draft': [('readonly', False)]},
|
|
|
|
|
check_company=True,
|
|
|
|
|
domain="[('id', 'in', suitable_journal_ids)]",
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@api.depends('company_id', 'invoice_filter_type_domain')
|
|
|
|
|
def _compute_suitable_journal_ids(self):
|
|
|
|
|
for m in self:
|
|
|
|
|
# journal_type = m.invoice_filter_type_domain or 'general'
|
|
|
|
|
company_id = m.company_id.id or self.env.company.id
|
|
|
|
|
domain = [('company_id', '=', company_id)]
|
|
|
|
|
m.suitable_journal_ids = self.env['account.journal'].search(domain)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@api.constrains('name', 'journal_id', 'state')
|
|
|
|
|
def _check_unique_sequence_number(self):
|
|
|
|
|
moves = self.filtered(lambda move: move.state == 'posted')
|
|
|
|
|
if not moves:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
# self.flush(['name', 'journal_id', 'move_type', 'state'])
|
|
|
|
|
self.flush_model(['name', 'journal_id', 'move_type', 'state'])
|
|
|
|
|
|
|
|
|
|
# /!\ Computed stored fields are not yet inside the database.
|
|
|
|
|
self._cr.execute('''
|
|
|
|
|
SELECT move2.id, move2.name
|
|
|
|
|
FROM account_move move
|
|
|
|
|
INNER JOIN account_move move2 ON
|
|
|
|
|
move2.name = move.name
|
|
|
|
|
AND move2.journal_id = move.journal_id
|
|
|
|
|
AND move2.move_type = move.move_type
|
|
|
|
|
AND move2.id != move.id
|
|
|
|
|
WHERE move.id IN %s AND move2.state = 'posted'
|
|
|
|
|
''', [tuple(moves.ids)])
|
|
|
|
|
res = self._cr.fetchall()
|
|
|
|
|
if res:
|
|
|
|
|
for order in self:
|
|
|
|
|
# 查询系统编号
|
|
|
|
|
sequence_name = self.env['ir.sequence'].search([('code', '=', 'move.sequence.constant'),
|
|
|
|
|
('company_id', '=', self.company_id.id)])
|
|
|
|
|
# 该公司无系统编号则创建
|
|
|
|
|
if not sequence_name:
|
|
|
|
|
sequence_name = self.env['ir.sequence'].create({
|
|
|
|
|
'name': '%s凭证序列(固定)' % order.company_id.name,
|
|
|
|
|
'code': 'move.sequence.constant',
|
|
|
|
|
'implementation': 'no_gap',
|
|
|
|
|
'padding': 4,
|
|
|
|
|
'prefix': '%(range_year)s/%(range_month)s/',
|
|
|
|
|
'use_date_range': True,
|
|
|
|
|
'date_range_type': 'month',
|
|
|
|
|
'company_id': order.company_id.id,
|
|
|
|
|
})
|
|
|
|
|
# 如果查询到,编号有误。那么自动获取最重排编号。
|
|
|
|
|
all_move = self.env['account.move'].search([('company_id', '=', self.company_id.id), ('fr_period_id', '=', self.fr_period_id.id)])
|
|
|
|
|
self.name = sequence_name.with_context(ir_sequence_date=self.date).next_by_id()
|
|
|
|
|
# self._generate_move_name_next(all_move, sequence_name)
|
|
|
|
|
# 此方法注释掉。报错提示。直接重新生成新的系统编号
|
|
|
|
|
# raise ValidationError(_('Posted journal entry must have an unique sequence number per company.\n'
|
|
|
|
|
# 'Problematic numbers: %s\n') % ', '.join(r[1] for r in res))
|
|
|
|
|
|
|
|
|
|
# 手动删除6月份,凭证明细行的,现金流量项目
|
|
|
|
|
def clean_line_fr_cash_flow_id(self):
|
|
|
|
|
account_move_line = self.env['account.move.line'].search([('fr_period_id', '=', 6)])
|
|
|
|
|
for line in account_move_line:
|
|
|
|
|
if line.account_id.user_type_id.name != '银行和现金':
|
|
|
|
|
line.fr_cash_flow_id = None
|
|
|
|
|
|
|
|
|
|
# 去除,删除,非银行科目,现金流量项目
|
|
|
|
|
def clean_line_fr_cash_flow(self):
|
|
|
|
|
account_move_line = self.env['account.move.line'].search([])
|
|
|
|
|
|
|
|
|
|
for line in account_move_line:
|
|
|
|
|
if line.account_id.user_type_id.name != '银行和现金':
|
|
|
|
|
line.fr_cash_flow_id = None
|
|
|
|
|
|
|
|
|
|
# 审批已完成的结算单,修改状态为已取消。目的:为了能删除
|
|
|
|
|
def cancel_passed_approval(self):
|
|
|
|
|
ai = self.env['approval.flow.instance'].search([('res_id', '=', self.id), ('model_name', '=', 'account.move')])
|
|
|
|
|
ai[0].state = 'cancel'
|
|
|
|
|
|
|
|
|
|
# 好。
|
|
|
|
|
def action_add_quick(self):
|
|
|
|
|
"""
|
|
|
|
|
快捷添加分析账户分析标签按钮
|
|
|
|
|
:return:
|
|
|
|
|
"""
|
|
|
|
|
self.ensure_one()
|
|
|
|
|
return {
|
|
|
|
|
'type': 'ir.actions.act_window',
|
|
|
|
|
'res_model': 'quick.add.wizard',
|
|
|
|
|
'view_mode': 'form',
|
|
|
|
|
'view_type': 'form',
|
|
|
|
|
'views': [[self.env.ref('account_ledger.QuickAddWizardViewForm').id, 'form']],
|
|
|
|
|
'context': {
|
|
|
|
|
'default_account_move_id': self.id,
|
|
|
|
|
},
|
|
|
|
|
'name': '快捷添加分析账户、分析标签',
|
|
|
|
|
'target': 'new'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# 会计发票,确认操作时,添加 凭证 审核人 ,审核日期 过账人,过账日期
|
|
|
|
|
def action_post(self):
|
|
|
|
|
res = super(AccountMove, self).action_post()
|
|
|
|
|
self.write({
|
|
|
|
|
'fr_approved_uid': self.env.user.id,
|
|
|
|
|
'fr_approved_date': datetime.datetime.now(),
|
|
|
|
|
'fr_posted_uid': self.env.user.id,
|
|
|
|
|
'fr_posted_date': datetime.datetime.now(),
|
|
|
|
|
})
|
|
|
|
|
# 检查分析标签-分析账户必填
|
|
|
|
|
for order in self:
|
|
|
|
|
for line in order.line_ids:
|
|
|
|
|
if line.account_id.cash_bool:
|
|
|
|
|
if len(line.fr_cash_flow_id) <= 0:
|
|
|
|
|
raise ValidationError('会计分录,账户:【' + line.account_id.name + '】没有选择现金流量,请选择后重试' + str(order))
|
|
|
|
|
if line.account_id.label_bool:
|
|
|
|
|
if len(line.analytic_tag_ids) <= 0:
|
|
|
|
|
raise ValidationError('对应科目分析标签/账户必填,请点击【快捷添加标签/账户】按钮,快捷添加!记录ID:' + str(order))
|
|
|
|
|
if line.account_id.analysis_bool:
|
|
|
|
|
if len(line.analytic_account_id) <= 0:
|
|
|
|
|
raise ValidationError('对应科目分析标签/账户必填,请点击【快捷添加标签/账户】按钮,快捷添加!记录ID:' + str(order))
|
|
|
|
|
# 发票点击确认 - 检查科目 相关业务伙伴是否 勾选必填。
|
|
|
|
|
# for order in self:
|
|
|
|
|
# for line in order.line_ids:
|
|
|
|
|
# if line.account_id.partner_bool:
|
|
|
|
|
# line.write({
|
|
|
|
|
# 'partner_id': order.partner_id.id,
|
|
|
|
|
# })
|
|
|
|
|
# else:
|
|
|
|
|
# line.write({
|
|
|
|
|
# 'partner_id': None,
|
|
|
|
|
# })
|
|
|
|
|
#
|
|
|
|
|
# # 如果科目中没有选择 标签和账户,那么将标签和账户 设置为空
|
|
|
|
|
# if not line.account_id.analysis_bool:
|
|
|
|
|
# line.write({
|
|
|
|
|
# 'analytic_account_id': None,
|
|
|
|
|
# })
|
|
|
|
|
# if not line.account_id.label_bool:
|
|
|
|
|
# line.write({
|
|
|
|
|
# 'analytic_tag_ids': None,
|
|
|
|
|
# })
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
# 重写并修改从销售发货过来生成的库存相关凭证方法
|
|
|
|
|
def _post(self, soft=True):
|
|
|
|
|
posted = super()._post(soft)
|
|
|
|
|
|
|
|
|
|
self.write({
|
|
|
|
|
'fr_approved_uid': self.env.user.id,
|
|
|
|
|
'fr_approved_date': datetime.datetime.now(),
|
|
|
|
|
'fr_posted_uid': self.env.user.id,
|
|
|
|
|
'fr_posted_date': datetime.datetime.now(),
|
|
|
|
|
})
|
|
|
|
|
# - 检查科目 相关业务伙伴是否 勾选必填。系统原生逻辑是将业务伙伴加上。实际是根据我们后台配置进行修改。科目上配置了
|
|
|
|
|
# - 那么就添加,未配置。就不添加
|
|
|
|
|
# for order in self:
|
|
|
|
|
# for line in order.line_ids:
|
|
|
|
|
# if line.account_id.partner_bool:
|
|
|
|
|
# line.write({
|
|
|
|
|
# 'partner_id': order.partner_id.id,
|
|
|
|
|
# })
|
|
|
|
|
# else:
|
|
|
|
|
# line.write({
|
|
|
|
|
# 'partner_id': None,
|
|
|
|
|
# })
|
|
|
|
|
return posted
|
|
|
|
|
|
|
|
|
|
# 会计发票,重置为草稿状态 不允许非当前会计期间单据重置为草稿操作
|
|
|
|
|
def button_draft(self):
|
|
|
|
|
res = super(AccountMove, self).button_draft()
|
|
|
|
|
# if self.fr_period_state != 'ongoing':
|
|
|
|
|
# raise UserError(_("当前单据对应的凭证的会计期间已关闭。不允许进行重置操作。"))
|
|
|
|
|
# 重置为草稿 、将审核人、审核日期 、 过账人、过账日期 清楚。
|
|
|
|
|
self.write({
|
|
|
|
|
'fr_posted_uid': None,
|
|
|
|
|
'fr_posted_date': None,
|
|
|
|
|
'fr_approved_uid': None,
|
|
|
|
|
'fr_approved_date': None,
|
|
|
|
|
})
|
|
|
|
|
return res
|
|
|
|
|
|
|
|
|
|
#
|