first commit
This commit is contained in:
commit
8c83703c30
1
__init__.py
Normal file
1
__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from . import models
|
||||||
15
__manifest__.py
Normal file
15
__manifest__.py
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
'name': 'Approval Cleaner',
|
||||||
|
'version': '1.0',
|
||||||
|
'summary': 'Delete approvals older than a specified date',
|
||||||
|
'category': 'Administration',
|
||||||
|
'author': 'Antigravity',
|
||||||
|
'depends': ['approvals'],
|
||||||
|
'data': [
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
'views/approval_cleaner_wizard_views.xml',
|
||||||
|
],
|
||||||
|
'installable': True,
|
||||||
|
'application': False,
|
||||||
|
'license': 'LGPL-3',
|
||||||
|
}
|
||||||
BIN
__pycache__/__init__.cpython-312.pyc
Normal file
BIN
__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
1
models/__init__.py
Normal file
1
models/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from . import approval_cleaner_wizard
|
||||||
BIN
models/__pycache__/__init__.cpython-312.pyc
Normal file
BIN
models/__pycache__/__init__.cpython-312.pyc
Normal file
Binary file not shown.
BIN
models/__pycache__/approval_cleaner_wizard.cpython-312.pyc
Normal file
BIN
models/__pycache__/approval_cleaner_wizard.cpython-312.pyc
Normal file
Binary file not shown.
48
models/approval_cleaner_wizard.py
Normal file
48
models/approval_cleaner_wizard.py
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
from odoo import models, fields, _
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
class ApprovalCleanerWizard(models.TransientModel):
|
||||||
|
_name = 'approval.cleaner.wizard'
|
||||||
|
_description = 'Approval Cleaner Wizard'
|
||||||
|
|
||||||
|
date_end = fields.Date(string="End Date", required=True, help="Delete all approvals created before this date")
|
||||||
|
|
||||||
|
def action_clean_approvals(self):
|
||||||
|
self.ensure_one()
|
||||||
|
# Search for approvals created before the specified date
|
||||||
|
# using 'create_date' as it is the standard Odoo field for creation time.
|
||||||
|
# However, the user request mentioned "Date below specified date i provide".
|
||||||
|
# 'approval.request' has a 'date' field (which seems to be a datetime) and 'create_date'.
|
||||||
|
# I will use 'date' field as per the user's initial description if implicit, but looking at approval_request.py
|
||||||
|
# date = fields.Datetime(string="Date")
|
||||||
|
# So I will use that.
|
||||||
|
|
||||||
|
domain = [('date', '<', self.date_end)]
|
||||||
|
approvals_to_delete = self.env['approval.request'].sudo().search(domain)
|
||||||
|
count = len(approvals_to_delete)
|
||||||
|
|
||||||
|
# Detach attachments to bypass ir.attachment unlink restriction
|
||||||
|
attachments = self.env['ir.attachment'].sudo().search([
|
||||||
|
('res_model', '=', 'approval.request'),
|
||||||
|
('res_id', 'in', approvals_to_delete.ids),
|
||||||
|
])
|
||||||
|
if attachments:
|
||||||
|
attachments.write({'res_model': 'approval.cleaner.temp', 'res_id': 0})
|
||||||
|
|
||||||
|
approvals_to_delete.unlink()
|
||||||
|
|
||||||
|
# Now delete the attachments safely
|
||||||
|
if attachments:
|
||||||
|
attachments.unlink()
|
||||||
|
|
||||||
|
return {
|
||||||
|
'type': 'ir.actions.client',
|
||||||
|
'tag': 'display_notification',
|
||||||
|
'params': {
|
||||||
|
'title': _('Success'),
|
||||||
|
'message': _('%s approvals have been deleted.', count),
|
||||||
|
'type': 'success',
|
||||||
|
'sticky': False,
|
||||||
|
'next': {'type': 'ir.actions.act_window_close'},
|
||||||
|
}
|
||||||
|
}
|
||||||
2
security/ir.model.access.csv
Normal file
2
security/ir.model.access.csv
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_approval_cleaner_wizard,approval.cleaner.wizard,model_approval_cleaner_wizard,approvals.group_approval_manager,1,1,1,1
|
||||||
|
1
tests/__init__.py
Normal file
1
tests/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from . import test_approval_cleaner
|
||||||
38
tests/test_approval_cleaner.py
Normal file
38
tests/test_approval_cleaner.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
from odoo.tests import common
|
||||||
|
from odoo import fields
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
|
class TestApprovalCleaner(common.TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestApprovalCleaner, self).setUp()
|
||||||
|
self.ApprovalRequest = self.env['approval.request']
|
||||||
|
self.category = self.env['approval.category'].create({
|
||||||
|
'name': 'Test Category',
|
||||||
|
'has_date': 'required',
|
||||||
|
})
|
||||||
|
|
||||||
|
# Create approvals with different dates
|
||||||
|
self.approval_old = self.ApprovalRequest.create({
|
||||||
|
'name': 'Old Approval',
|
||||||
|
'category_id': self.category.id,
|
||||||
|
'date': fields.Datetime.now() - timedelta(days=100),
|
||||||
|
})
|
||||||
|
|
||||||
|
self.approval_new = self.ApprovalRequest.create({
|
||||||
|
'name': 'New Approval',
|
||||||
|
'category_id': self.category.id,
|
||||||
|
'date': fields.Datetime.now() - timedelta(days=10),
|
||||||
|
})
|
||||||
|
|
||||||
|
def test_clean_approvals(self):
|
||||||
|
wizard = self.env['approval.cleaner.wizard'].create({
|
||||||
|
'date_end': fields.Date.today() - timedelta(days=30),
|
||||||
|
})
|
||||||
|
|
||||||
|
wizard.action_clean_approvals()
|
||||||
|
|
||||||
|
# Check that old approval is deleted
|
||||||
|
self.assertFalse(self.approval_old.exists(), "Old approval should be deleted")
|
||||||
|
|
||||||
|
# Check that new approval still exists
|
||||||
|
self.assertTrue(self.approval_new.exists(), "New approval should not be deleted")
|
||||||
34
views/approval_cleaner_wizard_views.xml
Normal file
34
views/approval_cleaner_wizard_views.xml
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_approval_cleaner_wizard_form" model="ir.ui.view">
|
||||||
|
<field name="name">approval.cleaner.wizard.form</field>
|
||||||
|
<field name="model">approval.cleaner.wizard</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Clean Approvals">
|
||||||
|
<group>
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
<strong>Warning:</strong> This action will permanently delete all approval requests created before the selected date. This cannot be undone.
|
||||||
|
</div>
|
||||||
|
<field name="date_end"/>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button name="action_clean_approvals" string="Delete Approvals" type="object" class="btn-danger"/>
|
||||||
|
<button string="Cancel" class="btn-secondary" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_approval_cleaner_wizard" model="ir.actions.act_window">
|
||||||
|
<field name="name">Clean Approvals</field>
|
||||||
|
<field name="res_model">approval.cleaner.wizard</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem id="menu_approval_cleaner_wizard"
|
||||||
|
name="Clean Approvals"
|
||||||
|
parent="approvals.approvals_menu_config"
|
||||||
|
action="action_approval_cleaner_wizard"
|
||||||
|
sequence="100"/>
|
||||||
|
</odoo>
|
||||||
Loading…
Reference in New Issue
Block a user