summaryrefslogtreecommitdiff
path: root/LedgerSMB/DBObject/Reconciliation.pm
blob: 7a7ba3135f8b067b814eb0e13458e0d56e4547bd (plain)
  1. =pod
  2. =head1 NAME
  3. LedgerSMB::DBObject::Reconciliation - LedgerSMB class defining the core
  4. database interaction logic for Reconciliation.
  5. =head1 SYOPSIS
  6. This module creates object instances based on LedgerSMB's in-database ORM.
  7. =head1 METHODS
  8. =over
  9. =item new ($class, base => $LedgerSMB::hash)
  10. This is the base constructor for all child classes. It must be used with base
  11. argument because this is necessary for database connectivity and the like.
  12. Of course the base object can be any object that inherits LedgerSMB, so you can
  13. use any subclass of that. The per-session dbh is passed between the objects
  14. this way as is any information that is needed.
  15. =item reconcile($self, $total, $month, $entries)
  16. Accepts the total balance, as well as a list of all entries from the bank
  17. statement as an array reference, and generates the pending report from
  18. this list.
  19. The first entry is always the total balance of the general ledger as
  20. compared to the balance held by the bank.
  21. Month is taken to be the date that the statement as represented by Entries
  22. is applicable to.
  23. Returns the new report ID. || An arrayref of entries.
  24. =item approve($self,$reportid)
  25. Approves the pending report $reportid.
  26. Checks for error codes in the pending report, and approves the report if none
  27. are found.
  28. Limitations: The creating user may not approve the report.
  29. Returns 1 on success.
  30. =item correct_entry($self, $report_id, $source_control_number, $new_balance)
  31. If the given entry $source_control_number in the report $report_id has an error
  32. code, the entry will be updated with $new_balance, and the error code
  33. recomputed.
  34. Returns the error code assigned to this entry.
  35. 0 for success
  36. 1 for found in general ledger, but does not match $new_balance
  37. 2 $source_control_number cannot be found in the general ledger
  38. =item get_report($self, $report_id)
  39. Collects all the rows from the database in the given report. Returns an
  40. arrayref of entries in the table for the given report_id.
  41. Returns undef in the event of no records found.
  42. =item get_corrections($self, $report_id, $entry_id)
  43. Returns the corrections made for the selected report and entry.
  44. Returns undef in the event of no corrections found.
  45. =item entry ($self,$report_id,$entry_id)
  46. Returns a single entry from the pending reports table, either cleared or
  47. uncleared.
  48. =back
  49. =head1 Copyright (C) 2007, The LedgerSMB core team.
  50. This file is licensed under the Gnu General Public License version 2, or at your
  51. option any later version. A copy of the license should have been included with
  52. your software.
  53. =cut
  54. package LedgerSMB::DBObject::Reconciliation;
  55. use base qw(LedgerSMB::DBObject);
  56. use LedgerSMB::DBObject;
  57. use LedgerSMB::Reconciliation::CSV;
  58. # don't need new
  59. sub import_file {
  60. my $self = shift @_;
  61. # We need to know what the format is, for the text file. We should have a set of formats
  62. # for the given file, listed in the DB, or based on modules available.
  63. #
  64. # Probably based on modules.
  65. # my $module = 'LedgerSMB/Reconciliaton/CSV/'.$self->{file_format};
  66. # require $module."pm";
  67. # my $obj_name = $module;
  68. # $obj_name =~ s/\//::/g;
  69. # my $parser = $obj_name::new(base=>$self);
  70. # $self->filename is currently a lie. There's no facility in the LSMB
  71. # design to accomadate an uploaded file.
  72. my $csv = LedgerSMB::Reconciliation::CSV->new(base=>$self);
  73. $csv->process();
  74. return $self->{entries};
  75. }
  76. sub approve {
  77. my $self = shift @_;
  78. # the user should be embedded into the $self object.
  79. my $report_id = shift @_;
  80. my $code = $self->exec_method(funcname=>'report_approve', args=>[$report_id]); # user
  81. if ($code == 0) { # no problem.
  82. return $code;
  83. }
  84. # this is destined to change as we figure out the Error system.
  85. elsif ($code == 99) {
  86. $self->error("User $self->{user}->{name} cannot approve report, must be a different user.");
  87. }
  88. }
  89. sub new_report {
  90. my $self = shift @_;
  91. my $total = shift @_;
  92. my $month = shift @_;
  93. my $entries = shift @_; # expects an arrayref.
  94. # Total is in here somewhere, too
  95. # gives us a report ID to insert with.
  96. my $report_id = $self->exec_method(funcname=>'reconciliation__new_report_id');
  97. # Now that we have this, we need to create the internal report representation.
  98. # Ideally, we OUGHT to not return anything here, save the report number.
  99. unshift @{$entries}, {
  100. scn => -1,
  101. balance=> $total,
  102. old_balance=> $self->exec_method(funcname=>'reconciliation__current_balance'),
  103. date=>$month
  104. };
  105. for my $entry ( @{$entries} ) {
  106. # Codes:
  107. # 0 is success
  108. # 1 is found, but mismatch
  109. # 2 is not found
  110. $code = $self->exec_method(
  111. funcname=>'reconciliation__add_entry',
  112. args=>[
  113. $report_id,
  114. ]
  115. );
  116. $entry{report_id} = $report_id;
  117. $entry{code} = $self->add_entry( $entry );
  118. }
  119. $self->exec_method(funcname=>'reconciliation__pending_transactions', args=>[$report_id, $date]);
  120. return ($report_id, $entries); # returns the report ID.
  121. }
  122. sub correct_entry {
  123. my $self = shift @_;
  124. my $report_id = $self->{report_id}; # shift @_;
  125. my $scn = $self->{id}; #shift @_;
  126. my $new_amount = $self->{new_amount}; #shift @_;
  127. # correct should return the new code value - whether or not it actually "matches"
  128. my $code = $self->exec_method(
  129. funcname=>'reconciliation__correct',
  130. args=>[$report_id, $scn, $new_amount]
  131. );
  132. return $code[0]->{'correct'};
  133. }
  134. sub get_report {
  135. my $self = shift @_;
  136. return $self->exec_method(funcname=>'reconciliation__report', args=>[$self->{report_id}]);
  137. }
  138. sub get_corrections {
  139. my $self = shift @_;
  140. return $self->exec_method(
  141. funcname=>'reconciliation__corrections',
  142. args=>[$self->{report_id}, $self->{entry_id}]
  143. );
  144. }
  145. sub entry {
  146. my $self = shift @_;
  147. return $self->exec_method(
  148. funcname=>'reconciliation__single_entry',
  149. args=>[$self->{report_id}, $self->{entry_id}]
  150. );
  151. }
  152. sub search {
  153. my $self = shift @_;
  154. return $self->exec_method(
  155. funcname=>'reconciliation__search',
  156. args=>[$self->{date_begin}, $self->{date_end}, $self->{account}, $self->{status}]
  157. );
  158. }
  159. sub get_pending {
  160. my $self = shift @_;
  161. return $self->exec_method(
  162. funcname=>'reconciliation__pending',
  163. args=>[$self->{month}]
  164. );
  165. }
  166. sub get_report_list {
  167. my $self = shift @_;
  168. return $self->exec_method(
  169. funcname=>'reconciliation__report_list',
  170. args=>[$self->{account},$self->{report}]
  171. );
  172. }
  173. 1;