[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SF.net SVN: ledger-smb: [1557] trunk



Revision: 1557
          http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=1557&view=rev
Author:   aurynn_cmd
Date:     2007-09-10 16:02:09 -0700 (Mon, 10 Sep 2007)

Log Message:
-----------
Creation of next-gen admin.pl, admin.pm, and admin.sql systems.

Admin.pm defines the new controller
admin.pl is the direct view-backing software.

POD is not completed, will be provided shortly.

Full UI templates provided for the Reconciliation, Vendor, Customer, and Employee as well. 
UI/  is being delineated by subdirectories for Admin, Vendor, Customer and Employee, to date.

Minor whitespace cleanup.

Modified Paths:
--------------
    trunk/LedgerSMB/Session/DB.pm
    trunk/bin/admin.pl
    trunk/import_members.pl

Added Paths:
-----------
    trunk/LedgerSMB/Admin.pm
    trunk/UI/Admin/
    trunk/UI/Admin/delete_group.html
    trunk/UI/Admin/delete_user.html
    trunk/UI/Admin/edit_group.html
    trunk/UI/Admin/edit_user.html
    trunk/UI/Admin/login.html
    trunk/UI/Admin/main.html
    trunk/UI/Customer/
    trunk/UI/Customer/customer.html
    trunk/UI/Reconciliation/
    trunk/UI/Reconciliation/approved.html
    trunk/UI/Reconciliation/correct.html
    trunk/UI/Reconciliation/corrections.html
    trunk/UI/Reconciliation/report.html
    trunk/UI/Vendor/
    trunk/UI/Vendor/vendor.html
    trunk/scripts/admin.pl
    trunk/sql/modules/admin.sql

Added: trunk/LedgerSMB/Admin.pm
===================================================================
--- trunk/LedgerSMB/Admin.pm	                        (rev 0)
+++ trunk/LedgerSMB/Admin.pm	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,179 @@
+package LedgerSMB::DBObject::Admin;
+
+use base LedgerSMB::DBObject;
+
+use LedgerSMB::DBObject::Location;
+use LedgerSMB::DBObject::Employee;
+use LedgerSMB::DBObject::Contact;
+
+sub save_user {
+    
+    my $self = shift @_;
+    
+    my $entity_id = shift @{ $self->exec_method( procname => "save_user" ) };
+    $self->merge($entity_id);
+    
+    my $employee = LedgerSMB::DBObject::Employee->new(base=>$self, copy=>'list',
+        merge=>[
+            'salutation',
+            'first_name',
+            'last_name',
+            'employeenumber',
+        ]    
+    );
+    
+    $employee->{entity_id} = $entity_id->{id};    
+    $employee->save_employee();
+        
+    my $loc = LedgerSMB::DBObject::Location->new(base=>$self, copy=>'list', 
+        merge=>[
+            'address1',
+            'address2',
+            'city',
+            'state',
+            'zipcode',
+            'country',
+            'companyname',            
+        ]
+    );
+    $loc->save_location();
+    $loc->join_to_person(person=>$employee);
+    
+    
+    my $contact = LedgerSMB::DBObject::Contact->new(base=>$self, copy=>'list', 
+        merge=>[
+            'workphone',
+            'homephone',
+            'email',
+        ]
+    );
+    
+    $contact->save_homephone(person=>$employee);
+    $contact->save_workphone(person=>$employee);
+    $contact->save_email(person=>$employee);
+    
+    my $roles = $self->exec_method( procname => "all_roles" );
+    my $user_roles = $self->exec_method(procname => "get_user_roles", args=>[ $self->{ modifying_user } ] );
+    
+    my %active_roles;
+    for my $role (@{$user_roles}) {
+       
+       # These are our user's roles.
+        
+       $active_roles{$role} = 1;
+    }
+    
+    my $status;
+    
+    for my $role ( @{ $roles } ) {
+        
+        # These roles are were ALL checked on the page, so they're the active ones.
+        
+        if ($active_roles{$role} && $self->{incoming_roles}->{$role}) {
+            
+            # do nothing.
+        }
+        elsif ($active_roles{$role} && !($self->{incoming_roles}->{$role} )) {
+            
+            # do remove function
+            $status = $self->exec_method(procname => "remove_user_from_role",
+                args=>[ $self->{ modifying_user }, $role ] 
+        }
+        elsif ($self->{incoming_roles}->{$role} and !($active_roles{$role} )) {
+            
+            # do add function
+            $status = $self->exec_method(procname => "add_user_to_role",
+               args=>[ $self->{ modifying_user }, $role ] 
+            );
+        }         
+    }
+}
+
+sub save_group {
+    
+     my $self = shift @_;
+     
+     my $existant = shift @{ $self->exec_method (procname=> "is_group", args=>[$self->{modifying_group}]) };
+     
+     my $group = shift @{ $self->exec_method (procname=> "save_group") };
+     
+     # first we grab all roles
+     
+     my $roles = $self->exec_method( procname => "all_roles" );
+     my $user_roles = $self->exec_method(procname => "get_user_roles", 
+        args=>[ $self->{ group_name } ] 
+    );
+
+     my %active_roles;
+     for my $role (@{$user_roles}) {
+
+        # These are our user's roles.
+
+        $active_roles{$role} = 1;
+     }
+
+     my $status;
+
+     for my $role ( @{ $roles } ) {
+
+         # These roles are were ALL checked on the page, so they're the active ones.
+
+         if ($active_roles{$role} && $self->{incoming_roles}->{$role}) {
+
+             # we don't need to do anything.
+         }
+         elsif ($active_roles{$role} && !($self->{incoming_roles}->{$role} )) {
+
+             # do remove function
+             $status = $self->exec_method(
+                 procname => "remove_group_from_role",
+                 args=>[ $self->{ modifying_user }, $role ] 
+             );
+         }
+         elsif ($self->{incoming_roles}->{$role} and !($active_roles{$role} )) {
+
+             # do add function
+             $status = $self->exec_method(
+                 procname => "add_group_to_role",
+                 args=>[ $self->{ modifying_user }, $role ] 
+             );
+         }         
+     }     
+}
+
+
+sub delete_user {
+    
+    my $self = shift @_;
+    
+    my $status = shift @{ $self->exec_method(procname=>'delete_user', args=>[$self->{modifying_user}]) };
+    
+    if ($status) {
+        
+        return 1;
+    } else {
+        
+        my $error = LedgerSMB::Error->new("Delete user failed.");
+        $error->set_status($status);
+        return $error;
+    }
+}
+
+sub delete_group {
+    
+    my $self = shift @_;
+    
+    my $status = shift @{ $self->exec_method(procname=>'delete_group', args=>[$self->{groupname}])};
+    
+    if ($status) {
+        
+        return 1;
+    } else {
+        
+        my $error = LedgerSMB::Error->new("Delete group failed.");
+        $error->set_status($status);
+        return $error;
+    }
+}
+
+1;
\ No newline at end of file

Modified: trunk/LedgerSMB/Session/DB.pm
===================================================================
--- trunk/LedgerSMB/Session/DB.pm	2007-09-10 21:16:04 UTC (rev 1556)
+++ trunk/LedgerSMB/Session/DB.pm	2007-09-10 23:02:09 UTC (rev 1557)
@@ -41,17 +41,17 @@
 
     my $checkQuery = $dbh->prepare(
         "SELECT u.username, s.transaction_id 
-									  FROM session as s, users as u 
-									 WHERE s.session_id = ? 
-									   AND s.users_id = u.id
-									   AND s.last_used > now() - ?::interval"
+                                      FROM session as s, users as u 
+                                     WHERE s.session_id = ? 
+                                       AND s.users_id = u.id
+                                       AND s.last_used > now() - ?::interval"
     );
 
     my $updateAge = $dbh->prepare(
         "UPDATE session 
-									  SET last_used = now(),
-										  transaction_id = ?
-									WHERE session_id = ?;"
+                                      SET last_used = now(),
+                                          transaction_id = ?
+                                    WHERE session_id = ?;"
     );
 
     #must be an integer
@@ -150,9 +150,9 @@
     # TODO Change this to use %myconfig
     my $deleteExisting = $dbh->prepare(
         "DELETE 
-		   FROM session
-		  WHERE session.users_id = (select id from users where username = ?) 
-		        AND age(last_used) > ?::interval"
+           FROM session
+          WHERE session.users_id = (select id from users where username = ?) 
+                AND age(last_used) > ?::interval"
     );
 
     my $seedRandom = $dbh->prepare("SELECT setseed(?);");
@@ -162,9 +162,9 @@
 
     my $createNew = $dbh->prepare(
         "INSERT INTO session (session_id, users_id, token, transaction_id) 
-										VALUES(?, (SELECT id
-													 FROM users
-													WHERE username = ?), ?, ?);"
+                                        VALUES(?, (SELECT id
+                                                     FROM users
+                                                    WHERE username = ?), ?, ?);"
     );
 
 # this is assuming that $form->{login} is safe, which might be a bad assumption
@@ -217,9 +217,9 @@
     my $dbh = ${LedgerSMB::Sysconfig::GLOBALDBH};
 
     my $deleteExisting = $dbh->prepare( "
-		DELETE FROM session 
-		       WHERE users_id = (select id from users where username = ?)
-	" );
+        DELETE FROM session 
+               WHERE users_id = (select id from users where username = ?)
+    " );
 
     $deleteExisting->execute($login)
       || $form->dberror(
@@ -243,9 +243,9 @@
 
     my $fetchPassword = $dbh->prepare(
         "SELECT u.username, uc.password, uc.crypted_password
-										 FROM users as u, users_conf as uc
-										WHERE u.username = ?
-										  AND u.id = uc.id;"
+           FROM users as u, users_conf as uc
+          WHERE u.username = ?
+            AND u.id = uc.id;"
     );
 
     $fetchPassword->execute($username)
@@ -269,11 +269,11 @@
             #password was good, convert to md5 password and null crypted
             my $updatePassword = $dbh->prepare(
                 "UPDATE users_conf
-												   SET password = md5(?),
-													   crypted_password = null
-												  FROM users
-												 WHERE users_conf.id = users.id
-												   AND users.username = ?;"
+                                                   SET password = md5(?),
+                                                       crypted_password = null
+                                                  FROM users
+                                                 WHERE users_conf.id = users.id
+                                                   AND users.username = ?;"
             );
 
             $updatePassword->execute( $password, $username )

Added: trunk/UI/Admin/delete_group.html
===================================================================

Added: trunk/UI/Admin/delete_user.html
===================================================================

Added: trunk/UI/Admin/edit_group.html
===================================================================
--- trunk/UI/Admin/edit_group.html	                        (rev 0)
+++ trunk/UI/Admin/edit_group.html	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,13 @@
+<?lsmb import base.html?>
+
+<?lsmb if user.username ?>
+
+    <center><b>Edit User</b></center>
+
+<?lsmb else ?>
+
+    <center><b>Create User</b></center>
+
+<?lsmb endif ?>
+
+<form name="submit_user" action="/admin.pl?"></form>
\ No newline at end of file

Added: trunk/UI/Admin/edit_user.html
===================================================================

Added: trunk/UI/Admin/login.html
===================================================================
--- trunk/UI/Admin/login.html	                        (rev 0)
+++ trunk/UI/Admin/login.html	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,11 @@
+<?lsmb include index.html ?>
+
+<?lsmb block 'main'?>
+
+    <div name="login" id="login">
+        
+        
+        
+    </div>
+
+<?lsmb end ?>
\ No newline at end of file

Added: trunk/UI/Admin/main.html
===================================================================
--- trunk/UI/Admin/main.html	                        (rev 0)
+++ trunk/UI/Admin/main.html	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,55 @@
+<?lsmb block main?>
+<div class="admin">
+    
+    <!-- first, a list of all active users -->
+    
+    <center>
+        <strong><font size="16"> Administration</font></strong>
+    </center>
+    
+    <?lsmb if message?>
+        <strong><font color="red"><?lsmb message?></font></strong>
+    <?lsmb end?>
+    <form name="userlist" method="POST" action="admin.pl">    
+    <table>
+        <tr>
+            <td></td>
+            <td>User ID</td>
+            <td>Username</td>
+            <td>Active</td>
+            <td>Date Added</td>
+        </tr>
+
+    <?lsmb FOREACH user = users.all ?>
+    
+        <tr>
+            <td></td>
+            <td>
+                <a href="/admin.pl?action=edit_user&amp;user=<?lsmb user.id?>">
+                    <?lsmb user.id?>
+                </a>
+            </td>
+            <td>
+                <?lsmb user.username?>
+            </td>
+            <td>
+                <?lsmb user.active?>
+            </td>
+            <td>
+                <?lsmb user.creation_date?>
+            </td>
+            
+        </tr>    
+    <?lsmb end?>
+    </table>
+    
+    <hr/>
+    <div class="buttons">
+        <button name="method" value="new_user">New User</button>
+        <button name="method" value="new_group">New Group</button>
+        <button name="method" value="delete_user">Delete User</button>
+        <button name="method" value="delete_group">Delete Group</button>
+    </div>    
+    </form>
+</div>
+<?end?>
\ No newline at end of file

Added: trunk/UI/Customer/customer.html
===================================================================
--- trunk/UI/Customer/customer.html	                        (rev 0)
+++ trunk/UI/Customer/customer.html	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,139 @@
+<div class="customer">
+    
+    <font size="17"><?lsmb customer.name?></font>
+    
+<form name="customer" method="POST" action="vendor.pl">
+        <table>
+        
+        <tr>
+            <td><b>Shipping Address</b></td>
+            
+            <td><b>Billing Address (if different)</p></td>
+            
+        </tr>
+        
+        <hr/>
+        
+        <?lsmb FOREACH entry = customer.ordered  ?>
+        <tr>
+            <td>
+                <label for="shipping_<?entry?>"><?entry?>:</label>
+                <input id="shipping_<?entry?>" type="textarea" name="shipping_<?entry?>" value="<? customer.entry ?>">
+            </td>
+            <td>
+                <input type="textarea" name="billing_<? entry ?>" value="<? customer.entry ?>">
+            </td>            
+        </tr>
+        <?lsmb end ?>
+        <tr>
+            <td>
+                <label for="startdate">Starting Date:</label>
+                    <input id="startdate" type="textarea" name="startdate" value="<? customer.startdate ?>">
+            </td>
+            <td>
+                <label for="enddate">End date:</label>
+                    <input id="enddate" type="textarea" name="startdate" value="<? customer.enddate ?>">
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <label for"creditlimit">Credit Limit:</label>
+                <input id="creditlimit" name="creditlimit" type="textarea" value="<?customer.creditlimit?>">
+            </td>
+            <td>
+                <label for="terms">Terms:</label>
+                <input id="terms" name="terms" type="textarea" value="<?customer.terms?>"> days
+            </td>
+            <td>
+                <label for="discount">Discount %:</label>
+                <input id="discount" name="discount" type="textarea" value="<?customer.discount?>">                
+            </td>
+        </tr>
+        <tr>
+            
+            <td>
+                <label for="taxnumber">Tax Number/SSN:</label>
+                <input id="taxnumber" name="taxnumber" type="textarea" value="<?customer.taxnumber?>">                
+            </td>
+            <td>
+                <label for"gifi_accno">Subcontract GFI:</label>
+                <input id="gifi_accno" name="gifi_accno" type="textarea" value="<?customer.gifi_accno?>">
+            </td>
+            <td>
+                <label for"sic_code">SIC Code:</label>
+                <input id="sic_code" name="sic_code" type="textarea" value="<?customer.sic_code?>">
+            </td>
+        </tr>
+        
+        <tr>
+            
+            <td></td>
+            <td>
+                <label for"bic">BIC:</label>
+                <input id="bic" name="bic" type="textarea" value="<?customer.bic?>">
+            </td>
+            <td>
+                <label for="iban">IBAN:</label>
+                <input id="iban" name="iban" type="textarea" value="<?customer.iban?>">
+            </td>
+        </tr>
+        
+        <tr>
+            <td>
+                <label for="notes">Notes:</label><br/>
+                <textarea name="notes" rows="3" cols="40" id="notes">
+                    <?customer.notes?>
+                </textarea>
+            </td>
+        </tr>
+
+        <tr>
+            <hr/>
+            <br/>
+            <td>
+                <button class="submit" type="submit" name="action" value="save" accesskey="S" title="Save [Alt-S]">Save</button>
+                </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="ap_transaction" 
+                        accesskey="A" 
+                        title="AP Transaction [Alt-A]">AP Transaction</button>
+                </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="customer_invoice" 
+                        accesskey="I" 
+                        title="customer Invoice [Alt-I]">customer Invoice</button>
+            </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="purchase_order" 
+                        accesskey="O" 
+                        title="Purchase Order [Alt-O]">Purchase Order</button>
+            </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="rfq" 
+                        accesskey="Q" 
+                        title="RFQ [Alt-Q]">RFQ</button>
+            </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="pricelist" 
+                        accesskey="P" 
+                        title="Pricelist [Alt-P]">Pricelist</button>
+            </td>
+        </tr>        
+    </table>
+    </form>
+</div>
\ No newline at end of file

Added: trunk/UI/Reconciliation/approved.html
===================================================================
--- trunk/UI/Reconciliation/approved.html	                        (rev 0)
+++ trunk/UI/Reconciliation/approved.html	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,28 @@
+<div>
+	<center>
+		Bank statement for <?lsmbaccount?> on <?lsmbdate?> has been approved!
+	</center>
+</div>
+
+<table border=0 style="opacity:50%;">
+	
+	<tr>
+		<td>Clear date</td>
+		<td>Transaction Type</td>
+		<td>Our Balance</td>
+		<td>Their Balance</td>
+		<td>Error Corrections</td>
+		<td>Error Code</td>
+	</tr>
+	
+	<?lsmb FOREACH row = records ?>
+		<tr>
+			<td><?lsmb row.clear_time ?></td>
+			<td><?lsmb row.transaction_type ?> </td>
+			<td><?lsmb row.our_balance ?></td>
+			<td><?lsmb row.their_balance?></td>
+			<td><?lsmb row.corrections  ?></td>
+			<td><?lsmb row.errorcode ?></td>
+		</tr>
+	<?lsmb END ?>
+</table>
\ No newline at end of file

Added: trunk/UI/Reconciliation/correct.html
===================================================================

Added: trunk/UI/Reconciliation/corrections.html
===================================================================
--- trunk/UI/Reconciliation/corrections.html	                        (rev 0)
+++ trunk/UI/Reconciliation/corrections.html	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,39 @@
+<table border=0>
+	<tr>
+		<td>Clear date</td>
+		<td>Transaction Type</td>
+		<td>Our Balance</td>
+		<td>Their Balance</td>
+	</tr>
+	<tr>
+		<td><?lsmb entry.clear_time ?></td>
+		<td><?lsmb entry.transaction_type ?> </td>
+		<td><?lsmb entry.our_balance ?></td>
+		<td><?lsmb entry.their_balance?></td>
+	</tr>
+</table>
+
+<?lsmb IF NOT corrections ?>
+Corrections:
+<table border=0>	
+	<?lsmb FOREACH row = corrections ?>
+	<tr>
+		<td>
+			<div>
+				<span><?lsmbrow.user?> at <?lsmbrow.insert_time?></span>
+				<div>
+					<?lsmbrow.reason?>
+				</div>
+			</div>
+		</td>
+	</tr>
+	<?lsmbEND?>
+	
+</table>
+<?lsmbELSE?>
+
+<div>
+	No corrections found.
+</div>
+
+<?lsmbEND?>
\ No newline at end of file

Added: trunk/UI/Reconciliation/report.html
===================================================================
--- trunk/UI/Reconciliation/report.html	                        (rev 0)
+++ trunk/UI/Reconciliation/report.html	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,52 @@
+<center>Reconciliation Report for [% total.account %] for the month of [%total.month%]</center>
+
+<center>
+	[%IF total.errorcode != 0 %]
+	<div style="color:blue; border-style:solid; border-width:1px; border-color: blue;">
+	[%ELSE%]
+	<div style="color:red; border-style:solid; border-width:1px; border-color: blue;">
+	[%END%]
+		Our Balance: total.our_balance | Bank Balance: total.their_balance
+	</div>
+</center>
+
+<center>Report generated by [% total.user %]</center>
+
+[% if recon.error %]
+<div style="border-color:red; border-width:1px; border-style:solid; margin:3px;" >
+	[% recon.error %]	
+</div>
+[%end%]
+
+<table border=0>
+	
+	<tr>
+		<td>Clear date</td>
+		<td>Transaction Type</td>
+		<td>Our Balance</td>
+		<td>Their Balance</td>
+		<td>Error Corrections</td>
+		<td>Error Code</td>
+	</tr>
+	
+	[% FOREACH row = records %]
+		[%IF row.errorcode != 0 %]
+		<tr style="background-color:red;">
+		[% ELSIF row.id = corrected %]
+		<tr style="background-color:yellow;">		
+		[%ELSE%]
+		<tr>
+		[%END%]
+			<td>[% row.clear_time %]</td>
+			<td>[% row.transaction_type %] </td>
+			<td>[% row.our_balance %]</td>
+			<td>[% row.their_balance%]</td>
+			<td>[% row.corrections  %]</td>
+			[% IF row.errorcode > 0 %]
+			<td>[% row.errorcode %] <a href="/reconciliation.pl?corrections&amp;entry=[%row.entry_id%]">View Corrections</a> </td>		
+			[%ELSE%]
+			<td>0</td>
+			[%END%]
+		</tr>
+	[% END %]
+</table>
\ No newline at end of file

Added: trunk/UI/Vendor/vendor.html
===================================================================
--- trunk/UI/Vendor/vendor.html	                        (rev 0)
+++ trunk/UI/Vendor/vendor.html	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,139 @@
+<div class="vendor">
+    
+    <font size="17"><?lsmb vendor.name?></font>
+    
+<form name="vendor">
+        <table>
+        
+        <tr>
+            <td><b>Shipping Address</b></td>
+            
+            <td><b>Billing Address (if different)</p></td>
+            
+        </tr>
+        
+        <hr/>
+        
+        <?lsmb FOREACH entry = vendor.ordered  ?>
+        <tr>
+            <td>
+                <label for="shipping_<?entry?>"><?entry?>:</label>
+                <input id="shipping_<?entry?>" type="textarea" name="shipping_<?entry?>" value="<? vendor.entry ?>">
+            </td>
+            <td>
+                <input type="textarea" name="billing_<? entry ?>" value="<? vendor.entry ?>">
+            </td>            
+        </tr>
+        <?lsmb end ?>
+        <tr>
+            <td>
+                <label for="startdate">Starting Date:</label>
+                    <input id="startdate" type="textarea" name="startdate" value="<? vendor.startdate ?>">
+            </td>
+            <td>
+                <label for="enddate">End date:</label>
+                    <input id="enddate" type="textarea" name="startdate" value="<? vendor.enddate ?>">
+            </td>
+        </tr>
+        <tr>
+            <td>
+                <label for"creditlimit">Credit Limit:</label>
+                <input id="creditlimit" name="creditlimit" type="textarea" value="<?vendor.creditlimit?>">
+            </td>
+            <td>
+                <label for="terms">Terms:</label>
+                <input id="terms" name="terms" type="textarea" value="<?vendor.terms?>"> days
+            </td>
+            <td>
+                <label for="discount">Discount %:</label>
+                <input id="discount" name="discount" type="textarea" value="<?vendor.discount?>">                
+            </td>
+        </tr>
+        <tr>
+            
+            <td>
+                <label for="taxnumber">Tax Number/SSN:</label>
+                <input id="taxnumber" name="taxnumber" type="textarea" value="<?vendor.taxnumber?>">                
+            </td>
+            <td>
+                <label for"gifi_accno">Subcontract GFI:</label>
+                <input id="gifi_accno" name="gifi_accno" type="textarea" value="<?vendor.gifi_accno?>">
+            </td>
+            <td>
+                <label for"sic_code">SIC Code:</label>
+                <input id="sic_code" name="sic_code" type="textarea" value="<?vendor.sic_code?>">
+            </td>
+        </tr>
+        
+        <tr>
+            
+            <td></td>
+            <td>
+                <label for"bic">BIC:</label>
+                <input id="bic" name="bic" type="textarea" value="<?vendor.bic?>">
+            </td>
+            <td>
+                <label for="iban">IBAN:</label>
+                <input id="iban" name="iban" type="textarea" value="<?vendor.iban?>">
+            </td>
+        </tr>
+        
+        <tr>
+            <td>
+                <label for="notes">Notes:</label><br/>
+                <textarea name="notes" rows="3" cols="40" id="notes">
+                    <?vendor.notes?>
+                </textarea>
+            </td>
+        </tr>
+
+        <tr>
+            <hr/>
+            <br/>
+            <td>
+                <button class="submit" type="submit" name="action" value="save" accesskey="S" title="Save [Alt-S]">Save</button>
+                </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="ap_transaction" 
+                        accesskey="A" 
+                        title="AP Transaction [Alt-A]">AP Transaction</button>
+                </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="vendor_invoice" 
+                        accesskey="I" 
+                        title="Vendor Invoice [Alt-I]">Vendor Invoice</button>
+            </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="purchase_order" 
+                        accesskey="O" 
+                        title="Purchase Order [Alt-O]">Purchase Order</button>
+            </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="rfq" 
+                        accesskey="Q" 
+                        title="RFQ [Alt-Q]">RFQ</button>
+            </td>
+            <td>
+                <button class="submit" 
+                        type="submit" 
+                        name="action" 
+                        value="pricelist" 
+                        accesskey="P" 
+                        title="Pricelist [Alt-P]">Pricelist</button>
+            </td>
+        </tr>        
+    </table>
+    </form>
+</div>
\ No newline at end of file

Modified: trunk/bin/admin.pl
===================================================================
--- trunk/bin/admin.pl	2007-09-10 21:16:04 UTC (rev 1556)
+++ trunk/bin/admin.pl	2007-09-10 23:02:09 UTC (rev 1557)
@@ -224,12 +224,12 @@
 
     my $fetchMembers = $dbh->selectall_arrayref(
         "SELECT uc.name, uc.company, uc.templates,
-														uc.dbuser, uc.dbdriver, uc.dbname, 
-														uc.dbhost, u.username
-												   FROM users as u, users_conf as uc
-												  WHERE u.id = uc.id	
-													AND u.id > 1
-											   ORDER BY u.username;", { Slice => {} }
+    			uc.dbuser, uc.dbdriver, uc.dbname, 
+    			uc.dbhost, u.username
+    	   FROM users as u, users_conf as uc
+    	  WHERE u.id = uc.id	
+    		AND u.id > 1
+       ORDER BY u.username;", { Slice => {} }
     );
 
     my @memberArray = ();

Modified: trunk/import_members.pl
===================================================================
--- trunk/import_members.pl	2007-09-10 21:16:04 UTC (rev 1556)
+++ trunk/import_members.pl	2007-09-10 23:02:09 UTC (rev 1557)
@@ -150,18 +150,18 @@
 
         my $userConfUpdate = $dbh->prepare(
             "UPDATE users_conf
-											   SET acs = ?, address = ?, businessnumber = ?,
-												   company = ?, countrycode = ?, currency = ?,
-												   dateformat = ?, dbdriver = ?,
-												   dbhost = ?, dbname = ?, dboptions = ?, 
-												   dbpasswd = ?, dbport = ?, dbuser = ?,
-												   email = ?, fax = ?, menuwidth = ?,
-												   name = ?, numberformat = ?, crypted_password = ?,
-												   print = ?, printer = ?, role = ?,
-												   sid = ?, signature = ?, stylesheet = ?,
-												   tel = ?, templates = ?, timeout = ?,
-												   vclimit = ?
-											 WHERE id = ?;"
+    		   SET acs = ?, address = ?, businessnumber = ?,
+    			   company = ?, countrycode = ?, currency = ?,
+    			   dateformat = ?, dbdriver = ?,
+    			   dbhost = ?, dbname = ?, dboptions = ?, 
+    			   dbpasswd = ?, dbport = ?, dbuser = ?,
+    			   email = ?, fax = ?, menuwidth = ?,
+    			   name = ?, numberformat = ?, crypted_password = ?,
+    			   print = ?, printer = ?, role = ?,
+    			   sid = ?, signature = ?, stylesheet = ?,
+    			   tel = ?, templates = ?, timeout = ?,
+    			   vclimit = ?
+    		 WHERE id = ?;"
         );
 
         $userConfUpdate->execute(
@@ -188,16 +188,16 @@
 
         my $userConfInsert = $dbh->prepare(
             "INSERT INTO users_conf(acs, address, businessnumber,
-																   company, countrycode, currency,
-																   dateformat, dbdriver,
-																   dbhost, dbname, dboptions, dbpasswd,
-																   dbport, dbuser, email, fax, menuwidth,
-																   name, numberformat, print, printer, role, 
-																   sid, signature, stylesheet, tel, templates, 
-																   timeout, vclimit, id, crypted_password)
-											VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 
-												   ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 
-												   ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
+    		 					   company, countrycode, currency,
+    		 					   dateformat, dbdriver,
+    		 					   dbhost, dbname, dboptions, dbpasswd,
+    		 					   dbport, dbuser, email, fax, menuwidth,
+    		 					   name, numberformat, print, printer, role, 
+    		 					   sid, signature, stylesheet, tel, templates, 
+    		 					   timeout, vclimit, id, crypted_password)
+    		 VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 
+    		 	   ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 
+    		 	   ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?);"
         );
 
         $userConfInsert->execute(

Added: trunk/scripts/admin.pl
===================================================================
--- trunk/scripts/admin.pl	                        (rev 0)
+++ trunk/scripts/admin.pl	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,155 @@
+package LedgerSMB::Scripts::Admin;
+
+use LedgerSMB::Template;
+use LedgerSMB::DBObject::Admin;
+
+sub new_user {
+    
+    # uses the same page as create_user, only pre-populated.
+    my ($class, $request) = @_;
+    my $admin = LedgerSMB::DBObject::Admin->new(base=>$request, copy=>'all');
+    
+    if ($request->type() == 'POST') {
+        
+        # do the save stuff
+        
+        my $entity = $admin->save_user();
+
+        
+        my $template = LedgerSMB::Template->new( user => $user, 
+    	template => 'admin/edit_user.html', language => $user->{language}, 
+            format => 'html');
+    
+        $template->render($entity);
+    } else {
+    
+        my $template = LedgerSMB::Template->new( user => $user, 
+    	template => 'admin/edit_user.html', language => $user->{language}, 
+            format => 'html');
+    
+        $template->render();
+    }
+}
+
+sub edit_user {
+    
+    # uses the same page as create_user, only pre-populated.
+    my ($class, $request) = @_;
+    my $admin = LedgerSMB::DBObject::Admin->new(base=>$request, copy=>'user_id');
+    
+    my $edited_user = $admin->get_entire_user();
+    my $all_roles = $admin->role_list();
+    
+    my $template = LedgerSMB::Template->new( user => $user, 
+	template => 'admin/edit_user.html', language => $user->{language}, 
+        format => 'html');
+    
+    $template->render($edited_user, $all_roles);
+}
+
+sub edit_group {
+    
+    my ($class, $request) = @_;
+    my $admin = LedgerSMB::DBObject::Admin->new(base=>$request, copy=>'all');
+    
+    my $all_roles = $admin->role_list();
+    my $group = $admin->get_group();
+    
+    my $template = LedgerSMB::Template->new( user => $user, 
+	template => 'admin/edit_group.html', language => $user->{language}, 
+        format => 'html');
+        
+    $template->render($all_roles);    
+}
+
+sub create_group {
+    
+    my ($class, $request) = @_;
+    my $admin = LedgerSMB::DBObject::Admin->new(base=>$request, copy=>'all');
+    
+    my $all_roles = $admin->role_list();
+    
+    my $template = LedgerSMB::Template->new( user => $user, 
+	template => 'admin/edit_group.html', language => $user->{language}, 
+        format => 'html');
+        
+    $template->render($all_roles);
+}
+
+sub delete_group {
+    
+    my ($class, $request) = @_;
+    
+    my $admin = LedgerSMB::DBObject::Admin->new(base=>$request, copy=>'all');
+    
+    # requires the field modifying_user to be set.
+    
+    my $status = $admin->delete_group($request->{modifying_user});
+    
+    # status can either be 1, or an error.
+    # if there's an error, $status->throw() is called by admin.pm. Or possibly
+    # in the template itself.
+    
+    my $template = LedgerSMB::Template->new ( user=>$user, 
+        template=>'admin/delete_group.html', language=>$user->{language}, 
+        format=>'html');    
+        
+    $template->render($status);    
+}
+
+sub delete_user {
+    
+    my ($class, $request) = @_;
+    
+    my $admin = LedgerSMB::DBObject::Admin->new(base=>$request, copy=>'all');
+    
+    # requires the field modifying_user to be set.
+    
+    my $status = $admin->delete_user($request->{modifying_user});
+    
+    # status can either be 1, or an error.
+    # if there's an error, $status->throw() is called by admin.pm. Or possibly
+    # in the template itself.
+    
+    my $template = LedgerSMB::Template->new ( user=>$user, 
+        template=>'admin/delete_user.html', language=>$user->{language}, 
+        format=>'html');
+        
+    $template->render($status);
+}
+
+sub new_user {
+    
+    my ($class, $request) = @_;
+    
+    my $template = LedgerSMB::Template->new( user=>$user, 
+        template=>'admin/new_user.html', language=>$user->{language},
+        format=>'html');
+    
+    $template->render();
+}
+
+sub new_group {
+    
+    my ($class, $request) = @_;
+    
+    my $template = LedgerSMB::Template->new( user=>$user, 
+        template=>'admin/new_group.html', language=>$user->{language},
+        format=>'html');
+    
+    $template->render();
+}
+
+sub __default {
+    
+    my ($class, $request) = @_;
+    
+    # check for login
+    my $template;
+        $template = LedgerSMB::Template->new( user=>$user, 
+            template=>'admin/main.html', language=>$user->{language},
+            format=>'html');
+    $template->render();
+}
+
+1;
\ No newline at end of file

Added: trunk/sql/modules/admin.sql
===================================================================
--- trunk/sql/modules/admin.sql	                        (rev 0)
+++ trunk/sql/modules/admin.sql	2007-09-10 23:02:09 UTC (rev 1557)
@@ -0,0 +1,403 @@
+CREATE OR REPLACE FUNCTION admin_add_user_to_role(in_user TEXT, in_role TEXT) returns INT AS $$
+    
+    declare
+        stmt TEXT;
+        a_role name;
+        a_user name;
+    BEGIN
+    
+        -- Issue the grant
+        select rolname into a_role from pg_roles where rolname = in_role;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot grant permissions of a non-existant role.';
+        END IF;
+        
+        select rolname into a_user from pg_roles where rolname = in_user;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot grant permissions to a non-existant user.';
+        END IF;
+        
+        stmt := 'GRANT '|| in_role ||' to '|| in_user;
+        
+        EXECUTE stmt;
+        
+        return 1;
+    END;
+    
+$$ language 'plpgsql';
+
+CREATE OR REPLACE FUNCTION admin_remove_user_from_role(in_user TEXT, in_role TEXT) returns INT AS $$
+    
+    declare
+        stmt TEXT;
+        a_role name;
+        a_user name;
+    BEGIN
+    
+        -- Issue the grant
+        select rolname into a_role from pg_roles where rolname = in_role;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot revoke permissions of a non-existant role.';
+        END IF;
+        
+        select rolname into a_user from pg_roles where rolname = in_user;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot revoke permissions from a non-existant user.';
+        END IF;
+        
+        stmt := 'REVOKE '|| in_role ||' FROM '|| in_user;
+        
+        EXECUTE stmt;
+        
+        return 1;    
+    END;
+    
+$$ language 'plpgsql';
+
+CREATE OR REPLACE FUNCTION admin_add_function_to_group(in_func TEXT, in_role TEXT) returns INT AS $$
+    
+    declare
+        stmt TEXT;
+        a_role name;
+        a_user name;
+    BEGIN
+    
+        -- Issue the grant
+        select rolname into a_role from pg_roles where rolname = in_role;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot grant permissions of a non-existant role.';
+        END IF;
+        
+        select rolname into a_user from pg_roles where rolname = in_user;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot grant permissions to a non-existant user.';
+        END IF;
+        
+        stmt := 'GRANT EXECUTE ON FUNCTION '|| in_func ||' to '|| in_role;
+        
+        EXECUTE stmt;
+        
+        return 1;
+    END;
+    
+$$ language 'plpgsql';
+
+CREATE OR REPLACE FUNCTION admin_remove_function_from_group(in_func TEXT, in_role TEXT) returns INT AS $$
+    
+    declare
+        stmt TEXT;
+        a_role name;
+        a_user name;
+    BEGIN
+    
+        -- Issue the grant
+        select rolname into a_role from pg_roles where rolname = in_role;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot revoke permissions of a non-existant role.';
+        END IF;
+        
+        select rolname into a_user from pg_roles where rolname = in_user;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot revoke permissions from a non-existant function.';
+        END IF;
+        
+        stmt := 'REVOKE EXECUTE ON FUNCTION '|| in_func ||' FROM '|| in_role;
+        
+        EXECUTE stmt;
+        
+        return 1;    
+    END;
+    
+    
+$$ language 'plpgsql';
+
+CREATE OR REPLACE FUNCTION admin_add_table_to_group(in_table TEXT, in_role TEXT, in_perm TEXT) returns INT AS $$
+    
+    declare
+        stmt TEXT;
+        a_role name;
+        a_user name;
+    BEGIN
+    
+        -- Issue the grant
+        select rolname into a_role from pg_roles where rolname = in_role;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot grant permissions of a non-existant role.';
+        END IF;
+        
+        select table_name into a_table from information_schema.tables 
+        where table_schema NOT IN ('information_schema','pg_catalog','pg_toast') 
+        and table_type='BASE TABLE' 
+        and table_name = in_table;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot grant permissions to a non-existant table.';
+        END IF;
+        
+        if lower(in_perm) not in ('select','insert','update','delete') THEN
+            raise exception 'Cannot add unknown permission';
+        END IF;
+        
+        stmt := 'GRANT '|| in_perm|| 'ON TABLE '|| in_table ||' to '|| in_role;
+        
+        EXECUTE stmt;
+        
+        return 1;
+    END;
+    
+$$ language 'plpgsql';
+
+CREATE OR REPLACE FUNCTION admin_remove_table_from_group(in_table TEXT, in_role TEXT) returns INT AS $$
+    
+    declare
+        stmt TEXT;
+        a_role name;
+        a_table text;
+    BEGIN
+    
+        -- Issue the grant
+        select rolname into a_role from pg_roles where rolname = in_role;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot revoke permissions of a non-existant role.';
+        END IF;
+        
+        SELECT table_schema, table_name from 
+        
+        select table_name into a_table from information_schema.tables 
+        where table_schema NOT IN ('information_schema','pg_catalog','pg_toast') 
+        and table_type='BASE TABLE' 
+        and table_name = in_table;
+        
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'Cannot revoke permissions from a non-existant table.';
+        END IF;
+        
+        stmt := 'REVOKE '|| in_role ||' FROM '|| in_user;
+        
+        EXECUTE stmt;
+        
+        return 1;    
+    END;
+        
+$$ language 'plpgsql';
+
+create or replace function admin_get_user(in_user TEXT) returns setof user as $$
+    
+    DECLARE
+        a_user user;
+    BEGIN
+        
+        select * into a_user from user where username = in_user;
+        IF NOT FOUND THEN
+            RAISE EXCEPTION 'cannot find user %', in_user;
+        END IF;
+        
+        return a_user;
+    
+    END;    
+$$ language plpgsql;
+
+create or replace function admin_get_roles_for_user(in_user TEXT) returns setof lsmb_roles as $$
+    
+    declare
+        u_role lsmb_roles;
+        a_user user;
+    begin
+        select * into a_user from admin_get_user(in_user);
+        
+        FOR u_role IN select * from lsmb_roles WHERE user = a_user.id LOOP
+        
+            RETURN NEXT a_role;
+        
+        END LOOP;
+        RETURN;
+    end;
+    
+$$ language 'plpgsql';
+
+CREATE OR REPLACE FUNCTION admin_save_user(
+    in_id int, 
+    in_username text, 
+    in_password TEXT, 
+    in_dbname TEXT, 
+    in_host TEXT, 
+    in_port TEXT
+) returns int AS $$
+    DECLARE
+    
+        a_user user;
+        v_entity_id int;
+        p_id int;
+        l_id int;
+        stmt text;
+    BEGIN
+    
+        select * into a_user from user where id = in_id;
+        
+        IF NOT FOUND THEN 
+            -- Insert cycle
+            
+            --- First, create an entity.
+            
+            if admin_is_user(in_username) then
+                
+                -- uhm, this is bad.
+                RAISE EXCEPTION 
+                    "Fatal exception: Username already exists in Postgres; not
+                    a valid lsmb user.";
+            end if;
+            
+            v_entity_id := nextval('entity_id_seq');
+                
+            INSERT INTO entity (id, name, entity_class) VALUES (
+                v_entity_id,
+                in_first_name || ' ' || in_last_name,
+                3
+            );
+            
+            -- create an actual user
+            insert into users (name, entity_id) VALUES (
+                in_username,
+                v_entity_id
+            );
+            
+            insert into user_connection (entity_id, database, host, port) 
+                VALUES (
+                    v_entity_id,
+                    in_database,
+                    in_host,
+                    in_port                    
+                );
+            
+            -- Finally, issue the create user statement
+            
+            stmt := $$CREATE USER $$||in_username||$$WITH ENCRYPTED PASSWORD '$$||in_password||$$;'$$;
+            execute stmt;
+            
+            return v_entity_id;
+
+        ELSIF FOUND THEN
+            
+            -- update cycle
+            
+            -- Only update if it's changed. Wewt.
+            UPDATE entity SET name = in_first_name || ' ' || in_last_name 
+            WHERE entity_id = a_user.entity_id and 
+            name <> in_first_name || ' ' || in_last_name;
+            
+            stmt := $$ alter user $$ || in_username || $$ with encrypted password $1$$$ || in_password || $$$1$ $$;
+            execute stmt;
+            
+            update user_connection set database = in_database, host = in_host, port = in_port
+            where database <> in_database
+            OR host <> in_host
+            OR port <> in_port;
+            
+            return a_user.id;
+        
+        END IF;
+    
+    END;
+$$ language 'plpgsql';
+
+create view role_view as 
+    select * from pg_auth_members m join pg_authid a ON (m.roleid = a.oid);
+        
+
+create or replace function admin_is_group(in_group_name text) returns bool as $$
+    
+    DECLARE
+        
+        existant_role role_view;
+        stmt text;
+        
+    BEGIN
+        select * into role_view from role_view where rolname = in_group_name;
+        
+        if not found then
+            return 'f'::bool;
+            
+        else
+            return 't'::bool;
+        end if;            
+    END;
+    
+$$ language 'plpgsql';
+
+CREATE OR REPLACE FUNCTION admin_create_group(in_group_name TEXT, in_dbname TEXT) RETURNS int as $$
+    
+    DECLARE
+        
+        stmt text;
+        
+    BEGIN
+        stmt := 'create role '||in_dbname||'_lsmb_$$' || in_group_name || '$$;';
+        execute stmt;
+        return 1;
+    END;
+    
+$$ language 'plpgsql';
+
+CREATE OR REPLACE FUNCTION admin_delete_user(in_username TEXT) returns INT as $$
+    
+    DECLARE
+        stmt text;
+        a_user user;
+    BEGIN
+    
+        select * into a_user from users where username = in_username;
+        
+        IF NOT FOUND THEN
+        
+            raise exception "User not found.";
+        ELSIF FOUND THEN
+    
+            stmt := $$ drop user $$ || a_user.username ||;
+            execute stmt;
+            
+            -- also gets user_connection
+            delete from users where id = a_user.id; 
+            delete from entity where id = a_user.entity_id;
+                                        
+        END IF;   
+    END;
+    
+$$ language 'plpgsql';
+
+comment on function admin_delete_user(text) is $$ 
+    Drops the provided user, as well as deletes the entity and user configuration data.
+$$;
+
+CREATE OR REPLACE FUNCTION admin_delete_group (in_group_name TEXT) returns bool as $$
+    
+    DECLARE
+        stmt text;
+        a_role role_view;
+    BEGIN
+        
+        select * into a_role from role_view where rolname = in_group_name;
+        
+        if not found then
+            return 'f'::bool;
+        else
+            stmt := 'drop role $dbname_lsmb_$$' || in_group_name || '$$;';
+            execute stmt;
+            return 't'::bool;
+        end if;
+    END;
+$$ language 'plpgsql';
+
+comment on function admin_delete_group(text) IS $$ 
+    Deletes the input group from the database. Not designed to be used to 
+    remove a login-capable user.
+$$;
\ No newline at end of file


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.