'Cannot create an empty shipment' while trying to create shipment in magento - magento-1.9

I am trying to create shipment and adding tracking number after placing an order,but i am getting an error like Cannot create an empty shipment. when i search through google i got one of the reason for this is item quantity is null, but what i used below is returning the exact quantities of products ordered.
$itemQty = $order->getItemsCollection()->count();
I don't know exactly it is only the reason for that error. what i done mistake? anybody knows please help me on this.
public function salesOrderInvoiceShipmentCreate($observer)
{
// $order = $observer->getEvent()->getOrder();
//$order = Mage::getModel('sales/order')->loadByIncrementId($orderId);
$order_id = $observer->getData('order_ids');
$order = Mage::getModel('sales/order')->load($order_id);
$token = '3acb6561b04117c6cbe3552c90f1d6815507e257';
$waybill_url = 'https://track.delhivery.com/waybill/api/fetch/json/?token='.$token.'&cl=GEECHOO';
$waybill = file_get_contents($waybill_url);
Mage::log($order, Zend_Log::INFO, 'order.log', true);
if (!$order->getId()) {
Mage::throwException('Order does not exist, for the Shipment process to complete');
}
if ($order->canShip()) {
try {
// $shipment = Mage::getModel('sales/service_order', $order)
// ->prepareShipment($this->_getItemQtys($order));
$itemQty = $order->getItemsCollection()->count();
$shipment = Mage::getModel('sales/service_order', $order)->prepareShipment($itemQty);
$shipmentCarrierCode = '';
$shipmentCarrierTitle = '';
$arrTracking = array(
'carrier_code' => isset($shipmentCarrierCode) ? $shipmentCarrierCode : $order->getShippingCarrier()->getCarrierCode(),
'title' => isset($shipmentCarrierTitle) ? $shipmentCarrierTitle : $order->getShippingCarrier()->getConfigData('title'),
'tracking_number' => $waybill,
);
$track = Mage::getModel('sales/order_shipment_track')->addData($arrTracking);
$shipment->addTrack($track);
// Register Shipment
$shipment->register();
// Save the Shipment
$this->_saveShipment($shipment, $order);
// Finally, Save the Order
$this->_saveOrder($order);
} catch (Exception $e) {
throw $e;
}
}
}

Try this for order item quantity
$quote = Mage::helper('checkout/cart')->getCart()->getQuote();
$value = [];
foreach ($quote->getAllItems() as $item) {
$value[]= array (
'id' => $item->getSku(),
'quantity' => $item->getQty(),
}

Related

How to retrive from other table and input it again into another table in laravel?

I want to retrieve some data from 'tbl_karyawan' and input into 'tbl_absen' which is if the NIP exist from 'tbl_karyawan' then parshing some data into 'tbl_absen'. I was create the code, and the data is going well. but i have something trouble with
i want the data input in Nip_kyn be like 'KIP001' not [{"Nip_kyn":"KIP001"}].
this is my Model
public function presensi($data)
{
$isExist = DB::table('tbl_karyawan')
->where('Nip_kyn', $data)->exists();
if ($isExist) {
$namakyn = DB::table('tbl_karyawan')->where($data)->get('Nama_kyn');
$nippppp = DB::table('tbl_karyawan')->where($data)->select('Nip_kyn')->get($data);
$values = array('Nip_kyn' => $nippppp, 'Nama_kyn' => $namakyn, 'Jam_msk' => now(), 'Log_date' => today());
DB::table('tbl_absen')->insert($values);
} else {
echo 'data not available';
}
}
this is my controller
public function get()
{
$day = [
'time_in' => $this->AbsenModel->timeIN(),
'time_out' => $this->AbsenModel->timeOut(),
'break' => $this->AbsenModel->break(),
// absen here
's' => $this->AbsenModel->absensi(),
];
$data = [
'Nip_kyn' => Request()->Nip_kyn,
];
$this->AbsenModel->presensi($data);
return view('v_absen', $data, $day);
}
Yup, I finally got it, the problem is on my model.
$nama_karyawan = DB::table('tbl_karyawan')->where($data)->value('Nama_kyn');
$nipkyn = DB::table('tbl_karyawan')->where($data)->value('Nip_kyn');
I just change 'get' to 'value'.

How to get current cart items for logged in user

Following is my code:-
try
{
$store = $this->_getStore();
Mage::app()->setCurrentStore($store->getId());
$customer_ID = 3;
$customer = Mage::getModel('customer/customer')->load($customer_ID);
// load quote by customer
$quote = Mage::getModel('sales/quote')->loadByCustomer($customer_ID);
$quote->assignCustomer($customer);
$product = Mage::getModel('catalog/product')
// set the current store ID
->setStoreId(Mage::app()->getStore()->getId())
// load the product object
->load(3);
// Add Product to Quote
$quote->addProduct($product,1);
// Calculate the new Cart total and Save Quote
$quote->collectTotals()->save();
return json_encode(array("", $quote->getId()));
}catch(Exception $e)
{
return $e->getMessage();;
}
Using this the product is getting added in cart successfully and returning quote_id, but using this id i want to fetch current cart items details for currently logged in user.
To get cart item details:
$quote = Mage::helper('checkout/cart')->getCart()->getQuote();
$value = [];
foreach ($quote->getAllItems() as $item) {
$value[]= array (
'id' => $item->getSku(),
'quantity' => $item->getQty(),
'price' => $item->getParentItemId()? $item->getParentItem()->getPrice(): $item->getPrice()
);
}

Insert Data to Database Codeigniter only if item does not exit

I'm having trouble trying to insert batch data.
All is fine with the insert_batch function but i would like to insert only the items that does not exist in database, not update it, just ignore and insert new items.
This is my Controller:
csv file:
col0,col1,col2,col3
data1,data1,data1,data1
data2,data2,data,2,data2
data3,data3,data3,data3
insert batch:
function mres($q) {
if(is_array($q))
foreach($q as $k => $v)
$q[$k] = $this->mres($v); //recursive
elseif(is_string($q))
$q = mysql_real_escape_string($q);
return $q;
}
function inserbatch(){
$csv = 'file.csv';
$arrResult = array();
$handle = fopen("uploads/csv/".$csv, "r");
if( $handle ) {
while (($row = fgetcsv($handle, 0, ",")) !== FALSE) {
$arrResult[] = array(
'col0' => $row[0],
'col1' => $row[1],
'col2' => $row[2],
'col3' => utf8_encode($row[3])
);
}
fclose($handle);
}
$final = $this->mres($arrResult);
$this->model_m->addBatch($final);
}
Model:
public function addBatch($final = array()){
if($this->db->insert_batch('mytable', $final)){
return true;
}
return false;
}
database:
id,col0,col1,col2,col3
col0 contain the unique value and if exist in csv file need to be skipped.
My question is how can i insert only the data that doesnt exist in database the col0 is the unique value and i think need to be like
if data from csv[col0] != database[col0] insert_batch.
Any help is appreciated.
Yes I think you on the right path. You only need to check your db if the value exists.
Something like this:
foreach(csv[col0] as $your_data)
{
$query = $this->db->query("SELECT * FROM my_table WHERE col0 = $your_data");
$rows = $query->num_rows();
if(!$rows)
{
// No record has been found so here you would write the code to insert the data
}
}

insert if not exists Codeigniter

my controller:
function getFeed()
{
$feed_url = $this->input->get("url");
$content = file_get_contents($feed_url);
$x = new SimpleXmlElement($content);
foreach($x->channel->item as $entry) {
$feeds[] = array(
'title' => (string)$entry->title,
'url'=> (string)$entry->link,
'username' => $this->session->userdata('username')
);
$this->load->model('membership_model');
$this->membership_model->feeds($feeds);
}
Model:
function feeds($feeds_data)
{
$this->db->insert_batch('feeds', $feeds_data);
}
Is there a function to insert if only the row doesn't exists in the table? I have a table with 4 column : id,title,url,username. I have an anchor when i click him it calls geFeed function and insert the info into table. But i want to insert only if not exists.
I had the same challenge, so i eventually come up with a function which might be helpful to you.
function safe_update_batch($table_name,$records,$filter_field)
{
$filters=array();
foreach($records as $record)$filters[]=$record[$filter_field];
$this->db->query("SET SESSION group_concat_max_len=10000000");
$query=$this->db->select("GROUP_CONCAT($filter_field) AS existing_keys",FALSE)->where_in($filter_field, $filters)->get($table_name);
$row=$query->row();
$found_fields=explode(',',$row->existing_keys);
$insert_batch=array();
$update_batch=array();
foreach($records as $record)
{
if(in_array($record[$filter_field],$found_fields))$update_batch[]=$record;
else $insert_batch[]=$record;
}
if(!empty($insert_batch))$this->db->insert_batch($table_name,$insert_batch);
if(!empty($update_batch))$this->db->update_batch($table_name,$update_batch,$filter_field);
}
//sample usage
$this->safe_update_batch('feeds', $feeds_data,'title');
You can try this in your model!!
function insertClient($array)
{
$this->db->from('MyTable');
$this->db->where('Id', $array['Id']);
$query = $this->db->get();
if($query->num_rows() != 0){
$data = array(
'name'=>$array['name'],
'phone'=>$array['phone'],
'email'=>$array['email']
);
$this->db->where('Id', $array['Id']);
$this->db->update('CLIENTS', $data);
}else{
$data = array(
'name'=>$array['name'],
'phone'=>$array['phone'],
'email'=>$array['email']
);
$this->db->insert('CLIENTS',$data);
}
}
In controller:
$this->site_model->insertClient($_POST);
Sadly if you are using the active record class an INSERT IF NOT EXISTS function doesn't exist. You could try
Extending the active record class (easier said than done)
You could set indexes on certain columns as UNIQUE so that MySQL will check to see if it already exists
You could do some kind of SELECT before your INSERT to determine if the record is already there
For the queries where you need to do INSERT IF NOT EXISTS do $this->db->query('INSERT IF NOT EXISTS...')
function getFeed()
{
// Load the model up here - otherwise you are loading it multiple times
$this->load->model('membership_model');
$feed_url = $this->input->get("url");
$content = file_get_contents($feed_url);
$x = new SimpleXmlElement($content);
foreach($x->channel->item as $entry) {
// check if the feed is unique, if true then add to array
if( $this->membership_model->singleFeedIsUnique($entry) == TRUE ){
$feeds[] = array(
'title' => (string)$entry->title,
'url'=> (string)$entry->link,
'username' => $this->session->userdata('username')); }
} //foreach
// check to make sure we got any feeds with isset()
// if yes, then add them
if (isset($feeds)){ $this->membership_model->feeds($feeds); }
}
You can try this in your model and leave you controller without changes
function feeds($feeds_data)
{
$data = array(
title => $feeds_data[0],
url => $feeds_data[1],
username => $feeds_data[2]
);
$this->db->select('*');
$this->db->from('mytable');
$this->db->where('title',$feeds_data[0]);//you can use another field
if ($this->db->count_all_results() == 0) {
$query = $this->db->insert('mytable', $data);//insert data
} else {
$query = $this->db->update('mytable', $data, array('title'=>$feeds_data[0]));//update with the condition where title exist
}
}
you can check the id if you have it, adding in the data array and use it to check if exist

Zend framework complains that "There is already an active transaction"

we are using zend_db_table and we are having some issues since Zend Framework is complaining about two transactions being active:
[message:protected] => There is already an active transaction
[string:Exception:private] =>
[code:protected] => 0
[file:protected] => /var/www/vhosts/test.local/private/library/Zend/Db/Adapter/Pdo/Abstract.php
[line:protected] => 305
[trace:Exception:private] => Array
This is the code in the Controller:
public function convertAction()
{
$this->setNoRender();
// If the quote is a copy of a previous one, fetch all the datas
$quoteId = Zend_Filter::filterStatic($this->getRequest()->getParam('qte_id'), 'int');
$quoteTable = new Model_QuotesTable();
$quoteRow = $quoteTable->findById($quoteId);
if (count($quoteRow)) {
$clonedId = $quoteRow->convertToJob();
$this->flashMessageRedirect('Quotation successfully converted', '/jobs/edit/job_id/' . $clonedId);
} else {
$this->flashMessageRedirect('Unable to find the quote to be converted', '/quotes');
}
}
which is recalling this function in QuotesTableRow which extends zend_db_table_abstract:
public function convertToJob()
{
$db = $this->_getTable()->getAdapter();
$db->beginTransaction();
$jobsTable = new Model_JobsTable();
try {
/*
* Update the status of the old row to match the $status passed into this function
*/
$this->qte_status = "Accepted";
$this->save();
/*
* Create new row with the same details as above
*/
$newRow = $jobsTable->createRow();
$newRow->job_title = $this->qte_title;
$newRow->job_cus_id = $this->qte_cus_id;
$newRow->job_enq_id = $this->qte_enq_id;
$newRow->job_qte_id = $this->qte_id;
$newRow->job_title = $this->qte_title;
$newRow->job_description = $this->qte_description;
$newRow->job_work_location_id = $this->qte_work_location_id;
$newRow->job_work_category_id = $this->qte_work_category_id;
$newRow->job_work_type_id = $this->qte_work_type_id;
$newRow->job_cus_code = $this->qte_cus_code;
$newRow->job_cus_name = $this->qte_cus_name;
$newRow->job_wt_ref_code = $this->qte_wt_ref_code;
$newRow->job_wt_description = $this->qte_wt_description;
$newRow->job_wl_code = $this->qte_wl_code;
$newRow->job_wl_description = $this->qte_wl_description;
$newRow->job_wc_ref_code = $this->qte_wc_ref_code;
$newRow->job_wc_description = $this->qte_wc_description;
$newRow->job_qte_title = $this->qte_title;
$newRow->job_datetime_created = date('Y-m-d H:i:s');
$newRowId = $newRow->save();
$db->commit();
return $newRowId;
}
catch (Exception $e) {
$db->rollback();
echo('<pre>');
print_r($e);
echo('</pre>');
exit();
throw new Exception($e->getMessage());
return false;
}
}
in addition, it seems to be related to the model we are not in since if we comment the row with the save() function related to the Model_JobsTable() the script is working, while it returns the same error when we comment the other save().
This error is being returned from MySQL and ZF is only telling you the error message.
Are you starting two transactions in the same request? That can explain why you got this error message, or you could have had an aborted connection that was in the middle of a transaction and it didn't get rolled back or auto-committed.
You should only start one transaction per database connection. If you need two models to have an active transaction in a single request, then you need to get 2 separate database connections.
See this (great) answer by Bill Karwin in regards to this issue.
You can run the query SHOW ENGINE InnoDB STATUS; to get a list of active transactions. If you have one that is open and you have no active transactions from PHP/ZF, then try closing that transaction, otherwise you'll have to look into your code and see how two transactions are getting started in the same request.
Thanks for your answer, we found a solution.
The problem was that, we were using the save() function twice; changing the first save() with an insert(), solved the problem:
public function convertToJob()
{
$db = $this->_getTable()->getAdapter();
$db->beginTransaction();
$jobsTable = new Model_JobsTable();
try {
/*
* Create new row with the same details as above
*/
$data = array(
'job_cus_id' => $this->qte_cus_id,
'job_enq_id' => $this->qte_enq_id,
'job_qte_id' => $this->qte_id,
'job_title' => $this->qte_title,
'job_description' => $this->qte_description,
'job_work_location_id' => $this->qte_work_location_id,
'job_work_category_id' => $this->qte_work_category_id,
'job_work_type_id' => $this->qte_work_type_id,
'job_cus_code' => $this->qte_cus_code,
'job_cus_name' => $this->qte_cus_name,
'job_wt_ref_code' => $this->qte_wt_ref_code,
'job_wt_description' => $this->qte_wt_description,
'job_wl_code' => $this->qte_wl_code,
'job_wl_description' => $this->qte_wl_description,
'job_wc_ref_code' => $this->qte_wc_ref_code,
'job_wc_description' => $this->qte_wc_description,
'job_qte_title' => $this->qte_title,
'job_datetime_created' => date('Y-m-d H:i:s')
);
$newRowId = $jobsTable->insert($data);
/*
* Update the status of the old row to match the $status passed into this function
*/
$this->qte_status = "Accepted";
$this->save();
$db->commit();
return $newRowId;
}
catch (Exception $e) {
throw new Exception($e->getMessage());
return false;
}
}