From cfb572660dfd823181e0867454a79e351ca39dfb Mon Sep 17 00:00:00 2001
From: tdruez <489057+tdruez@users.noreply.github.com>
Date: Mon, 27 May 2024 11:48:53 +0400
Subject: [PATCH] Add replace_existing_version field on the AddToProduct form
#12 (#124)
Signed-off-by: tdruez
---
CHANGELOG.rst | 4 +
component_catalog/forms.py | 19 ++-
component_catalog/models.py | 6 +-
.../component_catalog/add_to_product.html | 9 +-
.../component_catalog/includes/add_to.js.html | 48 ++++--
.../includes/add_to_modal.html | 4 +-
component_catalog/tests/test_models.py | 3 +
component_catalog/views.py | 15 +-
dje/models.py | 13 +-
policy/models.py | 2 +-
product_portfolio/models.py | 121 +++++++++----
product_portfolio/tests/test_models.py | 160 +++++++++++++++++-
12 files changed, 342 insertions(+), 62 deletions(-)
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index ee11fe2e..fb6b2937 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -78,6 +78,10 @@ Release notes
- Enhance Package Import to support modifications.
https://github.com/nexB/dejacode/issues/84
+- Add an option on the "Add to Product" form to to replace any existing relationships
+ with a different version of the same object by the selected object.
+ https://github.com/nexB/dejacode/issues/12
+
### Version 5.0.1
- Improve the stability of the "Check for new Package versions" feature.
diff --git a/component_catalog/forms.py b/component_catalog/forms.py
index 73a4cb60..e6c3ddf8 100644
--- a/component_catalog/forms.py
+++ b/component_catalog/forms.py
@@ -646,6 +646,17 @@ class AddToProductAdminForm(forms.Form):
queryset=Product.objects.none(),
)
ids = forms.CharField(widget=forms.widgets.HiddenInput)
+ replace_existing_version = forms.BooleanField(
+ required=False,
+ initial=False,
+ label="Replace existing relationships by newer version.",
+ help_text=(
+ "Select this option to replace any existing relationships with a different version "
+ "of the same object. "
+ "If more than one version of the object is already assigned, no replacements will be "
+ "made, and the new version will be added instead."
+ ),
+ )
def __init__(self, request, model, relation_model, *args, **kwargs):
super().__init__(*args, **kwargs)
@@ -663,9 +674,11 @@ def get_selected_objects(self):
def save(self):
product = self.cleaned_data["product"]
+
return product.assign_objects(
related_objects=self.get_selected_objects(),
user=self.request.user,
+ replace_version=self.cleaned_data["replace_existing_version"],
)
@@ -719,15 +732,15 @@ def new_component_from_package_link(self):
href = f"{component_add_url}?package_ids={package.id}"
return HTML(
+ f""
f'
"
- f""
)
def clean_component(self):
@@ -749,9 +762,9 @@ def helper(self):
helper.layout = Layout(
Fieldset(
None,
- self.new_component_from_package_link(),
"object_id",
"component",
+ self.new_component_from_package_link(),
),
)
return helper
diff --git a/component_catalog/models.py b/component_catalog/models.py
index a220135b..e4917f4c 100644
--- a/component_catalog/models.py
+++ b/component_catalog/models.py
@@ -1915,12 +1915,16 @@ def get_export_cyclonedx_url(self):
return self.get_url("export_cyclonedx")
@classmethod
- def get_identifier_fields(cls):
+ def get_identifier_fields(cls, *args, purl_fields_only=False, **kwargs):
"""
Explicit list of identifier fields as we do not enforce a unique together
on this model.
This is used in the Importer, to catch duplicate entries.
+ The purl_fields_only option can be use to limit the results.
"""
+ if purl_fields_only:
+ return PACKAGE_URL_FIELDS
+
return ["filename", "download_url", *PACKAGE_URL_FIELDS]
@property
diff --git a/component_catalog/templates/admin/component_catalog/add_to_product.html b/component_catalog/templates/admin/component_catalog/add_to_product.html
index 854add47..a1621436 100644
--- a/component_catalog/templates/admin/component_catalog/add_to_product.html
+++ b/component_catalog/templates/admin/component_catalog/add_to_product.html
@@ -19,17 +19,22 @@
Add {% trans opts.verbose_name %} to a product
The Product provides you with a group of {% trans opts.verbose_name_plural|title %} that are used together, so that
you can generate Attribution documentation for all of the {% trans opts.verbose_name_plural|title %} in that Product.
diff --git a/component_catalog/templates/component_catalog/includes/add_to.js.html b/component_catalog/templates/component_catalog/includes/add_to.js.html
index 77e2ffeb..a024fe67 100644
--- a/component_catalog/templates/component_catalog/includes/add_to.js.html
+++ b/component_catalog/templates/component_catalog/includes/add_to.js.html
@@ -1,29 +1,35 @@
\ No newline at end of file
+
\ No newline at end of file
diff --git a/component_catalog/templates/component_catalog/includes/add_to_modal.html b/component_catalog/templates/component_catalog/includes/add_to_modal.html
index 122323ce..847f1758 100644
--- a/component_catalog/templates/component_catalog/includes/add_to_modal.html
+++ b/component_catalog/templates/component_catalog/includes/add_to_modal.html
@@ -8,13 +8,13 @@