Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow orgs to not have a main contact if imported from an aggregator #10531

Merged
merged 5 commits into from
Jul 11, 2024
Merged
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
10 changes: 5 additions & 5 deletions lib/ProductOpener/CRM.pm
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ sub add_contact_to_company($contact_id, $company_id) {
return $result;
}

=head2 create_onboarding_opportunity ($name, $company_id, $contact_id)
=head2 create_onboarding_opportunity ($name, $company_id, $partner_id, salesperson_email = undef)

create an opportunity attached to a

Expand All @@ -454,20 +454,20 @@ The name of the opportunity
The id of the partner to attach the opportunity to.
It can be a contact or a company

=head4 $salesperson_id
=head4 $salesperson_email

The id of the salesperson to assign the opportunity to
The email of the salesperson to attach to the opportunity

=head3 Return values

the id of the created opportunity

=cut

sub create_onboarding_opportunity ($name, $company_id, $contact_id, $salesperson_email = undef) {
sub create_onboarding_opportunity ($name, $company_id, $partner_id, $salesperson_email = undef) {

my $query_params
= {name => $name, partner_id => $contact_id, tag_ids => [[$commands{link}, $crm_data->{tag}{onboarding}]]};
= {name => $name, partner_id => $partner_id, tag_ids => [[$commands{link}, $crm_data->{tag}{onboarding}]]};
if (defined $salesperson_email) {
my $user = (grep {$_->{email} eq $salesperson_email} @{$crm_data->{users}})[0];
if (defined $user) {
Expand Down
37 changes: 23 additions & 14 deletions lib/ProductOpener/Orgs.pm
Original file line number Diff line number Diff line change
Expand Up @@ -175,28 +175,30 @@ sub store_org ($org_ref) {

# We switched to validated, update CRM
my $main_contact_user = $org_ref->{main_contact};
my $user_ref = retrieve_user($main_contact_user);

eval {
my $contact_id = find_or_create_contact($user_ref);
defined $contact_id or die "Failed to get contact";
$user_ref->{crm_user_id} = $contact_id;
store_user($user_ref);
my $partner_id;
if (defined $main_contact_user) {
my $user_ref = retrieve_user($main_contact_user);
$partner_id = $user_ref->{crm_user_id} // find_or_create_contact($user_ref);
defined $partner_id or die "Failed to get contact";
$user_ref->{crm_user_id} = $partner_id;
store_user($user_ref);
}

my $company_id = find_or_create_company($org_ref, $contact_id);
my $company_id = find_or_create_company($org_ref, $partner_id);
defined $company_id or die "Failed to get company";

defined add_contact_to_company($contact_id, $company_id) or die "Failed to add contact to company";
if (defined $partner_id) {
defined add_contact_to_company($partner_id, $company_id) or die "Failed to add contact to company";
}

# admin validates the org, used to link the right salesperson
# The off admin who validates the org is the salesperson in crm
my $my_admin = retrieve_user($User_id);
$log->debug("store_org", {myuser => $my_admin}) if $log->is_debug();

my $opportunity_id = create_onboarding_opportunity(
"$org_ref->{name} - new",
$company_id, $user_ref->{crm_user_id},
$my_admin->{email}
);
my $opportunity_id
= create_onboarding_opportunity("$org_ref->{name} - new", $company_id, $partner_id, $my_admin->{email});
defined $opportunity_id or die "Failed to create opportunity";

$org_ref->{crm_org_id} = $company_id;
Expand Down Expand Up @@ -273,7 +275,7 @@ sub create_org ($creator, $org_id_or_name) {
protect_data => "on",
admins => {},
members => {},
main_contact => $creator,
main_contact => undef,
};

store_org($org_ref);
Expand Down Expand Up @@ -406,6 +408,13 @@ sub add_user_to_org ($org_id_or_ref, $user_id, $groups_ref) {
foreach my $group (@{$groups_ref}) {
(defined $org_ref->{$group}) or $org_ref->{$group} = {};
$org_ref->{$group}{$user_id} = 1;

# the first admin is main contact
if ($group eq "admins"
and (not exists $org_ref->{main_contact} or $org_ref->{main_contact} eq ''))
{
$org_ref->{main_contact} = $user_id;
}
}

# sync CRM
Expand Down
83 changes: 83 additions & 0 deletions scripts/migrations/2024_07_change_main_contact.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
#!/usr/bin/perl -w

# This file is part of Product Opener.
#
# Product Opener
# Copyright (C) 2011-2023 Association Open Food Facts
# Contact: [email protected]
# Address: 21 rue des Iles, 94100 Saint-Maur des Fossés, France
#
# Product Opener is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.

use Modern::Perl '2017';
use utf8;

# This file is used
# to change the main_contact field of orgs that are not users
# to an undef value
# or to the first admin of the org if it exists

use ProductOpener::Store qw/store/;
use ProductOpener::Orgs qw/list_org_ids retrieve_org/;
use ProductOpener::Paths qw/%BASE_DIRS/;
use ProductOpener::Config qw/%admins/;
use Encode;

binmode(STDOUT, ":encoding(UTF-8)");
binmode(STDERR, ":encoding(UTF-8)");

my @not_users = qw(agena3000 equadis codeonline bayard database-usda countrybot );
push @not_users, keys %admins;

foreach my $org_id (list_org_ids()) {

$org_id = decode utf8 => $org_id; # because of wide characters in org_id like greek letters
my $org_ref = retrieve_org($org_id);

if (
(defined $org_ref->{main_contact})
and (
($org_ref->{main_contact} =~ /^\s*$/) # empty or only whitespace
or ($org_ref->{main_contact} =~ /[\p{Z}\p{C}]/) # contains unicode whitespace or control characters
or (grep {$org_ref->{main_contact} eq $_} @not_users)
) # shouldn't be a main contact
)
{

$org_ref->{main_contact} = undef;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the case of an empty contact, don't you wan't to see if there are people in the admins group ? (and maybe, just log for now, and report this to producers team).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah thanks, I completely forgot, that's what I wanted to do initially :)


# take the first admin as main contact if available
if (defined $org_ref->{admins} and @{$org_ref->{admins}}) {
# find the first admin that is not in the list of users that are not users
# and set it as main contact

my $admin = undef;
foreach my $admin_id (@{$org_ref->{admins}}) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@{$org_ref->{admins} is a hash, changing to sort keys %{$org_ref->{admins}}

if (not grep {$admin_id eq $_} @not_users) {
$admin = $admin_id;
last;
}
}

print "main_contact of $org_id set to $org_ref->{main_contact}\n";
}
else {
print "main_contact of $org_id set to undef\n";
}
}

# not using store_org to avoid triggering the odoo sync
store("$BASE_DIRS{ORGS}/" . $org_id . ".sto", $org_ref);
}

Loading