├── composer.json
├── database
└── migrations
│ └── 2017_06_24_092243_create_ledger_entries_table.php
├── readme.md
├── resources
└── assets
│ └── js
│ └── components
│ └── ledger
│ └── Ledger.vue
└── src
├── EntryRepository.php
├── Exceptions
├── InsufficientBalanceException.php
└── InvalidRecipientException.php
├── Facades
└── Ledger.php
├── Http
└── Controllers
│ ├── Controller.php
│ └── LedgerController.php
├── Ledger.php
├── LedgerEntry.php
├── LedgerServiceProvider.php
└── Traits
└── Ledgerable.php
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "fannypack/ledger",
3 | "description": "ledger implementation for laravel",
4 | "keywords": ["library", "laravel", "php", "ledger"],
5 | "license": "MIT",
6 | "authors": [
7 | {
8 | "name": "Mpande Andrew",
9 | "email": "andrewmvp007@gmail.com"
10 | }
11 | ],
12 | "minimum-stability": "dev",
13 | "autoload": {
14 | "psr-4": {
15 | "FannyPack\\Ledger\\": "src/"
16 | }
17 | },
18 | "extra": {
19 | "laravel": {
20 | "providers": [
21 | "FannyPack\\Ledger\\LedgerServiceProvider"
22 | ],
23 | "aliases": {
24 | "Ledger": "FannyPack\\Ledger\\Facades\\Ledger"
25 | }
26 | }
27 | },
28 | "require": {
29 | "illuminate/database": "~5.4.0|~5.5.0|~5.6.0|~5.7.0|~5.8.0",
30 | "illuminate/support": "~5.4.0|~5.5.0|~5.6.0|~5.7.0|~5.8.0",
31 | "illuminate/routing": "~5.4.0|~5.5.0|~5.6.0|~5.7.0|~5.8.0",
32 | "illuminate/validation": "~5.4.0|~5.5.0|~5.6.0|~5.7.0|~5.8.0",
33 | "nesbot/carbon": "^1.26.3 || ^2.0"
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/database/migrations/2017_06_24_092243_create_ledger_entries_table.php:
--------------------------------------------------------------------------------
1 | increments('id');
16 | $table->morphs('ledgerable');
17 | $table->string('money_to')->nullable();
18 | $table->string('money_from')->nullable();
19 | $table->text('reason');
20 | $table->boolean('credit')->default(0);
21 | $table->boolean('debit')->default(0);
22 | $table->float('amount', 8, 2);
23 | $table->string('amount_currency')->nullable();
24 | $table->float('current_balance', 8, 2);
25 | $table->string('current_balance_currency')->nullable();
26 | $table->timestamps();
27 | });
28 | }
29 | /**
30 | * Reverse the migrations.
31 | *
32 | * @return void
33 | */
34 | public function down()
35 | {
36 | Schema::dropIfExists('ledger_entries');
37 | }
38 | }
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | ## About this library
2 |
3 | This is a simple/basic implementation of a ledger in laravel 5
4 |
5 | ## Actions supported
6 | - RECORDING DEBITS
7 | - RECORDING CREDITS
8 | - BALANCE COMPUTATION
9 |
10 | ## Installation
11 | git clone https://github.com/mpaannddreew/laravel-ledger.git
12 |
13 | Register service provider
14 | ```php
15 | FannyPack\Ledger\LedgerServiceProvider::class,
16 | ```
17 | Register Facade
18 | Register service provider
19 | ```php
20 | 'Ledger' => FannyPack\Ledger\Facades\Ledger::class,
21 | ```
22 |
23 | After the service provider is registered run this command
24 | ```
25 | php artisan vendor:publish --tag=ledger
26 | ```
27 | Run migrations
28 | ```
29 | php artisan migrate
30 | ```
31 | This command will copy the library's vue components into your codebase
32 |
33 | Register package routes in your app's RouteServiceProvider
34 | ```
35 | Ledger::routes();
36 | ```
37 |
38 | ## Usage
39 | Using it with your models, add
40 | ```php
41 | namespace App;
42 |
43 | use FannyPack\Ledger\Traits\Ledgerable;
44 | use Illuminate\Database\Eloquent\Model;
45 |
46 | class Account extends Model
47 | {
48 | use Ledgerable;
49 | }
50 | ```
51 |
52 | Show available balance
53 | ```php
54 | $account = Account::find(1);
55 | $balance = Ledger::balance($account);
56 | ```
57 | or
58 | ```php
59 | $account = Account::find(1);
60 | $balance = $account->balance();
61 | ```
62 | Record a credit entry
63 | ```php
64 | $account = Account::find(1);
65 | Ledger::credit($account, $to, $amount, $reason);
66 | ```
67 | or
68 | ```php
69 | $account = Account::find(1);
70 | $account->credit($to, $amount, $reason);
71 | ```
72 | Record a debit entry
73 | ```php
74 | $account = Account::find(1);
75 | Ledger::debit($account, $from, $amount, $reason);
76 | ```
77 | or
78 | ```php
79 | $account = Account::find(1);
80 | $account->debit($from, $amount, $reason);
81 | ```
82 |
83 | Recording debits and credits in one transaction
84 | ```php
85 | $account = Account::find(1);
86 | $account2 = Account::find(2);
87 | $account3 = Account::find(3);
88 | Ledger::transfer($account, [$account2, $account3], $amount, $reason);
89 | // or
90 | Ledger::transfer($account, $account2, $amount, $reason);
91 | Ledger::transfer($account, $account3, $amount, $reason);
92 | ```
93 | or
94 | ```php
95 | $account = Account::find(1);
96 | $account2 = Account::find(2);
97 | $account3 = Account::find(3);
98 | $account->transfer([$account2, $account3], $amount, $reason);
99 | // or
100 | $account->transfer($account2, $amount, $reason);
101 | $account->transfer($account3, $amount, $reason);
102 | ```
103 | Retrieving all entries of a ledgerable
104 | ```php
105 | $account = Account::find(1);
106 | $entries = $account->entries();
107 | ```
108 | Retrieving all debits of a ledgerable
109 | ```php
110 | $account = Account::find(1);
111 | debits = $account->debits();
112 | ```
113 | Retrieving all credits of a ledgerable
114 | ```php
115 | $account = Account::find(1);
116 | debits = $account->credits();
117 | ```
118 | Using the provided Ledger.vue component in your blade templates
119 | ```php
120 |
121 | ```
122 |
123 | ## Bugs
124 | For any bugs found, please email me at andrewmvp007@gmail.com or register an issue at [issues](https://github.com/mpaannddreew/laravel-ledger/issues)
125 |
--------------------------------------------------------------------------------
/resources/assets/js/components/ledger/Ledger.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | From |
49 | To |
50 | Amount |
51 | Reason |
52 | Transaction Type |
53 | Date |
54 |
55 |
56 |
57 |
58 | {{ entry.money_from }} |
59 | {{ entry.money_to }} |
60 | {{ entry.amount }} |
61 | {{ entry.reason }} |
62 | {{ entry.type }} |
63 | {{ entry.date }} |
64 |
65 |
66 |
67 |
68 | From |
69 | To |
70 | Amount |
71 | Reason |
72 | Transaction Type |
73 | Date |
74 |
75 |
76 |
77 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
90 |
255 |
--------------------------------------------------------------------------------
/src/EntryRepository.php:
--------------------------------------------------------------------------------
1 | 'credit', 'debit' => 'debit'];
32 |
33 | /**
34 | * EntryRepository constructor.
35 | * @param Carbon $carbon
36 | */
37 | public function __construct(Carbon $carbon)
38 | {
39 | $this->time = $carbon->setTimezone($carbon->getTimezone());
40 | }
41 |
42 | /**
43 | * get ledger entries
44 | *
45 | * @param int $days_ago
46 | * @param int $offset
47 | * @param int $limit
48 | * @return array
49 | */
50 | public function getEntries($days_ago = 0, $offset = 0, $limit = 10)
51 | {
52 | if($days_ago)
53 | return $this->fromDaysAgo(null, $days_ago, $offset, $limit);
54 |
55 | $response = [];
56 | $entries = LedgerEntry::select()->latest()->skip($offset)->take($limit)->orderBy('id', 'desc')->get();;
57 | foreach ($entries as $entry)
58 | {
59 | $item = $entry->toArray();
60 | $item['name'] = $entry->ledgerable->name;
61 | array_push($response, $item);
62 | }
63 |
64 | return $response;
65 | }
66 |
67 | /**
68 | * get ledger entries according to type
69 | *
70 | * @param $type
71 | * @param int $days_ago
72 | * @param int $offset
73 | * @param int $limit
74 | * @return array
75 | */
76 | public function getTypeEntries($type, $days_ago = 0, $offset = 0, $limit = 10)
77 | {
78 | if($days_ago)
79 | return $this->fromDaysAgo($type, $days_ago, $offset, $limit);
80 |
81 | if (!array_has($this->entry_type, strtolower($type)))
82 | return [];
83 |
84 | $response = [];
85 | $entries = LedgerEntry::select()->where(strtolower($type), '=', 1)->latest()->skip($offset)->take($limit)->orderBy('id', 'desc')->get();
86 | foreach ($entries as $entry)
87 | {
88 | $item = $entry->toArray();
89 | $item['name'] = $entry->ledgerable->name;
90 | array_push($response, $item);
91 | }
92 | return $response;
93 | }
94 |
95 | /**
96 | * find a specific ledger entry
97 | *
98 | * @param $entry_id
99 | * @return mixed
100 | */
101 | public function find($entry_id)
102 | {
103 | $entry = LedgerEntry::find($entry_id);
104 |
105 | $item = $entry->toArray();
106 | $item['name'] = $entry->ledgerable->name;
107 |
108 | return $item;
109 | }
110 |
111 | /**
112 | * get entries starting from specific date
113 | *
114 | * @param $date
115 | * @param int $days_from_date
116 | * @param null|string $type
117 | * @param int $offset
118 | * @param int $limit
119 | * @return array
120 | */
121 | public function findFromDate($date, $days_from_date = 1, $type = null, $offset = 0, $limit = 100)
122 | {
123 | $response = [];
124 | list($year, $month, $day) = $this->getYearMonthDay($date);
125 |
126 | $datetime = $this->time->setDate($year, $month, $day)->setTimeFromTimeString("00:01:00");
127 |
128 | if ($type){
129 | if (!array_has($this->entry_type, strtolower($type)))
130 | return [];
131 |
132 |
133 | $entries = LedgerEntry::select()->where($type, '=', 1)->where('created_at', '>=', $datetime->toDateTimeString())
134 | ->where('created_at', '<=', $datetime->addDay($days_from_date)->toDateTimeString())
135 | ->latest()->skip($offset)->take($limit)->orderBy('id', 'desc')->get();
136 | foreach ($entries as $entry)
137 | {
138 | $item = $entry->toArray();
139 | $item['name'] = $entry->ledgerable->name;
140 | array_push($response, $item);
141 | }
142 |
143 | return $response;
144 | }
145 |
146 | $entries = LedgerEntry::select()->where('created_at', '>=', $datetime->toDateTimeString())
147 | ->where('created_at', '<=', $datetime->addDay($days_from_date)->toDateTimeString())
148 | ->latest()->skip($offset)->take($limit)->orderBy('id', 'desc')->get();
149 | foreach ($entries as $entry)
150 | {
151 | $item = $entry->toArray();
152 | $item['name'] = $entry->ledgerable->name;
153 | array_push($response, $item);
154 | }
155 |
156 | return $response;
157 | }
158 |
159 | /**
160 | * get entries from a number of days ago
161 | *
162 | * @param null|string $type
163 | * @param int $days_ago
164 | * @param int $offset
165 | * @param int $limit
166 | * @return array
167 | */
168 | protected function fromDaysAgo($type = null, $days_ago = 0, $offset = 0, $limit = 10)
169 | {
170 | $response = [];
171 | $datetime = $this->dateFromThen($days_ago);
172 |
173 | if ($type){
174 | if (!array_has($this->entry_type, strtolower($type)))
175 | return [];
176 |
177 | $entries = LedgerEntry::select()->where($type, '=', 1)->where('created_at', '>=', $datetime->toDateTimeString())->latest()->skip($offset)->take($limit)->orderBy('id', 'desc')->get();
178 | foreach ($entries as $entry)
179 | {
180 | $item = $entry->toArray();
181 | $item['name'] = $entry->ledgerable->name;
182 | array_push($response, $item);
183 | }
184 |
185 | return $response;
186 | }
187 |
188 | $entries = LedgerEntry::select()->where('created_at', '>=', $datetime->toDateTimeString())->latest()->skip($offset)->take($limit)->orderBy('id', 'desc')->get();
189 | foreach ($entries as $entry)
190 | {
191 | $item = $entry->toArray();
192 | $item['name'] = $entry->ledgerable->name;
193 | array_push($response, $item);
194 | }
195 |
196 | return $response;
197 | }
198 |
199 | /**
200 | * get datetime from string
201 | *
202 | * @param string $datetime
203 | * @return static
204 | */
205 | protected function fromDateTimeString($datetime)
206 | {
207 | $datetime = explode(' ', $datetime);
208 | $date = $datetime[0];
209 | $time = $datetime[1];
210 |
211 | list($year, $month, $day) = $this->getYearMonthDay($date);
212 |
213 | return $this->time->setDate($year, $month, $day)->setTimeFromTimeString($time);
214 | }
215 |
216 | /**
217 | * get date days ago
218 | *
219 | * @param $days
220 | * @return static
221 | */
222 | protected function dateFromThen($days)
223 | {
224 | return $this->time->now()->subDays($days);
225 | }
226 |
227 | /**
228 | * get year, month, day from date string
229 | *
230 | * @param $date
231 | * @return array
232 | */
233 | protected function getYearMonthDay($date)
234 | {
235 | return explode('-', $date);
236 | }
237 | }
--------------------------------------------------------------------------------
/src/Exceptions/InsufficientBalanceException.php:
--------------------------------------------------------------------------------
1 | middleware('auth:api')->except(['index']);
33 | $this->middleware(['web', 'auth'])->only(['index']);
34 | $this->ledger = $ledger;
35 | $this->validator = $validator;
36 | }
37 |
38 | /**
39 | * Display a listing of the resource.
40 | *
41 | * @param Request $request
42 | * @return \Illuminate\Http\Response
43 | * @throws \Illuminate\Validation\ValidationException
44 | */
45 | public function index(Request $request)
46 | {
47 | $this->validator->make($request->all(), [
48 | 'offset' => 'numeric',
49 | 'limit' => 'numeric',
50 | 'days_ago' => 'numeric',
51 | 'entry_type' => 'alpha',
52 | 'from_date' => 'date|date_format:Y-m-d',
53 | 'days_from_date' => 'numeric',
54 | ])->validate();
55 |
56 | $offset = (int)$request->input('offset', 0);
57 | $limit = (int)$request->input('limit', 10);
58 | $days = (int)$request->input('days_ago', 0);
59 | $type = $request->input('entry_type', '');
60 | $from_date = $request->input('from_date', '');
61 | $days_from_date = $request->input('days_from_date', 1);
62 |
63 | if ($from_date)
64 | {
65 | $entries = $this->ledger->findFromDate($from_date, $days_from_date, $type, $offset, $limit);
66 | }else{
67 | if ($type)
68 | {
69 | $entries = $this->ledger->getTypeEntries($type, $days, $offset, $limit);
70 | }else {
71 | $entries = $this->ledger->getEntries($days, $offset, $limit);
72 | }
73 | }
74 |
75 | $response = [
76 | 'success' => true,
77 | 'count' => count($entries),
78 | 'offset' => $offset,
79 | 'limit' => $limit,
80 | 'data' => $entries
81 | ];
82 |
83 | if ($days) $response['days_ago'] = $days;
84 |
85 | if ($type) $response['entry_type'] = $type;
86 |
87 | if ($from_date) {
88 | $response['from_date'] = $from_date;
89 |
90 | if ($days_from_date) $response['days_from_date'] = $days_from_date;
91 | }
92 |
93 | return response()->json($response);
94 | }
95 |
96 | /**
97 | * Display the specified resource.
98 | *
99 | * @param Request $request
100 | * @param $entry_id
101 | * @return \Illuminate\Http\Response
102 | * @throws \Illuminate\Validation\ValidationException
103 | */
104 | public function show(Request $request, $entry_id)
105 | {
106 | $this->validator->make(['entry_id' => $entry_id], [
107 | 'entry_id' => 'required|numeric',
108 | ])->validate();
109 |
110 | $entry = $this->ledger->find((int)$entry_id);
111 | $response = [
112 | 'success' => true,
113 | 'item' => $entry
114 | ];
115 |
116 | return response()->json($response);
117 | }
118 | }
119 |
--------------------------------------------------------------------------------
/src/Ledger.php:
--------------------------------------------------------------------------------
1 | router = $router;
30 | }
31 |
32 | /**
33 | * debit a ledgerable instance
34 | *
35 | * @param $to
36 | * @param string $from
37 | * @param $amount
38 | * @param $reason
39 | * @return mixed
40 | */
41 | public function debit($to, $from, $amount, $amount_currency, $reason)
42 | {
43 | $balance = $to->balance();
44 | $current_balance_currency = isset($to->current_balance_currency) ? $to->current_balance_currency : Null;
45 |
46 | $data = [
47 | 'money_from' => $from,
48 | 'debit' => 1,
49 | 'reason' => $reason,
50 | 'amount' => $amount,
51 | 'amount_currency' => $amount_currency,
52 | 'current_balance' => (float)$balance + (float)$amount,
53 | 'current_balance_currency' => $current_balance_currency
54 | ];
55 |
56 | return $this->log($to, $data);
57 | }
58 |
59 | /**
60 | * credit a ledgerable instance
61 | *
62 | * @param $from
63 | * @param string $to
64 | * @param $amount
65 | * @param $reason
66 | * @return mixed
67 | * @throws InsufficientBalanceException
68 | */
69 | public function credit($from, $to, $amount, $amount_currency="UGX", $reason)
70 | {
71 | $balance = $from->balance();
72 | $current_balance_currency = isset($from->current_balance_currency) ? $from->current_balance_currency : Null;
73 |
74 | if ((float)$balance == 0 || (float)$amount > (float)$balance )
75 | throw new InsufficientBalanceException("Insufficient balance");
76 |
77 | $data = [
78 | 'money_to' => $to,
79 | 'credit' => 1,
80 | 'reason' => $reason,
81 | 'amount' => $amount,
82 | 'amount_currency' => $amount_currency,
83 | 'current_balance' => (float)$balance - (float)$amount,
84 | 'current_balance_currency' => $current_balance_currency
85 | ];
86 |
87 | return $this->log($from, $data);
88 | }
89 |
90 | /**
91 | * persist an entry to the ledger
92 | *
93 | * @param $ledgerable
94 | * @param array $data
95 | * @return mixed
96 | */
97 | protected function log($ledgerable, array $data)
98 | {
99 | return $ledgerable->entries()->create($data);
100 | }
101 |
102 | /**
103 | * balance of a ledgerable instance
104 | *
105 | * @param $ledgerable
106 | * @return float
107 | */
108 | public function balance($ledgerable)
109 | {
110 | $credits = $ledgerable->credits()->sum('amount');
111 | $debits = $ledgerable->debits()->sum('amount');
112 | $balance = $debits - $credits;
113 | return $balance;
114 | }
115 |
116 | /**
117 | * transfer an amount to each ledgerable instance
118 | *
119 | * @param $from
120 | * @param $to
121 | * @param $amount
122 | * @param string $reason
123 | * @return mixed
124 | * @throws InvalidRecipientException
125 | * @throws InsufficientBalanceException
126 | */
127 | public function transfer($from, $to, $amount, $amount_currency="UGX", $reason = "funds transfer")
128 | {
129 | if (!is_array($to))
130 | return $this->transferOnce($from, $to, $amount, $reason);
131 |
132 | $total_amount = (float)$amount * count($to);
133 | if ($total_amount > $from->balance())
134 | throw new InsufficientBalanceException("Insufficient balance");
135 |
136 | $recipients = [];
137 | foreach ($to as $recipient)
138 | {
139 | array_push($recipients, $this->transferOnce($from, $recipient, $amount, $amount_currency, $reason));
140 | }
141 |
142 | return $recipients;
143 | }
144 |
145 | /**
146 | * transfer an amount to one ledgerable instance
147 | *
148 | * @param $from
149 | * @param $to
150 | * @param $amount
151 | * @param $reason
152 | * @return mixed
153 | * @throws InsufficientBalanceException
154 | * @throws InvalidRecipientException
155 | */
156 | protected function transferOnce($from, $to, $amount, $amount_currency="UGX", $reason)
157 | {
158 | if (get_class($from) == get_class($to) && $from->id == $to->id)
159 | throw new InvalidRecipientException("Source and recipient cannot be the same object");
160 |
161 | $this->credit($from, $to->name, $amount, $amount_currency ,$reason);
162 | return $this->debit($to, $from->name, $amount, $amount_currency, $reason);
163 | }
164 |
165 | /**
166 | * register routes for ledger api access
167 | */
168 | public function routes()
169 | {
170 | $this->router->group(['namespace' => 'FannyPack\Ledger\Http\Controllers', 'prefix' => 'entries'], function() {
171 | $this->router->get('ledger', 'LedgerController@index');
172 | $this->router->get('ledger/{entry_id}', 'LedgerController@show');
173 | });
174 | }
175 | }
--------------------------------------------------------------------------------
/src/LedgerEntry.php:
--------------------------------------------------------------------------------
1 | 'boolean',
17 | 'debit' => 'boolean',
18 | 'created_at' => 'datetime'
19 | ];
20 |
21 |
22 | /**
23 | * The table associated with the model.
24 | *
25 | * @var string
26 | */
27 | protected $table = "ledger_entries";
28 |
29 | /**
30 | * @var array
31 | */
32 | protected $fillable = ['reason', 'debit', 'credit', 'amount_currency', 'amount', 'current_balance_currency', 'current_balance', 'money_to', 'money_from'];
33 |
34 | protected $hidden = ['ledgerable_id', 'ledgerable_type', 'current_balance', 'updated_at'];
35 |
36 | /**
37 | * Get the ledgerable entity that the entry belongs to.
38 | *
39 | * @return \Illuminate\Database\Eloquent\Relations\MorphTo
40 | */
41 | public function ledgerable()
42 | {
43 | return $this->morphTo();
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/LedgerServiceProvider.php:
--------------------------------------------------------------------------------
1 | loadMigrationsFrom(__DIR__.'/../database/migrations');
18 |
19 | if ($this->app->runningInConsole()) {
20 | $this->publishes([
21 | __DIR__.'/../resources/assets/js' => base_path('resources/assets/js'),
22 | ], 'ledger');
23 | }
24 | }
25 |
26 | /**
27 | * Register the application services.
28 | *
29 | * @return void
30 | */
31 | public function register()
32 | {
33 | $this->app->singleton(Ledger::class, function($app){
34 | return new Ledger($app['router']);
35 | });
36 |
37 | $this->app->when(EntryRepository::class)
38 | ->needs(Carbon::class)
39 | ->give(function(){
40 | return new Carbon($tz="EAT");
41 | });
42 | }
43 |
44 | /**
45 | * services this provider provides
46 | *
47 | * @return array
48 | */
49 | public function provides()
50 | {
51 | return [Ledger::class];
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/Traits/Ledgerable.php:
--------------------------------------------------------------------------------
1 | morphMany(LedgerEntry::class, 'ledgerable')->orderBy('id', 'desc');
25 | }
26 |
27 | /**
28 | * Get all of the entity's ledger debit entries.
29 | *
30 | * @return mixed
31 | */
32 | public function debits()
33 | {
34 | return $this->entries()->where('debit', '=', 1);
35 | }
36 |
37 | /**
38 | * Get all of the entity's ledger credit entries.
39 | *
40 | * @return mixed
41 | */
42 | public function credits()
43 | {
44 | return $this->entries()->where('credit', '=', 1);
45 | }
46 |
47 | /**
48 | * debit entity
49 | *
50 | * @param $from
51 | * @param $amount
52 | * @param $reason
53 | * @return mixed
54 | */
55 | public function debit($from, $amount, $amount_currency="UGX", $reason)
56 | {
57 | return Ledger::debit($this, $from, $amount, $amount_currency, $reason);
58 | }
59 |
60 | /**
61 | * credit entity
62 | *
63 | * @param $to
64 | * @param $amount
65 | * @param $reason
66 | * @return mixed
67 | */
68 | public function credit($to, $amount, $amount_currency="UGX", $reason)
69 | {
70 | return Ledger::credit($this, $to, $amount, $amount_currency, $reason);
71 | }
72 |
73 | /**
74 | * get entity's balance
75 | *
76 | * @return mixed
77 | */
78 | public function balance()
79 | {
80 | return Ledger::balance($this);
81 | }
82 |
83 | /**
84 | * transfer amount from entity to each recipient
85 | *
86 | * @param $to
87 | * @param $amount
88 | * @param $reason
89 | * @return mixed
90 | */
91 | public function transfer($to, $amount, $amount_currency="UGX", $reason)
92 | {
93 | return Ledger::transfer($this, $to, $amount, $amount_currency, $reason);
94 | }
95 | }
--------------------------------------------------------------------------------