Initial commit: Odoomates Odoo packages (12 packages)

This commit is contained in:
Ernad Husremovic 2025-08-29 15:49:21 +02:00
commit 3b38c49bf0
526 changed files with 34983 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# Odoo 16 Remove Data
Data Clean up, Remove Data, Database Clean UP, Reset Database
## Installation
```bash
pip install odoo-bringout-odoomates-om_data_remove
```
## Dependencies
This addon depends on:
- base
## Manifest Information
- **Name**: Odoo 16 Remove Data
- **Version**: 16.0.1.0.1
- **Category**: Tools
- **License**: LGPL-3
- **Installable**: True
## Source
Custom addon from bringout-odoomates vendor, addon `om_data_remove`.
## License
This package maintains the original LGPL-3 license from the addon.
## Documentation
- Overview: doc/OVERVIEW.md
- Architecture: doc/ARCHITECTURE.md
- Models: doc/MODELS.md
- Controllers: doc/CONTROLLERS.md
- Wizards: doc/WIZARDS.md
- Reports: doc/REPORTS.md
- Security: doc/SECURITY.md
- Install: doc/INSTALL.md
- Usage: doc/USAGE.md
- Configuration: doc/CONFIGURATION.md
- Dependencies: doc/DEPENDENCIES.md
- Troubleshooting: doc/TROUBLESHOOTING.md
- FAQ: doc/FAQ.md

View file

@ -0,0 +1,32 @@
# Architecture
```mermaid
flowchart TD
U[Users] -->|HTTP| V[Views and QWeb Templates]
V --> C[Controllers]
V --> W[Wizards Transient Models]
C --> M[Models and ORM]
W --> M
M --> R[Reports]
DX[Data XML] --> M
S[Security ACLs and Groups] -. enforces .-> M
subgraph Om_data_remove Module - om_data_remove
direction LR
M:::layer
W:::layer
C:::layer
V:::layer
R:::layer
S:::layer
DX:::layer
end
classDef layer fill:#eef8ff,stroke:#6ea8fe,stroke-width:1px
```
Notes
- Views include tree/form/kanban templates and report templates.
- Controllers provide website/portal routes when present.
- Wizards are UI flows implemented with `models.TransientModel`.
- Data XML loads data/demo records; Security defines groups and access.

View file

@ -0,0 +1,3 @@
# Configuration
Refer to Odoo settings for om_data_remove. Configure related models, access rights, and options as needed.

View file

@ -0,0 +1,3 @@
# Controllers
This module does not define custom HTTP controllers.

View file

@ -0,0 +1,5 @@
# Dependencies
This addon depends on:
- base

View file

@ -0,0 +1,4 @@
# FAQ
- Q: Which Odoo version? A: 16.0 (OCA/OCB packaged).
- Q: How to enable? A: Start server with --addon om_data_remove or install in UI.

View file

@ -0,0 +1,7 @@
# Install
```bash
pip install odoo-bringout-odoomates-om_data_remove"
# or
uv pip install odoo-bringout-odoomates-om_data_remove"
```

View file

@ -0,0 +1,12 @@
# Models
Detected core models and extensions in om_data_remove.
```mermaid
classDiagram
class res_config_settings
```
Notes
- Classes show model technical names; fields omitted for brevity.
- Items listed under _inherit are extensions of existing models.

View file

@ -0,0 +1,6 @@
# Overview
Packaged Odoo addon: om_data_remove. Provides features documented in upstream Odoo 16 under this addon.
- Source: OCA/OCB 16.0, addon om_data_remove
- License: LGPL-3

View file

@ -0,0 +1,3 @@
# Reports
This module does not define custom reports.

View file

@ -0,0 +1,8 @@
# Security
This module does not define custom security rules or access controls beyond Odoo defaults.
Default Odoo security applies:
- Base user access through standard groups
- Model access inherited from dependencies
- No custom row-level security rules

View file

@ -0,0 +1,5 @@
# Troubleshooting
- Ensure Python and Odoo environment matches repo guidance.
- Check database connectivity and logs if startup fails.
- Validate that dependent addons listed in DEPENDENCIES.md are installed.

View file

@ -0,0 +1,7 @@
# Usage
Start Odoo including this addon (from repo root):
```bash
python3 scripts/nix_odoo_web_server.py --db-name mydb --addon om_data_remove
```

View file

@ -0,0 +1,3 @@
# Wizards
This module does not include UI wizards.

View file

@ -0,0 +1,46 @@
===================
Odoo 16 Remove Data
===================
This Module will help to remove transactional data from database
Installation
============
To install this module, you need to:
Download the module and add it to your Odoo addons folder. Afterward, log on to
your Odoo server and go to the Apps menu. Trigger the debug mode and update the
list by clicking on the "Update Apps List" link. Now install the module by
clicking on the install button.
Upgrade
============
To upgrade this module, you need to:
Download the module and add it to your Odoo addons folder. Restart the server
and log on to your Odoo server. Select the Apps menu and upgrade the module by
clicking on the upgrade button.
Configuration
=============
There is Nothing to Configure
Credits
=======
Contributors
------------
* Odoo Mates <odoomates@gmail.com>
* Sunpop.cn
Author & Maintainer
-------------------
This module is maintained by the Odoo Mates

View file

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

View file

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
{
'name': 'Odoo 16 Remove Data',
'version': '16.0.1.0.1',
'author': 'Odoo Mates, Sunpop.cn',
'category': 'Tools',
'description': 'Data Clean up, Remove Data, Database Clean UP, Reset Database',
'summary': 'Data Clean up, Remove Data, Database Clean UP, Reset Database',
'maintainer': 'Odoo Mates',
'support': 'odoomates@gmail.com',
'license': 'LGPL-3',
'sequence': 20,
'live_test_url': '',
'summary': """""",
'depends': ['base',],
'data': [
'views/view.xml',
],
'installable': True,
'application': False,
'auto_install': False,
'images': ['static/description/banner.png'],
}

View file

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

View file

@ -0,0 +1,371 @@
# -*- coding: utf-8 -*-
import logging
from odoo import api, fields, models, _
_logger = logging.getLogger(__name__)
class ResConfigSettings(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('remove data 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('remove data 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)
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, [])
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/%'),
'|', ('prefix', '=ilike', '账单/%'),
('prefix', '=ilike', '杂项/%')
]
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)
return res
def remove_account_chart(self):
company_id = self.env.company.id
self = self.with_context(force_company=company_id, company_id=company_id)
to_removes = [
'res.partner.bank',
'account.move.line',
'account.invoice',
'account.payment',
'account.bank.statement',
'account.tax.account.tag',
'account.tax',
'account.account.account.tag',
'wizard_multi_charts_accounts',
'account.journal',
'account.account',
]
try:
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
sql = "delete from ir_default where (field_id = %s or field_id = %s) and company_id=%d" \
% (field1, field2, company_id)
sql2 = "update account_journal set bank_account_id=NULL where company_id=%d;" % company_id
self._cr.execute(sql)
self._cr.execute(sql2)
self._cr.commit()
except Exception as e:
_logger.error('remove data error: %s,%s', 'account_chart: set tax and account_journal', e)
if self.env['ir.model']._get('pos.config'):
self.env['pos.config'].write({
'journal_id': False,
})
try:
rec = self.env['res.partner'].search([])
for r in rec:
r.write({
'property_account_receivable_id': None,
'property_account_payable_id': None,
})
except Exception as e:
_logger.error('remove data error: %s,%s', 'account_chart', e)
try:
rec = self.env['product.category'].search([])
for r in rec:
r.write({
'property_account_income_categ_id': None,
'property_account_expense_categ_id': None,
'property_account_creditor_price_difference_categ': None,
'property_stock_account_input_categ_id': None,
'property_stock_account_output_categ_id': None,
'property_stock_valuation_account_id': None,
})
except Exception as e:
pass
try:
rec = self.env['product.template'].search([])
for r in rec:
r.write({
'property_account_income_id': None,
'property_account_expense_id': None,
})
except Exception as e:
pass
try:
rec = self.env['stock.location'].search([])
for r in rec:
r.write({
'valuation_in_account_id': None,
'valuation_out_account_id': None,
})
except Exception as e:
pass
seqs = []
res = self.remove_data(to_removes, seqs)
self.env.company.write({'chart_template_id': False})
return res
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
try:
ids = self.env['stock.location'].search([
('location_id', '!=', False),
('usage', '!=', 'views'),
], order='complete_name')
for rec in ids:
rec._compute_complete_name()
except:
pass
return True

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,70 @@
<section class="oe_container oe_dark">
<div class="col-md-12">
<h2 class="oe_slogan" style="font-size: 35px;color:#2C0091"><b>Odoo 16 Remove Data</b></h2>
</div>
</section>
<section class="oe_container">
<div class="oe_row oe_spaced">
<div style="align:center;">
<h1 style=" text-align: center;">
<span align="center" style="color:#148963;">
<span class="fa fa-star fa-spin">
</span>
Features:</span>
</h1>
<div class="col-sm-2"/>
<div class="col-sm-4" style="text-align:left">
<p class="fa fa-hand-o-right" style="color:CRIMSON;font-size: 25px;">
<span style="color:#2dd280;font-size: 15px;">Remove all data in single click.</span>
</p><br/>
<p class="fa fa-hand-o-right" style="color:CRIMSON;font-size: 25px;">
<span style="color:#2dd280;font-size: 15px;">Easy to test odoo.</span>
</p><br/>
</div>
</div>
<br/>
</div>
</section>
<section class="oe_container oe_dark">
<div class="oe_row oe_spaced">
<h2 class="oe_slogan" style="color:olive;">Remove Data Screen</h2>
<div class="oe_demo oe_picture oe_screenshot">
<img src="screen.png">
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<section class="oe_container oe_dark">
<div class="oe_row ">
<div class="oe_slogan text-center">
<img src="odoo_mates.png"/>
<div style="color:#269900;">
<h3 style="color:#2C0091;font-size: 25px;">If you need any support or want more features, just contact us:</h3><br>
<h3 style="color:#2C0091;font-size: 20px;">Email: <a href="odoomates@gmail.com">odoomates@gmail.com</a> <br></h3>
</div>
<div class="oe_slogan">
<h2>
<a target="_blank" href="https://www.facebook.com/odoomate/" target="new">
<i class="fa fa-facebook-square" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://twitter.com/odoomates/" target="new">
<i class="fa fa-twitter" style="font-size:38px;"></i>
</a>
<a href="#" target="_blank">
<i class="fa fa-linkedin" style="font-size:38px;"></i>
</a>
<a target="_blank" href="https://www.youtube.com/channel/UCVKlUZP7HAhdQgs-9iTJklQ">
<i class="fa fa-youtube-play" style="font-size:38px;"></i>
</a>
</h2>
</div>
</div>
</div>
</section>
<hr style="width: 100%;height: 4px;background: #148963;margin: 0px 0px;">
<hr style="width: 100%;height: 4px;background: #2C0091;margin: 0px 0px;">

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<record id="view_remove_data" model="ir.ui.view">
<field name="name">Remove Data</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="mt16 o_settings_container" name="data-clean">
<span>
<h2>Data Cleaning (Be careful to do that!)</h2>
<h2>
Data is deleted direcly from the database table using queries, once you done, it is not reversible !
</h2>
</span>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">Remove 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-start">Sale</span>
<button string="Delete All Sales Order" type="object" name="remove_sales"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">POS</span>
<button string="Delete All POS Order" type="object" name="remove_pos" confirm="Please confirm to delete the select data?"
class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">Purchase</span>
<button string="Delete All Purchase Order and Requisition" type="object" name="remove_purchase"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">Expense</span>
<button string="Delete All Expense and Sheet" type="object" name="remove_expense"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">MRP</span>
<button string="Delete All Manufacturing Order" type="object" name="remove_mrp"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
|
<button string="Delete All BOM" type="object" name="remove_mrp_bom"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">Inventory</span>
<button string="Delete All Move/Picking/Package/Lot" type="object" name="remove_inventory"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">
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 data?" class="oe_highlight"/>
|
<button string="Clean and reset Account Chart" type="object" name="remove_account_chart"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">Project</span>
<button string="Delete All Project/Task/Forecast" type="object" name="remove_project"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">Quality</span>
<button string="Delete All Quality" type="object" name="remove_quality"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
|
<button string="Delete All Quality Setting" type="object" name="remove_quality_setting"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">Website And Blog</span>
<button string="Delete All Website/Blog" type="object" name="remove_website"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
</div>
<div class="col-12 col-lg-12 mb4">
<span class="col-3 col-lg-2 text-start">Base Models</span>
<button string="Delete All Product" type="object" name="remove_product"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
|
<button string="Delete All Product Attribute" type="object" name="remove_product_attribute"
confirm="Please confirm to delete the select data?" class="oe_highlight"/>
|
<button string="Delete All Message" type="object" name="remove_message"
confirm="Please confirm to delete the select data?" 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_remove_data" model="ir.actions.act_window">
<field name="name">Customize Debrand</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_remove_data"/>
<field name="target">inline</field>
</record>
<menuitem
id="menu_remove_data"
name="Remove Data"
action="action_remove_data"
parent="base.menu_administration"
sequence="1"
groups="base.group_system"/>
</data>
</odoo>

View file

@ -0,0 +1,42 @@
[project]
name = "odoo-bringout-odoomates-om_data_remove"
version = "16.0.0"
description = "Odoo 16 Remove Data - "
authors = [
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
]
dependencies = [
"odoo-bringout-oca-ocb-base>=16.0.0",
"requests>=2.25.1"
]
readme = "README.md"
requires-python = ">= 3.11"
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Topic :: Office/Business",
]
[project.urls]
homepage = "https://github.com/bringout/0"
repository = "https://github.com/bringout/0"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.metadata]
allow-direct-references = true
[tool.hatch.build.targets.wheel]
packages = ["om_data_remove"]
[tool.rye]
managed = true
dev-dependencies = [
"pytest>=8.4.1",
]