I have bank table and transaction table which has one to many relationship. I want to calculate balance of each bank and also total banks balance.
bank model:
class Bank extends Model
{
use HasFactory;
protected $fillable = [
'name',
'code',
'accountNumber',
'swiftCode',
'currency',
'country',
'city',
'street',
'zipcode',
];
public function transactions()
{
return $this->hasMany(Transaction::class);
}
}
transactions model:
class Transaction extends Model
{
use HasFactory;
protected $fillable = [
'amount',
'currency',
'exchangeRate',
'reference',
'type',
'adjustment',
'partner_id',
'bank_id',
];
public function bank()
{
return $this->belongsTo(Bank::class);
}
}
I wrote the code below for balance which is not correct yet, because I can't access transactions columns using this collection.
<td>{{$bank->transactions->where('type', 'credit')->sum('amount') - $bank->transactions->where('type', 'debit')->sum('amount')}}</td>
there are many currencies which needs to be normalized using exchangRate.
I need to multiply amount with exchangeRate and sum all it's results. so it gives bank balance.
I should pass it from index function. it should be returned with bank collection.
BankController function index:
public function index()
{
$banks = Bank::all();
return view('inc.banks', compact('banks'));
}
based on these, how can I calculate each bank balance and total banks balance?
You have to fetch it from controller and pass it to the view, Create a function to get data
//Here You will get all transactions relevant to the bank as per your relationship
$banks =Transaction::with('transactions.bank')->get();
return view('inc.banks', compact('banks'));
with the array of output you can compute manually the amounts you need, Or else you can do it manually querying it.
To get a clear picture of your output try manually querying it on database with SQL Syntax. Once you got the right SQL syntax you can go for laravel eloquent (This method will help you a lot in understanding what your doing) !! Good Luck !
You can make two relations (credits and debits) and with them, calculate the bank balances and total balance.
Bank model
public function credits(){
return $this->hasMany(Transaction::class, foreign_id, primary_id)->where('type', 'credit);
}
public function debits(){
return $this->hasMany(Transaction::class, foreign_id, primary_id)->where('type', 'debit);
}
Blade:
Initialize $total variable first. Then loop through $banks to get balance for each bank and add them up for getting total balance.
#php( $total = 0)
#foreach($banks as $key => $bank)
$balance = $bank->credits->sum('amount') - $bank->debits->sum('amount'); // $balance will have each bank balance
$total += $balance;
#endforeach
{{ $total }} // get total balance for all banks
Edit
If you want to calculate using exchangeRate on amount:
#php($total = 0)
#foreach($banks as $key => $bank)
$credits = 0;
$debits = 0;
#foreach($bank->transactions as $key => $transaction)
#if($transaction->type == 'credit')
$credits += $transaction->amount*$transaction->exchangeRate;
#elseif($transaction->type == 'dedit')
$dedits += $transaction->amount*$transaction->exchangeRate;
#endif
#endforeach
$balance = $credits-$debits;
$total += $balance;
#endforeach
{{ $total }}
I have solved this in bank and transaction model. I defined a custom attribute and then append it to model.
Transaction Model:
protected $appends = [
'final_amount'
];
public function getFinalAmountAttribute() {
return $this->amount * $this->exchangeRate;
}
Bank Model:
public function getCreditSumAttribute(){
$sum = 0;
if($this->transactions){
$sum = $this->transactions->where('type', 'credit')->sum('final_amount');
}
return $sum;
}
public function getDebitSumAttribute(){
$sum = 0;
if($this->transactions){
$sum = $this->transactions->where('type', 'debit')->sum('final_amount');
}
return $sum;
}
public function getSubCreditDebitAttribute(){
return $this->credit_sum - $this->debit_sum;
}
and in banks view I put this code:
<td>{{'$ '}}{{$bank->sub_credit_debit}}</td>
Related
I made a system to calculate the total price of a basket, it works but I saw that there were duplicate requests, I would like to share the code with you to know if you would have done otherwise?
For the moment I have not found any other solution.
Userscontroller.php :
$carts =\Auth::user()->carts;
User.php (model) :
public function carts()
{
return $this->hasMany('App\Models\Cart')->with('product');
}
Cart.php (model) :
public function product()
{
return $this->belongsTo('App\Models\Product', 'product_id')->with('productCat');
}
public function getTotalPrice()
{
$price = 0;
foreach($this->user->carts as $carts)
{
$price += $carts->getPriceByQuantity();
}
return $price;
}
public function getPriceByQuantity()
{
$quantity = $this->quantity;
$price = ($this->product->product_total_price == '') ? $this->product->priceRender() : $this->product->product_total_price;
return $price * $quantity;
}
The problem is that i declare user->carts one time in userscontroller for the view, and one time in getTotalPrice. Before, i wanted to loop over $this instead of $this->user->carts, but the loop was repeated by the quantity number of a product.
If someone knows the best way to do this ? Thank you
I'm just learning Laravel, and this is probably super easy for someone experienced with the framework, but I'm trying to get data from a different table and not sure what I'm doing wrong.
I have two tables, Users, which has fields first_name, last_name, and pair_id. The pair_id column is programmatically restricted to either null or an integer in two rows that designates a "pair". The there's the confirmed_pair table that has one pair per row and has a unique pair_id column, that refers to the one in the Users table.
In the ConfirmedPair model, I did this:
class ConfirmedPair extends Model
{
public function pair() {
return $this->hasMany(User::class, 'pair_id');
}
public function pair_names() { // returns an array of names of the players in the confirmed pair
$names = User::where("pair_id", $this->get(["pair_id"])[0]->pair_id)->get(['first_name','last_name']);
if (count($names) == 2) { // if this pair exists
return [
$names[0]['first_name']." ".$names[0]['last_name'],
$names[1]['first_name']." ".$names[1]['last_name']
];
}
return null;
}
}
In the controller, I did this:
class PageController extends Controller
{
public function index()
{
$confirmed_pair = new ConfirmedPair;
return view('page', compact('confirmed_pair'));
}
}
And in the blade view if I do this:
#for ($i = 1; $i < 10; $i++)
{{ $confirmed_pair->find($i)->pair_names()[0] }}<br>
#endfor
No matter what $i's value is, it returns the values of confirmed_pair id #1.
What am I doing wrong? Thanks!
If pair_id is assigned to 2 users
class ConfirmedPair extends Model {
public function pairs() {
return $this->hasMany(User::class, 'pair_id', 'pair_id');
}
public function pair_names() {
if ($this->pairs->count() != 2) return null;
// $this->pairs returns you a Collection of Users
// try to dd($this->pairs) to see in action
$pairs = $this->pairs->toArray();
return [
$pairs[0]['first_name']." ".$pairs[0]['last_name'],
$pairs[1]['first_name']." ".$pairs[1]['last_name']
];
}
}
Can be done better but for your case this should work.
I want a rounding grand total; I have created a custom module and rewritten the core models to achieve this.
My rewrite Model code is below
1. Mage_Sales_Model_Quote_Address_Total_Grand
<?php
class Lr_Roundtotal_Model_Quote_Address_Total_Grand extends Mage_Sales_Model_Quote_Address_Total_Grand
{
public function collect(Mage_Sales_Model_Quote_Address $address)
{
$grandTotal = $address->getGrandTotal();
$baseGrandTotal = $address->getBaseGrandTotal();
$totals = array_sum($address->getAllTotalAmounts());
$baseTotals = array_sum($address->getAllBaseTotalAmounts());
$address->setGrandTotal(round($grandTotal+$totals)); //Modificated
$address->setBaseGrandTotal(round($baseGrandTotal+$baseTotals)); //Modificated
//$address->setGrandTotal($grandTotal+$totals); --Original
//$address->setBaseGrandTotal($baseGrandTotal+$baseTotals); --Original
return $this;
}
public function fetch(Mage_Sales_Model_Quote_Address $address)
{
$address->addTotal(array(
'code' => $this->getCode(),
'title' => Mage::helper('sales')->__('Grand Total'),
'value' => round($address->getGrandTotal()),
'netvalue' => round($address->getGrandTotal()),
'area' => 'footer',
));
return $this;
}
}
and second one is
2.Mage_Sales_Model_Order_Invoice
<?php
class Lr_Roundtotal_Model_Order_Invoice extends Mage_Sales_Model_Order_Invoice
{
public function pay()
{
if ($this->_wasPayCalled) {
return $this;
}
$this->_wasPayCalled = true;
$invoiceState = self::STATE_PAID;
if ($this->getOrder()->getPayment()->hasForcedState()) {
$invoiceState = $this->getOrder()->getPayment()->getForcedState();
}
$this->setState($invoiceState);
$this->getOrder()->getPayment()->pay($this);
$this->getOrder()->setTotalPaid(
round($this->getOrder()->getTotalPaid()+$this->getGrandTotal()) //Modificated
// $this->getOrder()->getTotalPaid()+$this->getGrandTotal() --Original
);
$this->getOrder()->setBaseTotalPaid(
round($this->getOrder()->getBaseTotalPaid()+$this->getBaseGrandTotal()) //Modificated
// $this->getOrder()->getBaseTotalPaid()+$this->getBaseGrandTotal() --Original
);
Mage::dispatchEvent('sales_order_invoice_pay', array($this->_eventObject=>$this));
return $this;
}
}
For example
Cart
sub-total : 990.00
discount : 120.70
Grand Total: 869.00(rounded)
Invoice
sub-total : 990.00
discount : 120.70
Grand Total: 869.30(not-rounded)
I want same grand total in cart and Invoice
Once you overwrite the core file in local then implement below code.
First create one function in the HELPER file like below(no need to create new module but you can put this function in any module helper file):
Namespace_module_helper_data extends Mage_Core_Helper_Abstract
{
public function getFormatedPrice($price)
{
return Mage::getModel('directory/currency')->format($price, array('display'=>Zend_Currency::NO_SYMBOL), false);
}
}
then you can just use this function where you need to round the price in any where in Magento.
You can use helper function like below:
$helper = Mage::helper('modulename'); // module name means name of the module in which you have create helper
Use function for round price like below:
$price = 120.12456;
echo $helper->getFormatedPrice($price); // you can get round price as per your store.
If I want to do the pagination, I have to fetch data twice, one for get total rows, one for get the rows with limit, for example
<?php
class Admins extends CI_Model
{
public function dataTotal()
{
$total = $this->db->get('admins')->num_rows();
return $total;
}
public function data()
{
return $this->db->limit(10, $this->start)->get('admins')->result();
}
}
Then assign total to pagination and assign the data to view, it's quite make sense, but if there are a lot of conditions, I need to do it twice, for example:
<?php
class Admins extends CI_Model
{
public function dataTotal()
{
$db = $this->db->from('admins')
->where('id >', 1)
->like('name', 'abc', 'both');
return $db->get()->num_rows();
}
public function data()
{
$data = $this->db->from('admins')
->where('id >', 1)
->like('name', 'abc', 'both')
->limit(10, $this->start);
return $data->get()->result();
}
}
More conditions means more duplicated code, any way to make condition filter as one?
You could make a function and use an SQL query as a parameter, that would be the most recommended option. If that's not an option you could do something like this:
public function data($option = "default")
{
if($option == 'default')
{
$data = $this->db->from('admins')
->where('id >', 1)
->like('name', 'abc', 'both')
}
else if($option == 'other')
{
$data = $this->db->from('admins')
->where('id >', 1)
->like('name', 'abc', 'both')
->limit(10, $this->start);
}
return $data->get()->result();
}
And then calling it:
data();
data("other");
That's the most efficient way I can come up with.
I've been searching endlessly for a clue on how I should properly go about creating a "Money Transfer" function (for a game, not real money) within Laravel 4.2.
Needlessly to say, I've come up empty handed and I'm turning to you guys.
The task:
Transfer funds from "Spending" to "Saving" accounts (or vice-versa)
Subtract the amount from the account it's exiting.
Add the amount to the account it's entering.
What I need:
A simple calculation to help me get started on building this out. I'm quite new to writing Eloquent and simply need someone to outline how this sort of thing should work.
Database:
id, user_id, spending, saving, bucks, pin, created_at, updated_at
Model:
class Bank extends Eloquent {
protected $table = 'banks';
protected $fillable = ['user_id, spending, saving, bucks, pin'];
// Connect to the User
public function user()
{
return $this->belongsTo('User');
}
}
Controller:
public function transferMoney()
{
$id = Auth::id();
$bank = Bank::find($id);
$spending = $bank->spending;
$saving = $bank->saving;
$transfer_type = Input::get('transfer_to');
$transfer_amount = Input::get('amount');
// Spending to Savings
if($transfer_type = 1) {
if($transfer_amount >= $spending) {
// the magic to transfer the funds goes here.
}
}
// Savings to Spending
if($transfer_type = 2) {
if($transfer_amount >= $savings) {
// the magic to transfer the funds goes here.
}
}
}
Form in View:
{{ Form::open(array('route' => array('transferMoney'), 'method' => 'post')) }}
{{ Form::select('transfer_to', array('1' => 'Spending to Saving', '2' => 'Saving to Spending')) }}
{{ Form::text('amount', null, ['placeholder' => 'Amount']) }}
{{ Form::submit('Transfer', array('class' => 'button secondary pull-right')) }}
{{ Form::close() }}
Route:
Route::post('/bank', array('as' => 'transferMoney', 'uses' => 'BankController#transferMoney'));
Any tips & tricks on best practices are hugely appreciated!
Apologies if this repeated - I swear I can't find a solution to this specific roadblock.
Thank you!
I believe you'll need to subtract the amount ($transfer_amount) from the transfer-er and add it to the transfer-ee
public function transferMoney()
{
$id = Auth::id();
$bank = Bank::find($id);
$transfer_type = Input::get('transfer_to');
$transfer_amount = Input::get('amount');
// Spending to Savings
if($transfer_type == 1)
{
if($transfer_amount > $bank->spending)
{
// Error - insufficient funds
}
else
{
$bank->spending -= $amount;
$bank->saving += $amount;
$bank->save();
}
}
// Savings to Spending
if($transfer_type == 2)
{
if($transfer_amount > $bank->saving)
{
// Error - insufficient funds
}
else
{
$bank->spending += $amount;
$bank->saving -= $amount;
$bank->save();
}
}
}
I also fixed a few syntactical things (if($transfer_type = 1) needs more than one =).
Make sure you validate that the transfer amount is a valid number! :)