· 7 years ago · Nov 26, 2018, 03:24 PM
1<?php if (!defined('BASEPATH')) {
2
3 exit('No direct script access allowed');
4
5}
6
7
8
9class Invoices extends MY_Controller
10
11{
12
13 public function __construct()
14
15 {
16
17 parent::__construct();
18
19 $access = false;
20
21 if ($this->client) {
22
23 redirect('demoproject');
24
25 } elseif ($this->user) {
26
27 foreach ($this->view_data['menu'] as $key => $value) {
28
29 if ($value->link == 'invoices') {
30
31 $access = true;
32
33 }
34
35 }
36
37 if (!$access) {
38
39 redirect('login');
40
41 }
42
43 } else {
44
45 redirect('login');
46
47 }
48
49 $this->view_data['submenu'] = [
50
51 $this->lang->line('application_all') => 'All',
52
53 $this->lang->line('application_open') => 'Open',
54
55 $this->lang->line('application_Sent') => 'Sent',
56
57 $this->lang->line('application_Paid') => 'Paid',
58
59 $this->lang->line('application_Canceled') => 'Canceled',
60
61 $this->lang->line('application_Overdue') => 'Overdue',
62
63 $this->lang->line('application_PartiallyPaid') => 'PartiallyPaid',
64
65 ];
66
67 }
68
69
70
71 public function index()
72
73 {
74
75 if ($this->user->admin == 0) {
76
77 $comp_array = [];
78
79 $thisUserHasNoCompanies = (array) $this->user->companies;
80
81 if (!empty($thisUserHasNoCompanies)) {
82
83 foreach ($this->user->companies as $value) {
84
85 array_push($comp_array, $value->id);
86
87 }
88
89 $options = ['conditions' => ['estimate != ? AND company_id in (?)', 1, $comp_array]];
90
91 $this->view_data['invoices'] = Invoice::find('all', $options);
92
93 } else {
94
95 $this->view_data['invoices'] = (object) [];
96
97 }
98
99 } else {
100
101 $options = ['conditions' => ['estimate != ?', 1]];
102
103 $this->view_data['invoices'] = Invoice::find('all', $options);
104
105 }
106
107
108
109 $days_in_this_month = days_in_month(date('m'), date('Y'));
110
111 $lastday_in_month = strtotime(date('Y') . '-' . date('m') . '-' . $days_in_this_month);
112
113 $firstday_in_month = strtotime(date('Y') . '-' . date('m') . '-01');
114
115
116
117 $this->view_data['invoices_paid_this_month'] = Invoice::count(['conditions' => 'UNIX_TIMESTAMP(`paid_date`) <= ' . $lastday_in_month . ' and UNIX_TIMESTAMP(`paid_date`) >= ' . $firstday_in_month . ' AND estimate != 1 AND status = "paid"']);
118
119 $this->view_data['invoices_due_this_month'] = Invoice::count(['conditions' => 'UNIX_TIMESTAMP(`due_date`) <= ' . $lastday_in_month . ' and UNIX_TIMESTAMP(`due_date`) >= ' . $firstday_in_month . ' AND estimate != 1 AND status != "paid" AND status != "canceled"']);
120
121
122
123 //statistic
124
125 $now = time();
126
127 $beginning_of_week = strtotime('last Monday', $now); // BEGINNING of the week
128
129 $end_of_week = strtotime('next Sunday', $now) + 86400; // END of the last day of the week
130
131 $this->view_data['invoices_due_this_month_graph'] = Invoice::find_by_sql('select count(id) AS "amount", DATE_FORMAT(`due_date`, "%w") AS "date_day", DATE_FORMAT(`due_date`, "%Y-%m-%d") AS "date_formatted" from invoices where UNIX_TIMESTAMP(`due_date`) >= "' . $beginning_of_week . '" AND UNIX_TIMESTAMP(`due_date`) <= "' . $end_of_week . '" AND estimate != 1 GROUP BY invoices.due_date');
132
133 $this->view_data['invoices_paid_this_month_graph'] = Invoice::find_by_sql("SELECT
134
135 COUNT(id) AS 'amount',
136
137 DATE_FORMAT(`paid_date`, '%w') AS 'date_day',
138
139 DATE_FORMAT(`paid_date`, '%Y-%m-%d') AS 'date_formatted'
140
141FROM
142
143 invoices
144
145WHERE
146
147 UNIX_TIMESTAMP(`paid_date`) >= '$beginning_of_week'
148
149 AND UNIX_TIMESTAMP(`paid_date`) <= '$end_of_week'
150
151 AND estimate != 1
152
153GROUP BY invoices.paid_date");
154
155
156
157 $this->content_view = 'invoices/all';
158
159 }
160
161
162
163 public function calc()
164
165 {
166
167 $invoices = Invoice::find('all', ['conditions' => ['estimate != ?', 1]]);
168
169 foreach ($invoices as $invoice) {
170
171 $settings = Setting::first();
172
173
174
175 $items = InvoiceHasItem::find('all', ['conditions' => ['invoice_id=?', $invoice->id]]);
176
177
178
179 //calculate sum
180
181 $i = 0;
182
183 $sum = 0;
184
185 foreach ($items as $value) {
186
187 $sum = $sum + $invoice->invoice_has_items[$i]->amount * $invoice->invoice_has_items[$i]->value;
188
189 $i++;
190
191 }
192
193 if (substr($invoice->discount, -1) == '%') {
194
195 $discount = sprintf('%01.2f', round(($sum / 100) * substr($invoice->discount, 0, -1), 2));
196
197 } else {
198
199 $discount = $invoice->discount;
200
201 }
202
203 $sum = $sum - $discount;
204
205
206
207 if ($invoice->tax != '') {
208
209 $tax_value = $invoice->tax;
210
211 } else {
212
213 $tax_value = $settings->tax;
214
215 }
216
217
218
219 if ($invoice->second_tax != '') {
220
221 $second_tax_value = $invoice->second_tax;
222
223 } else {
224
225 $second_tax_value = $core_settings->second_tax;
226
227 }
228
229
230
231 $tax = sprintf('%01.2f', round(($sum / 100) * $tax_value, 2));
232
233 $second_tax = sprintf('%01.2f', round(($sum / 100) * $second_tax_value, 2));
234
235
236
237 $sum = sprintf('%01.2f', round($sum + $tax + $second_tax, 2));
238
239
240
241 $invoice->sum = $sum;
242
243 $invoice->save();
244
245 }
246
247 redirect('invoices');
248
249 }
250
251
252
253 public function filter($condition = 'All', $period = false)
254
255 {
256
257 $days_in_this_month = days_in_month(date('m'), date('Y'));
258
259 $lastday_in_month = date('Y') . '-' . date('m') . '-' . $days_in_this_month;
260
261 $firstday_in_month = date('Y') . '-' . date('m') . '-01';
262
263 $this->view_data['invoices_paid_this_month'] = Invoice::count(['conditions' => 'paid_date <= ' . $lastday_in_month . ' and paid_date >= ' . $firstday_in_month . ' AND estimate != 1']);
264
265 $this->view_data['invoices_due_this_month'] = Invoice::count(['conditions' => 'due_date <= ' . $lastday_in_month . ' and due_date >= ' . $firstday_in_month . ' AND estimate != 1']);
266
267
268
269 //statistic
270
271 $now = time();
272
273 $beginning_of_week = strtotime('last Monday', $now); // BEGINNING of the week
274
275 $end_of_week = strtotime('next Sunday', $now) + 86400; // END of the last day of the week
276
277 $this->view_data['invoices_due_this_month_graph'] = Invoice::find_by_sql('select count(id) AS "amount", DATE_FORMAT(`due_date`, "%w") AS "date_day", DATE_FORMAT(`due_date`, "%Y-%m-%d") AS "date_formatted" from invoices where UNIX_TIMESTAMP(`due_date`) >= "' . $beginning_of_week . '" AND UNIX_TIMESTAMP(`due_date`) <= "' . $end_of_week . '" AND estimate != 1 GROUP BY due_date');
278
279 $this->view_data['invoices_paid_this_month_graph'] = Invoice::find_by_sql('select count(id) AS "amount", DATE_FORMAT(`paid_date`, "%w") AS "date_day", DATE_FORMAT(`paid_date`, "%Y-%m-%d") AS "date_formatted" from invoices where UNIX_TIMESTAMP(`paid_date`) >= "' . $beginning_of_week . '" AND UNIX_TIMESTAMP(`paid_date`) <= "' . $end_of_week . '" AND estimate != 1 GROUP BY paid_date');
280
281
282
283 $this->view_data['condition'] = $condition;
284
285 $this->view_data['currentPeriod'] = $period;
286
287 $periodFilter = getPeriodFilter();
288
289
290
291 switch ($condition) {
292
293 case 'Open':
294
295 $option = 'status = "Open" and estimate != 1';
296
297 break;
298
299 case 'Sent':
300
301 $option = 'status = "Sent" and estimate != 1';
302
303 break;
304
305 case 'Paid':
306
307 $option = 'status = "Paid" and estimate != 1';
308
309 break;
310
311 case 'PartiallyPaid':
312
313 $option = 'status = "PartiallyPaid" and estimate != 1';
314
315 break;
316
317 case 'Canceled':
318
319 $option = 'status = "Canceled" and estimate != 1';
320
321 break;
322
323 case 'Overdue':
324
325 $option = '(status = "Open" OR status = "Sent" OR status = "PartiallyPaid") and estimate != 1 and due_date < "' . date('Y') . '-' . date('m') . '-' . date('d') . '" ';
326
327 break;
328
329 case 'All':
330
331 $option = 'estimate != 1';
332
333 break;
334
335 default:
336
337 $option = 'estimate != 1';
338
339 break;
340
341 }
342
343 if ($period && $period != "All") {
344
345 if($condition){
346
347 $option .= ' AND ';
348
349 }
350
351 $option .= '`issue_date` BETWEEN "' . $periodFilter[$period]['startdate']->format('Y-m-d'). '" AND ';
352
353 $option .= '"' . $periodFilter[$period]['enddate']->format('Y-m-d'). '" ';
354
355 }
356
357 if ($this->user->admin == 0) {
358
359 $comp_array = [];
360
361 $thisUserHasNoCompanies = (array) $this->user->companies;
362
363 if (!empty($thisUserHasNoCompanies)) {
364
365 foreach ($this->user->companies as $value) {
366
367 array_push($comp_array, $value->id);
368
369 }
370
371 $options = ['conditions' => [$option . ' AND company_id in (?)', $comp_array]];
372
373 $this->view_data['invoices'] = Invoice::find('all', $options);
374
375 } else {
376
377 $this->view_data['invoices'] = (object) [];
378
379 }
380
381 } else {
382
383 $options = ['conditions' => [$option]];
384
385 $this->view_data['invoices'] = Invoice::find('all', $options);
386
387 }
388
389
390
391 $this->content_view = 'invoices/all';
392
393 }
394
395
396
397 public function create()
398
399 {
400
401 if ($_POST) {
402
403 unset($_POST['send'], $_POST['_wysihtml5_mode'], $_POST['files']);
404
405
406
407 $invoice = Invoice::create($_POST);
408
409 $new_invoice_reference = $_POST['reference'] + 1;
410
411
412
413 $invoice_reference = Setting::first();
414
415 $invoice_reference->update_attributes(['invoice_reference' => $new_invoice_reference]);
416
417 if (!$invoice) {
418
419 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_create_invoice_error'));
420
421 } else {
422
423 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_create_invoice_success'));
424
425 }
426
427 redirect('invoices');
428
429 } else {
430
431 $this->view_data['invoices'] = Invoice::all();
432
433 $this->view_data['next_reference'] = Invoice::last();
434
435 if ($this->user->admin != 1) {
436
437 $comp_array = [];
438
439 foreach ($this->user->companies as $value) {
440
441 array_push($comp_array, $value->id);
442
443 }
444
445 $this->view_data['companies'] = $this->user->companies;
446
447 } else {
448
449 $this->view_data['companies'] = Company::find('all', ['conditions' => ['inactive=?', '0']]);
450
451 }
452
453
454
455 $this->theme_view = 'modal';
456
457 $this->view_data['title'] = $this->lang->line('application_create_invoice');
458
459 $this->view_data['form_action'] = 'invoices/create';
460
461 $this->content_view = 'invoices/_invoice';
462
463 }
464
465 }
466
467
468
469 public function update($id = false, $getview = false)
470
471 {
472
473 if ($_POST) {
474
475 unset($_POST['send'], $_POST['_wysihtml5_mode'], $_POST['files']);
476
477
478
479 $id = $_POST['id'];
480
481 $view = false;
482
483 if (isset($_POST['view'])) {
484
485 $view = $_POST['view'];
486
487 }
488
489 unset($_POST['view']);
490
491 $invoice = Invoice::find($id);
492
493 if ($_POST['status'] == 'Paid' && !isset($_POST['paid_date'])) {
494
495 $_POST['paid_date'] = date('Y-m-d', time());
496
497 }
498
499 if ($_POST['status'] == 'Sent' && $invoice->status != 'Sent' && !isset($_POST['sent_date'])) {
500
501 $_POST['sent_date'] = date('Y-m-d', time());
502
503 }
504
505
506
507 $invoice->update_attributes($_POST);
508
509
510
511 if (!$invoice) {
512
513 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_save_invoice_error'));
514
515 } else {
516
517 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_save_invoice_success'));
518
519 }
520
521 if ($view == 'true') {
522
523 redirect('invoices/view/' . $id);
524
525 } else {
526
527 redirect('invoices');
528
529 }
530
531 } else {
532
533 $this->view_data['invoice'] = Invoice::find($id);
534
535 if ($this->user->admin != 1) {
536
537 $comp_array = [];
538
539 foreach ($this->user->companies as $value) {
540
541 array_push($comp_array, $value->id);
542
543 }
544
545 $this->view_data['companies'] = $this->user->companies;
546
547 } else {
548
549 $this->view_data['companies'] = Company::find('all', ['conditions' => ['inactive=?', '0']]);
550
551 }
552
553 //$this->view_data['projects'] = Project::all();
554
555 //$this->view_data['companies'] = Company::find('all',array('conditions' => array('inactive=?','0')));
556
557 if ($getview == 'view') {
558
559 $this->view_data['view'] = 'true';
560
561 }
562
563 $this->theme_view = 'modal';
564
565 $this->view_data['title'] = $this->lang->line('application_edit_invoice');
566
567 $this->view_data['form_action'] = 'invoices/update';
568
569 $this->content_view = 'invoices/_invoice';
570
571 }
572
573 }
574
575
576
577 public function view($id = false)
578
579 {
580
581 $this->view_data['submenu'] = [
582
583 $this->lang->line('application_back') => 'invoices',
584
585 ];
586
587
588
589 $this->view_data['invoice'] = Invoice::find($id);
590
591
592
593 if ($this->user->admin != 1) {
594
595 $comp_array = [];
596
597 foreach ($this->user->companies as $value) {
598
599 array_push($comp_array, $value->id);
600
601 }
602
603 if (!in_array($this->view_data['invoice']->company_id, $comp_array)) {
604
605 redirect('invoices');
606
607 }
608
609 }
610
611
612
613 $data['core_settings'] = Setting::first();
614
615 $invoice = $this->view_data['invoice'];
616
617 $this->view_data['items'] = $invoice->invoice_has_items;
618
619
620
621 // Calculate invoice sum
622
623 $invoice = Invoice::calculateSum($invoice);
624
625
626
627 $this->content_view = 'invoices/view';
628
629 }
630
631
632
633 public function banktransfer($id = false, $sum = false)
634
635 {
636
637 $this->theme_view = 'modal';
638
639 $this->view_data['title'] = $this->lang->line('application_bank_transfer');
640
641
642
643 $data['core_settings'] = Setting::first();
644
645 $this->view_data['invoice'] = Invoice::find($id);
646
647 $this->content_view = 'invoices/_banktransfer';
648
649 }
650
651
652
653 public function payment($id = false)
654
655 {
656
657 if ($_POST) {
658
659 $this->load->helper('notification');
660
661
662
663 $receipt = (isset($_POST['receipt'])) ? true : false;
664
665 unset($_POST['send'], $_POST['receipt'], $_POST['_wysihtml5_mode'], $_POST['files']);
666
667
668
669 $_POST['user_id'] = $this->user->id;
670
671 $_POST['amount'] = str_replace(',', '.', $_POST['amount']);
672
673 $invoice = Invoice::find_by_id($_POST['invoice_id']);
674
675 $invoiceHasPayment = InvoiceHasPayment::create($_POST);
676
677
678
679 if ($invoice->outstanding == $_POST['amount']) {
680
681 $new_status = 'Paid';
682
683 $payment_date = $_POST['date'];
684
685 } else {
686
687 $new_status = 'PartiallyPaid';
688
689 }
690
691
692
693 $invoice->update_attributes(['status' => $new_status]);
694
695 if (isset($payment_date)) {
696
697 $invoice->update_attributes(['paid_date' => $payment_date]);
698
699 }
700
701 if (!$invoiceHasPayment) {
702
703 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_create_payment_error'));
704
705 } else {
706
707 if($receipt){
708
709 receipt_notification($invoice->company->client->id, false, $invoiceHasPayment->id);
710
711 }
712
713 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_create_payment_success'));
714
715 }
716
717 redirect('invoices/view/' . $_POST['invoice_id']);
718
719 } else {
720
721 $this->view_data['invoice'] = Invoice::find_by_id($id);
722
723 $this->view_data['payment_reference'] = InvoiceHasPayment::count(['conditions' => 'invoice_id = ' . $id]) + 1;
724
725 $this->view_data['sumRest'] = sprintf('%01.2f', round($this->view_data['invoice']->sum - $this->view_data['invoice']->paid, 2));
726
727
728
729 $this->theme_view = 'modal';
730
731 $this->view_data['title'] = $this->lang->line('application_add_payment');
732
733 $this->view_data['form_action'] = 'invoices/payment';
734
735 $this->content_view = 'invoices/_payment';
736
737 }
738
739 }
740
741
742
743 public function payment_update($id = false)
744
745 {
746
747 if ($_POST) {
748
749 unset($_POST['send'], $_POST['_wysihtml5_mode'], $_POST['files']);
750
751
752
753 $_POST['amount'] = str_replace(',', '.', $_POST['amount']);
754
755
756
757 $payment = InvoiceHasPayment::find_by_id($_POST['id']);
758
759 $invoice_id = $payment->invoice_id;
760
761 $payment = $payment->update_attributes($_POST);
762
763
764
765 $invoice = Invoice::find_by_id($invoice_id);
766
767 $payment = 0;
768
769 $i = 0;
770
771 $payments = $invoice->invoice_has_payments;
772
773 if (isset($payments)) {
774
775 foreach ($payments as $value) {
776
777 $payment = sprintf('%01.2f', round($payment + $payments[$i]->amount, 2));
778
779 $i++;
780
781 }
782
783 }
784
785 $paymentsum = sprintf('%01.2f', round($payment + $_POST['amount'], 2));
786
787 if ($invoice->sum <= $paymentsum) {
788
789 $new_status = 'Paid';
790
791 $payment_date = $_POST['date'];
792
793 } else {
794
795 $new_status = 'PartiallyPaid';
796
797 }
798
799 $invoice->update_attributes(['status' => $new_status]);
800
801 if (isset($payment_date)) {
802
803 $invoice->update_attributes(['paid_date' => $payment_date]);
804
805 }
806
807 if (!$payment) {
808
809 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_edit_payment_error'));
810
811 } else {
812
813 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_edit_payment_success'));
814
815 }
816
817 redirect('invoices/view/' . $_POST['invoice_id']);
818
819 } else {
820
821 $this->view_data['payment'] = InvoiceHasPayment::find_by_id($id);
822
823 $this->view_data['invoice'] = Invoice::find_by_id($this->view_data['payment']->invoice_id);
824
825 $this->theme_view = 'modal';
826
827 $this->view_data['title'] = $this->lang->line('application_add_payment');
828
829 $this->view_data['form_action'] = 'invoices/payment_update';
830
831 $this->content_view = 'invoices/_payment';
832
833 }
834
835 }
836
837
838
839 public function payment_delete($id = false, $invoice_id = false)
840
841 {
842
843 $item = InvoiceHasPayment::find_by_id($id);
844
845 $item->delete();
846
847 $this->content_view = 'invoices/view';
848
849 if (!$item) {
850
851 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_delete_payment_error'));
852
853 } else {
854
855 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_delete_payment_success'));
856
857 }
858
859 redirect('invoices/view/' . $invoice_id);
860
861 }
862
863
864
865 public function twocheckout($id = false, $sum = false)
866
867 {
868
869 $data['core_settings'] = Setting::first();
870
871
872
873 if ($_POST) {
874
875 $invoice = Invoice::find_by_id($_POST['id']);
876
877 $invoice_reference = $data['core_settings']->invoice_prefix . $invoice->reference;
878
879 $this->load->file(APPPATH . 'helpers/2checkout/Twocheckout.php', true);
880
881 $token = $_POST['token'];
882
883 Twocheckout::privateKey($data['core_settings']->twocheckout_private_key);
884
885 Twocheckout::sellerId($data['core_settings']->twocheckout_seller_id);
886
887 //Twocheckout::sandbox(true); #Uncomment to use Sandbox
888
889
890
891 //Get currency
892
893 $currency = $invoice->currency;
894
895 $currency_codes = getCurrencyCodesForTwocheckout();
896
897 if (!array_key_exists($currency, $currency_codes)) {
898
899 $currency = $data['core_settings']->twocheckout_currency;
900
901 }
902
903 $total = floatval(str_replace(",", "", $_POST['sum']));
904
905 try {
906
907 $charge = Twocheckout_Charge::auth([
908
909 "sellerId" => $data['core_settings']->twocheckout_seller_id,
910
911 'merchantOrderId' => $invoice->reference,
912
913 'token' => $_POST['token'],
914
915 'currency' => $currency,
916
917 'total' => $total,
918
919 'billingAddr' => [
920
921 'name' => $invoice->company->name,
922
923 'addrLine1' => $invoice->company->address,
924
925 'city' => $invoice->company->city,
926
927 'state' => $invoice->company->province,
928
929 'zipCode' => $invoice->company->zipcode,
930
931 'country' => $invoice->company->country,
932
933 'email' => $invoice->company->client->email,
934
935 'phoneNumber' => $invoice->company->phone
936
937 ]
938
939 ]);
940
941
942
943 if ($charge['response']['responseCode'] == 'APPROVED') {
944
945
946
947 $attr = [];
948
949 $paid_date = date('Y-m-d', time());
950
951 $payment_reference = $invoice->reference . '00' . InvoiceHasPayment::count(['conditions' => 'invoice_id = ' . $invoice->id]) + 1;
952
953 $attributes = ['invoice_id' => $invoice->id, 'reference' => $payment_reference, 'amount' => $_POST['sum'], 'date' => $paid_date, 'type' => 'credit_card', 'notes' => ''];
954
955 $invoiceHasPayment = InvoiceHasPayment::create($attributes);
956
957
958
959 if ($_POST['sum'] >= $invoice->outstanding) {
960
961 $invoice->update_attributes(['paid_date' => $paid_date, 'status' => 'Paid']);
962
963 } else {
964
965 $invoice->update_attributes(['status' => 'PartiallyPaid']);
966
967 }
968
969
970
971 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_payment_complete'));
972
973 log_message('error', '2Checkout: Payment of ' . $_POST['sum'] . ' for invoice ' . $invoice_reference . ' received!');
974
975 }
976
977 } catch (Twocheckout_Error $e) {
978
979 $this->session->set_flashdata('message', 'error: Your payment could NOT be processed (i.e., you have not been charged) because the payment system rejected the transaction.');
980
981 log_message('error', '2Checkout: Payment of invoice ' . $invoice_reference . ' failed - ' . $e->getMessage());
982
983 }
984
985 redirect('invoices/view/' . $_POST['id']);
986
987 } else {
988
989 $this->view_data['invoices'] = Invoice::find_by_id($id);
990
991
992
993 $this->view_data['publishable_key'] = $data['core_settings']->twocheckout_publishable_key;
994
995 $this->view_data['seller_id'] = $data['core_settings']->twocheckout_seller_id;
996
997
998
999 $this->view_data['sum'] = $sum;
1000
1001 $this->theme_view = 'modal';
1002
1003 $this->view_data['title'] = $this->lang->line('application_pay_with_credit_card');
1004
1005 $this->view_data['form_action'] = 'invoices/twocheckout';
1006
1007 $this->content_view = 'invoices/_2checkout';
1008
1009 }
1010
1011 }
1012
1013
1014
1015 public function stripepay($id = false, $sum = false, $type = 'card')
1016
1017 {
1018
1019 $data['core_settings'] = Setting::first();
1020
1021
1022
1023 $stripe_keys = [
1024
1025 'secret_key' => $data['core_settings']->stripe_p_key,
1026
1027 'publishable_key' => $data['core_settings']->stripe_key
1028
1029 ];
1030
1031
1032
1033 if ($_POST) {
1034
1035 unset($_POST['send']);
1036
1037 $invoice = Invoice::find($_POST['id']);
1038
1039 // Stores errors:
1040
1041 $errors = [];
1042
1043
1044
1045 // Need a payment token:
1046
1047 if (isset($_POST['stripeToken'])) {
1048
1049 $token = $_POST['stripeToken'];
1050
1051
1052
1053 // Check for a duplicate submission, just in case:
1054
1055 // Uses sessions, you could use a cookie instead.
1056
1057 if (isset($_SESSION['token']) && ($_SESSION['token'] == $token)) {
1058
1059 $errors['token'] = 'You have apparently resubmitted the form. Please do not do that.';
1060
1061 $this->session->set_flashdata('message', 'error: You have apparently resubmitted the form. Please do not do that.');
1062
1063 } else { // New submission.
1064
1065 $_SESSION['token'] = $token;
1066
1067 }
1068
1069 } else {
1070
1071 $this->session->set_flashdata('message', 'error: The order cannot be processed. Please make sure you have JavaScript enabled and try again.');
1072
1073 $errors['token'] = 'The order cannot be processed. Please make sure you have JavaScript enabled and try again.';
1074
1075 log_message('error', 'Stripe: ERROR - Payment canceled for invoice #' . $data['core_settings']->invoice_prefix . $invoice->reference . '.');
1076
1077 }
1078
1079
1080
1081 // Set the order amount somehow:
1082
1083 $sum_exp = explode('.', $_POST['sum']);
1084
1085 $amount = $sum_exp[0] * 100 + $sum_exp[1]; // in cents
1086
1087
1088
1089 //Get currency
1090
1091
1092
1093 $currency = $invoice->currency;
1094
1095 $currency_codes = getCurrencyCodes();
1096
1097 if (!array_key_exists($currency, $currency_codes)) {
1098
1099 $currency = $data['core_settings']->stripe_currency;
1100
1101 }
1102
1103
1104
1105 // If no errors, process the order:
1106
1107 if (empty($errors)) {
1108
1109 // create the charge on Stripe's servers - this will charge the user's card
1110
1111 try {
1112
1113 // Set API key for stripe:
1114
1115 \Stripe\Stripe::setApiKey($stripe_keys['secret_key']);
1116
1117
1118
1119 // Charge the order:
1120
1121 $charge = \Stripe\Charge::create(
1122
1123 [
1124
1125 'amount' => $amount, // amount in cents, again
1126
1127 'currency' => $currency,
1128
1129 'card' => $token,
1130
1131 'receipt_email' => $invoice->company->client->email,
1132
1133 'description' => $data['core_settings']->invoice_prefix . $invoice->reference,
1134
1135 ]
1136
1137 );
1138
1139
1140
1141 // Check that it was paid:
1142
1143 if ($charge->paid == true) {
1144
1145 $attr = [];
1146
1147 $paid_date = date('Y-m-d', time());
1148
1149 $payment_reference = $invoice->reference . '00' . InvoiceHasPayment::count(['conditions' => 'invoice_id = ' . $invoice->id]) + 1;
1150
1151 $attributes = ['invoice_id' => $invoice->id, 'reference' => $payment_reference, 'amount' => $_POST['sum'], 'date' => $paid_date, 'type' => 'credit_card', 'notes' => ''];
1152
1153 $invoiceHasPayment = InvoiceHasPayment::create($attributes);
1154
1155
1156
1157 if ($_POST['sum'] >= $invoice->outstanding) {
1158
1159 $invoice->update_attributes(['paid_date' => $paid_date, 'status' => 'Paid']);
1160
1161 } else {
1162
1163 $invoice->update_attributes(['status' => 'PartiallyPaid']);
1164
1165 }
1166
1167
1168
1169 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_payment_complete'));
1170
1171 log_message('error', 'Stripe: Payment for Invoice #' . $data['core_settings']->invoice_prefix . $invoice->reference . ' successfully made');
1172
1173 } else { // Charge was not paid!
1174
1175 $this->session->set_flashdata('message', 'error: Your payment could NOT be processed (i.e., you have not been charged) because the payment system rejected the transaction.');
1176
1177 log_message('error', 'Stripe: ERROR - Payment for Invoice #' . $data['core_settings']->invoice_prefix . $invoice->reference . ' was not successful!');
1178
1179 }
1180
1181 } catch (\Stripe\Error\Card $e) {
1182
1183 // Card was declined.
1184
1185 $e_json = $e->getJsonBody();
1186
1187 $err = $e_json['error'];
1188
1189 $errors['stripe'] = $err['message'];
1190
1191 $this->session->set_flashdata('message', 'error: Card was declined!');
1192
1193 log_message('error', 'Stripe: ERROR - Credit Card was declined by Stripe! Payment process canceled for invoice #' . $data['core_settings']->invoice_prefix . $invoice->reference . '.');
1194
1195 } catch (\Stripe\Error\RateLimit $e) {
1196
1197 // Too many requests made to the API too quickly
1198
1199 $e_json = $e->getJsonBody();
1200
1201 $err = $e_json['error'];
1202
1203 $this->session->set_flashdata('message', 'error: Too many requests made to the API too quickly!');
1204
1205 log_message('error', 'Too many stripe requests: ' . $err['message']);
1206
1207 } catch (\Stripe\Error\Authentication $e) {
1208
1209 $e_json = $e->getJsonBody();
1210
1211 $err = $e_json['error'];
1212
1213 $this->session->set_flashdata('message', 'error: Payment could not be processed!');
1214
1215 log_message('error', 'Stripe authentication error: ' . $err['message']);
1216
1217 } catch (\Stripe\Error\InvalidRequest $e) {
1218
1219 $e_json = $e->getJsonBody();
1220
1221 $err = $e_json['error'];
1222
1223 $this->session->set_flashdata('message', 'error: Payment could not be processed!');
1224
1225 log_message('error', 'Stripe invalid request error: ' . $err['message']);
1226
1227 } catch (\Stripe\Error\ApiConnection $e) {
1228
1229 $e_json = $e->getJsonBody();
1230
1231 $err = $e_json['error'];
1232
1233 $this->session->set_flashdata('message', 'error: Payment could not be processed!');
1234
1235 log_message('error', 'Stripe API connection error: ' . $err['message']);
1236
1237 } catch (\Stripe\Error\Base $e) {
1238
1239 $e_json = $e->getJsonBody();
1240
1241 $err = $e_json['error'];
1242
1243 $this->session->set_flashdata('message', 'error: Payment could not be processed!');
1244
1245 log_message('error', 'Stripe error: ' . $err['message']);
1246
1247 } catch (Exception $e) {
1248
1249 $e_json = $e->getJsonBody();
1250
1251 $err = $e_json['error'];
1252
1253 $this->session->set_flashdata('message', 'error: Payment could not be processed!');
1254
1255 log_message('error', 'Error during stripe process: ' . $err['message']);
1256
1257 }
1258
1259 } else {
1260
1261 $this->session->set_flashdata('message', 'error: ' . $errors['token']);
1262
1263 log_message('error', 'Stripe: ' . $errors['token']);
1264
1265 }
1266
1267
1268
1269 redirect('invoices/view/' . $_POST['id']);
1270
1271 } else {
1272
1273 $this->view_data['invoices'] = Invoice::find_by_id($id);
1274
1275
1276
1277 $this->view_data['public_key'] = $data['core_settings']->stripe_key;
1278
1279 $this->view_data['sum'] = $sum;
1280
1281 $this->theme_view = 'modal';
1282
1283
1284
1285 switch ($type) {
1286
1287 case 'ideal':
1288
1289 $this->view_data['form_action'] = 'invoices/idealpay';
1290
1291 $this->view_data['title'] = $this->lang->line('application_pay_with_ideal');
1292
1293 $this->content_view = 'invoices/_stripe_ideal';
1294
1295 break;
1296
1297 default:
1298
1299 $this->view_data['form_action'] = 'invoices/stripepay';
1300
1301 $this->view_data['title'] = $this->lang->line('application_pay_with_credit_card');
1302
1303 $this->content_view = 'invoices/_stripe';
1304
1305 break;
1306
1307 }
1308
1309 }
1310
1311 }
1312
1313
1314
1315 public function idealpay($id = false, $sum = false)
1316
1317 {
1318
1319 $core_settings = Setting::first();
1320
1321 // Set API key for stripe:
1322
1323 \Stripe\Stripe::setApiKey($core_settings->stripe_p_key);
1324
1325 // Get Stripe source from url source id
1326
1327 $source = \Stripe\Source::retrieve($_GET['source']);
1328
1329 // Find invoice and get currecny
1330
1331 $invoice = Invoice::find_by_id($id);
1332
1333 $currency = $invoice->currency;
1334
1335
1336
1337 $sum_exp = explode('.', $sum);
1338
1339 $amount = $sum_exp[0] * 100 + $sum_exp[1]; // in cents
1340
1341
1342
1343 switch ($source->status) {
1344
1345 case 'chargeable':
1346
1347 $create = \Stripe\Charge::create([
1348
1349 'amount' => $amount,
1350
1351 'currency' => $currency,
1352
1353 'source' => $_GET['source'],
1354
1355 ]);
1356
1357
1358
1359 if ($create->status == 'succeeded') {
1360
1361 $attr = [];
1362
1363 $paid_date = date('Y-m-d', time());
1364
1365 $payment_reference = $invoice->reference . '00' . InvoiceHasPayment::count(['conditions' => 'invoice_id = ' . $invoice->id]) + 1;
1366
1367 $attributes = ['invoice_id' => $invoice->id, 'reference' => $payment_reference, 'amount' => $sum, 'date' => $paid_date, 'type' => 'iDEAL', 'notes' => ''];
1368
1369 $invoiceHasPayment = InvoiceHasPayment::create($attributes);
1370
1371
1372
1373 if ($sum >= $invoice->outstanding) {
1374
1375 $invoice->update_attributes(['paid_date' => $paid_date, 'status' => 'Paid']);
1376
1377 } else {
1378
1379 $invoice->update_attributes(['status' => 'PartiallyPaid']);
1380
1381 }
1382
1383
1384
1385 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_payment_complete'));
1386
1387 log_message('error', 'Stripe: Payment for Invoice #' . $core_settings->invoice_prefix . $invoice->reference . ' successfully made with iDEAL.');
1388
1389 redirect('invoices/view/' . $id);
1390
1391 } else {
1392
1393 $this->session->set_flashdata('message', 'error: Payment could not be processed!');
1394
1395 log_message('error', 'iDEAL Payment was canceled!');
1396
1397 redirect('invoices/view/' . $id);
1398
1399 }
1400
1401
1402
1403 break;
1404
1405 case 'canceled':
1406
1407 $this->session->set_flashdata('message', 'error: Payment could not be processed!');
1408
1409 log_message('error', 'iDEAL Payment was canceled!');
1410
1411 break;
1412
1413 case 'consumed':
1414
1415 $this->session->set_flashdata('message', 'error: Payment already completed!');
1416
1417 log_message('error', 'iDEAL Payment was called again but already compleated!');
1418
1419 break;
1420
1421 case 'failed':
1422
1423 $this->session->set_flashdata('message', 'error: Payment failed!');
1424
1425 log_message('error', 'iDEAL Payment failed during process!');
1426
1427 break;
1428
1429 }
1430
1431
1432
1433 redirect('invoices/view/' . $id);
1434
1435 }
1436
1437
1438
1439 public function authorizenet($id = false)
1440
1441 {
1442
1443 if ($_POST) {
1444
1445 // Authorize.net lib
1446
1447 $data['core_settings'] = Setting::first();
1448
1449 $this->load->library('authorize_net');
1450
1451 $invoice = Invoice::find_by_id($_POST['invoice_id']);
1452
1453 log_message('error', 'Authorize.net: Payment process started for invoice: #' . $data['core_settings']->invoice_prefix . $invoice->reference);
1454
1455
1456
1457 $amount = $_POST['sum'];
1458
1459
1460
1461 $auth_net = [
1462
1463 'x_card_num' => str_replace(' ', '', $_POST['x_card_num']),
1464
1465 'x_exp_date' => $_POST['x_card_month'] . '/' . $_POST['x_card_year'],
1466
1467 'x_card_code' => $_POST['x_card_code'],
1468
1469 'x_description' => $this->lang->line('application_invoice') . ' #' . $data['core_settings']->invoice_prefix . $invoice->reference,
1470
1471 'x_amount' => $amount,
1472
1473 'x_first_name' => $invoice->company->client->firstname,
1474
1475 'x_last_name' => $invoice->company->client->lastname,
1476
1477 'x_address' => $invoice->company->address,
1478
1479 'x_city' => $invoice->company->city,
1480
1481 //'x_state' => 'KY',
1482
1483 'x_zip' => $invoice->company->zipcode,
1484
1485 //'x_country' => 'US',
1486
1487 'x_phone' => $invoice->company->phone,
1488
1489 'x_email' => $invoice->company->client->email,
1490
1491 'x_customer_ip' => $this->input->ip_address(),
1492
1493 ];
1494
1495 $this->authorize_net->setData($auth_net);
1496
1497 // Try to AUTH_CAPTURE
1498
1499 if ($this->authorize_net->authorizeAndCapture()) {
1500
1501 $this->session->set_flashdata('message', 'success: ' . $this->lang->line('messages_payment_complete'));
1502
1503
1504
1505 log_message('error', 'Authorize.net: Transaction ID: ' . $this->authorize_net->getTransactionId());
1506
1507 log_message('error', 'Authorize.net: Approval Code: ' . $this->authorize_net->getApprovalCode());
1508
1509 log_message('error', 'Authorize.net: Payment completed.');
1510
1511 $invoice->status = 'Paid';
1512
1513 $invoice->paid_date = date('Y-m-d', time());
1514
1515
1516
1517 $invoice->save();
1518
1519 $attributes = ['invoice_id' => $invoice->id, 'reference' => $this->authorize_net->getTransactionId(), 'amount' => $amount, 'date' => date('Y-m-d', time()), 'type' => 'credit_card', 'notes' => $this->authorize_net->getApprovalCode()];
1520
1521 $invoiceHasPayment = InvoiceHasPayment::create($attributes);
1522
1523 redirect('invoices/view/' . $invoice->id);
1524
1525 } else {
1526
1527 log_message('error', 'Authorize.net: Payment failed.');
1528
1529 log_message('error', 'Authorize.net: ' . $this->authorize_net->getError());
1530
1531
1532
1533 $this->view_data['return_link'] = 'invoices/view/' . $invoice->id;
1534
1535
1536
1537 $this->view_data['message'] = $this->authorize_net->getError();
1538
1539 //$this->authorize_net->debug();
1540
1541
1542
1543 $this->content_view = 'error/error';
1544
1545 }
1546
1547 } else {
1548
1549 $this->view_data['invoices'] = Invoice::find_by_id($id);
1550
1551 $this->view_data['settings'] = Setting::first();
1552
1553 $this->view_data['sum'] = sprintf('%01.2f', $this->view_data['invoices']->outstanding);
1554
1555
1556
1557 $this->theme_view = 'modal';
1558
1559 $this->view_data['title'] = $this->lang->line('application_pay_with_credit_card');
1560
1561 $this->view_data['form_action'] = 'invoices/authorizenet';
1562
1563 $this->content_view = 'invoices/_authorizenet';
1564
1565 }
1566
1567 }
1568
1569
1570
1571 public function delete($id = false)
1572
1573 {
1574
1575 $invoice = Invoice::find($id);
1576
1577 $invoice->delete();
1578
1579 $this->content_view = 'invoices/all';
1580
1581 if (!$invoice) {
1582
1583 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_delete_invoice_error'));
1584
1585 } else {
1586
1587 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_delete_invoice_success'));
1588
1589 }
1590
1591 redirect('invoices');
1592
1593 }
1594
1595
1596
1597 public function preview($id = false, $attachment = false)
1598
1599 {
1600
1601 $this->load->helper(['dompdf', 'file']);
1602
1603 $this->load->library('parser');
1604
1605 $data['invoice'] = Invoice::find($id);
1606
1607 $data['items'] = InvoiceHasItem::find('all', ['conditions' => ['invoice_id=?', $id]]);
1608
1609 $data['core_settings'] = Setting::first();
1610
1611
1612
1613 $invoice_project = (is_object($data['invoice']->project)) ? $data['core_settings']->invoice_prefix . $data['invoice']->project->reference . ' - ' . $data['invoice']->project->name : '';
1614
1615
1616
1617
1618
1619 $due_date = date($data['core_settings']->date_format, human_to_unix($data['invoice']->due_date . ' 00:00:00'));
1620
1621 $parse_data = [
1622
1623 'client_contact' => $data['invoice']->company->client->firstname . ' ' . $data['invoice']->company->client->lastname,
1624
1625 'client_company' => $data['invoice']->company->name,
1626
1627 'due_date' => $due_date,
1628
1629 'invoice_project' => $invoice_project,
1630
1631 'invoice_id' => $data['core_settings']->invoice_prefix . $data['invoice']->reference,
1632
1633 'balance' => display_money($data['invoice']->outstanding, $data['invoice']->currency),
1634
1635 'client_link' => $data['core_settings']->domain,
1636
1637 'invoice_link' => base_url() . 'cinvoices/view/' . $data['invoice']->id,
1638
1639 'company' => $data['core_settings']->company,
1640
1641 'logo' => '<img src="' . base_url() . '' . $data['core_settings']->logo . '" alt="' . $data['core_settings']->company . '"/>',
1642
1643 'invoice_logo' => '<img src="' . base_url() . '' . $data['core_settings']->invoice_logo . '" alt="' . $data['core_settings']->company . '"/>'
1644
1645
1646
1647 ];
1648
1649 $html = $this->load->view($data['core_settings']->template . '/' . $data['core_settings']->invoice_pdf_template, $data, true);
1650
1651 $html = $this->parser->parse_string($html, $parse_data);
1652
1653
1654
1655 $filename = $this->lang->line('application_invoice') . '_' . $data['core_settings']->invoice_prefix . $data['invoice']->reference;
1656
1657 pdf_create($html, $filename, true, $attachment);
1658
1659 }
1660
1661
1662
1663 public function previewHTML($id = false)
1664
1665 {
1666
1667 $this->load->helper(['file']);
1668
1669 $this->load->library('parser');
1670
1671 $data['htmlPreview'] = true;
1672
1673 $data['invoice'] = Invoice::find($id);
1674
1675 $data['items'] = InvoiceHasItem::find('all', ['conditions' => ['invoice_id=?', $id]]);
1676
1677 $data['core_settings'] = Setting::first();
1678
1679
1680
1681 $invoice_project = (is_object($data['invoice']->project)) ? $data['core_settings']->invoice_prefix.$data['invoice']->project->reference.' - '.$data['invoice']->project->name : '';
1682
1683
1684
1685 $due_date = date($data['core_settings']->date_format, human_to_unix($data['invoice']->due_date . ' 00:00:00'));
1686
1687 $parse_data = [
1688
1689 'client_contact' => $data['invoice']->company->client->firstname . ' ' . $data['invoice']->company->client->lastname,
1690
1691 'client_company' => $data['invoice']->company->name,
1692
1693 'due_date' => $due_date,
1694
1695 'invoice_project' => $invoice_project,
1696
1697 'invoice_id' => $data['core_settings']->invoice_prefix . $data['invoice']->reference,
1698
1699 'balance' => display_money($data['invoice']->outstanding, $data['invoice']->currency),
1700
1701 'client_link' => $data['core_settings']->domain,
1702
1703 'invoice_link' => base_url() . 'cinvoices/view/' . $data['invoice']->id,
1704
1705 'company' => $data['core_settings']->company,
1706
1707 'logo' => '<img src="' . base_url() . '' . $data['core_settings']->logo . '" alt="' . $data['core_settings']->company . '"/>',
1708
1709 'invoice_logo' => '<img src="' . base_url() . '' . $data['core_settings']->invoice_logo . '" alt="' . $data['core_settings']->company . '"/>'
1710
1711
1712
1713 ];
1714
1715 $html = $this->load->view($data['core_settings']->template . '/' . $data['core_settings']->invoice_pdf_template, $data, true);
1716
1717 $html = $this->parser->parse_string($html, $parse_data);
1718
1719 $this->theme_view = 'blank';
1720
1721 $this->content_view = 'invoices/_preview';
1722
1723 }
1724
1725
1726
1727 public function sendinvoice($id = false)
1728
1729 {
1730
1731 $this->load->helper(['dompdf', 'file']);
1732
1733 $this->load->library('parser');
1734
1735
1736
1737 $data['invoice'] = Invoice::find($id);
1738
1739 $data['items'] = InvoiceHasItem::find('all', ['conditions' => ['invoice_id=?', $id]]);
1740
1741 $data['core_settings'] = Setting::first();
1742
1743 $due_date = date($data['core_settings']->date_format, human_to_unix($data['invoice']->due_date . ' 00:00:00'));
1744
1745 $invoice_project = (is_object($data['invoice']->project)) ? $data['core_settings']->invoice_prefix.$data['invoice']->project->reference.' - '.$data['invoice']->project->name : '';
1746
1747 //Set parse values
1748
1749 $parse_data = [
1750
1751 'client_contact' => $data['invoice']->company->client->firstname . ' ' . $data['invoice']->company->client->lastname,
1752
1753 'client_company' => $data['invoice']->company->name,
1754
1755 'due_date' => $due_date,
1756
1757 'invoice_id' => $data['core_settings']->invoice_prefix . $data['invoice']->reference,
1758
1759 'invoice_project' => $invoice_project,
1760
1761 'balance' => display_money($data['invoice']->outstanding, $data['invoice']->currency),
1762
1763 'client_link' => $data['core_settings']->domain,
1764
1765 'invoice_link' => base_url() . 'cinvoices/view/' . $data['invoice']->id,
1766
1767 'company' => $data['core_settings']->company,
1768
1769 'logo' => '<img src="' . base_url() . '' . $data['core_settings']->logo . '" alt="' . $data['core_settings']->company . '"/>',
1770
1771 'invoice_logo' => '<img src="' . base_url() . '' . $data['core_settings']->invoice_logo . '" alt="' . $data['core_settings']->company . '"/>'
1772
1773 ];
1774
1775 // Generate PDF
1776
1777 $html = $this->load->view($data['core_settings']->template . '/' . $data['core_settings']->invoice_pdf_template, $data, true);
1778
1779 $html = $this->parser->parse_string($html, $parse_data);
1780
1781 $filename = $this->lang->line('application_invoice') . '_' . $data['core_settings']->invoice_prefix . $data['invoice']->reference;
1782
1783 pdf_create($html, $filename, false);
1784
1785 //email
1786
1787 $subject = $this->parser->parse_string($data['core_settings']->invoice_mail_subject, $parse_data);
1788
1789 $this->email->from($data['core_settings']->email, $data['core_settings']->company);
1790
1791 if (!is_object($data['invoice']->company->client) && $data['invoice']->company->client->email == '') {
1792
1793 $this->session->set_flashdata('message', 'error:This client company has no primary contact! Just add a primary contact.');
1794
1795 redirect('invoices/view/' . $id);
1796
1797 }
1798
1799 $this->email->to($data['invoice']->company->client->email);
1800
1801 $this->email->subject($subject);
1802
1803 $this->email->attach('files/temp/' . $filename . '.pdf');
1804
1805
1806
1807 $email_invoice = read_file('./application/views/' . $data['core_settings']->template . '/templates/email_invoice.html');
1808
1809 $message = $this->parser->parse_string($email_invoice, $parse_data);
1810
1811 $this->email->message($message);
1812
1813 if ($this->email->send()) {
1814
1815 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_send_invoice_success'));
1816
1817 if ($data['invoice']->status == 'Open') {
1818
1819 $data['invoice']->update_attributes(['status' => 'Sent', 'sent_date' => date('Y-m-d')]);
1820
1821 }
1822
1823 log_message('error', 'Invoice #' . $data['core_settings']->invoice_prefix . $data['invoice']->reference . ' has been send to ' . $data['invoice']->company->client->email);
1824
1825 } else {
1826
1827 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_send_invoice_error'));
1828
1829 log_message('error', 'ERROR: Invoice #' . $data['core_settings']->invoice_prefix . $data['invoice']->reference . ' has not been send to ' . $data['invoice']->company->client->email . '. Please check your servers email settings.');
1830
1831 }
1832
1833 unlink('files/temp/' . $filename . '.pdf');
1834
1835 redirect('invoices/view/' . $id);
1836
1837 }
1838
1839
1840
1841 public function item($id = false)
1842
1843 {
1844
1845 if ($_POST) {
1846
1847 unset($_POST['send']);
1848
1849 $_POST = array_map('htmlspecialchars', $_POST);
1850
1851 if ($_POST['name'] != '') {
1852
1853 $_POST['name'] = $_POST['name'];
1854
1855 $_POST['value'] = str_replace(',', '.', $_POST['value']);
1856
1857 $_POST['type'] = $_POST['type'];
1858
1859 } else {
1860
1861 if ($_POST['item_id'] == '-') {
1862
1863 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_add_item_error'));
1864
1865 redirect('invoices/view/' . $_POST['invoice_id']);
1866
1867 } else {
1868
1869 $rebill = explode('_', $_POST['item_id']);
1870
1871 if ($rebill[0] == 'rebill') {
1872
1873 $itemvalue = Expense::find_by_id($rebill[1]);
1874
1875 $_POST['name'] = $itemvalue->description;
1876
1877 $_POST['type'] = $_POST['item_id'];
1878
1879 $_POST['value'] = $itemvalue->value;
1880
1881 $itemvalue->rebill = 2;
1882
1883 $itemvalue->invoice_id = $_POST['invoice_id'];
1884
1885 $itemvalue->save();
1886
1887 } else {
1888
1889 $itemvalue = Item::find_by_id($_POST['item_id']);
1890
1891 $_POST['name'] = $itemvalue->name;
1892
1893 $_POST['type'] = $itemvalue->type;
1894
1895 $_POST['value'] = $itemvalue->value;
1896
1897 }
1898
1899 }
1900
1901 }
1902
1903
1904
1905 $item = InvoiceHasItem::create($_POST);
1906
1907 if (!$item) {
1908
1909 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_add_item_error'));
1910
1911 } else {
1912
1913 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_add_item_success'));
1914
1915 }
1916
1917 redirect('invoices/view/' . $_POST['invoice_id']);
1918
1919 } else {
1920
1921 $this->view_data['invoice'] = Invoice::find($id);
1922
1923 $this->view_data['items'] = Item::find('all', ['conditions' => ['inactive=?', '0']]);
1924
1925 $this->view_data['rebill'] = Expense::find('all', ['conditions' => ['project_id=? and (rebill=? or invoice_id=?)', $this->view_data['invoice']->project_id, 1, $id]]);
1926
1927
1928
1929 $this->theme_view = 'modal';
1930
1931 $this->view_data['title'] = $this->lang->line('application_add_item');
1932
1933 $this->view_data['form_action'] = 'invoices/item';
1934
1935 $this->content_view = 'invoices/_item';
1936
1937 }
1938
1939 }
1940
1941
1942
1943 public function item_update($id = false)
1944
1945 {
1946
1947 if ($_POST) {
1948
1949 unset($_POST['send']);
1950
1951 $_POST = array_map('htmlspecialchars', $_POST);
1952
1953 $_POST['value'] = str_replace(',', '.', $_POST['value']);
1954
1955 $item = InvoiceHasItem::find($_POST['id']);
1956
1957 $item = $item->update_attributes($_POST);
1958
1959 if (!$item) {
1960
1961 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_save_item_error'));
1962
1963 } else {
1964
1965 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_save_item_success'));
1966
1967 }
1968
1969 redirect('invoices/view/' . $_POST['invoice_id']);
1970
1971 } else {
1972
1973 $this->view_data['invoice_has_items'] = InvoiceHasItem::find($id);
1974
1975 $this->theme_view = 'modal';
1976
1977 $this->view_data['title'] = $this->lang->line('application_edit_item');
1978
1979 $this->view_data['form_action'] = 'invoices/item_update';
1980
1981 $this->content_view = 'invoices/_item';
1982
1983 }
1984
1985 }
1986
1987
1988
1989 public function item_delete($id = false, $invoice_id = false)
1990
1991 {
1992
1993 $item = InvoiceHasItem::find($id);
1994
1995 $item->delete();
1996
1997 $this->content_view = 'invoices/view';
1998
1999 if (!$item) {
2000
2001 $this->session->set_flashdata('message', 'error:' . $this->lang->line('messages_delete_item_error'));
2002
2003 } else {
2004
2005 $this->session->set_flashdata('message', 'success:' . $this->lang->line('messages_delete_item_success'));
2006
2007 }
2008
2009 redirect('invoices/view/' . $invoice_id);
2010
2011 }
2012
2013
2014
2015 public function changestatus($id = false, $status = false)
2016
2017 {
2018
2019 $invoice = Invoice::find_by_id($id);
2020
2021 if ($this->user->admin != 1) {
2022
2023 $comp_array = [];
2024
2025 foreach ($this->user->companies as $value) {
2026
2027 array_push($comp_array, $value->id);
2028
2029 }
2030
2031 if (!in_array($invoice->company_id, $comp_array)) {
2032
2033 return false;
2034
2035 }
2036
2037 }
2038
2039 switch ($status) {
2040
2041 case 'Sent':
2042
2043 $invoice->sent_date = date('Y-m-d', time());
2044
2045 break;
2046
2047 case 'Paid':
2048
2049 $invoice->paid_date = date('Y-m-d', time());
2050
2051 break;
2052
2053 }
2054
2055 $invoice->status = $status;
2056
2057 $invoice->save();
2058
2059 die();
2060
2061 }
2062
2063
2064
2065 public function getterms($id = false)
2066
2067 {
2068
2069 $settings = Setting::first();
2070
2071
2072
2073 $company = Company::find_by_id($id);
2074
2075 $terms = ($company->terms == '') ? $settings->invoice_terms : $company->terms;
2076
2077 json_response('success', '', html_entity_decode($terms));
2078
2079 }
2080
2081}