From 33ce92a1198aec064a2392b56e874e8791c5b0ba 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 --- 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 | 39 ++++++++++++++-- 7 files changed, 113 insertions(+), 21 deletions(-) diff --git a/Koha/EDI.pm b/Koha/EDI.pm index 2f4a0ca..95972e7 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 9e2d4eb..6152faf 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 1a69172..20f9fa5 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 83cc113..9a31a31 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(); @@ -72,6 +73,9 @@ if ( $op eq 'acct_form' ) { ] ); + my @plugins = Koha::Plugins->new()->GetPlugins('edifact'); + $template->param( plugins => \@plugins ); + } elsif ( $op eq 'delete_confirm' ) { show_account(); @@ -98,6 +102,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 0511f7b..bfe86fa 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3160,6 +3160,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 d7e46ee..75e3343 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 @@ -77,6 +77,19 @@
  • + + +
  • +
  • diff --git a/misc/cronjobs/edi_cron.pl b/misc/cronjobs/edi_cron.pl index 8ba9a14..74e15a4 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'); } @@ -115,8 +130,26 @@ my @downloaded_invoices = $schema->resultset('EdifactMessage')->search( foreach my $invoice (@downloaded_invoices) { my $filename = $invoice->filename(); - $logger->trace("Processing invoice $filename"); - process_invoice($invoice); + #$logger->trace("Processing invoice $filename"); + + 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.1.4