Skip to content

Commit

Permalink
feat: new sync data in CRM (#10440)
Browse files Browse the repository at this point in the history
  • Loading branch information
4nt0ineB authored Jun 21, 2024
1 parent c24bc5a commit 797b22a
Show file tree
Hide file tree
Showing 12 changed files with 139 additions and 22 deletions.
8 changes: 7 additions & 1 deletion cgi/generate_sample_import_file.pl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
use CGI::Carp qw(fatalsToBrowser);

use ProductOpener::Config qw/:all/;
use ProductOpener::Display qw/init_request/;
use ProductOpener::Display qw/init_request $admin/;
use ProductOpener::Users qw/:all/;
use ProductOpener::Lang qw/lang/;
use ProductOpener::Mail qw/:all/;
Expand All @@ -37,6 +37,7 @@
use ProductOpener::Food qw/default_unit_for_nid/;
use ProductOpener::TaxonomySuggestions qw/:all/;
use ProductOpener::Paths qw/%BASE_DIRS/;
use ProductOpener::CRM qw/update_template_download_date/;

use Apache2::RequestRec ();
use Apache2::Const ();
Expand All @@ -47,6 +48,11 @@

my $request_ref = ProductOpener::Display::init_request();

# sync CRM
if (defined $Org_id and not $admin and not $User{moderator} and not $User{pro_moderator}) {
update_template_download_date($Org_id);
}

my $r = Apache2::RequestUtil->request();

$r->headers_out->set("Content-type" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
Expand Down
4 changes: 3 additions & 1 deletion cgi/import_file_process.pl
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
use ProductOpener::Lang qw/$lc lang/;
use ProductOpener::Mail qw/:all/;
use ProductOpener::Producers qw/convert_file get_minion load_csv_or_excel_file normalize_column_name/;
use ProductOpener::CRM qw/update_last_import_date/;
use ProductOpener::CRM qw/update_company_last_import_type/;

use Apache2::RequestRec ();
use Apache2::Const ();
Expand Down Expand Up @@ -202,6 +202,8 @@

store("$BASE_DIRS{IMPORT_FILES}/${Owner_id}/import_files.sto", $import_files_ref);

update_company_last_import_type($Org_id, 'CSV');

$template_data_ref->{process_file_id} = $file_id;
$template_data_ref->{process_import_id} = $import_id;
$template_data_ref->{link} = "/cgi/import_file_job_status.pl?file_id=$file_id&import_id=$import_id";
Expand Down
2 changes: 2 additions & 0 deletions cgi/product_multilingual.pl
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
use ProductOpener::APIProductWrite qw/skip_protected_field/;
use ProductOpener::ProductsFeatures qw/feature_enabled/;
use ProductOpener::Orgs qw/update_import_date/;
use ProductOpener::CRM qw/update_company_last_import_type/;

use Apache2::RequestRec ();
use Apache2::Const ();
Expand Down Expand Up @@ -276,6 +277,7 @@ ($product_ref)
# sync crm
if (defined $Org_id) {
update_import_date($Org_id, $product_ref->{created_t});
update_company_last_import_type($Org_id, 'Manual import');
}

$type = 'add';
Expand Down
96 changes: 82 additions & 14 deletions lib/ProductOpener/CRM.pm
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ BEGIN {
&change_company_main_contact
&update_last_import_date
&update_last_export_date
&update_company_last_logged_in_contact
&update_company_last_import_type
&add_category_to_company
&update_template_download_date
&update_contact_last_login
&get_company_url
&get_contact_url
);
Expand All @@ -83,7 +88,7 @@ my $crm_data;
my @required_tag_labels = qw(onboarding);
# Category (res.partner.category) must be defined in Odoo :
# Contact > contact (individual or company) form > Tags field > "Search More"
my @required_category_labels = qw(Producer);
my @required_category_labels = ('Producer', 'AGENA3000', 'EQUADIS', 'CSV', 'Manual import',);

# special commands to manipulate Odoo relation One2Many and Many2Many
# see https://www.odoo.com/documentation/15.0/developer/reference/backend/orm.html#odoo.fields.Command
Expand Down Expand Up @@ -568,25 +573,84 @@ sub change_company_main_contact($org_ref, $user_id) {
}

sub update_last_import_date($org_id, $time) {
return update_company_last_action_date($org_id, $time, 'x_off_last_import_date');
return _update_partner_field(retrieve_org($org_id), 'x_off_last_import_date', _time_to_odoo_date_str($time));
}

sub update_last_export_date($org_id, $time) {
return update_company_last_action_date($org_id, $time, 'x_off_last_export_date');
return _update_partner_field(retrieve_org($org_id), 'x_off_last_export_date', _time_to_odoo_date_str($time));
}

sub update_company_last_action_date($org_id, $time, $field) {
sub update_contact_last_login ($user_ref) {
return if not defined $user_ref->{crm_user_id};
return _update_partner_field($user_ref, 'x_off_user_login_date', _time_to_odoo_date_str($user_ref->{last_login_t}));
}

sub update_template_download_date ($org_id) {
my $org_ref = retrieve_org($org_id);
if (not defined $org_ref->{crm_org_id}) {
return;
}
return _update_partner_field($org_ref, 'x_off_last_template_download_date', _time_to_odoo_date_str(time()));
}

sub update_company_last_logged_in_contact($org_ref, $user_ref) {
return _update_partner_field($org_ref, 'x_off_last_logged_org_contact', $user_ref->{crm_user_id});
}

sub _update_partner_field($user_or_org, $field, $value) {
my $partner_id = $user_or_org->{crm_user_id} // $user_or_org->{crm_org_id};
return if not defined $partner_id;

$log->debug("update_partner_field", {partner_id => $partner_id, field => $field, value => $value})
if $log->is_debug();

return make_odoo_request('res.partner', 'write', [[$partner_id], {$field => $value}]);
}

sub _time_to_odoo_date_str($time) {
my ($sec, $min, $hour, $mday, $mon, $year) = localtime($time);
$year += 1900;
$mon += 1;
my $date_string = sprintf("%04d-%02d-%02d", $year, $mon, $mday);
$log->debug("update_last_company_action_date", {org_id => $org_id, date => $date_string, field => $field})
return sprintf("%04d-%02d-%02d", $year, $mon, $mday);
}

=head2 add_category_to_company ($org_id, $label)
Add a category to a company in Odoo
=head3 Arguments
=head4 $org_id
=head4 $label
=head3 Return values
1 if success, undef otherwise
=cut

sub add_category_to_company($org_id, $label) {
my $org_ref = retrieve_org($org_id);
return if not defined $org_ref->{crm_org_id};

my $category_id = $crm_data->{category}{$label};
return if not defined $category_id;
if (not defined $category_id) {
$log->debug("add_category_to_company", {error => "Category `$label` not found in CRM"})
if $log->is_debug();
return;
}
$log->debug("add_category_to_company", {org_id => $org_id, label => $label, category_id => $category_id})
if $log->is_debug();
return make_odoo_request('res.partner', 'write', [[$org_ref->{crm_org_id}], {$field => $date_string}]);
return make_odoo_request('res.partner', 'write',
[[$org_ref->{crm_org_id}], {category_id => [[$commands{link}, $category_id]]}]);
}

sub update_company_last_import_type($org_id, $label) {
my $org_ref = retrieve_org($org_id);
return if not defined $org_ref->{crm_org_id};
my $category_id = $crm_data->{category}{$label};
add_category_to_company($org_id, $label);
return make_odoo_request('res.partner', 'write',
[[$org_ref->{crm_org_id}], {x_off_last_import_type => $category_id}]);
}

=head2 get_company_url ($org_ref)
Expand Down Expand Up @@ -649,7 +713,10 @@ sub make_odoo_request(@params) {
}

my $uid;
eval {$uid = $xmlrpc->call('authenticate', $db, $username, $pwd, {});};
eval {
$uid = $xmlrpc->call('authenticate', $db, $username, $pwd, {});
die "uid from Odoo auth. is 0, your credentials may be wrong." if $uid eq '0';
};
if ($@) {
$log->error("Odoo", {error => $@, reason => "Could not authenticate to Odoo CRM"}) if $log->is_error();
$xmlrpc = undef;
Expand Down Expand Up @@ -685,7 +752,8 @@ It is called by lib/startup_apache.pl startup script
=head4 die if CRM data cannot be loaded
# Die if CRM environment variables are set and required data cannot be loaded from cache or fetched from CRM
Die if CRM environment variables are set but required
data can't be fetched from CRM nor be loaded from cache
=cut

Expand All @@ -708,8 +776,8 @@ sub init_crm_data() {
$crm_data = $tmp_crm_data;
} or do {
print STDERR "Failed to load CRM data from Odoo: $@\n";
die "Could not load CRM data from cache" if not defined $crm_data;
print STDERR "CRM data loaded from cache";
die "Could not load CRM data from cache\n" if not defined $crm_data;
print STDERR "CRM data loaded from cache\n";
};

store("$BASE_DIRS{CACHE_TMP}/crm_data.sto", $crm_data);
Expand Down
7 changes: 7 additions & 0 deletions lib/ProductOpener/Import.pm
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ use ProductOpener::Ecoscore qw/:all/;
use ProductOpener::ForestFootprint qw/:all/;
use ProductOpener::PackagerCodes qw/normalize_packager_codes/;
use ProductOpener::API qw/get_initialized_response/;
use ProductOpener::CRM qw/update_company_last_import_type/;

use CGI qw/:cgi :form escapeHTML/;
use URI::Escape::XS;
Expand Down Expand Up @@ -2773,6 +2774,12 @@ sub import_csv_file ($args_ref) {
# sync CRM
foreach my $org_id (keys %{$stats_ref->{orgs_existing}}) {
update_import_date($org_id, $time);
if ($args_ref->{source_id} eq 'agena3000') {
update_company_last_import_type($org_id, 'AGENA3000');
}
elsif ($args_ref->{source_id} eq 'equadis') {
update_company_last_import_type($org_id, 'EQUADIS');
}
}

$log->debug(
Expand Down
21 changes: 20 additions & 1 deletion lib/ProductOpener/Orgs.pm
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ BEGIN {
&org_name
&update_import_date
&update_export_date
&update_last_logged_in_member
); # symbols to export on request
%EXPORT_TAGS = (all => [@EXPORT_OK]);
Expand Down Expand Up @@ -216,7 +217,7 @@ sub store_org ($org_ref) {
and $org_ref->{main_contact} ne $previous_org_ref->{main_contact}
and not change_company_main_contact($previous_org_ref, $org_ref->{main_contact}))
{
# so we don't lose sync with CRM if main contact cannot be changed
# fail -> revert main contact, so we don't lose sync with CRM if main contact cannot be changed
$org_ref->{main_contact} = $previous_org_ref->{main_contact};
}

Expand Down Expand Up @@ -522,4 +523,22 @@ sub update_export_date($org_id, $time) {
return;
}

sub update_last_logged_in_member($user_ref) {

my $org_id = $user_ref->{org_id} // $user_ref->{requested_org_id};
return if not defined $org_id;

my $org_ref = retrieve_org($org_id);
return if not defined $org_ref;
is_user_in_org_group($org_ref, $user_ref->{userid}, "members") or return;

$org_ref->{last_logged_member} = $user_ref->{userid};

if (defined $org_ref->{crm_org_id}) {
update_company_last_logged_in_contact($org_ref, $user_ref);
}

return;
}

1;
2 changes: 1 addition & 1 deletion lib/ProductOpener/Test.pm
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,7 @@ We remove time dependent fields, password (which encryption use salt) and sort s
=cut

sub normalize_user_for_test_comparison ($user_ref) {
my %specification = (fields_ignore_content => [qw(registered_t user_sessions encrypted_password ip)],);
my %specification = (fields_ignore_content => [qw(registered_t last_login_t user_sessions encrypted_password ip)],);

normalize_object_for_test_comparison($user_ref, \%specification);
return;
Expand Down
14 changes: 13 additions & 1 deletion lib/ProductOpener/Users.pm
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ BEGIN {
&check_session
&generate_token
&update_login_time
); # symbols to export on request
%EXPORT_TAGS = (all => [@EXPORT_OK]);
Expand All @@ -88,10 +89,12 @@ use ProductOpener::Paths qw/%BASE_DIRS/;
use ProductOpener::Mail qw/get_html_email_content send_email_to_admin send_email_to_producers_admin send_html_email/;
use ProductOpener::Lang qw/$lc %Lang lang/;
use ProductOpener::Display qw/:all/;
use ProductOpener::Orgs qw/add_user_to_org create_org remove_user_from_org retrieve_or_create_org retrieve_org/;
use ProductOpener::Orgs
qw/add_user_to_org create_org remove_user_from_org retrieve_or_create_org retrieve_org update_last_logged_in_member/;
use ProductOpener::Products qw/find_and_replace_user_id_in_products/;
use ProductOpener::Text qw/remove_tags_and_quote/;
use ProductOpener::Brevo qw/add_contact_to_list/;
use ProductOpener::CRM qw/update_contact_last_login/;

use CGI qw/:cgi :form escapeHTML/;
use Encode;
Expand Down Expand Up @@ -1170,6 +1173,7 @@ sub init_user ($request_ref) {
migrate_password_hash($user_ref);

open_user_session($user_ref, $request_ref);
update_login_time($user_ref);
}
}
else {
Expand Down Expand Up @@ -1423,4 +1427,12 @@ sub check_session ($user_id, $user_session) {
return $results_ref;
}

sub update_login_time ($user_ref) {
$user_ref->{last_login_t} = time();
store_user($user_ref);
update_contact_last_login($user_ref);
update_last_logged_in_member($user_ref);
return;
}

1;
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
"origins_of_ingredients" : {
"aggregated_origins" : [
{
"epi_score" : 0,
"epi_score" : "0",
"origin" : "en:unknown",
"percent" : 100,
"transportation_score" : null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
"origins_of_ingredients" : {
"aggregated_origins" : [
{
"epi_score" : 0,
"epi_score" : "0",
"origin" : "en:unknown",
"percent" : 100,
"transportation_score" : null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
"origins_of_ingredients" : {
"aggregated_origins" : [
{
"epi_score" : 0,
"epi_score" : "0",
"origin" : "en:unknown",
"percent" : 100,
"transportation_score" : null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"initial_lc" : "en",
"initial_user_agent" : "Product-opener-tests/1.0",
"ip" : "--ignore--",
"last_login_t" : "--ignore--",
"name" : "Test",
"newsletter" : "",
"old_email" : null,
Expand Down

0 comments on commit 797b22a

Please sign in to comment.