Merge pull request #33 from expsa/ctp_database

ctp_database
This commit is contained in:
esam-sermah 2025-10-04 09:06:57 +03:00 committed by GitHub
commit dcf0785ece
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 507 additions and 0 deletions

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import models

View File

@ -0,0 +1,25 @@
{
"name": "Database Clean up",
"version": "18.0.1.0.0",
"summary": """
Cybernetics Plus Tools Database Clean up
.""",
"description": """
Cybernetics Plus Tools Database Clean up
.""",
"author": "Cybernetics Plus",
"website": "https://www.cybernetics.plus",
"live_test_url": "https://www.cybernetics.plus",
"images": ["static/description/banner.gif"],
"category": "Odex30-Base",
"license": "LGPL-3",
"installable": True,
"application": False,
"auto_install": False,
"contributors": [
"Developer <dev@cybernetics.plus>",
],
"data": [
"views/ctp_database_clean_up.xml",
],
}

View File

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import ctp_database_clean_up

View File

@ -0,0 +1,355 @@
# -*- coding: utf-8 -*-
import logging
from odoo import models, _
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class CtpDatabaseCleanUp(models.TransientModel):
_inherit = 'res.config.settings'
def remove_data(self, o, s=[]):
for line in o:
try:
if not self.env['ir.model']._get(line):
continue
except Exception as e:
_logger.warning('Database Clean up error get ir.model: %s,%s', line, e)
continue
obj_name = line
obj = self.pool.get(obj_name)
if not obj:
t_name = obj_name.replace('.', '_')
else:
t_name = obj._table
sql = "delete from %s" % t_name
try:
self._cr.execute(sql)
self._cr.commit()
except Exception as e:
_logger.warning('Database Clean up error: %s,%s', line, e)
for line in s:
domain = ['|', ('code', '=ilike', line + '%'), ('prefix', '=ilike', line + '%')]
try:
seqs = self.env['ir.sequence'].sudo().search(domain)
if seqs.exists():
seqs.write({
'number_next': 1,
})
except Exception as e:
_logger.warning('Reset Sequence Data error: %s,%s', line, e)
return True
def remove_sales(self):
to_removes = [
'sale.order.line',
'sale.order',
]
seqs = [
'sale',
]
return self.remove_data(to_removes, seqs)
def remove_product(self):
to_removes = [
'product.product',
'product.template',
]
seqs = [
'product.product',
]
return self.remove_data(to_removes, seqs)
def remove_product_attribute(self):
to_removes = [
'product.attribute.value',
'product.attribute',
]
seqs = []
return self.remove_data(to_removes, seqs)
def remove_pos(self):
to_removes = [
'pos.payment',
'pos.order.line',
'pos.order',
'pos.session',
]
seqs = [
'pos.',
]
res = self.remove_data(to_removes, seqs)
try:
statement = self.env['account.bank.statement'].sudo().search([])
for s in statement:
s._end_balance()
except Exception as e:
_logger.error('Reset Sequence Data error: %s', e)
return res
def remove_purchase(self):
to_removes = [
'purchase.order.line',
'purchase.order',
'purchase.requisition.line',
'purchase.requisition',
]
seqs = [
'purchase.',
]
return self.remove_data(to_removes, seqs)
def remove_expense(self):
to_removes = [
'hr.expense.sheet',
'hr.expense',
'hr.payslip',
'hr.payslip.run',
]
seqs = [
'hr.expense.',
]
return self.remove_data(to_removes, seqs)
def remove_mrp(self):
to_removes = [
'mrp.workcenter.productivity',
'mrp.workorder',
'mrp.production.workcenter.line',
'change.production.qty',
'mrp.production',
'mrp.production.product.line',
'mrp.unbuild',
'change.production.qty',
'sale.forecast.indirect',
'sale.forecast',
]
seqs = [
'mrp.',
]
return self.remove_data(to_removes, seqs)
def remove_mrp_bom(self):
to_removes = [
'mrp.bom.line',
'mrp.bom',
]
seqs = []
return self.remove_data(to_removes, seqs)
def remove_inventory(self):
to_removes = [
'stock.quant',
'stock.move.line',
'stock.package_level',
'stock.quantity.history',
'stock.quant.package',
'stock.move',
'stock.picking',
'stock.scrap',
'stock.picking.batch',
'stock.inventory.line',
'stock.inventory',
'stock.valuation.layer',
'stock.production.lot',
'procurement.group',
]
seqs = [
'stock.',
'picking.',
'procurement.group',
'product.tracking.default',
'WH/',
]
return self.remove_data(to_removes, seqs)
# VVVVVVVVVVV قم باستبدال الدالة التالية VVVVVVVVVVV
def remove_account(self):
to_removes = [
'payment.transaction',
'account.bank.statement.line',
'account.payment',
'account.analytic.line',
'account.analytic.account',
'account.partial.reconcile',
'account.move.line',
'hr.expense.sheet',
'account.move',
]
res = self.remove_data(to_removes, [])
# FIX: The domain syntax was incorrect (extra '|' at the end)
domain = [
('company_id', '=', self.env.company.id),
'|', ('code', '=ilike', 'account.%'),
'|', ('prefix', '=ilike', 'BNK1/%'),
'|', ('prefix', '=ilike', 'CSH1/%'),
'|', ('prefix', '=ilike', 'INV/%'),
'|', ('prefix', '=ilike', 'EXCH/%'),
('prefix', '=ilike', 'MISC/%')
]
try:
seqs = self.env['ir.sequence'].search(domain)
if seqs.exists():
seqs.write({
'number_next': 1,
})
except Exception as e:
_logger.error('Reset Sequence Data error: %s,%s', domain, e)
self._cr.rollback() # Rollback on error
return res
def remove_account_chart(self):
company_id = self.env.company.id
self = self.with_company(company_id)
try:
_logger.info("Starting to unlink accounting properties...")
if self.env['ir.model']._get('product.template'):
field1 = self.env['ir.model.fields']._get('product.template', "taxes_id")
field2 = self.env['ir.model.fields']._get('product.template', "supplier_taxes_id")
if field1 and field2:
sql = "DELETE FROM ir_default WHERE field_id IN (%s, %s) AND company_id=%s"
self._cr.execute(sql, (field1.id, field2.id, company_id))
self.env['res.partner'].search([]).write({
'property_account_receivable_id': False,
'property_account_payable_id': False,
})
if self.env['ir.model']._get('product.category'):
self.env['product.category'].search([]).write({
'property_account_income_categ_id': False,
'property_account_expense_categ_id': False,
})
if self.env['ir.model']._get('product.template'):
self.env['product.template'].search([]).write({
'property_account_income_id': False,
'property_account_expense_id': False,
})
# FIX: Check if 'stock.location' model exists before trying to access it
if self.env['ir.model']._get('stock.location'):
self.env['stock.location'].search([]).write({
'valuation_in_account_id': False, 'valuation_out_account_id': False,
})
_logger.info("Finished unlinking properties.")
_logger.info("Deleting from dependent M2M tax table...")
self._cr.execute("DELETE FROM account_reconcile_model_line_account_tax_rel")
_logger.info("Deleting main accounting tables...")
to_removes = [
'res.partner.bank', 'account.move.line', 'account.payment',
'account.bank.statement.line', 'account.bank.statement',
'account.tax.account.tag', 'account.tax',
'account.account.account.tag', 'wizard_multi_charts_accounts',
'account.journal', 'account.account',
]
res = self.remove_data(to_removes, [])
_logger.info("Finalizing account chart cleanup...")
self._cr.commit()
return res
except Exception as e:
_logger.error('Database Clean up error in remove_account_chart: %s', e, exc_info=True)
self._cr.rollback()
raise UserError(_('An error occurred while cleaning the account chart: %s') % e)
def remove_project(self):
to_removes = [
'account.analytic.line',
'project.task',
'project.forecast',
'project.project',
]
seqs = []
return self.remove_data(to_removes, seqs)
def remove_quality(self):
to_removes = [
'quality.check',
'quality.alert',
]
seqs = [
'quality.check',
'quality.alert',
]
return self.remove_data(to_removes, seqs)
def remove_quality_setting(self):
to_removes = [
'quality.point',
'quality.alert.stage',
'quality.alert.team',
'quality.point.test_type',
'quality.reason',
'quality.tag',
]
return self.remove_data(to_removes)
def remove_website(self):
to_removes = [
'blog.tag.category',
'blog.tag',
'blog.post',
'blog.blog',
'product.wishlist',
'website.published.multi.mixin',
'website.published.mixin',
'website.multi.mixin',
'website.visitor',
'website.redirect',
'website.seo.metadata',
]
seqs = []
return self.remove_data(to_removes, seqs)
def remove_message(self):
to_removes = [
'mail.message',
'mail.followers',
'mail.activity',
]
seqs = []
return self.remove_data(to_removes, seqs)
def remove_all(self):
self.remove_account()
self.remove_quality()
self.remove_website()
self.remove_quality_setting()
self.remove_inventory()
self.remove_purchase()
self.remove_mrp()
self.remove_sales()
self.remove_project()
self.remove_pos()
self.remove_expense()
self.remove_account_chart()
self.remove_message()
return True
def reset_cat_loc_name(self):
ids = self.env['product.category'].search([
('parent_id', '!=', False)
], order='complete_name')
for rec in ids:
try:
rec._compute_complete_name()
except:
pass
ids = self.env['stock.location'].search([
('location_id', '!=', False),
('usage', '!=', 'views'),
], order='complete_name')
for rec in ids:
try:
rec._compute_complete_name()
except:
pass
return True

Binary file not shown.

After

Width:  |  Height:  |  Size: 256 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -0,0 +1,24 @@
<div class="row my-5">
<div class="col-12">
<div class="m-0 text-center mb-5">
<img class="img img-responsive center-block mb-5" src="images/cyberneticsplus-logo.png">
<h1 style="font-size: 30px;">Database Clean Up Module</h1>
</div>
<img src="screen.jpg" style="width: 100%;">
</div>
</div>
<div id="footer" class="px-4">
<section class="s_call_to_action pt48">
<div class="container">
<div class="row">
<div class="col-lg-9 pb24 o_colored_level">
<h3>Become an exponential growth &amp; sustainable entrepreneur.</h3>
<p class="lead">Contact us and make your company a better workspace.<br /></p>
</div>
<div class="col-lg-3 pb24 o_colored_level"><a href="https://www.cybernetics.plus/contactus" class="btn-block btn btn-primary btn-lg" target="_blank" data-original-title="Cybernetics Plus Co., Ltd." title="Cybernetics Plus Co., Ltd."><i class="fa fa-envelope-o" aria-hidden="true"></i> Contact Us</a>&nbsp;<br /></div>
</div>
</div>
</section>
</div>

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

View File

@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_database_clean_up" model="ir.ui.view">
<field name="name">Database Clean up</field>
<field name="model">res.config.settings</field>
<field name="priority">20</field>
<field name="arch" type="xml">
<form string="odooApp Customize Settings" class="oe_form_configuration">
<div class="o_settings_container" name="data-clean">
<span class="mb4">
<h2>Database Cleaning (Be careful to do that!)</h2>
Data is Deleted Direcly from the Database Table using Queries, Once you done, It is not reversible !
</span>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Clean up All</span>
<button string="Delete All Transactions Except Master Data" type="object" name="remove_all" confirm="Please confirm to delete the data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Sale</span>
<button string="Delete All Sales Order" type="object" name="remove_sales" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">POS</span>
<button string="Delete All POS Order" type="object" name="remove_pos" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Purchase</span>
<button string="Delete All Purchase Order and Requisition" type="object" name="remove_purchase" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Expense</span>
<button string="Delete All Expense and Sheet" type="object" name="remove_expense" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">MRP</span>
<button string="Delete All Manufacturing Order" type="object" name="remove_mrp" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
|
<button string="Delete All BOM" type="object" name="remove_mrp_bom" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Inventory</span>
<button string="Delete All Move/Picking/Package/Lot" type="object" name="remove_inventory" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">
Accounting <span title="Values set here are company-specific." groups="base.group_multi_company"/>
</span>
<button string="Delete All Voucher/Invoice/Bill" type="object" name="remove_account" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
|
<button string="Clean and reset Account Chart" type="object" name="remove_account_chart" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Project</span>
<button string="Delete All Project/Task/Forecast" type="object" name="remove_project" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Quality</span>
<button string="Delete All Quality" type="object" name="remove_quality" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
|
<button string="Delete All Quality Setting" type="object" name="remove_quality_setting" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Website And Blog</span>
<button string="Delete All Website/Blog" type="object" name="remove_website" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-left">Base Models</span>
<button string="Delete All Product" type="object" name="remove_product" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
|
<button string="Delete All Product Attribute" type="object" name="remove_product_attribute" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
|
<button string="Delete All Message" type="object" name="remove_message" confirm="Please Confirm to Delete the select Database?" class="oe_highlight"/>
|
<button string="Reset Category And Location Complete Name" type="object" name="reset_cat_loc_name" class="oe_highlight"/>
</div>
</div>
</form>
</field>
</record>
<record id="action_database_clean_up" model="ir.actions.act_window">
<field name="name">C+ Database Clean up</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.config.settings</field>
<field name="view_mode">form</field>
<field name="view_id" ref="view_database_clean_up"/>
<field name="target">inline</field>
</record>
<menuitem id="menu_database_clean_up" name="C+ Data Clean up" action="action_database_clean_up" parent="base.menu_administration" sequence="1" groups="base.group_system"/>
</data>
</odoo>