Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 46 additions & 5 deletions partner_archive_propagate/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -67,15 +67,56 @@ Configuration
Usage
=====

Archiving a partner
-------------------

This module provides two distinct ways to archive a company or parent contact.

Archive via the action menu (gear icon)
---------------------------------------

Clicking **Archive** in the gear (⚙) menu archives **only the company
itself**. Child contacts, invoice/delivery addresses, and related partners
are left completely untouched. Use this when you want a quick archive
without touching any of the company's contacts.

.. note::

This behaviour is consistent regardless of the *Force propagation
outside UI* system setting. The gear menu never propagates.

Archive via the "Archive Contact and Children" button
-----------------------------------------------------

1. Open a partner (company or main contact).
2. Click the **"Archive Contact and Children"** button.
3. Review the list of child contacts to be archived.
4. Confirm the action.
* Non-contact types (e.g., invoice/delivery addresses) are archived silently.
3. Review the list of child contacts to be archived. Remove any row to
keep that contact active after archiving.
4. Confirm the action.

* Non-contact types (e.g., invoice/delivery addresses) are archived
silently in the background — they do not appear in the list.
* Contact-type descendants appear in the wizard for review.
* Contacts linked to active users are automatically excluded from the
list; a warning message is posted on the company.

If the company has no contact-type descendants, no wizard opens and the
company (and its non-contact addresses) are archived immediately.

Unarchiving
-----------

Unarchiving also follows propagation rules: if a parent partner is
unarchived, its propagated descendants are unarchived as well. Partners
that were independently archived are not affected.

System setting: Force propagation outside UI
--------------------------------------------

Unarchiving also follows propagation rules:
if a parent partner is unarchived, its propagated descendants are unarchived as well.
When **Force propagation outside UI** is enabled (under *Settings*),
archiving a company via any non-UI path (imports, RPC calls, automated
jobs, etc.) will also propagate to descendants, just as the wizard button
does. This setting has no effect on the gear menu action.

Bug Tracker
===========
Expand Down
8 changes: 8 additions & 0 deletions partner_archive_propagate/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,11 @@ def action_archive_with_contacts(self):
"target": "new",
"res_id": wiz.id,
}

def action_archive(self):
"""Archive only this partner via gear
Do not super, otherwise core odoo
archives children too
"""
self.filtered("active").write({"active": False})
return False
51 changes: 46 additions & 5 deletions partner_archive_propagate/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -1,9 +1,50 @@
Archiving a partner
-------------------

This module provides two distinct ways to archive a company or parent contact.

Archive via the action menu (gear icon)
---------------------------------------

Clicking **Archive** in the gear (⚙) menu archives **only the company
itself**. Child contacts, invoice/delivery addresses, and related partners
are left completely untouched. Use this when you want a quick archive
without touching any of the company's contacts.

.. note::

This behaviour is consistent regardless of the *Force propagation
outside UI* system setting. The gear menu never propagates.

Archive via the "Archive Contact and Children" button
-----------------------------------------------------

1. Open a partner (company or main contact).
2. Click the **"Archive Contact and Children"** button.
3. Review the list of child contacts to be archived.
4. Confirm the action.
* Non-contact types (e.g., invoice/delivery addresses) are archived silently.
3. Review the list of child contacts to be archived. Remove any row to
keep that contact active after archiving.
4. Confirm the action.

* Non-contact types (e.g., invoice/delivery addresses) are archived
silently in the background — they do not appear in the list.
* Contact-type descendants appear in the wizard for review.
* Contacts linked to active users are automatically excluded from the
list; a warning message is posted on the company.

If the company has no contact-type descendants, no wizard opens and the
company (and its non-contact addresses) are archived immediately.

Unarchiving
-----------

Unarchiving also follows propagation rules: if a parent partner is
unarchived, its propagated descendants are unarchived as well. Partners
that were independently archived are not affected.

System setting: Force propagation outside UI
--------------------------------------------

Unarchiving also follows propagation rules:
if a parent partner is unarchived, its propagated descendants are unarchived as well.
When **Force propagation outside UI** is enabled (under *Settings*),
archiving a company via any non-UI path (imports, RPC calls, automated
jobs, etc.) will also propagate to descendants, just as the wizard button
does. This setting has no effect on the gear menu action.
67 changes: 49 additions & 18 deletions partner_archive_propagate/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -397,13 +397,6 @@ <h2>Features</h2>
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="toc-entry-1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="toc-entry-2">Usage</a></li>
<li><a class="reference internal" href="#bug-tracker" id="toc-entry-3">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="toc-entry-4">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="toc-entry-5">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="toc-entry-6">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="toc-entry-7">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
Expand All @@ -416,41 +409,79 @@ <h3><a class="toc-backref" href="#toc-entry-1">Configuration</a></h3>
</div>
<div class="section" id="usage">
<h3><a class="toc-backref" href="#toc-entry-2">Usage</a></h3>
</div>
</div>
<div class="section" id="archiving-a-partner">
<h2>Archiving a partner</h2>
<p>This module provides two distinct ways to archive a company or parent contact.</p>
</div>
<div class="section" id="archive-via-the-action-menu-gear-icon">
<h2>Archive via the action menu (gear icon)</h2>
<p>Clicking <strong>Archive</strong> in the gear (⚙) menu archives <strong>only the company
itself</strong>. Child contacts, invoice/delivery addresses, and related partners
are left completely untouched. Use this when you want a quick archive
without touching any of the company’s contacts.</p>
<div class="admonition note">
<p class="first admonition-title">Note</p>
<p class="last">This behaviour is consistent regardless of the <em>Force propagation
outside UI</em> system setting. The gear menu never propagates.</p>
</div>
</div>
<div class="section" id="archive-via-the-archive-contact-and-children-button">
<h2>Archive via the “Archive Contact and Children” button</h2>
<ol class="arabic simple">
<li>Open a partner (company or main contact).</li>
<li>Click the <strong>“Archive Contact and Children”</strong> button.</li>
<li>Review the list of child contacts to be archived.</li>
<li>Confirm the action.
* Non-contact types (e.g., invoice/delivery addresses) are archived silently.
* Contact-type descendants appear in the wizard for review.</li>
<li>Review the list of child contacts to be archived. Remove any row to
keep that contact active after archiving.</li>
<li>Confirm the action.<ul>
<li>Non-contact types (e.g., invoice/delivery addresses) are archived
silently in the background — they do not appear in the list.</li>
<li>Contact-type descendants appear in the wizard for review.</li>
<li>Contacts linked to active users are automatically excluded from the
list; a warning message is posted on the company.</li>
</ul>
</li>
</ol>
<p>Unarchiving also follows propagation rules:
if a parent partner is unarchived, its propagated descendants are unarchived as well.</p>
<p>If the company has no contact-type descendants, no wizard opens and the
company (and its non-contact addresses) are archived immediately.</p>
</div>
<div class="section" id="unarchiving">
<h2>Unarchiving</h2>
<p>Unarchiving also follows propagation rules: if a parent partner is
unarchived, its propagated descendants are unarchived as well. Partners
that were independently archived are not affected.</p>
</div>
<div class="section" id="system-setting-force-propagation-outside-ui">
<h2>System setting: Force propagation outside UI</h2>
<p>When <strong>Force propagation outside UI</strong> is enabled (under <em>Settings</em>),
archiving a company via any non-UI path (imports, RPC calls, automated
jobs, etc.) will also propagate to descendants, just as the wizard button
does. This setting has no effect on the gear menu action.</p>
<div class="section" id="bug-tracker">
<h3><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h3>
<h3>Bug Tracker</h3>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/partner-contact/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/partner-contact/issues/new?body=module:%20partner_archive_propagate%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h3><a class="toc-backref" href="#toc-entry-4">Credits</a></h3>
<h3>Credits</h3>
<div class="section" id="authors">
<h4><a class="toc-backref" href="#toc-entry-5">Authors</a></h4>
<h4>Authors</h4>
<ul class="simple">
<li>Therp BV</li>
</ul>
</div>
<div class="section" id="contributors">
<h4><a class="toc-backref" href="#toc-entry-6">Contributors</a></h4>
<h4>Contributors</h4>
<ul class="simple">
<li>Nikos Tsirintanis &lt;<a class="reference external" href="mailto:ntsirintanis&#64;therp.nl">ntsirintanis&#64;therp.nl</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h4><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h4>
<h4>Maintainers</h4>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
Expand Down
27 changes: 27 additions & 0 deletions partner_archive_propagate/tests/test_archive.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,30 @@ def test_wizard_deleted_line_not_archived(self):
# B was removed from the list and must remain as it was
self.assertTrue(self.B.active)
self.assertFalse(bool(self.B.propagated_from_id))

def test_action_archive_gear_leaves_contacts_untouched(self):
"""action_archive archives only self.
Contact-type children are left untouched ."""
for p in (self.A, self.B, self.C, self.D, self.E):
p.write({"active": True, "propagated_from_id": False})
result = self.A.action_archive()
self.assertFalse(result)
self.assertFalse(self.A.active)
# All descendants left untouched
self.assertTrue(self.B.active)
self.assertTrue(self.C.active)
self.assertTrue(self.D.active)
self.assertTrue(self.E.active)

def test_action_archive_gear_no_contacts_still_only_archives_company(self):
"""action_archive archives only the company even when there
are no contact-type candidates."""
self.B.write({"active": False})
self.E.write({"active": False})
for p in (self.A, self.C, self.D):
p.write({"active": True, "propagated_from_id": False})
result = self.A.action_archive()
self.assertFalse(result)
self.assertFalse(self.A.active)
self.assertTrue(self.C.active)
self.assertTrue(self.D.active)
7 changes: 4 additions & 3 deletions partner_archive_propagate/wizard/archive_propagate_wizard.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@ def action_confirm(self):
- skip descendants linked to active users and notify
"""
self.ensure_one()
self.partner_id.with_context(partner_archive_propagate_ui=True).write(
{"active": False}
)
self.partner_id.with_context(
partner_archive_propagate_ui=True,
archive_propagate_wizard_line_ids=self.line_ids.mapped("partner_id").ids,
).write({"active": False})
partners = (
self.line_ids.mapped("partner_id").sudo().filtered(lambda p: p.active)
)
Expand Down
Loading