[freeside-commits] branch FREESIDE_3_BRANCH updated. 4d5a5d18c44bcd5b6b7d970434d6d271503e5442

Jonathan Prykop jonathan at 420.am
Tue Nov 10 20:49:54 PST 2015


The branch, FREESIDE_3_BRANCH has been updated
       via  4d5a5d18c44bcd5b6b7d970434d6d271503e5442 (commit)
       via  0000bd1322932cf4d6035391ed41f12d62441b02 (commit)
       via  be4e0c51a534945f6782d2b9c48a2b1e88292642 (commit)
       via  ee7e3cc614c860c8d0aa2fdc9b112c57fe548ff2 (commit)
       via  7a7776bc564aa2fb03c7c217d9e6f5fd39d8eb5f (commit)
      from  71852b4b08791527398656c42dcfc980891ca0b2 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 4d5a5d18c44bcd5b6b7d970434d6d271503e5442
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Tue Nov 10 22:47:42 2015 -0600

    RT#34960: Quotations [v3 only]

diff --git a/FS/FS/Template_Mixin.pm b/FS/FS/Template_Mixin.pm
index b9a934d..c331800 100644
--- a/FS/FS/Template_Mixin.pm
+++ b/FS/FS/Template_Mixin.pm
@@ -3141,6 +3141,8 @@ sub _items_cust_bill_pkg {
         # quotation_pkgs are never fees, so don't worry about the case where
         # part_pkg is undefined
 
+        my @details = $cust_bill_pkg->details;
+
         # and I guess they're never bundled either?
         if ( $cust_bill_pkg->setup != 0 ) {
           my $description = $desc;
@@ -3156,6 +3158,7 @@ sub _items_cust_bill_pkg {
             'amount'      => sprintf("%.2f", $cust_bill_pkg->setup),
             'unit_amount' => sprintf("%.2f", $cust_bill_pkg->unitsetup),
             'quantity'    => $cust_bill_pkg->quantity,
+            'ext_description' => \@details,
             'preref_html' => ( $opt{preref_callback}
                                  ? &{ $opt{preref_callback} }( $cust_bill_pkg )
                                  : ''
@@ -3170,6 +3173,7 @@ sub _items_cust_bill_pkg {
             'amount'      => sprintf("%.2f", $cust_bill_pkg->recur),
             'unit_amount' => sprintf("%.2f", $cust_bill_pkg->unitrecur),
             'quantity'    => $cust_bill_pkg->quantity,
+            'ext_description' => \@details,
            'preref_html'  => ( $opt{preref_callback}
                                  ? &{ $opt{preref_callback} }( $cust_bill_pkg )
                                  : ''

commit 0000bd1322932cf4d6035391ed41f12d62441b02
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Tue Nov 10 18:20:15 2015 -0600

    RT#34960: Quotations [billpkgnum removal--missed a spot]

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 8600217..d0b69ca 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1392,7 +1392,7 @@ sub tables_hashref {
       ],
       'primary_key'  => 'detailnum',
       'unique'       => [],
-      'index'        => [ [ 'billpkgnum' ] ],
+      'index'        => [ [ 'quotationpkgnum' ] ],
       'foreign_keys' => [
                           { columns    => [ 'quotationpkgnum' ],
                             table      => 'quotation_pkg',

commit be4e0c51a534945f6782d2b9c48a2b1e88292642
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Tue Nov 10 00:03:37 2015 -0600

    RT#34960: Quotations [added attribution for icon]

diff --git a/httemplate/docs/license.html b/httemplate/docs/license.html
index cebea72..226e781 100644
--- a/httemplate/docs/license.html
+++ b/httemplate/docs/license.html
@@ -142,5 +142,11 @@ Contains icons from
 by Mark James, licensed under the terms of the Creative Commons Attribution
 2.5 License.
 
+<P>
+Includes icon from 
+http://www.iconarchive.com/show/oxygen-icons-by-oxygen-icons.org/Actions-document-edit-icon.html
+licensed under GNU Lesser General Public License
+</P>
+
 </BODY>
 </HTML>

commit ee7e3cc614c860c8d0aa2fdc9b112c57fe548ff2
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Mon Nov 9 17:05:36 2015 -0600

    RT#34960: Quotations [changed billpkgnum to quotationpkgnum]

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index 429bc55..8600217 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1386,7 +1386,7 @@ sub tables_hashref {
     'quotation_pkg_detail' => {
       'columns' => [
         'detailnum', 'serial', '', '', '', '', 
-        'billpkgnum', 'int', '', '', '', '',        # actually links to quotationpkgnum
+        'quotationpkgnum', 'int', '', '', '', '',
         'format',  'char', 'NULL', 1, '', '',       # not used for anything
         'detail',  'varchar', '', 255, '', '',
       ],
@@ -1394,7 +1394,7 @@ sub tables_hashref {
       'unique'       => [],
       'index'        => [ [ 'billpkgnum' ] ],
       'foreign_keys' => [
-                          { columns    => [ 'billpkgnum' ],
+                          { columns    => [ 'quotationpkgnum' ],
                             table      => 'quotation_pkg',
                             references => [ 'quotationpkgnum' ],
                           },
diff --git a/FS/FS/TemplateItem_Mixin.pm b/FS/FS/TemplateItem_Mixin.pm
index dcd7ab3..248da3c 100644
--- a/FS/FS/TemplateItem_Mixin.pm
+++ b/FS/FS/TemplateItem_Mixin.pm
@@ -175,6 +175,7 @@ sub details {
   my $escape_function = $opt{escape_function} || sub { shift };
 
   my $csv = new Text::CSV_XS;
+  my $key = $self->primary_key;
 
   if ( $opt{format_function} ) {
 
@@ -189,14 +190,14 @@ sub details {
           )
         }
       qsearch ({ 'table'    => $self->detail_table,
-                 'hashref'  => { 'billpkgnum' => $self->billpkgnum },
+                 'hashref'  => { $key => $self->get($key) },
                  'order_by' => 'ORDER BY detailnum',
               });
 
   } elsif ( $opt{'no_usage'} ) {
 
     my $sql = "SELECT detail FROM ". $self->detail_table.
-              "  WHERE billpkgnum = ". $self->billpkgnum.
+              "  WHERE " . $key . " = ". $self->get($key).
               "    AND ( format IS NULL OR format != 'C' ) ".
               "  ORDER BY detailnum";
     my $sth = dbh->prepare($sql) or die dbh->errstr;
@@ -251,7 +252,7 @@ sub details {
     }
 
     my $sql = "SELECT format, detail FROM ". $self->detail_table.
-              "  WHERE billpkgnum = ". $self->billpkgnum.
+              "  WHERE " . $key . " = ". $self->get($key).
               "  ORDER BY detailnum";
     my $sth = dbh->prepare($sql) or die dbh->errstr;
     $sth->execute or die $sth->errstr;
diff --git a/FS/FS/quotation_pkg.pm b/FS/FS/quotation_pkg.pm
index 65e6b62..1a2fadc 100644
--- a/FS/FS/quotation_pkg.pm
+++ b/FS/FS/quotation_pkg.pm
@@ -98,21 +98,8 @@ sub display_table         { 'quotation_pkg'; }
 #                                                 #  (for invoice display order)
 
 sub discount_table        { 'quotation_pkg_discount'; }
-
-# detail table uses non-quotation fieldnames, see billpkgnum below
 sub detail_table          { 'quotation_pkg_detail'; }
 
-=item billpkgnum
-
-Sets/returns quotationpkgnum, for ease of integration with TemplateItem_Mixin::details
-
-=cut
-
-sub billpkgnum {
-  my $self = shift;
-  $self->quotationpkgnum(@_);
-}
-
 =item insert
 
 Adds this record to the database.  If there is an error, returns the error,
@@ -416,7 +403,7 @@ sub delete_details {
   local $FS::UID::AutoCommit = 0;
   my $dbh = dbh;
 
-  foreach my $detail ( qsearch('quotation_pkg_detail',{ 'billpkgnum' => $self->quotationpkgnum }) ) {
+  foreach my $detail ( qsearch('quotation_pkg_detail',{ 'quotationpkgnum' => $self->quotationpkgnum }) ) {
     my $error = $detail->delete;
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
@@ -452,8 +439,8 @@ sub set_details {
 
   foreach my $detail ( @details ) {
     my $quotation_pkg_detail = new FS::quotation_pkg_detail {
-      'billpkgnum' => $self->quotationpkgnum,
-      'detail'     => $detail,
+      'quotationpkgnum' => $self->quotationpkgnum,
+      'detail' => $detail,
     };
     $error = $quotation_pkg_detail->insert;
     if ( $error ) {
@@ -467,6 +454,10 @@ sub set_details {
 
 }
 
+sub details_header {
+  return ();
+}
+
 =item cust_bill_pkg_display [ type => TYPE ]
 
 =cut
diff --git a/FS/FS/quotation_pkg_detail.pm b/FS/FS/quotation_pkg_detail.pm
index be3d815..ce13589 100644
--- a/FS/FS/quotation_pkg_detail.pm
+++ b/FS/FS/quotation_pkg_detail.pm
@@ -34,10 +34,9 @@ currently supported:
 
 primary key
 
-=item billpkgnum
+=item quotationpkgnum
 
-named thusly for quick compatability with L<FS::TemplateItem_Mixin>,
-actually the quotationpkgnum for the relevant L<FS::quotation_pkg>
+for the relevant L<FS::quotation_pkg>
 
 =item detail
 
@@ -108,7 +107,7 @@ sub check {
 
   my $error = 
     $self->ut_numbern('detailnum')
-    || $self->ut_foreign_key('billpkgnum', 'quotation_pkg', 'quotationpkgnum')
+    || $self->ut_foreign_key('quotationpkgnum', 'quotation_pkg', 'quotationpkgnum')
     || $self->ut_text('detail')
   ;
   return $error if $error;
diff --git a/httemplate/edit/quotation_pkg_detail.html b/httemplate/edit/quotation_pkg_detail.html
index b8f589a..80a9044 100644
--- a/httemplate/edit/quotation_pkg_detail.html
+++ b/httemplate/edit/quotation_pkg_detail.html
@@ -21,15 +21,11 @@
     <TD BGCOLOR="#ffffff"><% $part_pkg->comment |h %></TD>
   </TR>
 
-  <TR>
-    <TD COLSPAN=2>Detail: </TD>
-  </TR>
-
 % my $row = 0;
 % for ( @details ) { 
 
     <TR>
-      <TD></TD>
+      <TD ALIGN="right"><% $row ? '' : 'Detail' %></TD>
       <TD>
         <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_ |h %>" rownum="<% $row++ %>" onkeyup="possiblyAddRow" onchange="possiblyAddrow">
       </TD>
@@ -63,6 +59,10 @@
     var row = document.createElement('TR');
 
     var empty_cell = document.createElement('TD');
+    if (!rownum) {
+      empty_cell.innerHTML = 'Detail:'
+      empty_cell.style.textAlign = 'right';
+    }
     row.appendChild(empty_cell);
 
     var detail_cell = document.createElement('TD');

commit 7a7776bc564aa2fb03c7c217d9e6f5fd39d8eb5f
Author: Jonathan Prykop <jonathan at freeside.biz>
Date:   Thu Oct 15 21:07:34 2015 -0500

    RT#34960: Quotations [v3 merge]

diff --git a/FS/FS/Schema.pm b/FS/FS/Schema.pm
index b852112..429bc55 100644
--- a/FS/FS/Schema.pm
+++ b/FS/FS/Schema.pm
@@ -1383,6 +1383,24 @@ sub tables_hashref {
       'index' => [ ['pkgpart'], ],
     },
 
+    'quotation_pkg_detail' => {
+      'columns' => [
+        'detailnum', 'serial', '', '', '', '', 
+        'billpkgnum', 'int', '', '', '', '',        # actually links to quotationpkgnum
+        'format',  'char', 'NULL', 1, '', '',       # not used for anything
+        'detail',  'varchar', '', 255, '', '',
+      ],
+      'primary_key'  => 'detailnum',
+      'unique'       => [],
+      'index'        => [ [ 'billpkgnum' ] ],
+      'foreign_keys' => [
+                          { columns    => [ 'billpkgnum' ],
+                            table      => 'quotation_pkg',
+                            references => [ 'quotationpkgnum' ],
+                          },
+                        ],
+    },
+
     'quotation_pkg_discount' => {
       'columns' => [
         'quotationpkgdiscountnum', 'serial', '', '', '', '',
diff --git a/FS/FS/quotation_pkg.pm b/FS/FS/quotation_pkg.pm
index d5c02e1..65e6b62 100644
--- a/FS/FS/quotation_pkg.pm
+++ b/FS/FS/quotation_pkg.pm
@@ -7,6 +7,7 @@ use FS::part_pkg;
 use FS::cust_location;
 use FS::quotation;
 use FS::quotation_pkg_discount; #so its loaded when TemplateItem_Mixin needs it
+use FS::quotation_pkg_detail;
 use List::Util qw(sum);
 
 =head1 NAME
@@ -98,6 +99,20 @@ sub display_table         { 'quotation_pkg'; }
 
 sub discount_table        { 'quotation_pkg_discount'; }
 
+# detail table uses non-quotation fieldnames, see billpkgnum below
+sub detail_table          { 'quotation_pkg_detail'; }
+
+=item billpkgnum
+
+Sets/returns quotationpkgnum, for ease of integration with TemplateItem_Mixin::details
+
+=cut
+
+sub billpkgnum {
+  my $self = shift;
+  $self->quotationpkgnum(@_);
+}
+
 =item insert
 
 Adds this record to the database.  If there is an error, returns the error,
@@ -147,15 +162,21 @@ sub delete {
   my $oldAutoCommit = $FS::UID::AutoCommit;
   local $FS::UID::AutoCommit = 0;
 
+  my $error = $self->delete_details;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
   foreach ($self->quotation_pkg_discount, $self->quotation_pkg_tax) {
-    my $error = $_->delete;
+    $error = $_->delete;
     if ( $error ) {
       $dbh->rollback if $oldAutoCommit;
       return $error . ' (deleting discount)';
     }
   }
 
-  my $error = $self->SUPER::delete;
+  $error = $self->SUPER::delete;
   if ( $error ) {
     $dbh->rollback if $oldAutoCommit;
     return $error;
@@ -382,6 +403,70 @@ sub recur {
     * ($self->quantity || 1);
 }
 
+=item delete_details
+
+Deletes all quotation_pkgs_details associated with this pkg (see L<FS::quotation_pkg_detail>).
+
+=cut
+
+sub delete_details {
+  my $self = shift;
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  foreach my $detail ( qsearch('quotation_pkg_detail',{ 'billpkgnum' => $self->quotationpkgnum }) ) {
+    my $error = $detail->delete;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "error removing old detail: $error";
+    }
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
+=item set_details [ DETAIL, DETAIL, ... ]
+
+Sets quotation details for this package (see L<FS::quotation_pkg_detail>).
+
+If there is an error, returns the error, otherwise returns false.
+
+=cut
+
+sub set_details {
+  my( $self, @details ) = @_;
+
+  my $oldAutoCommit = $FS::UID::AutoCommit;
+  local $FS::UID::AutoCommit = 0;
+  my $dbh = dbh;
+
+  my $error = $self->delete_details;
+  if ( $error ) {
+    $dbh->rollback if $oldAutoCommit;
+    return $error;
+  }
+
+  foreach my $detail ( @details ) {
+    my $quotation_pkg_detail = new FS::quotation_pkg_detail {
+      'billpkgnum' => $self->quotationpkgnum,
+      'detail'     => $detail,
+    };
+    $error = $quotation_pkg_detail->insert;
+    if ( $error ) {
+      $dbh->rollback if $oldAutoCommit;
+      return "error adding new detail: $error";
+    }
+  }
+
+  $dbh->commit or die $dbh->errstr if $oldAutoCommit;
+  '';
+
+}
+
 =item cust_bill_pkg_display [ type => TYPE ]
 
 =cut
diff --git a/FS/FS/quotation_pkg_detail.pm b/FS/FS/quotation_pkg_detail.pm
new file mode 100644
index 0000000..be3d815
--- /dev/null
+++ b/FS/FS/quotation_pkg_detail.pm
@@ -0,0 +1,130 @@
+package FS::quotation_pkg_detail;
+use base qw(FS::Record);
+
+use strict;
+
+=head1 NAME
+
+FS::quotation_pkg_detail - Object methods for quotation_pkg_detail records
+
+=head1 SYNOPSIS
+
+  use FS::quotation_pkg_detail;
+
+  $record = new FS::quotation_pkg_detail \%hash;
+  $record = new FS::quotation_pkg_detail { 'column' => 'value' };
+
+  $error = $record->insert;
+
+  $error = $new_record->replace($old_record);
+
+  $error = $record->delete;
+
+  $error = $record->check;
+
+=head1 DESCRIPTION
+
+An FS::quotation_pkg_detail object represents additional customer package details
+for a quotation.  FS::quotation_pkg_detail inherits from FS::Record.  The following fields are
+currently supported:
+
+=over 4
+
+=item detailnum
+
+primary key
+
+=item billpkgnum
+
+named thusly for quick compatability with L<FS::TemplateItem_Mixin>,
+actually the quotationpkgnum for the relevant L<FS::quotation_pkg>
+
+=item detail
+
+detail text
+
+=cut
+
+# 'format' field isn't used, there for TemplateItem_Mixin
+
+=back
+
+=head1 METHODS
+
+=over 4
+
+=item new HASHREF
+
+Creates a new record.  To add the record to the database, see L<"insert">.
+
+Note that this stores the hash reference, not a distinct copy of the hash it
+points to.  You can ask the object for a copy with the I<hash> method.
+
+=cut
+
+# the new method can be inherited from FS::Record, if a table method is defined
+
+sub table { 'quotation_pkg_detail'; }
+
+=item insert
+
+Adds this record to the database.  If there is an error, returns the error,
+otherwise returns false.
+
+=cut
+
+# the insert method can be inherited from FS::Record
+
+=item delete
+
+Delete this record from the database.
+
+=cut
+
+# the delete method can be inherited from FS::Record
+
+=item replace OLD_RECORD
+
+Replaces the OLD_RECORD with this one in the database.  If there is an error,
+returns the error, otherwise returns false.
+
+=cut
+
+# the replace method can be inherited from FS::Record
+
+=item check
+
+Checks all fields to make sure this is a valid record.  If there is
+an error, returns the error, otherwise returns false.  Called by the insert
+and replace methods.
+
+=cut
+
+# the check method should currently be supplied - FS::Record contains some
+# data checking routines
+
+sub check {
+  my $self = shift;
+
+  my $error = 
+    $self->ut_numbern('detailnum')
+    || $self->ut_foreign_key('billpkgnum', 'quotation_pkg', 'quotationpkgnum')
+    || $self->ut_text('detail')
+  ;
+  return $error if $error;
+
+  $self->SUPER::check;
+}
+
+=back
+
+=head1 BUGS
+
+=head1 SEE ALSO
+
+L<FS::quotation_pkg>, L<FS::Record>
+
+=cut
+
+1;
+
diff --git a/httemplate/edit/cust_pkg_detail.html b/httemplate/edit/cust_pkg_detail.html
index 5e10706..b1e60da 100644
--- a/httemplate/edit/cust_pkg_detail.html
+++ b/httemplate/edit/cust_pkg_detail.html
@@ -46,7 +46,7 @@
     <TR>
       <TD></TD>
       <TD>
-        <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_->detail |h %>" rownum="<% $row++ %>" onkeyup = "possiblyAddRow;" >
+        <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_->detail |h %>" rownum="<% $row++ %>" onkeyup="possiblyAddRow" onchange="possiblyAddRow" >
       </TD>
     </TR>
 
@@ -88,6 +88,7 @@
       detail_input.setAttribute('maxLength', 65);
       detail_input.setAttribute('rownum',   rownum);
       detail_input.onkeyup = possiblyAddRow;
+      detail_input.onchange = possiblyAddRow;
       detail_cell.appendChild(detail_input);
 
     row.appendChild(detail_cell);
diff --git a/httemplate/edit/process/quotation_pkg_detail.html b/httemplate/edit/process/quotation_pkg_detail.html
new file mode 100644
index 0000000..2fc4202
--- /dev/null
+++ b/httemplate/edit/process/quotation_pkg_detail.html
@@ -0,0 +1,45 @@
+% if ( $error ) {
+<% header('Error') %>
+<FONT COLOR="#ff0000"><B><% $error |h %></B></FONT><BR><BR>
+<CENTER><INPUT TYPE="BUTTON" VALUE="OK" onClick="parent.cClick()"></CENTER>
+</BODY></HTML>
+% } else {
+<% header($action) %>
+  <SCRIPT TYPE="text/javascript">
+    window.top.location.reload();
+  </SCRIPT>
+  </BODY></HTML>
+% }
+<%init>
+
+my $curuser = $FS::CurrentUser::CurrentUser;
+
+die "access denied"
+  unless $curuser->access_right('Generate quotation');
+
+$cgi->param('pkgnum') =~ /^(\d+)$/ or die 'illegal pkgnum';
+my $pkgnum = $1;
+
+my $quotation_pkg = qsearchs({
+  'table'     => 'quotation_pkg',
+  'addl_from' => 'LEFT JOIN quotation USING ( quotationnum )'.
+                 'LEFT JOIN cust_main USING ( custnum )',
+  'hashref'   => { 'quotationpkgnum' => $pkgnum },
+  'extra_sql' => ' AND '. $curuser->agentnums_sql,
+});
+
+my @orig_details = $quotation_pkg->details();
+
+my $action = 'Quotation details'.
+             ( scalar(@orig_details) ? ' changed ' : ' added ' );
+
+my $param = $cgi->Vars;
+my @details = ();
+for ( my $row = 0; exists($param->{"detail$row"}); $row++ ) {
+  push @details, $param->{"detail$row"}
+    if $param->{"detail$row"} =~ /\S/;
+}
+
+my $error = $quotation_pkg->set_details(@details);
+
+</%init>
diff --git a/httemplate/edit/cust_pkg_detail.html b/httemplate/edit/quotation_pkg_detail.html
similarity index 61%
copy from httemplate/edit/cust_pkg_detail.html
copy to httemplate/edit/quotation_pkg_detail.html
index 5e10706..b8f589a 100644
--- a/httemplate/edit/cust_pkg_detail.html
+++ b/httemplate/edit/quotation_pkg_detail.html
@@ -5,22 +5,12 @@
 
 %# <% include('/elements/error.html') %>
 
-<FORM ACTION="process/cust_pkg_detail.html" NAME="DetailForm" ID="DetailForm" METHOD="POST">
+<FORM ACTION="process/quotation_pkg_detail.html" NAME="DetailForm" ID="DetailForm" METHOD="POST">
 
 <INPUT TYPE="hidden" NAME="pkgnum" VALUE="<% $pkgnum %>">
-<INPUT TYPE="hidden" NAME="detailtype" VALUE="<% $detailtype %>">
 
 <TABLE ID="DetailTable" BGCOLOR="#cccccc" BORDER=0 CELLSPACING=1 STYLE="background-color: #cccccc">
 
-% if ( $curuser->option('show_pkgnum') ) {
-
-    <TR>
-      <TD ALIGN="right">Package #</TD>
-      <TD BGCOLOR="#ffffff"><% $pkgnum %></TD>
-    </TR>
-
-% }
-
   <TR>
     <TD ALIGN="right">Package</TD>
     <TD BGCOLOR="#ffffff"><% $part_pkg->pkg %></TD>
@@ -32,12 +22,7 @@
   </TR>
 
   <TR>
-    <TD ALIGN="right">Status</TD>
-    <TD BGCOLOR="#ffffff"><FONT COLOR="#<% $cust_pkg->statuscolor %>"><B><% ucfirst($cust_pkg->status) %></B></FONT></TD>
-  </TR>
-
-  <TR>
-    <TD COLSPAN=2><% ucfirst($name{$detailtype}) %>: </TD>
+    <TD COLSPAN=2>Detail: </TD>
   </TR>
 
 % my $row = 0;
@@ -46,7 +31,7 @@
     <TR>
       <TD></TD>
       <TD>
-        <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_->detail |h %>" rownum="<% $row++ %>" onkeyup = "possiblyAddRow;" >
+        <INPUT TYPE="text" NAME="detail<% $row %>" SIZE="60" MAXLENGTH="65" VALUE="<% $_ |h %>" rownum="<% $row++ %>" onkeyup="possiblyAddRow" onchange="possiblyAddrow">
       </TD>
     </TR>
 
@@ -60,6 +45,7 @@
 </FORM>
 
 <SCRIPT TYPE="text/javascript">
+% # abject false laziness with edit/cust_pkg_detail.html
 
   var rownum = <% $row %>;
 
@@ -88,6 +74,7 @@
       detail_input.setAttribute('maxLength', 65);
       detail_input.setAttribute('rownum',   rownum);
       detail_input.onkeyup = possiblyAddRow;
+      detail_input.onchange = possiblyAddRow;
       detail_cell.appendChild(detail_input);
 
     row.appendChild(detail_cell);
@@ -104,39 +91,26 @@
 </HTML>
 <%init>
 
-my %access_right = (
-  'I' => 'Edit customer package invoice details', 
-  'C' => 'Edit customer package comments',
-);
-
-my %name = (
-  'I' => 'invoice details',
-  'C' => 'package comments',
-);
-
 my $curuser = $FS::CurrentUser::CurrentUser;
 
-$cgi->param('detailtype') =~ /^(\w)$/ or die 'illegal detailtype';
-my $detailtype = $1;
-
-my $right = $access_right{$detailtype};
 die "access denied"
-  unless $curuser->access_right($right);
+  unless $curuser->access_right('Generate quotation');
 
 $cgi->param('pkgnum') =~ /^(\d+)$/ or die 'illegal pkgnum';
 my $pkgnum = $1;
 
-my $cust_pkg = qsearchs({
-  'table'     => 'cust_pkg',
-  'addl_from' => 'LEFT JOIN cust_main USING ( custnum )',
-  'hashref'   => { 'pkgnum' => $pkgnum },
+my $quotation_pkg = qsearchs({
+  'table'     => 'quotation_pkg',
+  'addl_from' => 'LEFT JOIN quotation USING ( quotationnum )'.
+                 'LEFT JOIN cust_main USING ( custnum )',
+  'hashref'   => { 'quotationpkgnum' => $pkgnum },
   'extra_sql' => ' AND '. $curuser->agentnums_sql,
 });
 
-my $part_pkg = $cust_pkg->part_pkg;
+my $part_pkg = $quotation_pkg->part_pkg;
 
-my @details = $cust_pkg->cust_pkg_detail($detailtype);
+my @details = $quotation_pkg->details;
 
-my $title = ( scalar(@details) ? 'Edit ' : 'Add ' ). $name{$detailtype};
+my $title = ( scalar(@details) ? 'Edit ' : 'Add ' ). 'Quotation Details';
 
 </%init>
diff --git a/httemplate/elements/popup_link.html b/httemplate/elements/popup_link.html
index e5f8c61..841c084 100644
--- a/httemplate/elements/popup_link.html
+++ b/httemplate/elements/popup_link.html
@@ -18,17 +18,20 @@ Example:
     'height'         => 336,
     'color'          => '#ff0000',
     'closetext'      => 'Go Away',      # the value '' removes the link
+    'title'          => 'Hover Text',
 
     #uncommon opt
     'aname'          => "target", # link NAME= value, useful for #targets
     'target'         => '_parent',
     'style'          => 'css-attribute:value',
+    'html_label'     => '<IMG SRC="something.png">',  # overrides label
   } )
 
 </%doc>
 % if ($params->{'action'} && $label) {
 <A HREF="javascript:void(0);"
    onClick="<% $onclick |n %>"
+   <% $params->{'title'}  ? 'TITLE="' . $params->{'title'}.  '"' : '' |n %>
    <% $params->{'aname'}  ? 'NAME="'.   $params->{'aname'}.  '"' : '' |n %>
    <% $params->{'target'} ? 'TARGET="'. $params->{'target'}. '"' : '' |n %>
    <% $params->{'style'}  ? 'STYLE="'.  $params->{'style'}.  '"' : '' |n %>
@@ -47,6 +50,7 @@ if (ref($_[0]) eq 'HASH') {
 
 my $label = $params->{'label'};
 $label =~ s/ / /g;
+$label = $params->{'html_label'} || $label;
 my $onclick = include('/elements/popup_link_onclick.html', $params);
 
 </%init>
diff --git a/httemplate/images/Actions-document-edit-icon.png b/httemplate/images/Actions-document-edit-icon.png
new file mode 100644
index 0000000..8bfc329
Binary files /dev/null and b/httemplate/images/Actions-document-edit-icon.png differ
diff --git a/httemplate/view/quotation.html b/httemplate/view/quotation.html
index bd998bb..265ea07 100755
--- a/httemplate/view/quotation.html
+++ b/httemplate/view/quotation.html
@@ -88,6 +88,8 @@ my $curuser = $FS::CurrentUser::CurrentUser;
 #die "access denied"
 #  unless $curuser->access_right('View quotations');
 
+my $can_generate_quotation = $curuser->access_right('Generate quotation');
+
 my $quotationnum;
 my($query) = $cgi->keywords;
 if ( $query =~ /^(\d+)$/ ) {
@@ -114,11 +116,23 @@ my $link = "quotationnum=$quotationnum";
 #$link .= ';notice_name='. $notice_name if $notice_name;
 
 my $preref_callback = sub {
-  areyousure_link("${p}misc/delete-quotation_pkg.html?". shift->quotationpkgnum,
+  my $quotation_pkg = shift;
+  $can_generate_quotation ?
+  areyousure_link("${p}misc/delete-quotation_pkg.html?". $quotation_pkg->quotationpkgnum,
                   emt('Are you sure you want to remove this package from the quotation?'),
                   emt('Remove this package'), #tooltip
                   qq(<img src="${p}images/cross.png">), #link
-                 );
+                 ) .
+  include('/elements/popup_link.html',
+    action      => "${p}edit/quotation_pkg_detail.html?pkgnum=" .
+                   $quotation_pkg->quotationpkgnum,
+    html_label  => qq(<IMG SRC="${p}images/Actions-document-edit-icon.png">),
+    title       => emt('Edit quotation details'),
+    actionlabel => emt('Edit quotation details'),
+    color       => '#333399',
+    width       => 763,
+  )
+  : '';
 };
 
 sub areyousure_link {

-----------------------------------------------------------------------

Summary of changes:
 FS/FS/Schema.pm                                    |   18 +++++
 FS/FS/TemplateItem_Mixin.pm                        |    7 +-
 FS/FS/Template_Mixin.pm                            |    4 +
 FS/FS/quotation_pkg.pm                             |   80 +++++++++++++++++++-
 ...lientapi_session.pm => quotation_pkg_detail.pm} |   44 ++++++-----
 httemplate/docs/license.html                       |    6 ++
 httemplate/edit/cust_pkg_detail.html               |    3 +-
 ...t_pkg_detail.html => quotation_pkg_detail.html} |   32 +++-----
 ...t_pkg_detail.html => quotation_pkg_detail.html} |   62 +++++----------
 httemplate/elements/popup_link.html                |    4 +
 httemplate/images/Actions-document-edit-icon.png   |  Bin 0 -> 733 bytes
 httemplate/view/quotation.html                     |   18 ++++-
 12 files changed, 185 insertions(+), 93 deletions(-)
 copy FS/FS/{clientapi_session.pm => quotation_pkg_detail.pm} (64%)
 copy httemplate/edit/process/{cust_pkg_detail.html => quotation_pkg_detail.html} (53%)
 copy httemplate/edit/{cust_pkg_detail.html => quotation_pkg_detail.html} (60%)
 create mode 100644 httemplate/images/Actions-document-edit-icon.png




More information about the freeside-commits mailing list