From 7544c01c476448b2a93c6e5944f9636193531356 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 --- 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 26f05e1..8f460e2 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 d905554..bca7701 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 7d86af8..69c270b 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 154cadb..10598bf 100644 --- a/installer/data/mysql/kohastructure.sql +++ b/installer/data/mysql/kohastructure.sql @@ -3196,6 +3196,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 732b4ec..93c2ce4 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..2d04018 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.1.4