fix Clean up accounting errors清理会计科目报错(App Customize Odoo 14) #48

This commit is contained in:
ivan deng
2021-11-09 11:57:41 +08:00
parent 0220aa24e8
commit d431d44641
5 changed files with 86 additions and 87 deletions

View File

@@ -23,7 +23,7 @@
{ {
'name': 'Odoo 15,14,13 Customize OEM(Boost, Data reset)', 'name': 'Odoo 15,14,13 Customize OEM(Boost, Data reset)',
'version': '14.21.03.31', 'version': '14.21.11.09',
'author': 'Sunpop.cn', 'author': 'Sunpop.cn',
'category': 'Productivity', 'category': 'Productivity',
'website': 'https://www.sunpop.cn', 'website': 'https://www.sunpop.cn',

View File

@@ -3,14 +3,13 @@
import logging import logging
from odoo import api, fields, models, _ from odoo import api, fields, models, _
from odoo.exceptions import UserError, ValidationError
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
class ResConfigSettings(models.TransientModel): class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings' _inherit = 'res.config.settings'
app_system_name = fields.Char('System Name', help="Setup System Name,which replace Odoo") app_system_name = fields.Char('System Name', help="Setup System Name,which replace Odoo")
app_show_lang = fields.Boolean('Show Quick Language Switcher', app_show_lang = fields.Boolean('Show Quick Language Switcher',
help="When enable,User can quick switch language in user menu") help="When enable,User can quick switch language in user menu")
@@ -26,7 +25,7 @@ class ResConfigSettings(models.TransientModel):
group_show_author_in_apps = fields.Boolean(string="Show Author in Apps Dashboard", implied_group='app_odoo_customize.group_show_author_in_apps', group_show_author_in_apps = fields.Boolean(string="Show Author in Apps Dashboard", implied_group='app_odoo_customize.group_show_author_in_apps',
help="Uncheck to Hide Author and Website in Apps Dashboard") help="Uncheck to Hide Author and Website in Apps Dashboard")
module_odoo_referral = fields.Boolean('Show Odoo Referral', help="Uncheck to remove the Odoo Referral") module_odoo_referral = fields.Boolean('Show Odoo Referral', help="Uncheck to remove the Odoo Referral")
app_documentation_url = fields.Char('Documentation Url') app_documentation_url = fields.Char('Documentation Url')
app_documentation_dev_url = fields.Char('Developer Documentation Url') app_documentation_dev_url = fields.Char('Developer Documentation Url')
app_support_url = fields.Char('Support Url') app_support_url = fields.Char('Support Url')
@@ -34,13 +33,13 @@ class ResConfigSettings(models.TransientModel):
app_account_url = fields.Char('My Odoo.com Account Url') app_account_url = fields.Char('My Odoo.com Account Url')
app_enterprise_url = fields.Char('Customize Module Url(eg. Enterprise)') app_enterprise_url = fields.Char('Customize Module Url(eg. Enterprise)')
app_ribbon_name = fields.Char('Show Demo Ribbon') app_ribbon_name = fields.Char('Show Demo Ribbon')
@api.model @api.model
def get_values(self): def get_values(self):
res = super(ResConfigSettings, self).get_values() res = super(ResConfigSettings, self).get_values()
ir_config = self.env['ir.config_parameter'].sudo() ir_config = self.env['ir.config_parameter'].sudo()
app_system_name = ir_config.get_param('app_system_name', default='odooApp') app_system_name = ir_config.get_param('app_system_name', default='odooApp')
app_show_lang = True if ir_config.get_param('app_show_lang') == "True" else False app_show_lang = True if ir_config.get_param('app_show_lang') == "True" else False
app_show_debug = True if ir_config.get_param('app_show_debug') == "True" else False app_show_debug = True if ir_config.get_param('app_show_debug') == "True" else False
app_show_documentation = True if ir_config.get_param('app_show_documentation') == "True" else False app_show_documentation = True if ir_config.get_param('app_show_documentation') == "True" else False
@@ -50,7 +49,7 @@ class ResConfigSettings(models.TransientModel):
app_show_enterprise = True if ir_config.get_param('app_show_enterprise') == "True" else False app_show_enterprise = True if ir_config.get_param('app_show_enterprise') == "True" else False
app_show_share = True if ir_config.get_param('app_show_share') == "True" else False app_show_share = True if ir_config.get_param('app_show_share') == "True" else False
app_show_poweredby = True if ir_config.get_param('app_show_poweredby') == "True" else False app_show_poweredby = True if ir_config.get_param('app_show_poweredby') == "True" else False
app_documentation_url = ir_config.get_param('app_documentation_url', app_documentation_url = ir_config.get_param('app_documentation_url',
default='https://www.sunpop.cn/documentation/user/12.0/en/index.html') default='https://www.sunpop.cn/documentation/user/12.0/en/index.html')
app_documentation_dev_url = ir_config.get_param('app_documentation_dev_url', app_documentation_dev_url = ir_config.get_param('app_documentation_dev_url',
@@ -71,7 +70,7 @@ class ResConfigSettings(models.TransientModel):
app_show_enterprise=app_show_enterprise, app_show_enterprise=app_show_enterprise,
app_show_share=app_show_share, app_show_share=app_show_share,
app_show_poweredby=app_show_poweredby, app_show_poweredby=app_show_poweredby,
app_documentation_url=app_documentation_url, app_documentation_url=app_documentation_url,
app_documentation_dev_url=app_documentation_dev_url, app_documentation_dev_url=app_documentation_dev_url,
app_support_url=app_support_url, app_support_url=app_support_url,
@@ -81,7 +80,7 @@ class ResConfigSettings(models.TransientModel):
app_ribbon_name=app_ribbon_name app_ribbon_name=app_ribbon_name
) )
return res return res
def set_values(self): def set_values(self):
super(ResConfigSettings, self).set_values() super(ResConfigSettings, self).set_values()
ir_config = self.env['ir.config_parameter'].sudo() ir_config = self.env['ir.config_parameter'].sudo()
@@ -95,7 +94,7 @@ class ResConfigSettings(models.TransientModel):
ir_config.set_param("app_show_enterprise", self.app_show_enterprise or "False") ir_config.set_param("app_show_enterprise", self.app_show_enterprise or "False")
ir_config.set_param("app_show_share", self.app_show_share or "False") ir_config.set_param("app_show_share", self.app_show_share or "False")
ir_config.set_param("app_show_poweredby", self.app_show_poweredby or "False") ir_config.set_param("app_show_poweredby", self.app_show_poweredby or "False")
ir_config.set_param("app_documentation_url", ir_config.set_param("app_documentation_url",
self.app_documentation_url or "https://www.sunpop.cn/documentation/user/12.0/en/index.html") self.app_documentation_url or "https://www.sunpop.cn/documentation/user/12.0/en/index.html")
ir_config.set_param("app_documentation_dev_url", ir_config.set_param("app_documentation_dev_url",
@@ -105,7 +104,7 @@ class ResConfigSettings(models.TransientModel):
ir_config.set_param("app_account_url", self.app_account_url or "https://www.sunpop.cn/my-account/") ir_config.set_param("app_account_url", self.app_account_url or "https://www.sunpop.cn/my-account/")
ir_config.set_param("app_enterprise_url", self.app_enterprise_url or "https://www.sunpop.cn") ir_config.set_param("app_enterprise_url", self.app_enterprise_url or "https://www.sunpop.cn")
ir_config.set_param("app_ribbon_name", self.app_ribbon_name or "*Sunpop.cn") ir_config.set_param("app_ribbon_name", self.app_ribbon_name or "*Sunpop.cn")
def set_module_url(self): def set_module_url(self):
sql = "UPDATE ir_module_module SET website = '%s' WHERE license like '%s' and website <> ''" % (self.app_enterprise_url, 'OEEL%') sql = "UPDATE ir_module_module SET website = '%s' WHERE license like '%s' and website <> ''" % (self.app_enterprise_url, 'OEEL%')
try: try:
@@ -113,12 +112,16 @@ class ResConfigSettings(models.TransientModel):
self._cr.commit() self._cr.commit()
except Exception as e: except Exception as e:
pass pass
# 清数据o=对象, s=序列 # 清数据o=对象, s=序列
def remove_app_data(self, o, s=[]): def remove_app_data(self, o, s=[]):
for line in o: for line in o:
# 检查是否存在 # 检查是否存在
if not self.env['ir.model']._get(line): try:
if not self.env['ir.model']._get(line):
continue
except Exception as e:
_logger.warning('remove data error get ir.model: %s,%s', line, e)
continue continue
obj_name = line obj_name = line
obj = self.pool.get(obj_name) obj = self.pool.get(obj_name)
@@ -127,19 +130,14 @@ class ResConfigSettings(models.TransientModel):
t_name = obj_name.replace('.', '_') t_name = obj_name.replace('.', '_')
else: else:
t_name = obj._table t_name = obj._table
sql = "delete from %s" % t_name sql = "delete from %s" % t_name
# 增加多公司处理 # 增加多公司处理
if hasattr(self.env[obj_name], 'company_id'):
field = self.env[obj_name]._fields['company_id']
if not field.related or field.store:
sql = "%s where company_id=%d" % (sql, self.env.company.id)
_logger.warning('remove_app_data where add company_id: %s' % obj_name)
try: try:
self._cr.execute(sql) self._cr.execute(sql)
# self._cr.commit() self._cr.commit()
except Exception as e: except Exception as e:
_logger.error('remove data error: %s,%s', line, e) _logger.warning('remove data error: %s,%s', line, e)
# 更新序号 # 更新序号
for line in s: for line in s:
domain = ['|', ('code', '=ilike', line + '%'), ('prefix', '=ilike', line + '%')] domain = ['|', ('code', '=ilike', line + '%'), ('prefix', '=ilike', line + '%')]
@@ -150,7 +148,7 @@ class ResConfigSettings(models.TransientModel):
'number_next': 1, 'number_next': 1,
}) })
except Exception as e: except Exception as e:
_logger.error('reset sequence data error: %s,%s', line, e) _logger.warning('reset sequence data error: %s,%s', line, e)
return True return True
def remove_sales(self): def remove_sales(self):
@@ -169,7 +167,7 @@ class ResConfigSettings(models.TransientModel):
'sale', 'sale',
] ]
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_product(self): def remove_product(self):
to_removes = [ to_removes = [
# 清除产品数据 # 清除产品数据
@@ -180,7 +178,7 @@ class ResConfigSettings(models.TransientModel):
'product.product', 'product.product',
] ]
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_product_attribute(self): def remove_product_attribute(self):
to_removes = [ to_removes = [
# 清除产品属性 # 清除产品属性
@@ -189,7 +187,7 @@ class ResConfigSettings(models.TransientModel):
] ]
seqs = [] seqs = []
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_pos(self): def remove_pos(self):
to_removes = [ to_removes = [
# 清除POS单据 # 清除POS单据
@@ -202,9 +200,9 @@ class ResConfigSettings(models.TransientModel):
'pos.', 'pos.',
] ]
res = self.remove_app_data(to_removes, seqs) res = self.remove_app_data(to_removes, seqs)
# 更新要关帐的值,因为 store=true 的计算字段要重置 # 更新要关帐的值,因为 store=true 的计算字段要重置
try: try:
statement = self.env['account.bank.statement'].sudo().search([]) statement = self.env['account.bank.statement'].sudo().search([])
for s in statement: for s in statement:
@@ -212,7 +210,7 @@ class ResConfigSettings(models.TransientModel):
except Exception as e: except Exception as e:
_logger.error('reset sequence data error: %s', e) _logger.error('reset sequence data error: %s', e)
return res return res
def remove_purchase(self): def remove_purchase(self):
to_removes = [ to_removes = [
# 清除采购单据 # 清除采购单据
@@ -225,7 +223,7 @@ class ResConfigSettings(models.TransientModel):
'purchase.', 'purchase.',
] ]
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_expense(self): def remove_expense(self):
to_removes = [ to_removes = [
# 清除 # 清除
@@ -238,7 +236,7 @@ class ResConfigSettings(models.TransientModel):
'hr.expense.', 'hr.expense.',
] ]
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_mrp(self): def remove_mrp(self):
to_removes = [ to_removes = [
# 清除生产单据 # 清除生产单据
@@ -257,7 +255,7 @@ class ResConfigSettings(models.TransientModel):
'mrp.', 'mrp.',
] ]
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_mrp_bom(self): def remove_mrp_bom(self):
to_removes = [ to_removes = [
# 清除生产BOM # 清除生产BOM
@@ -266,7 +264,7 @@ class ResConfigSettings(models.TransientModel):
] ]
seqs = [] seqs = []
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_inventory(self): def remove_inventory(self):
to_removes = [ to_removes = [
# 清除库存单据 # 清除库存单据
@@ -291,10 +289,11 @@ class ResConfigSettings(models.TransientModel):
'stock.', 'stock.',
'picking.', 'picking.',
'procurement.group', 'procurement.group',
'product.tracking.default',
'WH/', 'WH/',
] ]
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_account(self): def remove_account(self):
to_removes = [ to_removes = [
# 清除财务会计单据 # 清除财务会计单据
@@ -314,7 +313,7 @@ class ResConfigSettings(models.TransientModel):
'account.move', 'account.move',
] ]
res = self.remove_app_data(to_removes, []) res = self.remove_app_data(to_removes, [])
# extra 更新序号 # extra 更新序号
domain = [ domain = [
('company_id', '=', self.env.company.id), ('company_id', '=', self.env.company.id),
@@ -336,9 +335,8 @@ class ResConfigSettings(models.TransientModel):
except Exception as e: except Exception as e:
_logger.error('reset sequence data error: %s,%s', domain, e) _logger.error('reset sequence data error: %s,%s', domain, e)
return res return res
def remove_account_chart(self): def remove_account_chart(self):
# todo: 安装会计模块后,会有问题,后续处理
company_id = self.env.company.id company_id = self.env.company.id
self = self.with_context(force_company=company_id, company_id=company_id) self = self.with_context(force_company=company_id, company_id=company_id)
to_removes = [ to_removes = [
@@ -360,73 +358,74 @@ class ResConfigSettings(models.TransientModel):
try: try:
field1 = self.env['ir.model.fields']._get('product.template', "taxes_id").id field1 = self.env['ir.model.fields']._get('product.template', "taxes_id").id
field2 = self.env['ir.model.fields']._get('product.template', "supplier_taxes_id").id field2 = self.env['ir.model.fields']._get('product.template', "supplier_taxes_id").id
sql = "delete from ir_default where (field_id = %s or field_id = %s) and company_id=%d" \ sql = "delete from ir_default where (field_id = %s or field_id = %s) and company_id=%d" \
% (field1, field2, company_id) % (field1, field2, company_id)
sql2 = "update account_journal set bank_account_id=NULL where company_id=%d;" % company_id sql2 = "update account_journal set bank_account_id=NULL where company_id=%d;" % company_id
self._cr.execute(sql) self._cr.execute(sql)
self._cr.execute(sql2) self._cr.execute(sql2)
self._cr.commit() self._cr.commit()
except Exception as e: except Exception as e:
_logger.error('remove data error: %s,%s', 'account_chart: set tax and account_journal', e) _logger.error('remove data error: %s,%s', 'account_chart: set tax and account_journal', e)
# 增加对 pos的处理 # 增加对 pos的处理
if self.env['ir.model']._get('pos.config'): try:
self.env['pos.config'].write({ rec = self.env['pos.config'].search([])
'journal_id': False, rec.write({
'journal_id': None,
'invoice_journal_id': None,
}) })
except Exception as e:
_logger.error('remove data error: %s,%s', 'account_chart', e)
# todo: 以下处理参考 res.partner的合并将所有m2o的都一次处理不需要次次找模型 # todo: 以下处理参考 res.partner的合并将所有m2o的都一次处理不需要次次找模型
# partner 处理 # partner 处理
try: try:
rec = self.env['res.partner'].search([]) rec = self.env['res.partner'].search([])
for r in rec: rec.write({
r.write({ 'property_account_receivable_id': None,
'property_account_receivable_id': None, 'property_account_payable_id': None,
'property_account_payable_id': None, })
})
except Exception as e: except Exception as e:
_logger.error('remove data error: %s,%s', 'account_chart', e) _logger.error('remove data error: %s,%s', 'account_chart', e)
# 品类处理 # 品类处理
try: try:
rec = self.env['product.category'].search([]) rec = self.env['product.category'].search([])
for r in rec: rec.write({
r.write({ 'property_account_income_categ_id': None,
'property_account_income_categ_id': None, 'property_account_expense_categ_id': None,
'property_account_expense_categ_id': None, 'property_account_creditor_price_difference_categ': None,
'property_account_creditor_price_difference_categ': None, 'property_stock_account_input_categ_id': None,
'property_stock_account_input_categ_id': None, 'property_stock_account_output_categ_id': None,
'property_stock_account_output_categ_id': None, 'property_stock_valuation_account_id': None,
'property_stock_valuation_account_id': None, })
})
except Exception as e: except Exception as e:
pass pass
# 产品处理 # 产品处理
try: try:
rec = self.env['product.template'].search([]) rec = self.env['product.template'].search([])
for r in rec: rec.write({
r.write({ 'property_account_income_id': None,
'property_account_income_id': None, 'property_account_expense_id': None,
'property_account_expense_id': None, })
})
except Exception as e: except Exception as e:
pass pass
# 库存计价处理 # 库存计价处理
try: try:
rec = self.env['stock.location'].search([]) rec = self.env['stock.location'].search([])
for r in rec: rec.write({
r.write({ 'valuation_in_account_id': None,
'valuation_in_account_id': None, 'valuation_out_account_id': None,
'valuation_out_account_id': None, })
})
except Exception as e: except Exception as e:
pass # raise Warning(e) pass # raise Warning(e)
seqs = [] seqs = []
res = self.remove_app_data(to_removes, seqs) res = self.remove_app_data(to_removes, seqs)
self.env.company.write({'chart_template_id': False}) self._cr.commit()
self.env.company.sudo().write({'chart_template_id': False})
return res return res
def remove_project(self): def remove_project(self):
to_removes = [ to_removes = [
# 清除项目 # 清除项目
@@ -437,7 +436,7 @@ class ResConfigSettings(models.TransientModel):
] ]
seqs = [] seqs = []
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_quality(self): def remove_quality(self):
to_removes = [ to_removes = [
# 清除质检数据 # 清除质检数据
@@ -456,7 +455,7 @@ class ResConfigSettings(models.TransientModel):
# 'quality.point', # 'quality.point',
] ]
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_quality_setting(self): def remove_quality_setting(self):
to_removes = [ to_removes = [
# 清除质检设置 # 清除质检设置
@@ -468,7 +467,7 @@ class ResConfigSettings(models.TransientModel):
'quality.tag', 'quality.tag',
] ]
return self.remove_app_data(to_removes) return self.remove_app_data(to_removes)
def remove_website(self): def remove_website(self):
to_removes = [ to_removes = [
# 清除网站数据w, w_blog # 清除网站数据w, w_blog
@@ -489,7 +488,7 @@ class ResConfigSettings(models.TransientModel):
] ]
seqs = [] seqs = []
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_message(self): def remove_message(self):
to_removes = [ to_removes = [
# 清除消息数据 # 清除消息数据
@@ -499,7 +498,7 @@ class ResConfigSettings(models.TransientModel):
] ]
seqs = [] seqs = []
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_workflow(self): def remove_workflow(self):
to_removes = [ to_removes = [
# 清除工作流 # 清除工作流
@@ -508,7 +507,7 @@ class ResConfigSettings(models.TransientModel):
] ]
seqs = [] seqs = []
return self.remove_app_data(to_removes, seqs) return self.remove_app_data(to_removes, seqs)
def remove_all_biz(self): def remove_all_biz(self):
self.remove_account() self.remove_account()
self.remove_quality() self.remove_quality()
@@ -521,7 +520,7 @@ class ResConfigSettings(models.TransientModel):
self.remove_expense() self.remove_expense()
self.remove_message() self.remove_message()
return True return True
def reset_cat_loc_name(self): def reset_cat_loc_name(self):
ids = self.env['product.category'].search([ ids = self.env['product.category'].search([
('parent_id', '!=', False) ('parent_id', '!=', False)

View File

@@ -9,9 +9,9 @@
{ {
'name': '2021最新中国企业会计表.Latest Chinese Accounting.', 'name': '2021最新中国企业会计表.Latest Chinese Accounting.',
'version': '14.21.11.07', 'version': '14.21.11.09',
'author': 'Sunpop.cn', 'author': 'Sunpop.cn',
'category': 'Localization', 'category': 'Accounting/Localizations/Account Charts',
'website': 'https://www.sunpop.cn', 'website': 'https://www.sunpop.cn',
'license': 'LGPL-3', 'license': 'LGPL-3',
'sequence': 12, 'sequence': 12,

View File

@@ -1,7 +1,7 @@
"id","code_prefix","name" "id","code_prefix_start","code_prefix_end","name"
"account_group_1","1","资产类" "account_group_1","1","1","资产类"
"account_group_2","2","负债类" "account_group_2","2","2","负债类"
"account_group_3","3","共同类" "account_group_3","3","3","共同类"
"account_group_4","4","所有者权益类" "account_group_4","4","4","所有者权益类"
"account_group_5","5","成本类" "account_group_5","5","5","成本类"
"account_group_6","6","损益类" "account_group_6","6","6","损益类"
1 id code_prefix code_prefix_start code_prefix_end name
2 account_group_1 1 1 1 资产类
3 account_group_2 2 2 2 负债类
4 account_group_3 3 3 3 共同类
5 account_group_4 4 4 4 所有者权益类
6 account_group_5 5 5 5 成本类
7 account_group_6 6 6 6 损益类

View File

@@ -12,7 +12,7 @@
</record> </record>
<function model="account.chart.template" name="try_loading"> <function model="account.chart.template" name="try_loading">
<value eval="[ref('l10n_chart_china_standard_business_latest')]"/> <value eval="[ref('l10n_cn_standard_latest.l10n_chart_china_standard_business_latest')]"/>
</function> </function>
</data> </data>
</odoo> </odoo>