PluginProbe
ERP: Complete HR, Accounting & CRM Suite Built for WooCommerce / 1.6.7
ERP: Complete HR, Accounting & CRM Suite Built for WooCommerce v1.6.7
1.17.9 1.17.8 1.17.7 1.17.6 1.17.5 1.17.4 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.3.0 1.3.1 1.3.11 1.3.12 1.3.13 1.3.14 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 All 143 releases
erp / modules / accounting / includes / functions / bills.php

bills.php in ERP: Complete HR, Accounting & CRM Suite Built for WooCommerce 1.6.7, at modules/accounting/includes/functions/bills.php

643 lines 19.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 if ( ! defined( 'ABSPATH' ) ) {
4 exit; // Exit if accessed directly
5 }
6
7 /**
8 * Get all bills
9 *
10 * @param array $args
11 *
12 * @return mixed
13 */
14 function erp_acct_get_bills( $args = [] ) {
15 global $wpdb;
16
17 $defaults = [
18 'number' => 20,
19 'offset' => 0,
20 'orderby' => 'id',
21 'order' => 'DESC',
22 'count' => false,
23 's' => '',
24 ];
25
26 $args = wp_parse_args( $args, $defaults );
27
28 $limit = '';
29
30 if ( $args['number'] != '-1' ) {
31 $limit = "LIMIT {$args['number']} OFFSET {$args['offset']}";
32 }
33
34 $sql = 'SELECT';
35 $sql .= $args['count'] ? ' COUNT( id ) as total_number ' : ' * ';
36 $sql .= "FROM {$wpdb->prefix}erp_acct_bills WHERE `trn_by_ledger_id` IS NULL ORDER BY {$args['orderby']} {$args['order']} {$limit}";
37
38 if ( $args['count'] ) {
39 return $wpdb->get_var( $sql );
40 }
41
42 $rows = $wpdb->get_results( $sql, ARRAY_A );
43
44 return $rows;
45 }
46
47 /**
48 * Get a single bill
49 *
50 * @param $bill_no
51 *
52 * @return mixed
53 */
54 function erp_acct_get_bill( $bill_no ) {
55 global $wpdb;
56
57 $sql = $wpdb->prepare(
58 "SELECT
59
60 voucher.editable,
61 bill.id,
62 bill.voucher_no,
63 bill.vendor_id,
64 bill.vendor_name,
65 bill.address AS billing_address,
66 bill.trn_date,
67 bill.due_date,
68 bill.amount,
69 bill.ref,
70 bill.particulars,
71 bill.status,
72 bill.created_at,
73 bill.attachments
74
75 FROM {$wpdb->prefix}erp_acct_bills AS bill
76 LEFT JOIN {$wpdb->prefix}erp_acct_voucher_no as voucher ON bill.voucher_no = voucher.id
77 LEFT JOIN {$wpdb->prefix}erp_acct_bill_account_details AS b_ac_detail ON bill.voucher_no = b_ac_detail.trn_no
78 WHERE bill.voucher_no = %d",
79 $bill_no
80 );
81
82 $row = $wpdb->get_row( $sql, ARRAY_A );
83
84 $row['bill_details'] = erp_acct_format_bill_line_items( $bill_no );
85
86 return $row;
87 }
88
89 /**
90 * Format bill line items
91 *
92 * @param $voucher_no
93 *
94 * @return array|object|null
95 */
96 function erp_acct_format_bill_line_items( $voucher_no ) {
97 global $wpdb;
98
99 $sql = $wpdb->prepare(
100 "SELECT
101 b_detail.id,
102 b_detail.trn_no,
103 b_detail.ledger_id,
104 b_detail.particulars,
105 b_detail.amount,
106
107 ledger.name AS ledger_name
108
109 FROM {$wpdb->prefix}erp_acct_bills AS bill
110 LEFT JOIN {$wpdb->prefix}erp_acct_bill_details AS b_detail ON bill.voucher_no = b_detail.trn_no
111 LEFT JOIN {$wpdb->prefix}erp_acct_ledgers AS ledger ON ledger.id = b_detail.ledger_id
112 WHERE bill.voucher_no = %d",
113 $voucher_no
114 );
115
116 return $wpdb->get_results( $sql, ARRAY_A );
117 }
118
119 /**
120 * Insert a bill
121 *
122 * @param $data
123 *
124 * @return mixed
125 */
126 function erp_acct_insert_bill( $data ) {
127 global $wpdb;
128
129 $created_by = get_current_user_id();
130 $voucher_no = null;
131 $draft = 1;
132
133 $data['created_at'] = date( 'Y-m-d H:i:s' );
134 $data['created_by'] = $created_by;
135 $data['updated_at'] = date( 'Y-m-d H:i:s' );
136 $data['updated_by'] = $created_by;
137 $currency = erp_get_currency( true );
138
139 try {
140 $wpdb->query( 'START TRANSACTION' );
141
142 $wpdb->insert(
143 $wpdb->prefix . 'erp_acct_voucher_no',
144 [
145 'type' => 'bill',
146 'currency' => $currency,
147 'editable' => 1,
148 'created_at' => $data['created_at'],
149 'created_by' => $data['created_by'],
150 'updated_at' => isset( $data['updated_at'] ) ? $data['updated_at'] : '',
151 'updated_by' => isset( $data['updated_by'] ) ? $data['updated_by'] : '',
152 ]
153 );
154
155 $voucher_no = $wpdb->insert_id;
156
157 $bill_data = erp_acct_get_formatted_bill_data( $data, $voucher_no );
158 $bill_data['trn_no'] = $voucher_no;
159
160 $wpdb->insert(
161 $wpdb->prefix . 'erp_acct_bills',
162 [
163 'voucher_no' => $bill_data['voucher_no'],
164 'vendor_id' => $bill_data['vendor_id'],
165 'vendor_name' => $bill_data['vendor_name'],
166 'address' => $bill_data['billing_address'],
167 'trn_date' => $bill_data['trn_date'],
168 'due_date' => $bill_data['due_date'],
169 'amount' => $bill_data['amount'],
170 'ref' => $bill_data['ref'],
171 'particulars' => $bill_data['particulars'],
172 'status' => $bill_data['status'],
173 'attachments' => $bill_data['attachments'],
174 'created_at' => $bill_data['created_at'],
175 'created_by' => $bill_data['created_by'],
176 ]
177 );
178
179 $items = $bill_data['bill_details'];
180
181 foreach ( $items as $key => $item ) {
182 $wpdb->insert(
183 $wpdb->prefix . 'erp_acct_bill_details',
184 [
185 'trn_no' => $voucher_no,
186 'ledger_id' => $item['ledger_id'],
187 'particulars' => isset( $item['description'] ) ? $item['description'] : '',
188 'amount' => $item['amount'],
189 'created_at' => $bill_data['created_at'],
190 'created_by' => $bill_data['created_by'],
191 ]
192 );
193
194 erp_acct_insert_bill_data_into_ledger( $bill_data, $item );
195 }
196
197 if ( $draft === $bill_data['status'] ) {
198 $wpdb->query( 'COMMIT' );
199
200 return erp_acct_get_bill( $voucher_no );
201 }
202
203 $wpdb->insert(
204 $wpdb->prefix . 'erp_acct_bill_account_details',
205 [
206 'bill_no' => $voucher_no,
207 'trn_no' => $voucher_no,
208 'trn_date' => $bill_data['trn_date'],
209 'particulars' => $bill_data['particulars'],
210 'debit' => 0,
211 'credit' => $bill_data['amount'],
212 'created_at' => $bill_data['created_at'],
213 'created_by' => $bill_data['created_by'],
214 ]
215 );
216
217 $data['dr'] = 0;
218 $data['cr'] = $bill_data['amount'];
219 erp_acct_insert_data_into_people_trn_details( $data, $voucher_no );
220
221 do_action( 'erp_acct_after_bill_create', $data, $voucher_no );
222
223 $wpdb->query( 'COMMIT' );
224 } catch ( Exception $e ) {
225 $wpdb->query( 'ROLLBACK' );
226
227 return new WP_error( 'bill-exception', $e->getMessage() );
228 }
229
230 $bill = erp_acct_get_bill( $voucher_no );
231
232 $bill['email'] = erp_get_people_email( $bill_data['vendor_id'] );
233
234 do_action( 'erp_acct_new_transaction_bill', $voucher_no, $bill );
235
236 return $bill;
237 }
238
239 /**
240 * Update a bill
241 *
242 * @param $data
243 * @param $bill_id
244 *
245 * @return mixed
246 */
247 function erp_acct_update_bill( $data, $bill_id ) {
248 global $wpdb;
249
250 $user_id = get_current_user_id();
251 $draft = 1;
252 $voucher_no = null;
253
254 $data['created_at'] = date( 'Y-m-d H:i:s' );
255 $data['created_by'] = $user_id;
256 $data['updated_at'] = date( 'Y-m-d H:i:s' );
257 $data['updated_by'] = $user_id;
258 $currency = erp_get_currency( true );
259
260 try {
261 $wpdb->query( 'START TRANSACTION' );
262
263 if ( $draft === $data['status'] ) {
264 erp_acct_update_draft_bill( $data, $bill_id );
265 } else {
266 // disable editing on old bill
267 $wpdb->update( $wpdb->prefix . 'erp_acct_voucher_no', [ 'editable' => 0 ], [ 'id' => $bill_id ] );
268
269 // insert contra voucher
270 $wpdb->insert(
271 $wpdb->prefix . 'erp_acct_voucher_no',
272 [
273 'type' => 'bill',
274 'currency' => $currency,
275 'editable' => 0,
276 'created_at' => $data['created_at'],
277 'created_by' => $data['created_by'],
278 'updated_at' => $data['updated_at'],
279 'updated_by' => $data['updated_by'],
280 ]
281 );
282
283 $voucher_no = $wpdb->insert_id;
284
285 $old_bill = erp_acct_get_bill( $bill_id );
286
287 // insert contra `erp_acct_bills` (basically a duplication of row)
288 $wpdb->query( $wpdb->prepare( "CREATE TEMPORARY TABLE acct_tmptable SELECT * FROM {$wpdb->prefix}erp_acct_bills WHERE voucher_no = %d", $bill_id ) );
289 $wpdb->query(
290 $wpdb->prepare(
291 "UPDATE acct_tmptable SET id = %d, voucher_no = %d, particulars = 'Contra entry for voucher no \#%d', created_at = '%s'",
292 0,
293 $voucher_no,
294 $bill_id,
295 $data['created_at']
296 )
297 );
298 $wpdb->query( "INSERT INTO {$wpdb->prefix}erp_acct_bills SELECT * FROM acct_tmptable" );
299 $wpdb->query( 'DROP TABLE acct_tmptable' );
300
301 // change bill status and other things
302 $status_closed = 7;
303 $wpdb->query(
304 $wpdb->prepare(
305 "UPDATE {$wpdb->prefix}erp_acct_bills SET status = %d, updated_at ='%s', updated_by = %d WHERE voucher_no IN (%d, %d)",
306 $status_closed,
307 $data['updated_at'],
308 $user_id,
309 $bill_id,
310 $voucher_no
311 )
312 );
313
314 $items = $old_bill['bill_details'];
315
316 foreach ( $items as $key => $item ) {
317 // insert contra `erp_acct_bill_details`
318 $wpdb->insert(
319 $wpdb->prefix . 'erp_acct_bill_details',
320 [
321 'trn_no' => $voucher_no,
322 'ledger_id' => $item['ledger_id'],
323 'particulars' => isset( $item['description'] ) ? $item['description'] : '',
324 'amount' => $item['amount'],
325 'created_at' => $data['created_at'],
326 'created_by' => $data['created_by'],
327 ]
328 );
329
330 // insert contra `erp_acct_ledger_details`
331 erp_acct_update_bill_data_into_ledger( $old_bill, $voucher_no, $item );
332 }
333
334 // insert contra `erp_acct_bill_account_details`
335 $wpdb->insert(
336 $wpdb->prefix . 'erp_acct_bill_account_details',
337 [
338 'bill_no' => $bill_id,
339 'trn_no' => $voucher_no,
340 'trn_date' => $old_bill['trn_date'],
341 'particulars' => $old_bill['particulars'],
342 'debit' => $old_bill['amount'],
343 'updated_at' => $data['updated_at'],
344 'updated_by' => $data['updated_by'],
345 ]
346 );
347
348 // insert new bill with edited data
349 $new_bill = erp_acct_insert_bill( $data );
350
351 do_action( 'erp_acct_after_bill_update', $data, $bill_id );
352
353 $data['dr'] = 0;
354 $data['cr'] = $data['amount'];
355 erp_acct_update_data_into_people_trn_details( $data, $old_bill['voucher_no'] );
356 }
357
358 $wpdb->query( 'COMMIT' );
359 } catch ( Exception $e ) {
360 $wpdb->query( 'ROLLBACK' );
361
362 return new WP_error( 'bill-exception', $e->getMessage() );
363 }
364
365 return erp_acct_get_bill( $new_bill['voucher_no'] );
366 }
367
368 /**
369 * Make bill draft on update
370 *
371 * @param $data
372 * @param $bill_id
373 *
374 * @return void
375 */
376 function erp_acct_update_draft_bill( $data, $bill_id ) {
377 global $wpdb;
378
379 $bill_data = erp_acct_get_formatted_bill_data( $data, $bill_id );
380
381 $wpdb->update(
382 $wpdb->prefix . 'erp_acct_bills',
383 [
384 'vendor_id' => $bill_data['vendor_id'],
385 'vendor_name' => $bill_data['vendor_name'],
386 'address' => $bill_data['billing_address'],
387 'trn_date' => $bill_data['trn_date'],
388 'due_date' => $bill_data['due_date'],
389 'amount' => $bill_data['amount'],
390 'ref' => $bill_data['ref'],
391 'particulars' => $bill_data['particulars'],
392 'attachments' => $bill_data['attachments'],
393 'updated_at' => $bill_data['updated_at'],
394 'updated_by' => $bill_data['updated_by'],
395 ],
396 [
397 'voucher_no' => $bill_id,
398 ]
399 );
400
401 /**
402 *? We can't update `bill_details` directly
403 *? suppose there were 5 detail rows previously
404 *? but on update there may be 2 detail rows
405 *? that's why we can't update because the foreach will iterate only 2 times, not 5 times
406 *? so, remove previous rows and insert new rows
407 */
408 $prev_detail_ids = $wpdb->get_results( $wpdb->prepare( "SELECT id FROM {$wpdb->prefix}erp_acct_bill_details WHERE trn_no = %d", $bill_id ), ARRAY_A );
409
410 $prev_detail_ids = implode( ',', array_map( 'absint', $prev_detail_ids ) );
411
412 $wpdb->delete( $wpdb->prefix . 'erp_acct_bill_details', [ 'trn_no' => $bill_id ] );
413
414 $items = $bill_data['bill_details'];
415
416 foreach ( $items as $item ) {
417 $wpdb->insert(
418 $wpdb->prefix . 'erp_acct_bill_details',
419 [
420 'trn_no' => $bill_id,
421 'ledger_id' => $item['ledger_id'],
422 'particulars' => isset( $item['description'] ) ? $item['description'] : '',
423 'amount' => $item['amount'],
424 'created_at' => $bill_data['created_at'],
425 'created_by' => $bill_data['created_by'],
426 ]
427 );
428 }
429 }
430
431 /**
432 * Void a bill
433 *
434 * @param $id
435 *
436 * @return void
437 */
438 function erp_acct_void_bill( $id ) {
439 global $wpdb;
440
441 if ( ! $id ) {
442 return;
443 }
444
445 $wpdb->update(
446 $wpdb->prefix . 'erp_acct_bills',
447 [
448 'status' => 8,
449 ],
450 [ 'voucher_no' => $id ]
451 );
452
453 $wpdb->delete( $wpdb->prefix . 'erp_acct_ledger_details', [ 'trn_no' => $id ] );
454 $wpdb->delete( $wpdb->prefix . 'erp_acct_bill_account_details', [ 'bill_no' => $id ] );
455 }
456
457 /**
458 * Get formatted bill data
459 *
460 * @param $data
461 * @param $voucher_no
462 *
463 * @return mixed
464 */
465 function erp_acct_get_formatted_bill_data( $data, $voucher_no ) {
466 $bill_data = [];
467
468 $vendor = erp_get_people( $data['vendor_id'] );
469
470 $bill_data['voucher_no'] = ! empty( $voucher_no ) ? $voucher_no : 0;
471 $bill_data['vendor_id'] = isset( $data['vendor_id'] ) ? $data['vendor_id'] : 1;
472 $bill_data['vendor_name'] = isset( $vendor ) ? $vendor->first_name . ' ' . $vendor->last_name : '';
473 $bill_data['billing_address'] = isset( $data['billing_address'] ) ? $data['billing_address'] : '';
474 $bill_data['trn_date'] = isset( $data['trn_date'] ) ? $data['trn_date'] : date( 'Y-m-d' );
475 $bill_data['due_date'] = isset( $data['due_date'] ) ? $data['due_date'] : date( 'Y-m-d' );
476 $bill_data['created_at'] = date( 'Y-m-d' );
477 $bill_data['amount'] = isset( $data['amount'] ) ? $data['amount'] : 0;
478 $bill_data['ref'] = isset( $data['ref'] ) ? $data['ref'] : '';
479 $bill_data['due'] = isset( $data['due'] ) ? $data['due'] : 0;
480 $bill_data['attachments'] = isset( $data['attachments'] ) ? $data['attachments'] : '';
481 // translators: %s: voucher_no
482 $bill_data['particulars'] = ! empty( $data['particulars'] ) ? $data['particulars'] : sprintf( __( 'Bill created with voucher no %s', 'erp' ), $voucher_no );
483 $bill_data['bill_details'] = isset( $data['bill_details'] ) ? $data['bill_details'] : '';
484 $bill_data['status'] = isset( $data['status'] ) ? $data['status'] : 1;
485 $bill_data['trn_by_ledger_id'] = isset( $data['trn_by'] ) ? $data['trn_by'] : null;
486 $bill_data['created_at'] = date( 'Y-m-d' );
487 $bill_data['created_by'] = isset( $data['created_by'] ) ? $data['created_by'] : '';
488 $bill_data['updated_at'] = isset( $data['updated_at'] ) ? $data['updated_at'] : '';
489 $bill_data['updated_by'] = isset( $data['updated_by'] ) ? $data['updated_by'] : '';
490
491 return $bill_data;
492 }
493
494 /**
495 * Insert bill/s data into ledger
496 *
497 * @param array $bill_data
498 * @param array $item_data
499 *
500 * @return mixed
501 */
502 function erp_acct_insert_bill_data_into_ledger( $bill_data, $item_data ) {
503 global $wpdb;
504
505 $draft = 1;
506
507 if ( $draft === $bill_data['status'] ) {
508 return;
509 }
510
511 // Insert items amount in ledger_details
512 $wpdb->insert(
513 $wpdb->prefix . 'erp_acct_ledger_details',
514 [
515 'ledger_id' => $item_data['ledger_id'],
516 'trn_no' => $bill_data['voucher_no'],
517 'particulars' => $bill_data['particulars'],
518 'debit' => $item_data['amount'],
519 'credit' => 0,
520 'trn_date' => $bill_data['trn_date'],
521 'created_at' => $bill_data['created_at'],
522 'created_by' => $bill_data['created_by'],
523 'updated_at' => $bill_data['updated_at'],
524 'updated_by' => $bill_data['updated_by'],
525 ]
526 );
527 }
528
529 /**
530 * Update bill/s data into ledger
531 *
532 * @param array $bill_data
533 * @param array $bill_no
534 * @param array $item_data
535 *
536 * @return mixed
537 */
538 function erp_acct_update_bill_data_into_ledger( $bill_data, $bill_no, $item_data ) {
539 global $wpdb;
540
541 $user_id = get_current_user_id();
542
543 $bill_data['created_at'] = date( 'Y-m-d H:i:s' );
544 $bill_data['created_by'] = $user_id;
545 $bill_data['updated_at'] = date( 'Y-m-d H:i:s' );
546 $bill_data['updated_by'] = $user_id;
547
548 $wpdb->insert(
549 $wpdb->prefix . 'erp_acct_ledger_details',
550 [
551 'ledger_id' => $item_data['ledger_id'],
552 'trn_no' => $bill_no,
553 'particulars' => $bill_data['particulars'],
554 'debit' => 0,
555 'credit' => $item_data['amount'],
556 'trn_date' => $bill_data['trn_date'],
557 'created_at' => $bill_data['created_at'],
558 'created_by' => $bill_data['created_by'],
559 'updated_at' => $bill_data['updated_at'],
560 'updated_by' => $bill_data['updated_by'],
561 ]
562 );
563 }
564
565 /**
566 * Get Bill count
567 *
568 * @return int
569 */
570 function erp_acct_get_bill_count() {
571 global $wpdb;
572
573 $row = $wpdb->get_row( 'SELECT COUNT(*) as count FROM ' . $wpdb->prefix . 'erp_acct_bills' );
574
575 return $row->count;
576 }
577
578 /**
579 * Get bills with due of a people
580 *
581 * @param array $args
582 *
583 * @return mixed
584 */
585 function erp_acct_get_due_bills_by_people( $args = [] ) {
586 global $wpdb;
587
588 $defaults = [
589 'number' => 20,
590 'offset' => 0,
591 'orderby' => 'id',
592 'order' => 'DESC',
593 'count' => false,
594 's' => '',
595 ];
596
597 $args = wp_parse_args( $args, $defaults );
598
599 $limit = '';
600
601 if ( $args['number'] != '-1' ) {
602 $limit = "LIMIT {$args['number']} OFFSET {$args['offset']}";
603 }
604
605 $bills = "{$wpdb->prefix}erp_acct_bills";
606 $bill_act_details = "{$wpdb->prefix}erp_acct_bill_account_details";
607 $items = $args['count'] ? ' COUNT( id ) as total_number ' : ' * ';
608
609 $query = $wpdb->prepare(
610 "SELECT $items FROM $bills as bill INNER JOIN (
611 SELECT bill_no, ABS(SUM( ba.debit - ba.credit)) as due
612 FROM $bill_act_details as ba
613 GROUP BY ba.bill_no HAVING due > 0 ) as bs
614 ON bill.voucher_no = bs.bill_no
615 WHERE bill.vendor_id = %d AND bill.status != 1
616 ORDER BY %s %s $limit",
617 $args['people_id'],
618 $args['orderby'],
619 $args['order']
620 );
621
622 if ( $args['count'] ) {
623 return $wpdb->get_var( $query );
624 }
625
626 return $wpdb->get_results( $query, ARRAY_A );
627 }
628
629 /**
630 * Get due of a bill
631 *
632 * @param $bill_no
633 *
634 * @return int
635 */
636 function erp_acct_get_bill_due( $bill_no ) {
637 global $wpdb;
638
639 $result = $wpdb->get_row( $wpdb->prepare( "SELECT bill_no, SUM( ba.debit - ba.credit) as due FROM {$wpdb->prefix}erp_acct_bill_account_details as ba WHERE ba.bill_no = %d GROUP BY ba.bill_no", $bill_no ), ARRAY_A );
640
641 return $result['due'];
642 }
643