From 60257c54f3bde37e539075faa713b7fe0ef7c691 Mon Sep 17 00:00:00 2001
From: Chris Hall <chrish@catalyst.net.nz>
Date: Fri, 25 Nov 2011 10:44:45 +1300
Subject: [PATCH] Added ability to duplicate a budget tree (from the edit sub menu) bug 6953

---
 admin/aqbudgetperiods.pl                           |   73 +++++++++++++++++++
 .../prog/en/includes/budgets-admin-toolbar.inc     |    2 +-
 .../prog/en/modules/admin/aqbudgetperiods.tt       |   75 ++++++++++++++++++++
 3 files changed, 149 insertions(+), 1 deletions(-)

diff --git a/admin/aqbudgetperiods.pl b/admin/aqbudgetperiods.pl
index e74935e..b83736a 100755
--- a/admin/aqbudgetperiods.pl
+++ b/admin/aqbudgetperiods.pl
@@ -37,6 +37,10 @@ script to administer the budget periods table
 	- we show the record having primkey=$primkey and ask for deletion validation form
  if $op=delete_confirmed
 	- we delete the record having primkey=$primkey
+ if $op=duplicate_form
+  - displays the duplication of budget period form (allowing specification of dates)
+ if $op=duplicate_budget
+  - we perform the duplication of the budget period specified as budget_period_id
 
 =cut
 
@@ -54,6 +58,7 @@ use C4::Output;
 use C4::Acquisition;
 use C4::Budgets;
 use C4::Debug;
+use C4::SQLHelper;
 
 my $dbh = C4::Context->dbh;
 
@@ -169,6 +174,74 @@ elsif ( $op eq 'delete_confirmed' ) {
 	$op='else';
 }
 
+# display the form for duplicating
+elsif ( $op eq 'duplicate_form'){
+    $template->param(
+        DHTMLcalendar_dateformat 	=> C4::Dates->DHTMLcalendar(),
+        'duplicate_form' => '1',
+        'budget_period_id' => $budget_period_id,
+    );
+}
+
+# handle the actual duplication
+elsif ( $op eq 'duplicate_budget' ){
+    die "please specify a budget period id\n" if( !defined $budget_period_id || $budget_period_id eq '' );
+    my $startdate = $input->param('budget_period_startdate');
+    my $enddate = $input->param('budget_period_enddate');
+
+    my $data = GetBudgetPeriod( $budget_period_id);
+
+    $data->{'budget_period_startdate'} = $startdate;
+    $data->{'budget_period_enddate'} = $enddate;
+    delete $data->{'budget_period_id'};
+    my $new_budget_period_id = C4::SQLHelper::InsertInTable('aqbudgetperiods', $data);
+
+    my $tree = GetBudgetHierarchy( $budget_period_id ); 
+
+    # hash mapping old ids to new
+    my %old_new;
+    # hash mapping old parent ids to list of new children ids
+    # only store a child here if the parents old id isnt in the old_new map
+    # when the parent is found, this map will be used, and then the entry removed and their id placed in old_new
+    my %parent_children;
+
+    for my $entry( @$tree ){
+        die "serious errors, parent period $budget_period_id doesnt match child ", $entry->{'budget_period_id'}, "\n" if( $entry->{'budget_period_id'} != $budget_period_id );
+        my $orphan = 0; # set to 1 if we need to make an entry in parent_children
+        my $old_id = delete $entry->{'budget_id'};
+        my $parent_id = delete $entry->{'budget_parent_id'};
+        $entry->{'budget_period_id'} = $new_budget_period_id;
+
+        if( !defined $parent_id ){
+        } elsif( defined $parent_id && $parent_id eq '' ){
+        } elsif( defined $old_new{$parent_id} ){
+            # set parent id now
+            $entry->{'budget_parent_id'} = $old_new{$parent_id};
+        } else {
+            # make an entry in parent_children
+            $parent_children{$parent_id} = [] unless defined $parent_children{$parent_id};
+            $orphan = 1;
+        }
+
+        # write it to db
+        my $new_id = C4::SQLHelper::InsertInTable('aqbudgets', $entry);
+        $old_new{$old_id} = $new_id;
+        push @{$parent_children{$parent_id}}, $new_id if $orphan;
+
+        # deal with any children
+        if( defined $parent_children{$old_id} ){
+            # tell my children my new id
+            for my $child ( @{$parent_children{$old_id}} ){
+                C4::SQLHelper::UpdateInTable('aqcudgets', [ 'budget_id' => $child, 'budget_parent_id' => $new_id ]);
+            }
+            delete $parent_children{$old_id};
+        }
+    }
+
+    # display the list of budgets
+    $op = 'else';
+}
+
 # DEFAULT - DISPLAY AQPERIODS TABLE
 # -------------------------------------------------------------------
 # display the list of budget periods
diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/budgets-admin-toolbar.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/budgets-admin-toolbar.inc
index da64ca4..ee24d76 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/includes/budgets-admin-toolbar.inc
+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/budgets-admin-toolbar.inc
@@ -33,7 +33,7 @@
         [% IF ( budget_period_id ) %]
                 var periods_menu = [
                         { text: _("Edit budget") + " '[% budget_period_description %]'", url: "/cgi-bin/koha/admin/aqbudgetperiods.pl?op=add_form&budget_period_id=[% budget_period_id %]" },
-                        <!-- { text: _("Duplicate budget") + " '[% budget_period_description %]'" } -->
+                        { text: _("Duplicate budget") + " '[% budget_period_description %]'", url: "/cgi-bin/koha/admin/aqbudgetperiods.pl?op=duplicate_form&budget_period_id=[% budget_period_id %]" },
                 ]
         [% END %]
 
diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt
index dbbcdd5..29dcf7f 100644
--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt
+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/aqbudgetperiods.tt
@@ -8,6 +8,29 @@
 // #################################################################################
 // Javascript
 // #################################################################################
+    function CheckDuplicateForm(f){
+            var ok=1;
+            var _alertString="";
+            var alertString="";
+            if(!(isNotNull(f.budget_period_startdate,1))){
+              _alertString += "\n- " + _("Start date missing");
+            }
+            if (!(isNotNull(f.budget_period_enddate,1))){
+              _alertString += "\n- " + _("End date missing");
+            }
+            if( f.budget_period_startdate > f.budget_period_enddate ) {
+              _alertString += "\n- " + _("Start date must be before end date");
+            }
+
+            if(_alertString.length==0){
+              f.submit();
+            } else {
+              alertString += _("Form not submitted because of the following problem(s)");
+              alertString += "\n-----------------------------------------\n";
+              alertString += _alertString;
+              alert(alertString);
+            }
+    }
     function Check(f) {
             var ok=1;
             var _alertString="";
@@ -128,6 +151,57 @@
 
 [% INCLUDE 'budgets-admin-toolbar.inc' %]
 
+[% IF ( duplicate_form ) %]
+<form action="/cgi-bin/koha/admin/aqbudgetperiods.pl" name="f" method="post">
+    <fieldset class="rows">
+    <input type="hidden" name="op" value="duplicate_budget" />
+    <input type="hidden" name="budget_period_id" value="[% budget_period_id %]" />
+
+    <ol>
+
+    <li>
+    <label class="required" for="budget_period_startdate">Start date</label>
+    <input type="text" size="10" id="budget_period_startdate" name="budget_period_startdate"   value="[% budget_period_startdate %]"  />
+    <img src="/intranet-tmpl/prog/en/lib/calendar/cal.gif" border="0" id="openCalendarFrom" style="cursor: pointer;" alt="Show start date calendar" />
+    <script type="text/javascript">
+        Calendar.setup({
+        inputField     :    "budget_period_startdate",
+        ifFormat         :    "[% DHTMLcalendar_dateformat %]",
+        button         :    "openCalendarFrom",
+        align          :    "Tl",
+        singleClick    :    false
+        });
+    </script>
+				<div class="hint">[% INCLUDE 'date-format.inc' %]</div>
+    </li>
+    <li>
+
+    <label class="required" for="budget_period_enddate">End date</label>
+    <input type="text" size="10" id="budget_period_enddate" name="budget_period_enddate" value="[% budget_period_enddate %]" />
+    <img src="/intranet-tmpl/prog/en/lib/calendar/cal.gif" border="0" id="openCalendarTo" style="cursor: pointer;" alt="Show end date calendar" />
+
+    <script type="text/javascript">
+        Calendar.setup({
+        inputField     :    "budget_period_enddate",
+        ifFormat         :    "[% DHTMLcalendar_dateformat %]",
+        button         :    "openCalendarTo",
+        align          :    "Tl"
+        });
+    </script>
+				<div class="hint">[% INCLUDE 'date-format.inc' %]</div>
+    </li>
+
+    </ol>
+    </fieldset>
+
+    <fieldset class="action">
+        <input type="button" value="Save Changes"  onclick="CheckDuplicateForm(this.form)"    />
+    </fieldset>
+
+</form>
+
+[% END %]
+
 [% IF ( add_form ) %]
     <!--  add or modify a budget period   -->
 
@@ -297,6 +371,7 @@
     <div class="pages">[% pagination_bar %]</div>
 [% END %]
 
+
 </div>
 </div>
 <div class="yui-b">
-- 
1.7.4.1