This commit is contained in:
gsinghpal
2026-04-02 17:55:32 -04:00
parent f715570e0c
commit 1c560c6df2
5 changed files with 87 additions and 8 deletions

View File

@@ -1,5 +1,12 @@
import logging
from odoo import api, fields, models from odoo import api, fields, models
_logger = logging.getLogger(__name__)
SUCCESS_RETENTION_DAYS = 30
ERROR_RETENTION_DAYS = 90
class WooSyncLog(models.Model): class WooSyncLog(models.Model):
_name = 'woo.sync.log' _name = 'woo.sync.log'
@@ -32,11 +39,50 @@ class WooSyncLog(models.Model):
@api.model @api.model
def _cron_cleanup_logs(self): def _cron_cleanup_logs(self):
"""Purge sync logs older than 90 days (180 for errors).""" """Purge success/conflict logs older than 30 days, errors older than 90."""
cutoff_success = fields.Datetime.subtract(fields.Datetime.now(), hours=90 * 24) now = fields.Datetime.now()
cutoff_error = fields.Datetime.subtract(fields.Datetime.now(), hours=180 * 24) cutoff_success = fields.Datetime.subtract(now, days=SUCCESS_RETENTION_DAYS)
self.search([ cutoff_error = fields.Datetime.subtract(now, days=ERROR_RETENTION_DAYS)
logs = self.search([
'|', '|',
'&', ('state', '!=', 'failed'), ('create_date', '<', cutoff_success), '&', ('state', '!=', 'failed'), ('create_date', '<', cutoff_success),
'&', ('state', '=', 'failed'), ('create_date', '<', cutoff_error), '&', ('state', '=', 'failed'), ('create_date', '<', cutoff_error),
]).unlink() ])
count = len(logs)
if count:
logs.unlink()
_logger.info("WooCommerce: purged %d old sync log entries", count)
def action_purge_old_logs(self):
"""Manual purge: delete success logs > 7 days, error logs > 30 days."""
self.env['woo.sync.log'].check_access_rights('unlink')
now = fields.Datetime.now()
cutoff_success = fields.Datetime.subtract(now, days=7)
cutoff_error = fields.Datetime.subtract(now, days=30)
logs = self.env['woo.sync.log'].search([
'|',
'&', ('state', '!=', 'failed'), ('create_date', '<', cutoff_success),
'&', ('state', '=', 'failed'), ('create_date', '<', cutoff_error),
])
count = len(logs)
logs.unlink()
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': 'Sync Logs Purged',
'message': f'{count} old log entries deleted.',
'type': 'success',
'next': {'type': 'ir.actions.act_window_close'},
},
}
@api.model
def action_clear_errors(self):
"""Clear all failed sync log entries. Called from dashboard."""
self.check_access_rights('unlink')
logs = self.search([('state', '=', 'failed')])
count = len(logs)
logs.unlink()
_logger.info("WooCommerce: manually cleared %d error log entries", count)
return count

View File

@@ -406,3 +406,6 @@
outline: none; outline: none;
} }
.woo-edit-input-text { text-align: left; width: 120px; } .woo-edit-input-text { text-align: left; width: 120px; }
/* Clear errors button inside dashboard card */
.woo-clear-btn { font-size: 0.72rem; padding: 1px 8px; }

View File

@@ -199,12 +199,23 @@ export class WooDashboard extends Component {
type: "ir.actions.act_window", type: "ir.actions.act_window",
name: "Sync Errors (Last 24 h)", name: "Sync Errors (Last 24 h)",
res_model: "woo.sync.log", res_model: "woo.sync.log",
view_mode: "list,form", views: [[false, "list"], [false, "form"]],
domain: [["state", "=", "failed"]], domain: [["state", "=", "failed"]],
target: "current", target: "current",
}); });
} }
async clearErrors() {
const count = await rpc("/web/dataset/call_kw", {
model: "woo.sync.log",
method: "action_clear_errors",
args: [],
kwargs: {},
});
this.state.errors24h = 0;
this.notification.add(`${count} error log entries cleared.`, { type: "success" });
}
openConflicts() { openConflicts() {
this.actionService.doAction("fusion_woocommerce.action_woo_conflict"); this.actionService.doAction("fusion_woocommerce.action_woo_conflict");
} }

View File

@@ -50,7 +50,16 @@
<div class="woo-card-icon">⚠️</div> <div class="woo-card-icon">⚠️</div>
<div class="woo-card-value" t-esc="state.errors24h"/> <div class="woo-card-value" t-esc="state.errors24h"/>
<div class="woo-card-label">Errors (Last 24 h)</div> <div class="woo-card-label">Errors (Last 24 h)</div>
<div class="woo-card-sub">Click to view sync log</div> <div class="woo-card-sub d-flex align-items-center gap-2">
<span>Click to view sync log</span>
<t t-if="state.errors24h > 0">
<button class="btn btn-sm btn-outline-danger woo-clear-btn"
t-on-click.stop="clearErrors"
title="Clear all error logs">
<i class="fa fa-trash-o"/> Clear
</button>
</t>
</div>
</div> </div>
<!-- Products mapped --> <!-- Products mapped -->

View File

@@ -6,7 +6,7 @@
<field name="name">woo.sync.log.tree</field> <field name="name">woo.sync.log.tree</field>
<field name="model">woo.sync.log</field> <field name="model">woo.sync.log</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<list create="0" edit="0" delete="0"> <list create="0" edit="0">
<field name="create_date" string="Date"/> <field name="create_date" string="Date"/>
<field name="instance_id"/> <field name="instance_id"/>
<field name="sync_type"/> <field name="sync_type"/>
@@ -87,4 +87,14 @@
<field name="search_view_id" ref="woo_sync_log_view_search"/> <field name="search_view_id" ref="woo_sync_log_view_search"/>
</record> </record>
<!-- ===== Server Action: Purge Old Logs (appears in list view action menu) ===== -->
<record id="action_purge_old_sync_logs" model="ir.actions.server">
<field name="name">Purge Old Logs</field>
<field name="model_id" ref="model_woo_sync_log"/>
<field name="binding_model_id" ref="model_woo_sync_log"/>
<field name="binding_view_types">list</field>
<field name="state">code</field>
<field name="code">action = records.action_purge_old_logs()</field>
</record>
</odoo> </odoo>