I am trying to save datas into two different tables depends on selection(x-editable). Here is my code and Help me by pointing where i am doing mistake.
Result i am looking for: I change payment status pending to paid in TBL:Product, paid values also change 0 to 1 in TBL:Product_payment
TBL:Product
- product_id
- client_id
...
- status {paid/pending}
TBL:Product_payment
- product_id
- payment_id
....
- paid {1/0}
Controller:
public function update()
{
$inputs = Input::all();
if ($row = Product::with('payments')->find($inputs['pk']))
{
$row->$inputs['name'] = $inputs['value'];
if($row['status'] == 'paid') {
$row['paid'] = 1;
}
$row->save();
return $row;
}
Product.php(model)
class Product extends Eloquent
{
protected $primaryKey = 'product_id';
protected $table = 'products';
protected $fillable = array('client_id', 'date', 'amount', 'status', 'notes');
public function payments()
{
return $this->hasMany('ProductPayment');
}
}
ProductPayment.php(model)
class ProductPayment extends Eloquent
{
public $table = 'product_payments';
protected $primaryKey = 'product_payment_id';
protected $fillable = array('product_id', 'client_id', 'payment_method', 'amount_paid', 'paid');
public function product()
{
return $this->belongsTo('Products');
}
public function clients()
{
return $this->belongsTo('Clients');
}
}
Add a model event listener to boot in your AppServiceProvider for whenever an instance of Product is saved.
Product::saved(function ($product) {
$paymentStatus = [
'pending' => 0,
'paid' => 1,
];
if(array_key_exists($product->status, $paymentStatus))
{
ProductPayment::where('product_id', $product->id)
->update(['paid' => $paymentStatus[$product->status]]);
}
});
Related
I have a problem with mapping objects in a Laravel eloquent query.
How to map relations in a query builder.
How to connect two separate collections.
For example. Having models:
class CartProduct extends Model
{
protected $fillable = [
'quantity',
'cart_id',
'product_id',
'unit_price',
'product_code'
];
function product(){
return $this->belongsTo(Product::class);
}
function cart(){
return $this->belongsTo(Cart::class);
}
}
class Cart extends Model
{
function productsInCart()
{
return $this->hasMany(CartProduct::class);
}
public function products()
{
return $this->belongsToMany(
Product::class,
'cart_products',
'cart_id',
"product_id");
}
}
class Product extends Model
{
protected $fillable = [
'name',
'code',
'description',
'price',
];
}
The tasks are:
Get a set of products that are in the same cart (doesn't matter which one) as $product_id (excluding $product_id)
Get a set of products that were in any cart together with $product_id (excluding $product_id, without duplications)
I would solve it like this:
1.
public function task_one($product_id)
{
return $products = CartProduct::where('product_id', $product_id)->first()->cart->products
->filter(function (Product $p) use ($product_id) {
return $p->id !== $product_id;
});
}
public function task_two($product_id)
{
$cartProducts = CartProduct::where('product_id', $product_id)->get();
$products = collect(new Product);
foreach ($cartProducts as $cartProduct) {
$productsInCart = $cartProduct->cart->products
->filter(function (Product $p) use ($product_id) {
return $p->id !== $product_id;
});
$products = $products->merge($productsInCart);
}
return $products->unique();
}
However, the 2nd function seems to be awful. How can I do this properly, to achieve fast execution and a good style of code?
Is there any method to "map" the whole collection to related model objects? For example by
$carts = CartProduct::getByProductId($product_id)->"mapByRelationship('cart)";
//The result should be a collection od Carts
$products = CartProduct::getByProductId($product_id)->"mapByRelationship('cart)"->"mapByRelationship('products')"->unique();
//The result should be the same as task_two($product_id);
Thank you in advance
I think I have done this Controller-Model Relationship.
Controller:
class MakeAWishController extends Controller
{
public function getMakeAWishes(Request $request)
{
$limit = (int) ($request->limit ?? 1);
$offset = (int) ($limit * (($request->page ?? 1) - 1));
$wishes = MakeAWish::with('product')
->offset($offset)->limit($limit)->where('product_quantity', '>' , '0')->get()
->map(function ($wish) {
$wish->children_image = asset(Storage::url($wish->children_image));
if(!empty($variant = $wish->product->variant())) {
$wish->product->variant_id = $variant->variant_id;
$wish->product->variant_price = $variant->variant_price ?? "0.00";
$wish->product->variant_compare_at_price = $variant->variant_compare_at_price ?? "0.00";
}
return $wish;
});
$response = [
'status' => 200,
'data' => $wishes
];
return response()->json($response);
}
}
Model:
class MakeAWish extends Model
{
protected $collection = 'make_a_wishes';
protected $fillable = [
'children_name',
'children_name_for_isis',
'age',
'country',
'children_image',
'product_id',
'quantity'
];
protected $casts = [
'product_id' => 'string'
];
public function product()
{
return $this->hasOne(Product::class, 'product_id', 'product_id');
}
public function orders()
{
return $this->hasMany(OrderHistory::class, 'type_id', '_id');
}
public function orderCount()
{
return $this->orders()->where('type', 'M')->count();
}
}
I have been trying to save the data coming from the dynamically generated fields in the form of an array. I have a oneToMany relationship for the customer table.
I have tried to loop through each field but I am unable to achieve it, please correct me if I am wrong.
public function store(Request $request)
{
$res = $request->all();
$res['address'] = implode(' ', array_values($request->address));
$customer = Customer::create($res);
if ($res) {
$customerData = [];
foreach ($request->department_name as $key => $n) {
$customerData = array(
'department_name' => $request->department_name[$key],
'person_name' => $request->person_name[$key],
'person_number' => $request->person_number[$key],
'person_email' => $request->person_email[$key],
'notification_flag' => !isset($request->notification_flag[$key]) ? 0 : $request->notification_flag[$key] === "on" ? 1 : 0,
'custinvoice_noti' => !isset($request->outstanding[$key]) ? 0 : $request->outstanding[$key] === "on" ? 1 : 0,
'invoice_noti' => !isset($request->invoice[$key]) ? 0 : $request->invoice[$key] === "on" ? 1 : 0,
);
$deptModel[] = new Department($customerData);
$customer->department()->saveMany($deptModel);
}
}
return redirect('admin/customers');
}
Customer model and Department model have the following relationship.
class Customer extends Model
{
protected $fillable = ['owner_name', 'address', 'country', 'state', 'city', 'pincode', 'number', 'correspondance_check'];
public function department()
{
return $this->hasMany('App\Department');
}
}
Department Model.
class Department extends Model
{
protected $fillable = ['customer_id', 'department_name', 'person_name', 'person_number', 'person_email', 'notification_flag', 'notification_type'];
public function customer()
{
return $this->belongsTo('App\Customer');
}
}
public function store(Request $request)
{
$customer = new Customer();
$customer->owner_name = $request['owner_name'];
$customer->country = $request['country'];
$customer->state = $request['state'];
$customer->city = $request['city'];
$customer->pincode = $request['pincode'];
$customer->number = $request['number'];
$customer->correspondance_check = $request['correspondance_check'];
$res = $customer->save();
$cus = Customer::where(['id'=> $res->id])->firstOrFail();
$dep = new Department();
$dep->customer()->associate($cus);
$dep->save();
return redirect('admin/customers');
// return response()->json($customerData);
}
Customer model and Department model have the following relationship.
class Customer extends Model
{
protected $fillable = ['owner_name', 'address', 'country', 'state', 'city', 'pincode', 'number', 'correspondance_check'];
public function department()
{
return $this->hasMany('App\Department');
}
}
//Department Model.
class Department extends Model
{
protected $fillable = ['customer_id', 'department_name', 'person_name', 'person_number', 'person_email', 'notification_flag', 'notification_type'];
public function customer()
{
return $this->belongsTo('App\Customer');
}
}
i have relation between Service and Services_Gallery one to many, and i want to use id of Service when i insert new image to Services_Gallery, and this is my Controller:
public function save(Request $request)
{
$this->validate($request,[
'image' => 'required|image|mimes:jpeg,jpg,png,svg|max:1024'
]);
$services_Gallery = new Services_Gallery();
$services_Gallery->image = $request->image->move('Uploads', str_random('6') . time() . $request->image->getClientOriginalName());
$services_Gallery->Service::all(id) = $request->service_id; //The problem here
$services_Gallery->save();
return back();
}
this is my Models:
class Service extends Model
{
protected $table = 'services';
protected $fillable = [
'en_main_title',
'ar_main_title',
'en_sub_title',
'ar_sub_title',
'en_content_title',
'ar_content_title',
'en_content',
'ar_content',
'priority',
];
public function gallery()
{
return $this->hasMany('App\Services_Gallery','service_id');
}
}
class Services_Gallery extends Model
{
protected $table = 'services_galleries';
protected $fillable = [
'image',
'service_id',
];
public function gallery(){
return $this->belongsTo('App\Service','service_id');
}
}
Exapmle:
$modelOfService = Service::where('param_x', $request->service_id)->first();
$id = $modelOfService->id;
Is that you need?
I have a project that has a project model which looks like this:
class Product extends Model
{
public $timestamps = true;
protected $guarded = ['id'];
protected $table = 'products';
protected $hidden = ['created_at', 'updated_at'];
protected $fillable = ['name', 'category_id', 'units', 'b_price', 's_price', 'warn_count', 'added_by'];
public function category()
{
return $this->belongsTo('App\Category');
}
public function stock(){
$product_id = $this->id;
$filter = ['product_id' => $product_id];
//STOCK PLUS
//credit purchases
$cr_purchases = CreditPurchase::where($filter)->sum('qty');
//purchases
$purchases = Purchase::where($filter)->sum('qty');
//returns in
$re_in = ReturnIn::where($filter)->sum('qty');
//STOCK MINUS
//credit sales
$cr_sales = CreditSale::where($filter)->sum('qty');
//sales
$sales = Sale::where($filter)->sum('qty');
//returns out
$re_out = ReturnOut::where($filter)->sum('qty');
//damaged
$damaged = DamagedProduct::where($filter)->sum('qty');
return $cr_purchases + $purchases + $re_in - ($cr_sales + $sales + $re_out + $damaged);
}
}
As can be seen stock is a calculated value for each model. I wish to make queries based on it as though it were a column of the products table.
Method 1
Change the stock method to be an Laravel model accessor.
public function getStockAttribute(){
//code logic
}
Fetch the results as a Collection and perform filters on the 'stock; attribute
I would do something like.
Products::where('product','like','miraa') //where
->get()
->filter(function($item) {
return $item->stock > 100;
});
Read about filtering collections
Method 2
Use dynamic query scopes
See scopes in laravel.
public function scopeAvailbaleStock($query, $type)
{
return $query->where('type', $type);
// could perform filters here for the query above
}
Fetch using scope
$users = Products::available_stock()->get();
Method 3
I saw out this package jarektkaczyk/eloquence
public function scopeWhereStock($query, $price, $operator = '=', $bool = 'and'){
$query->where('info1', $operator, $price, $bool);
}
// then
Products::whereStock(25); // where('info1', 25);
Products::whereStcok(25, '>'); // where('info1', '>', 25);
Products::whereStock(25, '=', 'or'); // orWhere('info1', 25);
Howerever, i would recomend to use method 1 or 2. The 3rd solution works but not sure if it is the best
I solved it by overriding $appends on the model and using an accessor for the stock field. So that the model now looks like:
class Product extends Model
{
public $timestamps = true;
protected $guarded = ['id'];
protected $table = 'products';
protected $hidden = ['created_at', 'updated_at'];
protected $fillable = ['name', 'category_id', 'units', 'b_price', 's_price', 'warn_count', 'added_by'];
protected $appends = ['stock'];
public function category()
{
return $this->belongsTo('App\Category');
}
public function getStockAttribute(){
$product_id = $this->id;
$filter = ['product_id' => $product_id];
//STOCK PLUS
//credit purchases
$cr_purchases = CreditPurchase::where($filter)->sum('qty');
//purchases
$purchases = Purchase::where($filter)->sum('qty');
//returns in
$re_in = ReturnIn::where($filter)->sum('qty');
//STOCK MINUS
//credit sales
$cr_sales = CreditSale::where($filter)->sum('qty');
//sales
$sales = Sale::where($filter)->sum('qty');
//returns out
$re_out = ReturnOut::where($filter)->sum('qty');
//damaged
$damaged = DamagedProduct::where($filter)->sum('qty');
return $cr_purchases + $purchases + $re_in - ($cr_sales + $sales + $re_out + $damaged);
}
}
I built this solution on #samueldervis answer. A simple example can be seen here: http://laraveldaily.com/why-use-appends-with-accessors-in-eloquent/
I have the following relations:
Discount:
<?php
class Discount extends Eloquent {
protected $table = 'discount';
public $timestamps = true;
public function title()
{
return $this->hasOne('Translation', 'labelId', 'titleLabelId')->where('languageId', T::getLang())->first()['phrase'];
}
public function titles()
{
return $this->hasMany('Translation', 'labelId', 'titleLabelId');
}
}
?>
Translation:
<?php
class Translation extends Eloquent {
protected $table = 'translations';
public $timestamps = false;
protected $fillable = array('phrase', 'languageId', 'labelId');
public function language()
{
return $this->belongsTo('Language', 'languageId');
}
public function label()
{
return $this->belongsTo('Label', 'labelId');
}
}
?>
Label:
<?php
class Label extends Eloquent {
protected $table = 'label';
public $timestamps = false;
protected $fillable = array('key');
public function translations()
{
return $this->hasMany('Translation', 'labelId', 'id');
}
}
?>
There are three database tables with the following columns:
Discount:
id | titleLabelId
Translation:
id | languageId | labelId
Label:
id
The problem: I'd like to create a title (translation) and associate it with the discount. Here's what I've tried:
$discount = new Discount;
/*create a new label*/
$labelKey = Label::max('key') + 1;
$label = new Label(array('key' => $labelKey));
$label->save();
/*create a new title (and associate it with the label)*/
$title = new Translation(
array(
'phrase' => $input['title'],
'languageId' => 3,
'labelId' => $label->id
));
$title->save();
$discount->save();
$discount->titles()->save($title);
Apparently, the $discount->titles()->save($title); part doesn't work. The title is only attached to the discount if I do it manually: $discount->titleLabelId = $label->id. Is there a way to do it using the ORM?
In your Discount Model, do you have your relationship set up to use the proper table and foreign key?
class Discount extends Eloquent
{
public function titles()
{
return $this->belongsTo('Translation', 'translations', 'titleLabelId');
}
}
When trying to associate one model with another through a defined relationship in Eloquent, you should use the associate() method rather than the save() method.
$discount->titles()->associate($title);
Before this happens though, you should be sure to call the save() method on anything that has been altered or is new.