From fb0d0ddf392d65f6689e91d698ced25b3a0965d4 Mon Sep 17 00:00:00 2001 From: Kyle M Hall Date: Mon, 21 Dec 2015 13:05:45 +0000 Subject: [PATCH] Bug 15630 - Make Edifact module pluggable Koha's EDIFACT module works great for many European vendors, but does not work will for US vendors, which have a much different interpretation of 'standard'. In fact, each vendor may require different arrangements of values in EDIFACT messages. It would be impossible to encompass all these requirements within Koha's EDIFACT module itself. Instead, we should allow the module to be pluggable, so versions of the module can be developed for vendors that require EDIFACT messages that don't conform to the standard set by Koha's EDIFACT module. Test Plan: 1) Apply this patch 2) Run updatedatabase 3) Enable Koha plugins 4) Install the Edifact stub plugin available at https://github.com/bywatersolutions/koha-plugin-edifact-stub 5) Edit the EDI Vendor account, assign the plugin to a Vendor EDI account 6) Test EDI functionality ( ORDER, INVOICE ), there should be no errors or changes to the EDIFACT message input or output Signed-off-by: Jason DeShaw Signed-off-by: Martin Renvoize Signed-off-by: Brendan A Gallagher --- Koha/EDI.pm | 53 +++++++++++++++---- Koha/Plugins.pm | 2 +- Koha/Schema/Result/VendorEdiAccount.pm | 21 +++++--- admin/edi_accounts.pl | 5 ++ installer/data/mysql/kohastructure.sql | 1 + .../prog/en/modules/admin/edi_accounts.tt | 13 +++++ misc/cronjobs/edi_cron.pl | 37 ++++++++++++- 7 files changed, 112 insertions(+), 20 deletions(-) diff --git a/Koha/EDI.pm b/Koha/EDI.pm index 26f05e186f..8f460e2051 100644 --- a/Koha/EDI.pm +++ b/Koha/EDI.pm @@ -35,6 +35,7 @@ use Koha::Edifact::Order; use Koha::Edifact; use Log::Log4perl; use Text::Unidecode; +use Koha::Plugins::Handler; our $VERSION = 1.1; our @EXPORT_OK = @@ -86,18 +87,31 @@ sub create_edi_order { ); my $response = @{$arr_ref} ? 1 : 0; - my $edifact = Koha::Edifact::Order->new( - { - orderlines => \@orderlines, - vendor => $vendor, - ean => $ean_obj, - is_response => $response, - } - ); - if ( !$edifact ) { - return; + my $edifact_order_params = { + orderlines => \@orderlines, + vendor => $vendor, + ean => $ean_obj, + is_response => $response, + }; + + my $edifact; + if ( $vendor->plugin ) { + $edifact = Koha::Plugins::Handler->run( + { + class => $vendor->plugin, + method => 'edifact_order', + params => { + params => $edifact_order_params, + } + } + ); + } + else { + $edifact = Koha::Edifact::Order->new($edifact_order_params); } + return unless $edifact; + my $order_file = $edifact->encode(); # ingest result @@ -185,8 +199,25 @@ sub process_invoice { my $schema = Koha::Database->new()->schema(); my $logger = Log::Log4perl->get_logger(); my $vendor_acct; - my $edi = + + my $plugin = $invoice_message->edi_acct()->plugin(); + my $edi_plugin; + if ( $plugin ) { + $edi_plugin = Koha::Plugins::Handler->run( + { + class => $plugin, + method => 'edifact', + params => { + invoice_message => $invoice_message, + transmission => $invoice_message->raw_msg, + } + } + ); + } + + my $edi = $edi_plugin || Koha::Edifact->new( { transmission => $invoice_message->raw_msg, } ); + my $messages = $edi->message_array(); if ( @{$messages} ) { diff --git a/Koha/Plugins.pm b/Koha/Plugins.pm index d9055548c8..bca7701134 100644 --- a/Koha/Plugins.pm +++ b/Koha/Plugins.pm @@ -20,7 +20,7 @@ package Koha::Plugins; use Modern::Perl; use Module::Load::Conditional qw(can_load); -use Module::Pluggable search_path => ['Koha::Plugin']; +use Module::Pluggable search_path => ['Koha::Plugin'], except => qr/::Edifact(|::Line|::Message|::Order|::Segment|::Transport)$/; use C4::Context; use C4::Output; diff --git a/Koha/Schema/Result/VendorEdiAccount.pm b/Koha/Schema/Result/VendorEdiAccount.pm index 1a6917288a..20f9fa5095 100644 --- a/Koha/Schema/Result/VendorEdiAccount.pm +++ b/Koha/Schema/Result/VendorEdiAccount.pm @@ -130,6 +130,13 @@ __PACKAGE__->table("vendor_edi_accounts"); is_foreign_key: 1 is_nullable: 1 +=head2 plugin + + data_type: 'varchar' + default_value: (empty string) + is_nullable: 0 + size: 256 + =cut __PACKAGE__->add_columns( @@ -169,6 +176,8 @@ __PACKAGE__->add_columns( { data_type => "tinyint", default_value => 0, is_nullable => 0 }, "shipment_budget", { data_type => "integer", is_foreign_key => 1, is_nullable => 1 }, + "plugin", + { data_type => "varchar", default_value => "", is_nullable => 0, size => 256 }, ); =head1 PRIMARY KEY @@ -215,8 +224,8 @@ __PACKAGE__->belongs_to( { is_deferrable => 1, join_type => "LEFT", - on_delete => "RESTRICT", - on_update => "RESTRICT", + on_delete => "CASCADE", + on_update => "CASCADE", }, ); @@ -235,14 +244,14 @@ __PACKAGE__->belongs_to( { is_deferrable => 1, join_type => "LEFT", - on_delete => "RESTRICT", - on_update => "RESTRICT", + on_delete => "CASCADE", + on_update => "CASCADE", }, ); -# Created by DBIx::Class::Schema::Loader v0.07042 @ 2015-08-19 11:41:15 -# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:0CgJuFAItI71dfSG88NWhg +# Created by DBIx::Class::Schema::Loader v0.07025 @ 2015-12-21 12:59:02 +# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:xPfUnPxnQOmWWX3shkTVRA # You can replace this text with custom code or comments, and it will be preserved on regeneration diff --git a/admin/edi_accounts.pl b/admin/edi_accounts.pl index 7d86af80d9..69c270b0e2 100755 --- a/admin/edi_accounts.pl +++ b/admin/edi_accounts.pl @@ -23,6 +23,7 @@ use CGI; use C4::Auth; use C4::Output; use Koha::Database; +use Koha::Plugins; my $input = CGI->new(); @@ -51,6 +52,9 @@ if ( $op eq 'acct_form' ) { } ); $template->param( vendors => \@vendors ); + + my @plugins = Koha::Plugins->new()->GetPlugins('edifact'); + $template->param( plugins => \@plugins ); } elsif ( $op eq 'delete_confirm' ) { show_account(); @@ -77,6 +81,7 @@ else { responses_enabled => defined $input->param('responses_enabled'), auto_orders => defined $input->param('auto_orders'), id_code_qualifier => $input->param('id_code_qualifier'), + plugin => $input->param('plugin'), }; if ($id) { diff --git a/installer/data/mysql/kohastructure.sql b/installer/data/mysql/kohastructure.sql index 9136847550..e6e3142c9e 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3197,6 +3197,7 @@ CREATE TABLE IF NOT EXISTS vendor_edi_accounts ( responses_enabled TINYINT(1) not null default 0, auto_orders TINYINT(1) not null default 0, shipment_budget INTEGER(11) REFERENCES aqbudgets( budget_id ), + plugin varchar(256) NOT NULL DEFAULT "", PRIMARY KEY (id), KEY vendorid (vendor_id), KEY shipmentbudget (shipment_budget), diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/edi_accounts.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/edi_accounts.tt index 732b4ec6b6..93c2ce4dca 100644 --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/edi_accounts.tt +++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/edi_accounts.tt @@ -76,6 +76,19 @@ [% END %] +
  • + + +
  • diff --git a/misc/cronjobs/edi_cron.pl b/misc/cronjobs/edi_cron.pl index e22ab42944..a383033fac 100755 --- a/misc/cronjobs/edi_cron.pl +++ b/misc/cronjobs/edi_cron.pl @@ -66,7 +66,22 @@ for my $acct (@edi_accts) { } if ( $acct->invoices_enabled ) { - my $downloader = Koha::Edifact::Transport->new( $acct->id ); + my $downloader; + + if ( $acct->plugin ) { + $downloader = Koha::Plugins::Handler->run( + { + class => $acct->plugin, + method => 'edifact_transport', + params => { + vendor_edi_account_id => $acct->id, + } + } + ); + } + + $downloader ||= Koha::Edifact::Transport->new( $acct->id ); + $downloader->download_messages('INVOICE'); } @@ -116,7 +131,25 @@ my @downloaded_invoices = $schema->resultset('EdifactMessage')->search( foreach my $invoice (@downloaded_invoices) { my $filename = $invoice->filename(); $logger->trace("Processing invoice $filename"); - process_invoice($invoice); + + my $plugin_used = 0; + if ( my $plugin_class = $invoice->edi_acct->plugin ) { + my $plugin = $plugin_class->new(); + if ( $plugin->can('edifact_process_invoice') ) { + $plugin_used = 1; + Koha::Plugins::Handler->run( + { + class => $plugin_class, + method => 'edifact_process_invoice', + params => { + invoice => $invoice, + } + } + ); + } + } + + process_invoice($invoice) unless $plugin_used; } my @downloaded_responses = $schema->resultset('EdifactMessage')->search( -- 2.20.1