[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
SF.net SVN: ledger-smb:[4743] trunk
- Subject: SF.net SVN: ledger-smb:[4743] trunk
- From: ..hidden..
- Date: Mon, 21 May 2012 10:19:27 +0000
Revision: 4743
http://ledger-smb.svn.sourceforge.net/ledger-smb/?rev=4743&view=rev
Author: einhverfr
Date: 2012-05-21 10:19:27 +0000 (Mon, 21 May 2012)
Log Message:
-----------
Merging neglected budget entry in, porting to Moose and business unit framework
Added Paths:
-----------
trunk/LedgerSMB/DBObject/Budget.pm
trunk/LedgerSMB/DBObject/Budget_Report.pm
trunk/LedgerSMB/Scripts/budgets.pm
trunk/UI/budgetting/
trunk/UI/budgetting/budget_entry.html
trunk/UI/budgetting/budgetting.css
trunk/UI/budgetting/search_criteria.html
trunk/budgets.pl
Added: trunk/LedgerSMB/DBObject/Budget.pm
===================================================================
--- trunk/LedgerSMB/DBObject/Budget.pm (rev 0)
+++ trunk/LedgerSMB/DBObject/Budget.pm 2012-05-21 10:19:27 UTC (rev 4743)
@@ -0,0 +1,356 @@
+=head1 NAME
+
+LedgerSMB::DBObject::Budget
+
+=cut
+
+package LedgerSMB::DBObject::Budget;
+use strict;
+our $VERSION = 0.1;
+
+=head1 SYNOPSIS
+
+This module provides budget management routines, such as entering budgets,
+approving or rejecting them, and marking them obsolete. It does not include
+more free-form areas like reporting. For those, see
+LedgerSMB::DBObject::Budget_Report.
+
+=head1 INHERITANCE
+
+=over
+
+=item LedgerSMB
+
+=item LedgerSMB::DBObject
+
+=back
+
+=cut
+
+use Moose;
+extends LedgerSMB::DBObject_Moose;
+
+=head1 PROPERTIES
+
+=over
+
+=item $id INT
+ The id of the budget
+
+=cut
+
+has 'id' => (is => 'rw', isa => 'Maybe[Int]');
+
+=item $start_date date
+ The start date of the budget, inclusive
+
+=cut
+
+has 'start_date' => (is => 'rw', isa => 'Maybe[LedgerSMB::PGDate]');
+
+=item $end_date date
+ The end date of the budget, inclusive
+
+=cut
+
+has 'end_date' => (is => 'rw', isa => 'Maybe[LedgerSMB::PGDate]');
+
+=item $reference text
+ This is a text reference identifier for the budget
+
+=cut
+
+has 'reference' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item $description text
+ This is a text field for the budget description. It is searchable.
+
+=cut
+
+has 'description' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item $entered_by int
+ Entity id of the employee or contractor who entered the budget
+
+=cut
+
+has 'entered_by' => (is => 'rw', isa => 'Maybe[Int]');
+
+=item $approved_by int
+ Entity id of the employee or contractor who approved the budget
+
+=cut
+
+has 'approved_by' => (is => 'rw', isa => 'Maybe[Int]');
+
+=item $obsolete_by int
+ Entity id for the employee or contractor who marked the budget obsolete
+
+=cut
+
+has 'obsolete_by' => (is => 'rw', isa => 'Maybe[Int]');
+
+=item $entered_at timestamp
+ Time the budget was entered
+
+=cut
+
+has 'entered_at' => (is => 'rw', isa => 'Maybe[LedgerSMB::PGDate]');
+
+=item $approved_at timestamp
+ Time the budget was approved
+
+=cut
+
+has 'approved_at' => (is => 'rw', isa => 'Maybe[LedgerSMB::PGDate]');
+
+=item $obsolete_at timestamp
+ Time the budget was deleted
+
+=cut
+
+has 'obsolete_at' => (is => 'rw', isa => 'Maybe[LedgerSMB::PGDate]');
+
+=item $entered_by_name text
+ Name of entity who entered the budget.
+
+=cut
+
+has 'entered_by_name' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item $approved_by_name text
+ Name of entity who approved the budget
+
+=cut
+
+has 'approved_by_name' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item $obsolete_by_name text
+ Name of entity who obsoleted the budget
+
+=cut
+
+has 'obsolete_by_name' => (is => 'rw', isa => 'Maybe[Str]');
+
+=item @business_unit_ids
+
+List of id's of business units which the budget covers
+
+=cut
+
+has 'business_unit_ids' => (is => 'rw', isa => 'Maybe[ArrayRef[Int]]');
+
+=item @lines
+ These are the actual lines of the budget. Each one is a hashref containing
+
+=cut
+
+has 'lines' => (is => 'rw', isa => 'Maybe[ArrayRef[Hashref[Any]]]');
+=over
+
+=item $budget_id int
+ Optional. Don't use. Use the $id field of the parent instead.
+
+=item $account_id int
+ The id of the chart of accounts entry
+
+=item $accno text
+ The account number for the coa entry
+
+=item $amount numeric
+ The amount budgetted
+
+=item $description text
+ Description of line item
+
+=back
+
+=item @notes
+Where each note is a hashref containing
+
+=over
+
+=item $subject string
+ Subject of note
+
+=item $note string
+ The body of the note.
+
+=item $created timestamp
+ This is when the note was created
+
+=item $created_by string
+ Username of the individual who created the note at the time of its creation.
+
+=back
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item save
+
+Saves the current budget.
+
+=cut
+
+sub save {
+ my ($self) = @_;
+ my ($ref) = $self->exec_method({funcname => 'budget__save_info'});
+ $self->{details} = [];
+ for my $line (@{$self->lines}){
+ my $l_info = [$line->{account_id},
+ $line->{description},
+ $line->{amount},
+ ];
+ push @{$self->{details}}, $l_info;
+ }
+ $self->exec_method({funcname => 'budget__save_details'});
+ $self->get($ref->{id});
+ $self->{dbh}->commit;
+}
+
+=item
+
+=item search
+This method uses the object as the search criteria. Nulls/undefs match all
+values. The properties used are:
+
+=over
+
+=item start_date
+Matches the start date of the budget. Full match only.
+
+=item end_date
+Matches the end date of the budget. Full match only
+
+=item includes_date
+This date is between start date and end date of budget, inclusive.
+
+=item reference
+Partial match on budget reference
+
+=item description
+Full text search against description
+
+=item entered_by
+Exact match of entered by.
+
+=item approved_by
+Exact match of approved by
+
+=item department_id
+Exact match of department_id
+
+=item project_id
+Exact match of project_id
+
+=item is_approved
+true lists approved budgets, false lists unapproved budgets. null/undef lists
+all.
+
+=item is_obsolete
+true lists obsolete budgets. False lists non-obsolete budgets. null/undef lists
+all.
+
+=back
+
+=cut
+
+sub search {
+ my ($self) = @_; # self is search criteria here.
+ @{$self->{search_results}}
+ = $self->exec_method({funcname => 'budget__search'});
+ return @{$self->{search_results}};
+}
+
+=item get(id)
+takes a new (base) object and populates with info for the budget.
+
+=cut
+
+sub get {
+ my ($self, $id) = @_;
+ my ($info) = $self->call_procedure(
+ procname => 'budget__get_info', args => [$id]
+ );
+ $self = $self->new(%$info);
+ @{$self->{lines}} = $self->exec_method({funcname => 'budget__get_details'});
+ @{$self->{notes}} = $self->exec_method({funcname => 'budget__get_notes'});
+}
+
+=item approve
+Marks the budget as approved.
+
+=cut
+
+sub approve {
+ my ($self) = @_;
+ $self->exec_method({funcname => 'budget__approve'});
+ $self->{dbh}->commit;
+}
+
+=item reject
+Reject and deletes the budget.
+
+=cut
+
+sub reject {
+ my ($self) = @_;
+ $self->exec_method({funcname => 'budget__reject'});
+ $self->{dbh}->commit;
+}
+
+=item obsolete
+Marks the budget as obsolete/superceded.
+
+=cut
+
+sub obsolete {
+ my ($self) = @_;
+ $self->exec_method({funcname => 'budget__mark_obsolete'});
+ $self->{dbh}->commit;
+}
+
+=item save_note(subject string, note string)
+Attaches a note with this subject and content to the budget.
+
+=cut
+
+sub save_note {
+ my ($self, $subject, $note) = @_;
+ my ($info) = $self->call_procedure(
+ procname => 'budget__save_note',
+ args => [$self->{id}, $subject, $note]
+ );
+}
+
+=back
+
+=head1 SEE ALSO
+
+=over
+
+=item LedgerSMB
+
+=item LedgerSMB::DBObject
+
+=item LedgerSMB::DBObject::Budget_Report
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2011 LedgerSMB Core Team. This file is licensed under the GNU
+General Public License version 2, or at your option any later version. Please
+see the included License.txt for details.
+
+=cut
+
+__PACKAGE__->meta->make_immutable;
+return 1;
+
+
+
Added: trunk/LedgerSMB/DBObject/Budget_Report.pm
===================================================================
--- trunk/LedgerSMB/DBObject/Budget_Report.pm (rev 0)
+++ trunk/LedgerSMB/DBObject/Budget_Report.pm 2012-05-21 10:19:27 UTC (rev 4743)
@@ -0,0 +1,150 @@
+=head1 NAME
+
+LedgerSMB::DBObject::Budget_Report
+
+=cut
+
+package LedgerSMB::DBObject::Budget_Report;
+use strict;
+
+=head1 SYNOPSIS
+
+Reporting routines for budgets. Currently only displays a variance report.
+
+=head1 INHERITANCE
+
+=cut
+
+=over
+
+=item LedgerSMB
+
+=item LedgerSMB::DBObject
+
+=back
+
+=cut
+
+use base qw(LedgerSMB::DBObject);
+
+=head1 PROPERTIES
+
+=over
+
+=item id
+The id of the budget
+
+=item start_date
+The start date of the budget, inclusive
+
+=item end_date
+The end date of the budget, inclusive
+
+=item reference
+The reference or control code of the budget
+
+=item description
+Description of the budget
+
+=item entered_by
+entity id of the one who entered the budget
+
+=item approved_by
+entity id of the one who approved the budget
+
+=item obsolete_by
+entity id of the one who marked the budget obsolete
+
+=item entered_at
+Timestamp when the budget was saved
+
+=item approved_at
+Timestamp when the budget was approved
+
+=item obsolete_at
+Timestamp when the budget was marked obsolete
+
+=item entered_by_name
+Name of the entity who entered the budget
+
+=item approved_by_name
+Name of the entity who approved the budget
+
+=item obsolete_by_name
+Name of the entity who marked the budget obsolete
+
+=item department_id
+The ID of the department for which this budget was written
+
+=item department_name
+Name of the department for which this budget was written
+
+=item project_id
+ID of project for which this budget was written
+
+=item projectnumber
+Project number for which this budget was written
+
+=item lines
+Lines of the report. Each line is a hashref containing:
+
+=over
+
+=item accno
+Account number for the account in question
+
+=item account_label
+Description for the account in question
+
+=item account_id
+ID for the account in question
+
+=item budget_description
+Description for the line item of the budget
+
+=item budget_amount
+The amount budgetted
+
+=item used_amount
+The amount actually used
+
+=item variance
+budgetted - used
+
+=back
+
+=back
+
+=head1 METHODS
+
+=over
+
+=item run_report($id);
+
+Takes a blank (base) object and populates with the variance report data provided
+by the id argument.
+
+=cut
+
+sub run_report {
+ my ($self) = @_;
+ my ($info) = $self->call_procedure(
+ procname => 'budget__get_info', args => [$self->{id}]
+ );
+ $self->merge($info);
+ @{$self->{lines}} = $self->exec_method(
+ {funcname => 'budget__variance_report'}
+ );
+
+ return @{$self->{lines}};
+}
+
+1;
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2011 LedgerSMB Core Team. This file is licensed under the GNU
+General Public License version 2, or at your option any later version. Please
+see the included License.txt for details.
Added: trunk/LedgerSMB/Scripts/budgets.pm
===================================================================
--- trunk/LedgerSMB/Scripts/budgets.pm (rev 0)
+++ trunk/LedgerSMB/Scripts/budgets.pm 2012-05-21 10:19:27 UTC (rev 4743)
@@ -0,0 +1,441 @@
+=head1 NAME
+LedgerSMB::Scripts::budgets
+
+=cut
+
+package LedgerSMB::Scripts::budgets;
+use strict;
+
+=head1 SYNOPSYS
+Budget workflow scripts.
+
+=head1 REQUIRES
+
+=over
+
+=item LedgerSMB::DBObject::Budget
+=item LedgerSMB::DBObject::Budget_Report
+
+=cut
+
+use LedgerSMB::DBObject::Budget;
+use LedgerSMB::DBObject::Budget_Report;
+use LedgerSMB::DBObject::Business_Unit;
+use LedgerSMB::DBObject::Business_Unit_Class;
+
+=head1 METHODS
+
+=over
+
+=item variance_report
+Requires id field to be set.
+
+=cut
+
+sub variance_report {
+ my ($request) = @_;
+ my $report = LedgerSMB::DBObject::Budget_Report->new({base => $request});
+ my @rows = $report->run_report();
+ my @cols = qw(accno account_label budget_description budget_amount
+ used_amount variance);
+ my $heading = {
+ budget_description => $request->{_locale}->text('Description'),
+ accno => $request->{_locale}->text('Account Number'),
+ account_label => $request->{_locale}->text('Account Label'),
+ budget_amount => $request->{_locale}->text('Amount Budgetted'),
+ used_amount => $request->{_locale}->text('- Used'),
+ variance => $request->{_locale}->text('= Variance'),
+ };
+ for my $row(@rows){
+ $row->{budget_amount} = $report->format_amount(
+ {amount => $row->{budget_amount}, money => 1}
+ );
+ $row->{used_amount} = $report->format_amount(
+ {amount => $row->{used_amount}, money => 1}
+ );
+ $row->{variance} = $report->format_amount(
+ {amount => $row->{variance}, money => 1}
+ );
+ }
+ my $template = LedgerSMB::Template->new(
+ user => $request->{_user},
+ locale => $request->{_locale},
+ path => 'UI',
+ template => 'form-dynatable',
+ format => ($report->{format}) ? $report->{format} : 'HTML',
+ );
+ $template->render({
+ form => $report,
+ columns => ..hidden..,
+ rows => ..hidden..,
+ heading => $heading,
+ });
+
+}
+
+=item new_budget
+No inputs provided. LedgerSMB::DBObject::Budget properties can be used to set
+defaults however.
+
+=cut
+
+sub new_budget {
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new(%$request);
+ _render_screen($budget);
+}
+
+
+# Private method _render_screen
+# used by new_budget, view_budget, and update
+# Prepares and renders screen with budget info.
+
+sub _render_screen {
+ my ($budget) = @_;
+ my $additional_rows = 5;
+ $additional_rows +=20 unless $budget->{rowcount};
+ $additional_rows = 0 if $budget->{id};
+ $request->{class_id} = 0 unless $request->{class_id};
+ $request->{control_code} = '' unless $request->{control_code};
+ my $buc = LedgerSMB::DBObject::Business_Unit_Class->new(%$request);
+ my $bu = LedgerSMB::DBObject::Business_Unit->new(%$request);
+ @{$request->{bu_classes}} = $buc->list(1, 'gl');
+ for my $bc (@{$request->{bu_classes}}){
+ @{$request->{b_units}->{$bc->{id}}}
+ = $bu->list($bc->{id}, undef, 0, undef);
+ for my $bu (@{$request->{b_units}->{$bc->{id}}}){
+ $bu->{text} = $bu->control_code . ' -- '. $bu->description;
+ }
+ }
+ $budget->{rowcount} ||= 0;
+ for my $row (@{$budget->{display_rows}}){
+ $row->{debit} = $budget->format_amount(amount => $row->{debit},
+ money => 1) if $row->{debit} ;
+ $row->{credit} = $budget->format_amount(amount => $row->{credit},
+ money => 1) if $row->{credit};
+ }
+ for (1 .. $additional_rows) {
+ push @{$budget->{display_rows}},
+ {accnoset => 0, index => $_ + $budget->{rowcount}};
+ ++$budget->{rowcount};
+ }
+ $budget->error('Invalid object')
+ unless $budget->isa('LedgerSMB::DBObject::Budget');
+ # The button logic is kinda complicated here. The basic idea is that there
+ # are three stages in the handling of the budget: Initial entry, review and
+ # approval, and review with the possibility of obsolescence.
+ #
+ # In the initial entry, there is no budget yet. Therefore id is not set.
+ # One can update the screen and save, but nothing else.
+ #
+ # Once id is set, if the budget has not been approved, it can be approved or
+ # rejected. Rejecting deletes the budgets in the current implementation,
+ # but other options are possible as customizations.
+ #
+ # Once the budget is approved, it can no longer be deleted. If
+ # circumstances change, however, it can still be marked obsolete. Obsolete
+ # budgets are available for review, but one would not generally run variance
+ # reports against them.
+ if (!$budget->{id}){
+ $budget->{buttons} = [
+ { name => 'action',
+ text => $budget->{_locale}->text('Update'),
+ type => 'submit',
+ value => 'update',
+ class => 'submit',
+ },
+ { name => 'action',
+ text => $budget->{_locale}->text('Save'),
+ type => 'submit',
+ value => 'save',
+ class => 'submit',
+ },
+ ];
+ } elsif (!$budget->{approved_by}){
+ $budget->{buttons} = [
+ { name => 'action',
+ text => $budget->{_locale}->text('Approve'),
+ type => 'submit',
+ value => 'approve',
+ class => 'submit',
+ },
+ { name => 'action',
+ text => $budget->{_locale}->text('Reject'),
+ type => 'submit',
+ value => 'reject',
+ class => 'submit',
+ },
+ ];
+ } else {
+ $budget->{buttons} = [
+ { name => 'action',
+ text => $budget->{_locale}->text('Obsolete'),
+ type => 'submit',
+ value => 'obsolete',
+ class => 'submit',
+ },
+ ];
+ }
+ my $template = LedgerSMB::Template->new(
+ user => $budget->{_user},
+ locale => $budget->{_locale},
+ path => 'UI/budgetting',
+ template => 'budget_entry',
+ format => 'HTML'
+ );
+ $budget->{hiddens} = {
+ rowcount => $budget->{rowcount},
+ id => $budget->{id},
+ };
+ $template->render($budget);
+}
+
+=item update
+Updates the screen. Part of initial entry workflow only.
+
+=cut
+
+sub update {
+ my ($request) = @_;
+ for (1 .. $request->{rowcount}){
+ push @{$request->{display_rows}},
+ { account_id => $request->{"account_id_$_"},
+ debit => $request->{"debit_$_"},
+ credit => $request->{"credit_$_"},
+ description => $request->{"description_$_"},
+ } if ($request->{"debit_$_"} or $request->{"credit_$_"});
+
+ }
+ $request->{rowcount} = scalar @{$request->{display_rows}};
+ new_budget(@_);
+}
+
+=item view_budget
+Reuuires id to be set. Displays a budget for review.
+
+=cut
+
+sub view_budget {
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new(%$request);
+ $budget->get($request->{id});
+ $budget->{display_rows} = [];
+ for my $line (@{$budget->{lines}}){
+ my $row = {};
+ $row->{description} = $line->{description};
+ if ($line->{amount} < 0 ) {
+ $row->{debit} = $line->{amount} * -1;
+ } else {
+ $row->{credit} = $line->{amount};
+ }
+ my ($account) = $budget->call_procedure(
+ procname => 'account_get',
+ args => [$line->{account_id}]
+ );
+ $row->{account_id} = "$account->{accno}--$account->{description}";
+ push @{$budget->{display_rows}}, $row;
+ }
+ _render_screen($budget);
+}
+
+=item save
+LedgerSMB::DBObject::Budget properties required. Lines represented by
+[property]_[line number] notation.
+
+=cut
+
+sub save {
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new({base => $request});
+ for my $rownum (1 .. $request->{rowcount}){
+ my $line = {};
+ $request->{"debit_$rownum"} = $request->parse_amount(
+ amount => $request->{"debit_$rownum"}
+ );
+ $request->{"debit_$rownum"} = $request->format_amount(
+ {amount => $request->{"debit_$rownum"}, format => '1000.00'}
+ );
+ $request->{"credit_$rownum"} = $request->parse_amount(
+ amount => $request->{"credit_$rownum"}
+ );
+ $request->{"credit_$rownum"} = $request->format_amount(
+ {amount => $request->{"credit_$rownum"}, format => '1000.00'}
+ );
+ if ($request->{"debit_$rownum"} and $request->{"credit_$rownum"}){
+ $request->error($request->{_locale}->text(
+ 'Cannot specify both debits and credits for budget line [_1]',
+ $rownum
+ ));
+ } elsif(!$request->{"debit_$rownum"} and !$request->{"credit_$rownum"}){
+ next;
+ } else {
+ $line->{amount} = $request->{"credit_$rownum"}
+ - $request->{"debit_$rownum"};
+ }
+ my ($accno) = split /--/, $request->{"account_id_$rownum"};
+ my ($ref) = $request->call_procedure(
+ procname => 'account__get_from_accno',
+ args => [$accno]
+ );
+ $line->{description} = $request->{"description_$rownum"};
+ $line->{account_id} = $ref->{id};
+ push @{$budget->{lines}}, $line;
+ }
+ $budget->save();
+ view_budget($budget);
+}
+
+=item approve
+Requires id. Approves the budget.
+
+=cut
+
+sub approve {
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new(%$request);
+ $budget->approve;
+ view_budget($request);
+}
+
+=item reject
+Requires id. Rejects unapproved budget and deletes it.
+
+=cut
+
+sub reject {
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new(%$request);
+ $budget->reject;
+ begin_search($request);
+}
+
+=item obsolete
+Requires id, Marks budget obsolete.
+
+=cut
+
+sub obsolete {
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new(%$request);
+ $budget->obsolete;
+ view_budget($request);
+}
+
+=item add_note
+Requires id, subject, and note. Adds a note to the budget.
+
+=cut
+
+sub add_note {
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new(%$request);
+ $budget->save_note($request->{subject}, $request->{note});
+ view_budget($request);
+}
+
+=item begin_search
+No inputs expected or used
+
+=cut
+
+sub begin_search{
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new(%$request);
+ @{$budget->{projects}} = $budget->list_projects;
+ unshift @{$budget->{projects}}, {};
+ @{$budget->{departments}} = $budget->list_departments;
+ unshift @{$budget->{departments}}, {};
+ my $template = LedgerSMB::Template->new(
+ user => $request->{_user},
+ locale => $request->{_locale},
+ path => 'UI/budgetting',
+ template => 'search_criteria',
+ format => 'HTML'
+ );
+
+ $template->render($budget);
+}
+
+1;
+
+=item search
+See LedgerSMB::Budget's search routine for expected inputs.
+
+=cut
+
+sub search {
+ my ($request) = @_;
+ my $budget = LedgerSMB::DBObject::Budget->new({base => $request});
+ my @rows = $budget->search;
+ my $cols = ['start_date',
+ 'end_date',
+ 'reference',
+ 'description',
+ 'entered_by_name',
+ 'approved_by_name',
+ 'obsolete_by_name',
+ 'department_name',
+ 'project_number',
+ ];
+ my $heading = {
+ start_date => $budget->{_locale}->text('Start Date'),
+ end_date => $budget->{_locale}->text('End Date'),
+ reference => $budget->{_locale}->text('Reference'),
+ description => $budget->{_locale}->text('Description'),
+ entered_by_name => $budget->{_locale}->text('Entered by'),
+ approved_by_name => $budget->{_locale}->text('Approved By'),
+ obsolete_by_name => $budget->{_locale}->text('Obsolete By'),
+ department_name => $budget->{_locale}->text('Department'),
+ project_number => $budget->{_locale}->text('Project'),
+ };
+
+ my $base_url = 'budgets.pl';
+
+ for my $row (@rows){
+ $row->{reference} = { href => $base_url
+ . '?action=view_budget'
+ . '&id=' . $row->{id},
+ text => $row->{reference},
+ };
+ $row->{start_date} = { href => $base_url
+ . '?action=variance_report'
+ . '&id=' . $row->{id},
+ text => $row->{start_date},
+ };
+ $row->{end_date} = { href => $row->{start_date}->{href},
+ text => $row->{end_date}
+ };
+
+ }
+ my $template = LedgerSMB::Template->new(
+ user => $request->{_user},
+ locale => $request->{_locale},
+ path => 'UI',
+ template => 'form-dynatable',
+ format => ($budget->{format}) ? $budget->{format} : 'HTML',
+ );
+ $template->render({
+ form => $budget,
+ columns => $cols,
+ rows => ..hidden..,
+ heading => $heading,
+ });
+}
+
+=back
+
+=head1 SEE ALSO
+
+=over
+
+=item LedgerSMB::DBObject::Budget
+=item LedgerSMB::DBObject::Budget_Report
+
+=back
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright (C) 2011 LedgerSMB Core Team. This file is licensed under the GNU
+General Public License version 2, or at your option any later version. Please
+see the included License.txt for details.
+
Added: trunk/UI/budgetting/budget_entry.html
===================================================================
--- trunk/UI/budgetting/budget_entry.html (rev 0)
+++ trunk/UI/budgetting/budget_entry.html 2012-05-21 10:19:27 UTC (rev 4743)
@@ -0,0 +1,236 @@
+<?lsmb INCLUDE 'ui-header.html'
+ include_script = [
+ "UI/ajax/scriptaculous/lib/prototype.js",
+ "UI/ajax/scriptaculous/src/scriptaculous.js?load=builder,effects,dragdrop,controls",
+ "UI/ajax/helpers.js"]
+ stylesheet=stylesheet
+ include_stylesheet = ["UI/budgetting/budgetting.css"];
+ PROCESS elements.html; ?>
+<body>
+
+<form method="post" action="<?lsmb script ?>">
+<div id="budget-header">
+<div class="listtop"><?lsmb title ?></div>
+<div class="input_row" id = "reference_row">
+<div class="input_group">
+ <?lsmb INCLUDE input element_data = {
+ name = "reference",
+ value = reference,
+ type = "text",
+ size = "20",
+ class = 'reference',
+ label = text('Reference')
+ } ?>
+</div>
+<div class="input_group">
+ <?lsmb INCLUDE input element_data = {
+ name = "description",
+ value = description,
+ type = "text",
+ size = "50",
+ class = 'description'
+ label = text('Description')
+ }
+ ?>
+</div></div>
+<div class="input_row" id = "date_row">
+<div class="input_group">
+ <?lsmb INCLUDE input element_data = {
+ name = "start_date"
+ value = start_date
+ type = "text"
+ size = "11"
+ class = 'date'
+ label = text('Start Date') #'
+ } ?>
+</div>
+<div class="input_group">
+ <?lsmb INCLUDE input element_data = {
+ name = "end_date"
+ value = end_date
+ type = "text"
+ size = "11"
+ class = 'date'
+ label = text('End Date') #'
+ } ?>
+</div>
+
+</div></div>
+
+<?FOREACH BUC IN bu_classes ?>
+<div class="inputrow"><div class="inputgroup">
+ <?lsmb PROCESS select element_data = {
+ name = 'business_unit_' _ loop.count
+ options = b_units.${BUC.id}
+ text_attr = 'text'
+ value_attr = 'id'
+ class = 'business_unit'
+ label = text(BUC.label)
+ } ?>
+</div></div>
+<?lsmb END # FOREACH BUC ?>
+
+ <!-- Move notes to bottom and add subject line
+ <tr>
+ <th align="right"><?lsmb text('Notes') ?></th>
+ <td colspan="3">
+ <?lsmb IF colrownotes ==1 ?>
+ <?lsmb INCLUDE textarea element_data={
+ name = "notes"
+ rows = form.rowsnotes
+ cols = form.colsnotes
+ value = form.notes
+ id = "not_1"
+ }
+ ?>
+ <?lsmb ELSE ?>
+ <?lsmb INCLUDE input element_data = {
+ name = "notes",
+ value = form.notes,
+ type = "text",
+ size = "50",
+ class = 'notes'
+ id = "not_1"
+ }
+ ?>
+
+ <?lsmb END ?>
+
+
+ </td>
+ </tr> -->
+ <table width="100%">
+ <tr class="listheading">
+ <th class="listheading"><?lsmb text('Account') ?></th>
+ <?lsmb IF transfer == 1 ?>
+ <th class="listheading"><?lsmb text('FX') ?></th>
+ <?lsmb END ?>
+ <th class="listheading"><?lsmb text('Debit') ?></th>
+ <th class="listheading"><?lsmb text('Credit') ?></th>
+ <th class="listheading"><?lsmb text('Description') ?></th>
+ </tr>
+ <?lsmb FOREACH displayrow IN display_rows ?>
+ <tr>
+ <?lsmb INDEX= loop.count ?>
+ <td>
+ <?lsmb IF displayrow.accnoset == 0 ?>
+ <?lsmb PROCESS ajaxselect element_data = {
+ name = "account_id_$INDEX"
+ initial_value = ${"accno_$INDEX"}
+ text_attr = 'accno'
+ value_attr = 'id'
+ ajax_target = 'journal.pl'
+ } ?>
+
+ <?lsmb ELSE ?>
+
+ <?lsmb PROCESS input element_data = {
+ label = displayrow.account_id
+ type = "hidden"
+ value = displayrow.account_id
+ name = "account_id_$INDEX"
+ id = "acc_$INDEX"
+ } ?>
+
+
+ <?lsmb END ?>
+
+ </td>
+
+ <td>
+ <?lsmb PROCESS input element_data = {
+ value = displayrow.debit
+ name = "debit_$INDEX"
+ type = "text"
+ size = 12
+ accesskey = displayrow.index
+ } ?>
+
+ </td>
+
+ <td>
+ <?lsmb PROCESS input element_data = {
+ value = displayrow.credit
+ name = "credit_$INDEX"
+ type = "text"
+ size = 12
+ } ?>
+
+ </td>
+
+ <td>
+ <?lsmb PROCESS input element_data = {
+ value = displayrow.description
+ name = "description_$INDEX"
+ type = "text"
+ size = 30
+ } ?>
+
+ </td>
+ </tr>
+ <?lsmb END ?>
+ </table>
+ <hr size="3">
+
+<?lsmb FOREACH hidden IN hiddens.keys;
+ PROCESS input element_data={
+ type = 'hidden',
+ name = hidden,
+ value = hiddens.item(hidden)
+ }; END ?>
+
+<?lsmb FOREACH button IN buttons; PROCESS button element_data=button; END ?>
+</form>
+<?lsmb IF id ?>
+<form name="note" action="<?lsmb script ?>" method="POST">
+<?lsmb PROCESS input element_data = {
+ name = "id"
+ value = id
+ type = "hidden"
+} ?>
+<div class="inputrow">
+<div class="inputgroup">
+<?lsmb PROCESS input element_data = {
+ type = "text"
+ name = "subject"
+ size = "64"
+ label = text('Subject')
+}
+?>
+</div></div>
+<div class="inputrow">
+<div class="inputgroup">
+<?lsmb PROCESS textarea element_data = {
+ name = "note"
+ cols = '64'
+ rows = '5'
+ label = text('Content')
+}
+?>
+</div></div>
+<div class="inputrow">
+<div class="inputgroup">
+<?lsmb PROCESS button element_data = {
+ name = "action"
+ value = 'add_note'
+ type = "submit"
+ class = "submit"
+ text = text('Add Note') #'
+}
+?>
+</div></div>
+</form>
+<?lsmb END # IF id ?>
+<?lsmb FOREACH note IN notes ?>
+<div class="note">
+<div class="note_subject"><label><?lsmb text('Subject') ?>:</label>
+<?lsmb note.subject ?></div>
+<div class="note_entry_info"><label> :</label>
+<?lsmb note.created_by ?>:<?lsmb note.created ?>
+</div>
+<div class="note_content"><label><?lsmb text('Content') ?>:</label>
+<?lsmb note.note ?>
+</div>
+<?lsmb END # FOREACH Note ?>
+</body>
+</html>
Added: trunk/UI/budgetting/budgetting.css
===================================================================
--- trunk/UI/budgetting/budgetting.css (rev 0)
+++ trunk/UI/budgetting/budgetting.css 2012-05-21 10:19:27 UTC (rev 4743)
@@ -0,0 +1,14 @@
+div.input_row {
+ overflow: auto;
+}
+div.input_group {
+ float: left;
+ width: 35em;
+}
+
+div label {
+ text-align: right;
+ width: 5em;
+ display: block;
+ float: left;
+}
Added: trunk/UI/budgetting/search_criteria.html
===================================================================
--- trunk/UI/budgetting/search_criteria.html (rev 0)
+++ trunk/UI/budgetting/search_criteria.html 2012-05-21 10:19:27 UTC (rev 4743)
@@ -0,0 +1,87 @@
+<?lsmb INCLUDE 'ui-header.html'
+ stylesheet=stylesheet
+ include_stylesheet = ["UI/budgetting/budgetting.css"] ?>
+<?lsmb PROCESS elements.html ?>
+<body>
+<form action="<?lsmb script ?>" method="get">
+<div class="listtop"><?lsmb title ?></div>
+<div class="input_row" id = "reference_row">
+<div class="input_group">
+ <?lsmb INCLUDE input element_data = {
+ name = "reference",
+ value = reference,
+ type = "text",
+ size = "20",
+ class = 'reference',
+ label = text('Reference')
+ } ?>
+</div>
+<div class="input_group">
+ <?lsmb INCLUDE input element_data = {
+ name = "description",
+ value = description,
+ type = "text",
+ size = "50",
+ class = 'description'
+ label = text('Description')
+ }
+ ?>
+</div></div>
+<div class="input_row" id = "date_row">
+<div class="input_group">
+ <?lsmb INCLUDE input element_data = {
+ name = "start_date"
+ value = start_date
+ type = "text"
+ size = "11"
+ class = 'date'
+ label = text('Start Date') #'
+ } ?>
+</div>
+<div class="input_group">
+ <?lsmb INCLUDE input element_data = {
+ name = "end_date"
+ value = end_date
+ type = "text"
+ size = "11"
+ class = 'date'
+ label = text('End Date') #'
+ } ?>
+</div>
+
+</div></div>
+<div class="input_row" id = "description_row">
+<div class="input_group">
+ <?lsmb INCLUDE select element_data = {
+ text_attr = "description"
+ value_attr = "id"
+ default_values = [department_id]
+ options = departments
+ name = "department_id"
+ label = text('Department')
+ } ?>
+
+</div>
+<div class="input_group">
+ <?lsmb INCLUDE select element_data = {
+ text_attr = "description"
+ value_attr = "id"
+ default_values = [project_id]
+ options = projects
+ name = "project_id"
+ label = text('Project')
+ } ?>
+
+</div></div>
+<div class="input_row" id = "button_row">
+<?lsmb PROCESS button element_data = {
+ text = text('Search')
+ value = 'search'
+ name = 'action'
+ type = 'submit'
+ class = 'submit'
+} ?>
+</div>
+</form>
+</body>
+</html>
Copied: trunk/budgets.pl (from rev 4729, trunk/recon.pl)
===================================================================
--- trunk/budgets.pl (rev 0)
+++ trunk/budgets.pl 2012-05-21 10:19:27 UTC (rev 4743)
@@ -0,0 +1,8 @@
+#!/usr/bin/perl
+
+use FindBin;
+BEGIN {
+ lib->import($FindBin::Bin) unless $ENV{mod_perl}
+}
+
+require 'lsmb-request.pl';
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.