I am trying to get (order_id, product_id and quantity) to be stored in Order Product table in database, so when placed an order it should store orders and order product in database . But now it only store orders and gives this error "Trying to get property of non-object".
I have tried some solutions from other sources but still not working.
CheckoutController
<?php
namespace App\Http\Controllers;
use App\Order;
use App\OrderProduct;
use Illuminate\Http\Request;
use cart;
class CheckoutController extends Controller
{
public function index()
{
return view('checkout');
}
public function create()
{
//
}
public function store(Request $request)
{
//Insert into orders table
$order = Order::create([
'user_id' => auth()->user() ? auth()->user()->id : null,
'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
//Insert into order product table
$cart = session('cart');
foreach(session('cart') as $products) {
OrderProduct::create([
'order_id' => $order->id,
'product_id' => $products->id,
'quantity' => $products->quantity,
]);
}
$cart = session()->remove('cart');
return redirect()->route('confirmation.index')->with('success_message', 'Thank you! Your payment has been successfully accepted!');
}
public function show($id)
{
//
}
public function edit($id)
{
//
}
public function update(Request $request, $id)
{
//
}
public function destroy($id)
{
//
}
}
OrderProduct.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class OrderProduct extends Model
{
protected $table = 'order_product';
protected $fillable = ['order_id', 'product_id', 'quantity'];
}
Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
protected $fillable = [
'user_id', 'shipping_email', 'shipping_name', 'shipping_city', 'shipping_phone',
];
public function user()
{
return $this->belongsTo('App\User');
}
public function products()
{
return $this->belongsToMany('App\Product')->withPivot('quantity');
}
}
Updated:
I have changed code now it shows quantity but can't show product_id it gives error "Trying to get property of non-object"
if ($order) {
foreach(session('cart') as $products) {
if (empty($products)) {
continue;
}
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $products['id'], //-> This not working
'quantity' => $products['quantity'],
]);
Related
I'm working on a project where users can sell and also buy products, and in my database there are two tables(orders and order products table)in orders tables there's a buyer_id and seller_id. So if a user buys product it shows buyer_id now the problem comes to seller_id. It doesn't show the seller_id.
Here is my code.
User.php
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'Seller'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
//public function isSeller() {
// return $this->seller;
//}
public function products()
{
return $this->hasMany(Products_model::class);
}
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function orders()
{
return $this->hasManyThrough(Order::class, Products_model::class, 'buyer_id', 'seller_id', 'product_id');
}
public function orderFromBuyers()
{
$this->hasManyThrough(OrderProduct::class, Products_model::class, 'buyer_id', 'product_id');
}
public function orderFromSellers()
{
$this->hasManyThrough(OrderProduct::class, Products_model::class, 'seller_id', 'product_id');
}
}
Products_model.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class products_model extends Model
{
protected $table='products';
protected $primaryKey='id';
protected $fillable= ['seller_id','pro_name','pro_price','pro_info','image','stock','category_id'];
}
OrderProduct.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class OrderProduct extends Model
{
protected $table = 'order_product';
protected $fillable = ['order_id', 'buyer_id', 'seller_id','product_id', 'quantity'];
public function products()
{
return $this->belongsTo('App\Products_model');
}
public function buyer()
{
return $this->belongsTo(User::class, 'id', 'buyer_id');
}
public function seller()
{
return $this->belongsTo(User::class, 'id', 'seller_id');
}
}
Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
//protected $table = 'orders';
protected $fillable = [
'shipping_email', 'shipping_name', 'shipping_city', 'shipping_phone', 'billing_subtotal', 'billing_total',
];
public function user()
{
return $this->belongsTo('App\User');
}
public function products()
{
return $this->belongsToMany('App\Products_model')->withPivot('quantity');
}
public function orders(){
return $this->hasMany('App\OrderProduct', 'order_id');
}
My store Function
public function store(Request $request)
{
//Insert into orders table
$order = Order::create([
'buyer_id' => auth()->user() ? auth()->user()->id : null,
'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
//Insert into order product table
if ($order) {
foreach(session('cart') as $productId =>$item) {
if (empty($item)) {
continue;
}
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $productId,
// $products=DB::table('products')->where('id',$id)->get();
'quantity' => $item['quantity'],
//dd($item)
]);
}
}
CheckoutController(function)
public function store(Request $request)
{
//Insert into orders table
$order = Order::create([
'buyer_id' => auth()->user() ? auth()->user()->id : null,
'seller_id' => auth()->user() ? auth()->user()->id : null, 'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
//Insert into order product table
if ($order) {
foreach(session('cart') as $productId =>$item) {
if (empty($item)) {
continue;
}
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $productId,
// $products=DB::table('products')->where('id',$id)->get();
'quantity' => $item['quantity'],
//dd($item)
]);
}
}
//Empty Cart After order created
$cart = session()->remove('cart');
return redirect()->route('confirmation.index')->with('success_message', 'Thank you! Your payment has been successfully accepted!');
}
ProductController(function)
public function viewOrders(User $user)
{
$products = Products_model::where('seller_id', '=', $user->id)->get();
// all sells
$sells = $user->sells;
// all buys
$buys = $user->buys;
}
//dd( $products);
return view('orders')->with(compact('orders'));
My View File(blade)
#foreach($sells as $sell)
<tr>
<td>{{$sell->orders}}</td>
<td>{{$sell->products}}</td>
#foreach($sell->orders as $order)
<td>{{$order->created_at}}</td>
<td>{{$order->shipping_name}}</td>
<td>{{$order->shipping_city}}</td>
<td>{{$order->shipping_phone}}</td>
<td>
View Order Details
</td>
</tr>
#endforeach
#endforeach
Let's see if we can find probably the easiest solution. I can see from your product model that it has a seller_id field. When you are looping over the products to display them, why don't you use a hidden input which has a value of seller_id? i.e.
#foreach ( $products as $product )
<form> // assuming you will be creating a form for the buy button
<input type="hidden" value={{ $product->seller_id }} />
<button type="submit">Buy Now</button>
</form>
#endforeach
Now in your Controller, you will have access to seller_id as
$seller_id = request('seller_id');
hope that helps
There is an issue that is every product must have a seller. If then, you should use buyer and seller relation with OrderProduct model not Order model.
Or you may collect seller by make relation with product-seller.
First
remove 'buyer_id', 'seller_id', from Order model and orders migration.
Second
Add 'buyer_id', 'seller_id', from OrderProduct model and order_product migration.
Third
Transfer relation buyer and seller from Order model to OrderProduct model
Fourth
When you create the OrderProduct data, you add buyer_id and seller_id. Finally catch and use them as you want.
Fifth
Dont forget to update buys and sells relation Order model to OrderProduct model on User model.
Sixth
you have to updatye orders relation on User model. It should be ,
public function orderFromBuyers()
{
$this->hasManyThrough(OrderProduct::class, Products_model::class, 'buyer_id', 'product_id');
}
and
public function orderFromSellers()
{
$this->hasManyThrough(OrderProduct::class, Products_model::class, 'seller_id', 'product_id');
}
Note that, You cannot make them from one function.
Finally update any other things relation to these changes.
Add this to OrderProduct.php
public function order()
{
return $this->belongsTo(Order::class);
}
Update product Controller
public function viewOrders(User $user)
{
// $products = Products_model::where('seller_id', '=', $user->id)->get();
// all sells
$sells = $user->orderFromSellers;
return view('orders')->with(compact('sells'));
}
//dd( $products);
Update your view to,
#foreach($sells as $sell)
<tr>
<td>{{$sell->orders}}</td>
<td>{{$sell->products}}</td>
<td>{{$sell->created_at}}</td>
<td>{{$sell->order->shipping_name}}</td>
<td>{{$sell->order->shipping_city}}</td>
<td>{{$sell->order->shipping_phone}}</td>
<td>
View Order Details
</td>
</tr>
#endforeach
On CheckoutController (store) update to,
public function store(Request $request)
{
//Insert into orders table
$order = Order::create([
'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
//Insert into order product table
if ($order) {
foreach(session('cart') as $productId =>$item) {
if (empty($item)) {
continue;
}
OrderProduct::create([
'buyer_id' => auth()->user() ? auth()->user()->id : null,
'seller_id' => $products=DB::table('products')->find('productId')? $products=DB::table('products')->find('productId')->seller_id : null,
'order_id' => $order->id ?? null,
'product_id' => $productId,
// $products=DB::table('products')->where('id',$id)->get();
'quantity' => $item['quantity'],
//dd($item)
]);
}
}
//Empty Cart After order created
$cart = session()->remove('cart');
return redirect()->route('confirmation.index')->with('success_message', 'Thank you! Your payment has been successfully accepted!');
}
I'm having issues with how to deal with tables relationships in laravel. i have three tables Orders table, Order_product table and User table. A User can either be described as a seller or a buyer depending on if they listed or bought something. Now when a user submit order form i get an error
"General error: 1364 Field 'seller_id' doesn't have a default value (SQL: insert into order_product (order_id, product_id, quantity, `up ▶"
Here is how those tables look like in phpmyAdmin
https://imgur.com/a/fvxo1YZ
And below are the models
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'Seller'
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
//public function isSeller() {
// return $this->seller;
//}
public function products()
{
return $this->hasMany(Products_model::class);
}
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function orders()
{
return $this->hasManyThrough(Order::class, Products_model::class, 'buyer_id', 'seller_id', 'product_id');
}
public function orderFromBuyers()
{
return $this->hasManyThrough(OrderProduct::class, Products_model::class, 'buyer_id', 'product_id');
}
public function orderFromSellers()
{
return $this->hasManyThrough(OrderProduct::class, Products_model::class, 'seller_id', 'product_id');
}
}
Products_model
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class products_model extends Model
{
protected $table='products';
protected $primaryKey='id';
protected $fillable= ['seller_id','pro_name','pro_price','pro_info','image','stock','category_id'];
}
OrderProduct.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class OrderProduct extends Model
{
protected $table = 'order_product';
protected $fillable = ['order_id', 'buyer_id', 'seller_id','product_id', 'quantity'];
public function products()
{
return $this->belongsTo('App\Products_model');
}
public function buyer()
{
return $this->belongsTo(User::class, 'id', 'buyer_id');
}
public function seller()
{
return $this->belongsTo(User::class, 'id', 'seller_id');
}
public function order()
{
return $this->belongsTo(Order::class);
}
}
Order.php
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Order extends Model
{
//protected $table = 'orders';
protected $fillable = [
'shipping_email', 'shipping_name', 'shipping_city', 'shipping_phone', 'billing_subtotal', 'billing_total',
];
public function user()
{
return $this->belongsTo('App\User');
}
public function products()
{
return $this->belongsToMany('App\Products_model')->withPivot('quantity');
}
public function orders(){
return $this->hasMany('App\OrderProduct', 'order_id');
}
}
Here is my store Function
public function store(Request $request)
{
//Insert into orders table
$order = Order::create([
'buyer_id' => auth()->user() ? auth()->user()->id : null,
'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
//Insert into order product table
if ($order) {
foreach(session('cart') as $productId =>$item) {
if (empty($item)) {
continue;
}
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $productId,
// $products=DB::table('products')->where('id',$id)->get();
'quantity' => $item['quantity'],
//dd($item)
]);
}
}
//Empty Cart After order created
$cart = session()->remove('cart');
return redirect()->route('confirmation.index')->with('success_message', 'Thank you! Your payment has been successfully accepted!');
}
the error is very specific:
General error: 1364 Field 'seller_id' doesn't have a default value
(SQL: insert into order_product
And looking at the code you posted, assume it happens here:
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $productId,
'quantity' => $item['quantity'],
]);
You can not create an OrderProduct without giving a value to seller_id when that field doesn't have a default value or is not nullable in DB. So, give it a value when creating the record. Looking at the models, I think you could do something like this:
$product = products_model::find($productId);
OrderProduct::create([
'order_id' => $order->id ?? null,
'product_id' => $productId,
'quantity' => $item['quantity'],
'seller_id' => $product->seller_id,
'buyer_id' => $order->buyer_id,
]);
You need to send value of the seller id.
$order = Order::create([
'buyer_id' => auth()->user() ? auth()->user()->id : null,
'seller_id' => $request->seller_id,
'shipping_email' => $request->email,
'shipping_name' => $request->name,
'shipping_city' => $request->city,
'shipping_phone' => $request->phone,
// 'error' => null,
]);
or you can remove the seller_id on your Order Table because you can get the seller information from the Product Model
Post model to relationship one to one,
and User model to relationship one to many.
I made a Models controller and use it as resources for almost all my Model. Now, when I try to get the data of a model and the related models, Laravel replace upper case letter with an underscore and the lower case letter. I need to let it with the upper case.
So there is the model where I got the issue at App\Models\Rate:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Rate extends Model
{
use SoftDeletes;
protected $dates = ['deleted_at'];
protected $table = 'rates';
protected $fillable = [
'institution_id',
'name',
];
protected $info = [
'relations' => [
'rateRistournes' => [
'model' => 'RateRistourne',
'type' => 'hasMany',
],
'rateRows' => [
'model' => 'RateRow',
'type' => 'hasMany',
],
'rateTables' => [
'model' => 'RateTable',
'type' => 'hasMany',
],
],
'rules' => [
],
'hashid' => false,
];
public function getRelations()
{
return $this->info['relations'];
}
public function getRules()
{
return $this->info['rules'];
}
public function useHashid()
{
return $this->info['hashid'];
}
public function institution()
{
return $this->belongsTo(Institution::class);
}
public function rateTables()
{
return $this->hasMany(RateTable::class);
}
public function rateRows()
{
return $this->hasMany(RateRow::class);
}
public function rateRistournes()
{
return $this->hasMany(RateRistourne::class);
}
}
And this is the function that contain the query into ModelsController:
public function show($name, $id)
{
$data = $this->retrieveModelAndRelations($name, $id);
if (is_null($data)) {
return $this->sendError('Model not found.');
}
return $this->sendResponse($data->toArray(), 'Model retrieved successfully.');
}
private function retrieveModelAndRelations($name, $id)
{
$modelName = 'App\Models\\'.$name;
$model = new $modelName;
if ($id === 'null') {
...
} else {
$data = $modelName::when(isset($model->getRelations()['customer']), function($query) {
return $query->with('customer');
})...
})->when(isset($model->getRelations()['rateTables']), function($query) {
return $query->with(array('rateTables' => function($q) {
$q->orderBy('cashStart', 'ASC');
}));
})->when(isset($model->getRelations()['rateRows']), function($query) {
return $query->with(array('rateRows' => function($q) {
$q->orderBy('rate', 'ASC');
}));
})->when(isset($model->getRelations()['rateRistournes']), function($query) {
return $query->with(array('rateRistournes' => function($q) {
$q->orderBy('ristourne', 'ASC');
}));
})->find($id);
}
return $data;
}
And there is the result into the console:
created_at:(...)
deleted_at:(...)
id:(...)
institution_id:(...)
name:(...)
rate_ristournes:Array(1)
rate_rows:Array(1)
rate_tables:Array(1)
The 3 last line should be:
rateRistournes:Array(1)
rateRows:Array(1)
rateTables:Array(1)
Is there a way to force laravel to keep the relation key as I wrote it?
Something under the hood change the name and I don't know how to bypass it.
Change $snakeAttributes:
class Rate extends Model
{
public static $snakeAttributes = false;
}
I'm trying to set validation on my controller method, but on validation failure I'm getting error that method is not allowed http exception.
My controller:
namespace App\Http\Controllers\Web;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Services\InvoicesService;
class InvoiceController extends Controller
{
private $invoice;
public function __construct(InvoicesService $invoice) {
$this->invoice = $invoice;
}
public function startNewInvoice($id, $customer)
{
$ticket = $this->invoice->getTicketByInvoice($id);
$ticket = $ticket->Ticket;
return view('form', ['InvoiceId' => $id,'CustomerInfo' => $customer, 'records' => null, 'recordState' => null, 'ticket' => $ticket, 'invoices' => null]);
}
public function generateInvoice(Request $request)
{
//dd($request);
$this->validate($request, [
'CustomerNumber' => 'required|numeric'
]);
$invoiceId = $request->input('Invoice');
$customer = array('CustomerCode' => $request->input('CustomerNumber'),'CustomerName' => $request->input('CustomerName'),'CustomerAddress' => $request->input('CustomerAddress'),
'CustomerVATCode' => $request->input('CustomerVatNumber'));
$hash = $this->invoice->generateInvoice($invoiceId, $customer);
$newInvoice = $this->invoice->newInvoice($request->input('CustomerNumber'), $hash->Id);
return $this->startNewInvoice($newInvoice->Id, $customer);
}
}
Any help would be really appreciated
I need to update the items for specific order with Eloquent.
I have this models:
class Orders extends \Illuminate\Database\Eloquent\Model
{
public $timestamps = false;
protected $fillable = ['items_array'];
public function items()
{
return $this->hasMany(Items::class, 'order_id', 'order_id');
}
public function setItemsArrayAttribute($data)
{
$this->items()->whereIn('article_id', array_map(function($item){
return $item['article_id'];
}, $data['items']))->update($data);
}
}
class Items extends \Illuminate\Database\Eloquent\Model
{
protected $table = 'order_to_items';
public $timestamps = false;
protected $fillable = ['internal_code'];
public function order()
{
return $this->belongsTo(Orders::class, 'order_id', 'order_id');
}
}
I have the api response like that:
$response = [
'message'=>'some',
'order_id'=>'111-222-333',
'items'=>[
[
'article_id' => 'R-320108',
'internal_code' => 333
],
[
'article_id' => 'R-320116',
'internal_code' => 444
],
]
];
So I make this
$order = Orders::where('order_id', $response['order_id'])->with('items')->first();
and I was trying to make this:
$order->update([
'is_sent' => true,
'items_array' => $response['items']
]);
but that doesn't work. Is there any way to match the related model with API response and make update?
Thanks!
You can use save():
$order->is_sent = true;
$order->items_array = $response['items'];
$order->save();
Or update():
$order = Orders::where('order_id', $response['order_id'])
->update([
'is_sent' => true,
'items_array' => $response['items']
]);