summaryrefslogtreecommitdiff
path: root/scripts/payment.pl
blob: 4f13e395d6beb89f56b8016d762a57968885d564 (plain)
  1. =pod
  2. =head1 NAME
  3. LedgerSMB::Scripts::payment - LedgerSMB class defining the Controller functions for payment handling.
  4. =head1 SYNOPSIS
  5. Defines the controller functions and workflow logic for payment processing.
  6. =head1 COPYRIGHT
  7. Copyright (c) 2007, David Mora R and Christian Ceballos B.
  8. Licensed to the public under the terms of the GNU GPL version 2 or later.
  9. Original copyright notice below.
  10. #=====================================================================
  11. # PLAXIS
  12. # Copyright (c) 2007
  13. #
  14. # Author: David Mora R
  15. # Christian Ceballos B
  16. #
  17. #
  18. #
  19. #
  20. #
  21. # This program is free software; you can redistribute it and/or modify
  22. # it under the terms of the GNU General Public License as published by
  23. # the Free Software Foundation; either version 2 of the License, or
  24. # (at your option) any later version.
  25. #
  26. # This program is distributed in the hope that it will be useful,
  27. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  28. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  29. # GNU General Public License for more details.
  30. # You should have received a copy of the GNU General Public License
  31. # along with this program; if not, write to the Free Software
  32. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  33. =head1 METHODS
  34. =cut
  35. package LedgerSMB::Scripts::payment;
  36. use LedgerSMB::Template;
  37. use LedgerSMB::DBObject::Payment;
  38. use LedgerSMB::DBObject::Date;
  39. use strict;
  40. # CT: A few notes for future refactoring of this code:
  41. # 1: I don't think it is a good idea to make the UI too dependant on internal
  42. # code structures but I don't see a good alternative at the moment.
  43. # 2: CamelCasing: -1
  44. =pod
  45. =item payment
  46. This method is used to set the filter screen and prints it, using the
  47. TT2 system. (hopefully it will... )
  48. =back
  49. =cut
  50. sub payments {
  51. my ($request) = @_;
  52. my $payment = LedgerSMB::DBObject::Payment->new({'base' => $request});
  53. $payment->get_metadata();
  54. my $template = LedgerSMB::Template->new(
  55. user => $request->{_user},
  56. locale => $request->{_locale},
  57. path => 'UI/payments',
  58. template => 'payments_filter',
  59. format => 'HTML',
  60. );
  61. $template->render($payment);
  62. }
  63. sub check_job {
  64. my ($request) = @_;
  65. my $payment = LedgerSMB::DBObject::Payment->new({'base' => $request});
  66. $payment->check_job;
  67. my $template = LedgerSMB::Template->new(
  68. user => $request->{_user},
  69. locale => $request->{_locale},
  70. path => 'UI/payments',
  71. template => 'check_job',
  72. format => 'HTML',
  73. );
  74. $template->render($payment);
  75. }
  76. sub post_payments_bulk {
  77. my ($request) = @_;
  78. my $payment = LedgerSMB::DBObject::Payment->new({'base' => $request});
  79. $payment->post_bulk();
  80. my $template;
  81. if ($payment->{queue_payments}){
  82. $payment->{job_label} = 'Payments';
  83. $template = LedgerSMB::Template->new(
  84. user => $request->{_user},
  85. locale => $request->{_locale},
  86. path => 'UI/payments',
  87. template => 'check_job',
  88. format => 'HTML',
  89. );
  90. } else {
  91. $template = LedgerSMB::Template->new(
  92. user => $request->{_user},
  93. locale => $request->{_locale},
  94. path => 'UI/payments',
  95. template => 'payments_filter',
  96. format => 'HTML',
  97. );
  98. }
  99. $template->render($payment);
  100. }
  101. sub display_payments {
  102. my ($request) = @_;
  103. my $payment = LedgerSMB::DBObject::Payment->new({'base' => $request});
  104. $payment->get_payment_detail_data();
  105. $payment->debug({file => '/tmp/delme'});
  106. for (@{$payment->{contact_invoices}}){
  107. $_->{total_due} = $payment->format_amount(amount => $_->{total_due});
  108. }
  109. my $template = LedgerSMB::Template->new(
  110. user => $request->{_user},
  111. locale => $request->{_locale},
  112. path => 'UI/payments',
  113. template => 'payments_detail',
  114. format => 'HTML',
  115. );
  116. $template->render($payment);
  117. }
  118. sub payment {
  119. my ($request) = @_;
  120. my $locale = $request->{_locale};
  121. my $dbPayment = LedgerSMB::DBObject::Payment->new({'base' => $request});
  122. # Lets get the project data...
  123. my @projectOptions;
  124. my @arrayOptions = $dbPayment->list_open_projects();
  125. push @projectOptions, {}; #A blank field on the select box
  126. for my $ref (0 .. $#arrayOptions) {
  127. push @projectOptions, { value => $arrayOptions[$ref]->{id}."--".$arrayOptions[$ref]->{projectnumber}."--".$arrayOptions[$ref]->{description},
  128. text => $arrayOptions[$ref]->{projectnumber}."--".$arrayOptions[$ref]->{description}};
  129. }
  130. # Lets get the departments data...
  131. my @departmentOptions;
  132. my $role = $request->{type} eq 'receipt' ? 'P' : 'C';
  133. @arrayOptions = $dbPayment->list_departments($role);
  134. push @departmentOptions, {}; # A blank field on the select box
  135. for my $ref (0 .. $#arrayOptions) {
  136. push @departmentOptions, { value => $arrayOptions[$ref]->{id}."--".$arrayOptions[$ref]->{description},
  137. text => $arrayOptions[$ref]->{description}};
  138. }
  139. # Lets get the customer or vendor :)
  140. my @vcOptions;
  141. @arrayOptions = $dbPayment->get_open_accounts();
  142. for my $ref (0 .. $#arrayOptions) {
  143. push @vcOptions, { value => $arrayOptions[$ref]->{id}.'--'.$arrayOptions[$ref]->{name},
  144. text => $arrayOptions[$ref]->{name}};
  145. }
  146. # Lets get the open currencies (this uses the $dbPayment->{account_class} property)
  147. my @currOptions;
  148. @arrayOptions = $dbPayment->get_open_currencies();
  149. for my $ref (0 .. $#arrayOptions) {
  150. push @currOptions, { value => $arrayOptions[$ref]->{payments_get_open_currencies},
  151. text => $arrayOptions[$ref]->{payments_get_open_currencies} };
  152. }
  153. # Lets build filter by period
  154. my $date = LedgerSMB::DBObject::Date->new({base => $request});
  155. $date->build_filter_by_period($locale);
  156. # Lets set the data in a hash for the template system. :)
  157. my $select = {
  158. stylesheet => $request->{_user}->{stylesheet},
  159. login => { name => 'login',
  160. value => $request->{_user}->{login} },
  161. projects => {
  162. name => 'projects',
  163. options => \@projectOptions
  164. },
  165. department => {
  166. name => 'department',
  167. options => \@departmentOptions
  168. },
  169. vendor_customer => {
  170. name => 'vendor-customer',
  171. options => \@vcOptions
  172. },
  173. curr => {
  174. name => 'curr',
  175. options => \@currOptions
  176. },
  177. month => {
  178. name => 'month',
  179. options => $date->{monthsOptions}
  180. },
  181. year => {
  182. name => 'year',
  183. options => $date->{yearsOptions}
  184. },
  185. interval_radios => $date->{radioOptions},
  186. amountfrom => {
  187. name => 'amountfrom',
  188. },
  189. amountto => {
  190. name => 'amountto',
  191. },
  192. accountclass => {
  193. name => 'account_class',
  194. value => $dbPayment->{account_class}
  195. },
  196. type => {
  197. name => 'type',
  198. value => $request->{type}
  199. },
  200. action => {
  201. name => 'action',
  202. value => 'payment2',
  203. text => $locale->text("Continue"),
  204. },
  205. };
  206. # Lets call upon the template system
  207. my $template;
  208. $template = LedgerSMB::Template->new(
  209. user => $request->{_user},
  210. locale => $request->{_locale},
  211. path => 'UI/payments',
  212. # path => 'UI',
  213. template => 'payment1',
  214. format => 'HTML', );
  215. $template->render($select);# And finally, Lets print the screen :)
  216. }
  217. =pod
  218. =item payment2
  219. This method is used for the payment module, it is a consecuence of the payment sub,
  220. and its used for all the mechanics of an invoices payment module.
  221. =back
  222. =cut
  223. sub payment2 {
  224. my ($request) = @_;
  225. my $locale = $request->{_locale};
  226. my $dbPayment = LedgerSMB::DBObject::Payment->new({'base' => $request});
  227. my @array_options;
  228. # LETS GET THE CUSTOMER/VENDOR INFORMATION
  229. ($dbPayment->{entity_id}, my $vendor_customer_name) = split /--/ , $request->{'vendor-customer'};
  230. my @array_options;
  231. my $exchangerate;
  232. # LETS BUILD THE PROJECTS INFO
  233. # I DONT KNOW IF I NEED ALL THIS, BUT AS IT IS AVAILABLE I'LL STORE IT FOR LATER USAGE.
  234. my ($project_id, $project_number, $project_name) = split /--/ , $request->{projects} ;
  235. my @project = { name => 'project', text => $project_number.' '.$project_name, value => $project_id };
  236. # LETS GET THE DEPARTMENT INFO
  237. my ($department_id, $department_name) = split /--/, $request->{department};
  238. my @department = { name => 'department', text => $department_name, value => $department_id };
  239. # LETS GET ALL THE ACCOUNTS
  240. my @account_options;
  241. @array_options = $dbPayment->list_accounting();
  242. for my $ref (0 .. $#array_options) {
  243. push @account_options, { value => $array_options[$ref]->{id},
  244. text => $array_options[$ref]->{description}};
  245. }
  246. # LETS GET THE POSSIBLE SOURCES
  247. my @sources_options;
  248. @array_options = $dbPayment->get_sources(\%$locale);
  249. for my $ref (0 .. $#array_options) {
  250. push @sources_options, { value => $array_options[$ref],
  251. text => $array_options[$ref]};
  252. }
  253. # WE MUST PREPARE THE ENTITY INFORMATION
  254. @array_options = $dbPayment->get_vc_info();
  255. # LETS BUILD THE CURRENCIES INFORMATION
  256. # FIRST, WE NEED TO KNOW THE DEFAULT CURRENCY
  257. my $default_currency = $dbPayment->get_default_currency();
  258. my @currency_options;
  259. # LETS BUILD THE COLUMN HEADERS WE ALWAYS NEED
  260. # THE OTHER HEADERS WILL BE BUILT IF THE RIGHT CONDITIONS ARE MET.
  261. # -----------------------------------------------
  262. # SOME USERS WONT USE MULTIPLE CURRENCIES, AND WONT LIKE THE FACT CURRENCY BEING
  263. # ON THE SCREEN ALL THE TIME, SO IF THEY ARE USING THE DEFAULT CURRENCY WE WONT PRINT IT
  264. my $currency_text = $request->{curr} eq $default_currency ? '' : '('.$request->{curr}.')';
  265. my $default_currency_text = $currency_text ? '('.$default_currency.')' : '';
  266. my @columnAS = ({text => $locale->text('Invoice')},
  267. {text => $locale->text('Date')},
  268. {text => $locale->text('Total').$default_currency_text},
  269. {text => $locale->text('Paid').$default_currency_text},
  270. {text => $locale->text('Amount Due').$default_currency_text},
  271. {text => $locale->text('To pay').$default_currency_text}
  272. );
  273. my @column_headers = ({text => $locale->text('Invoice')},
  274. {text => $locale->text('Date')},
  275. {text => $locale->text('Total').$default_currency_text},
  276. {text => $locale->text('Paid').$default_currency_text},
  277. {text => $locale->text('Amount Due').$default_currency_text},
  278. {text => $locale->text('To pay').$default_currency_text}
  279. );
  280. # WE NEED TO KNOW IF WE ARE USING A CURRENCY THAT NEEDS AN EXCHANGERATE
  281. if ($default_currency ne $request->{curr} ) {
  282. # FIRST WE PUSH THE OTHER COLUMN HEADERS WE NEED
  283. push @column_headers, {text => $locale->text('Exchange Rate')},
  284. {text => $locale->text('Amount Due').$currency_text},
  285. {text => $locale->text('To pay').$currency_text};
  286. # WE SET THEM IN THE RIGHT ORDER FOR THE TABLE INSIDE THE UI
  287. @column_headers[5,6,7] = @column_headers[6,7,5];
  288. # DOES THE CURRENCY IN USE HAS AN EXCHANGE RATE?, IF SO
  289. # WE MUST SET THE VALUE, OTHERWISE THE UI WILL HANDLE IT
  290. $exchangerate = $dbPayment->get_exchange_rate($request->{curr}, $dbPayment->{current_date});
  291. if ($exchangerate) {
  292. @currency_options = {
  293. name => 'date_curr',
  294. value => "$exchangerate", #THERE IS A STRANGE BEHAVIOUR WITH THIS,
  295. text => "$exchangerate" #IF I DONT USE THE DOUBLE QUOTES, IT WILL PRINT THE ADDRESS
  296. #THERE MUST BE A REASON FOR THIS, I MUST RETURN TO IT LATER
  297. };
  298. } else {
  299. @currency_options = {
  300. name => 'date_curr'};
  301. }
  302. } else {
  303. # WE MUST SET EXCHANGERATE TO 1 FOR THE MATHS SINCE WE
  304. # ARE USING THE DEFAULT CURRENCY
  305. $exchangerate = 1;
  306. }
  307. # WE NEED TO QUERY THE DATABASE TO CHECK FOR OPEN INVOICES
  308. # IF WE DONT HAVE ANY INVOICES MATCHING THE FILTER PARAMETERS, WE WILL WARN THE USER AND STOP
  309. # THE PROCCESS.
  310. my @invoice_data;
  311. @array_options = $dbPayment->get_open_invoices();
  312. if (!$array_options[0]->{invoice_id}) {
  313. $request->error($locale->text("Nothing to do"));
  314. }
  315. for my $ref (0 .. $#array_options) {
  316. push @invoice_data, { invoice => { number => $array_options[$ref]->{invnumber},
  317. href => 'ar.pl?id='."$array_options[$ref]->{invoice_id}"
  318. },
  319. invoice_date => "$array_options[$ref]->{invoice_date}",
  320. amount => "$array_options[$ref]->{amount}",
  321. due => "$array_options[$ref]->{due}",
  322. paid => "$array_options[$ref]->{amount}" - "$array_options[$ref]->{due}",
  323. exchange_rate => "$exchangerate",
  324. due_fx => "$exchangerate"? "$array_options[$ref]->{due}"/"$exchangerate" : 'N/A',
  325. topay => "$array_options[$ref]->{due}",
  326. topay_fx => { name => "topay_fx_$ref",
  327. value => "$exchangerate" ? "$array_options[$ref]->{due}"/"$exchangerate" : 'N/A'
  328. }
  329. };
  330. }
  331. # LETS BUILD THE SELECTION FOR THE UI
  332. my $select = {
  333. stylesheet => $request->{_user}->{stylesheet},
  334. header => { text => $request->{type} eq 'receipt' ? $locale->text('Receipt') : $locale->text('Payment') },
  335. project => @project,
  336. department => @department,
  337. account => {
  338. name => 'account',
  339. options => \@account_options},
  340. datepaid => {
  341. name => 'datepaid',
  342. value => $dbPayment->{current_date}
  343. },
  344. source => {
  345. name => 'source',
  346. options => \@sources_options
  347. },
  348. source_text => {
  349. name => 'source_text',
  350. },
  351. defaultcurrency => {
  352. text => $default_currency
  353. },
  354. curr => {
  355. text => $request->{curr}
  356. },
  357. column_headers => \@column_headers,
  358. rows => \@invoice_data,
  359. vc => { name => $vendor_customer_name,
  360. address => [ {text => 'Crra 83 #32 -1'},
  361. {text => '442 6464'},
  362. {text => 'Medellín'},
  363. {text => 'Colombia'}]},
  364. post => {
  365. accesskey => 'O',
  366. title => 'POST ALT+O',
  367. name => 'action',
  368. value => 'post',
  369. text => "POST"
  370. },
  371. post_and_print => {
  372. accesskey => 'R',
  373. title => 'POST AND PRINT ALT+R',
  374. name => 'action',
  375. value => 'post_and_print',
  376. text => "POST AND PRINT"
  377. },
  378. format => {
  379. name => 'FORMAT',
  380. options => [
  381. {value => 1, text => "HTML" },
  382. {value => 2, text => "PDF" },
  383. {value => 3, text => "POSTSCRIPT" }
  384. ],
  385. },
  386. media => {
  387. name => 'MEDIA',
  388. options => [
  389. {value => 1, text => "Screen" },
  390. {value => 2, text => "PRINTER" },
  391. {value => 3, text => "EMAIL" }
  392. ],
  393. },
  394. date_curr => @currency_options # I HAVE TO PUT THIS LAST, BECAUSE IT CAN BE NULL
  395. # THIS IS AN UGLY HACK THAT MUST BE FIXED.
  396. };
  397. my $template = LedgerSMB::Template->new(
  398. user => $request->{_user},
  399. locale => $request->{_locale},
  400. # path => 'UI/payments',
  401. path => 'UI',
  402. template => 'payment2',
  403. format => 'HTML' );
  404. eval {$template->render($select) };
  405. if ($@) { $request->error("$@"); }
  406. }
  407. eval { do "scripts/custom/payment.pl"};
  408. 1;