I make a parser of items from DotA 2 user inventory in the Steam service. Every time I try to parse user data, I get an empty value:
{"success":true,"items":[]}, but there are items in my Steam inventory.
My function to parse items:
public function loadMyInventory() {
if(Auth::guest()) return ['success' => false];
$prices = json_decode(Storage::get('prices.txt'), true);
$response = json_decode(file_get_contents('https://steamcommunity.com/inventory/'.$this->user->steamid64.'/570/2?l=russian&count=5000'), true);
if(time() < (Session::get('InvUPD') + 5)) {
return [
'success' => false,
'msg' => 'Error, repeat in '.(Session::get('InvUPD') - time() + 5).' сек.',
'status' => 'error'
];
}
//return $response;
$inventory = [];
foreach($response['assets'] as $item) {
$find = 0;
foreach($response['descriptions'] as $descriptions) {
if($find == 0) {
if(($descriptions['classid'] == $item['classid']) && ($descriptions['instanceid'] == $item['instanceid'])) {
$find++;
# If we find the price of an item, then move on.
if(isset($prices[$descriptions['market_hash_name']])) {
# Search data
$price = $prices[$descriptions['market_hash_name']]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($descriptions['tradable'] == 0) || ($descriptions['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
# Adding to Array
$inventory[] = [
'name' => $descriptions['market_name'],
'price' => floor($price),
'color' => $this->getRarity($descriptions['tags']),
'tradable' => $descriptions['tradable'],
'class' => $class,
'text' => $text,
'classid' => $item['classid'],
'assetid' => $item['assetid'],
'instanceid' => $item['instanceid']
];
}
}
}
}
}
Session::put('InvUPD', (time() + 5));
return [
'success' => true,
'items' => $inventory
];
}
But should return approximately the following value:
{"success":true,"items":[{"classid":"2274725521","instanceid":"57949762","assetid":"18235196074","market_hash_name":"Full-Bore Bonanza","price":26}]}
Where my mistake?
First of all, you are iterating on descriptions for every assets, which is assets*descriptions iteration, it's quite a lot, but you can optimize this.
let's loop once for descriptions and assign classid and instanceid as object key.
$assets = $response["assets"];
$descriptions = $response["descriptions"];
$newDescriptions=[];
foreach($descriptions as $d){
$newDescriptions[$d["classid"]][$d["instanceid"]] = $d;
}
this will give as the ability to not loop over description each time, we can access the description of certain asset directly $newDescriptions[$classid][$instanceid]]
foreach($assets as $a){
if(isset($newDescriptions[$a["classid"]]) && isset($newDescriptions[$a["classid"]][$a["instanceid"]])){
$assetDescription = $newDescriptions[$a["classid"]][$a["instanceid"]];
$inventory = [];
if(isset($prices[$assetDescription["market_hash_name"]])){
$price = $prices[$assetDescription['market_hash_name']]["price"]*$this->config->curs;
$class = false;
$text = false;
if($price <= $this->config->min_dep_sum) {
$price = 0;
$text = 'Cheap';
$class = 'minPrice';
}
if(($assetDescription['tradable'] == 0) || ($assetDescription['marketable'] == 0)) {
$price = 0;
$class = 'minPrice';
$text = 'Not tradable';
}
$inventory["priceFound"][] = [
'name' => $assetDescription['market_name'],
'price' => floor($price),
'color' => $this->getRarity($assetDescription['tags']),
'tradable' => $assetDescription['tradable'],
'class' => $class,
'text' => $text,
'classid' => $a['classid'],
'assetid' => $a['assetid'],
'instanceid' => $a['instanceid']
];
}else{
$inventory["priceNotFound"][] = $assetDescription["market_hash_name"];
}
}
}
About your mistake:
are you Sure your "prices.txt" contains market_hash_name?
I don't see any other issue yet, operationg on the data you have provided in comment, I got print of variable $assetDescription. Please doublecheck variable $prices.
this is my controller i need to divide the each rating which is posted by the max_rating which is in another table, how can i do this? i get an error now
A PHP Error was encountered Severity: Error
Message: Unsupported operand types
Filename: controllers/Performance.php
Line Number: 74
my model
public function get_max_rating($kpiid){
$this->db->select('max_rating');
$this->db->where_in('id',$kpiid);
$query = $this->db->get('kpi');
return $query->row();
}
My Controller:
...........
public function evaluate($r_id = 0) {
$this->form_validation->set_rules('rating[]', 'Rating', 'Trim|required');
if ($this->form_validation->run() == FALSE) {
$data = ['errors' => validation_errors()];
$this->session->set_flashdata($data);
$data['emp_review'] = $this->performance_model->get_emp_kpi($r_id);
$data['main_view'] = 'performance/evaluate_emp';
$this->load->view('layouts/main', $data);
} else {
$rating = $this->input->post('rating');
$comment = $this->input->post('comment');
$kpiid = $this->input->post('kpi_id');
$max_rating = $this->performance_model->get_max_rating($kpiid);
$decimal_rating = $rating / $max_rating->max_rating;
$reviewer = $this->session->userdata('user_id');
$ratingd = array();
for ($i = 0; $i < count($kpiid); $i++) {
$ratingd[] = array(
'rating' => $rating[$i],
'comment' => $comment[$i],
'decimal_rating' => $decimal_rating[$i],
'kpi_id' => $kpiid[$i],
'reviewer_id' => $reviewer,
'review_id' => $r_id
);
}
$this->performance_model->add_reviewer_rating($ratingd);
$data = [
'final_comment' => $this->input->post('final_comment')
];
$this->performance_model->insert_final_comment($r_id, $data);
redirect('performance/display');
}
You could calculate the decimal_rating inside the for loop like this :
for ($i = 0; $i < count($kpiid); $i++) {
$ratingd[] = array(
'rating' => $rating[$i],
'comment' => $comment[$i],
'decimal_rating' => $rating[$i] / $max_rating->max_rating,
'kpi_id' => $kpiid[$i],
'reviewer_id' => $reviewer,
'review_id' => $r_id
);
Please tell me why I have a " Declaration of BlockRealization::updatePosition($way, $position, $id) should be compatible with ModuleCore::updatePosition($id_hook, $way, $position = NULL)"
I have this code in module.php
A similar question was here
Prestashop custom admin module draggable sort/order not working?
Under my code in module.php
<?php
if (!defined('_PS_VERSION_')) exit;
class BlockRealization extends Module {
protected $_html = '';
public function __construct() {
$this->name = 'blockrealization';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
$this->author = 'XXX';
$this->need_instance = 0;
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Module realization');
$this->description = $this->l('Display realization on homepage.');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
}
public function install() {
if (!parent::install() ||
!$this->registerHook('displayHeader') ||
!$this->registerHook('home') ||
!$this->createTables()
)
return false;
return true;
}
public function uninstall() {
if (!parent::uninstall() ||
!$this->removeTable())
return false;
return true;
}
protected function createTables() {
/* Realization */
$res = (bool)Db::getInstance()->execute('
CREATE TABLE IF NOT EXISTS `'._DB_PREFIX_.'realization` (
`id_realization_slides` int(10) unsigned NOT NULL AUTO_INCREMENT,
`image_realization` varchar(255) NOT NULL,
`position` int(10) unsigned NOT NULL,
PRIMARY KEY (`id_realization_slides`, `image_realization`)
) ENGINE='._MYSQL_ENGINE_.' DEFAULT CHARSET=UTF8;
');
return $res;
}
protected function removeTable() {
if (!Db::getInstance()->Execute('DROP TABLE `'. _DB_PREFIX_ . 'realization`'))
return false;
return true;
}
public function getContent() {
$output = null;
if (Tools::isSubmit('submit'.$this->name)) {
$errors = '';
if ($_FILES) {
$helper = new HelperImageUploader('realization_img');
$files = $helper->process();
if ($files) {
foreach ($files as $file) {
if (isset($file['save_path'])) {
if (!ImageManager::checkImageMemoryLimit($file['save_path']))
$errors = Tools::displayError('Limit');
if (!$errors) {
if (!ImageManager::resize($file['save_path'], dirname(__FILE__) . '/img/' . $file['name']))
$errors = Tools::displayError('error');
else {
$previous_file = Configuration::get('realization_img');
$file_path = dirname(__FILE__) . '/img/' . $previous_file;
if (file_exists($file_path))
unlink($file_path);
$realization['image_realization'] = $file['name'];
$realization['position'] = count($this->getAll());
if (!Db::getInstance()->insert('realization', $realization))
$errors = Tools::displayError('error');
}
}
unlink($file['save_path']);
}
}
}
}
if ($errors)
$output .= $this->displayError($errors);
else
$output .= $this->displayConfirmation($this->l('Settings updated'));
}
$output .= $this->generateList();
$output .= $this->displayForm();
return $output;
}
public function displayForm() {
// Init Fields form array
$fields_form[0]['form'] = array(
'legend' => array(
'title' => $this->l('Add the realization'),
),
'input' => array(
array(
'type' => 'file',
'label' => $this->l('Image:'),
'name' => 'realization_img',
'hint' => $this->l('Upload image for contact:'),
)
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
)
);
$helper = new HelperForm();
// Module, token and currentIndex
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
// Title and toolbar
$helper->title = $this->displayName;
$helper->show_toolbar = true; // false -> remove toolbar
$helper->toolbar_scroll = true; // yes - > Toolbar is always visible on the top of the screen.
$helper->submit_action = 'submit'.$this->name;
$helper->toolbar_btn = array(
'save' =>
array(
'desc' => $this->l('Save'),
'href' => AdminController::$currentIndex.'&configure='.$this->name.'&save'.$this->name.
'&token='.Tools::getAdminTokenLite('AdminModules'),
),
'back' => array(
'href' => AdminController::$currentIndex.'&token='.Tools::getAdminTokenLite('AdminModules'),
'desc' => $this->l('Back to list')
)
);
// Load current value
$helper->tpl_vars = array(
'fields_value' => array(
'realization_img' => Configuration::get('realization_img')
)
);
return $helper->generateForm($fields_form);
}
public function generateList() {
$content = $this->getAll();
$fields_list = array(
'id_realization_slides' => array(
'title' => 'ID',
'align' => 'center',
'class' => 'fixed-width-xs',
),
'image_realization' => array(
'title' => $this->l('Image'),
'orderby' => false,
'search' => false
),
'position' => array(
'title' => $this->l('Position'),
'position' => 'position' ,
'orderby' => false,
'search' => false
),
);
$helper = new HelperList();
$helper->shopLinkType = '';
$helper->actions = array('edit', 'delete');
$helper->module = $this;
$helper->listTotal = count($content);
$helper->identifier = 'id_realization_slides';
$helper->title = $this->l('Realizations');
$helper->table = $this->name;
$helper->imageType = 'jpg';
$helper->orderBy = 'position';
$helper->orderWay = 'asc';
$helper->position_identifier = 'id_realization_slides';
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex.'&configure='.$this->name;
return $helper->generateList($content, $fields_list);
}
public function getAll() {
return Db::getInstance()->ExecuteS('
SELECT *
FROM '._DB_PREFIX_.'realization
');
}
public function ajaxProcessUpdatePositions()
{
$way = (int)Tools::getValue('way');
$id_quicklinks = (int)Tools::getValue('id');
$positions = Tools::getValue('realization_slides');
if (is_array($positions))
foreach ($positions as $position => $value)
{
$pos = explode('_', $value);
if (isset($pos[2]) && (int)$pos[2] === $id_velcroquicklinks)
{
if (isset($position) && $this->updatePosition($way, $position, $id_quicklinks))
echo 'ok position '.(int)$position.' for id '.(int)$pos[1].'\r\n';
else
echo '{"hasError" : true, "errors" : "Can not update id '.(int)$id_quicklinks.' to position '.(int)$position.' "}';
break;
}
}
}
public function updatePosition($way, $position, $id)
{
if (!$res = Db::getInstance()->executeS('
SELECT `id_realization_slides`, `position`
FROM `'._DB_PREFIX_.'realization`
ORDER BY `position` ASC'
))
return false;
foreach ($res as $quicklinks)
if ((int)$quicklinks['id_realization_slides'] == (int)$id)
$moved_quicklinks = $quicklinks;
if (!isset($moved_quicklinks) || !isset($position))
return false;
return (Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'realization`
SET `position`= `position` '.($way ? '- 1' : '+ 1').'
WHERE `position`
'.($way
? '> '.(int)$moved_quicklinks['position'].' AND `position` <= '.(int)$position
: '< '.(int)$moved_quicklinks['position'].' AND `position` >= '.(int)$position.'
'))
&& Db::getInstance()->execute('
UPDATE `'._DB_PREFIX_.'realization`
SET `position` = '.(int)$position.'
WHERE `id_realization_slides` = '.(int)$moved_quicklinks['id_quicklinks']));
}
public function hookHome($params) {
return $this->display(__FILE__, "views/templates/hook/realization.tpl");
}
Because you extend the class Module and it already has the same method which you basically override. And in PHP 7+ if you want to override or extend method you have to declare the same parameters(even if they have default values in the parent class method) and the same access level. So you just need to follow the rule and use the same declaration or you can rename your method if it's not necessary to override/extend the parent class one(and it seems so)
public function add($quote_id = null)
{
$this->sma->checkPermissions();
$sale_id = $this->input->get('sale_id') ? $this->input->get('sale_id') : NULL;
$this->form_validation->set_message('is_natural_no_zero', lang("no_zero_required"));
$this->form_validation->set_rules('customer', lang("customer"), 'required');
$this->form_validation->set_rules('biller', lang("biller"), 'required');
$this->form_validation->set_rules('sale_status', lang("sale_status"), 'required');
$this->form_validation->set_rules('payment_status', lang("payment_status"), 'required');
if ($this->form_validation->run() == true) {
$reference = $this->input->post('reference_no') ? $this->input->post('reference_no') : $this->site->getReference('so');
if ($this->Owner || $this->Admin) {
$date = $this->sma->fld(trim($this->input->post('date')));
} else {
$date = date('Y-m-d H:i:s');
}
$warehouse_id = $this->input->post('warehouse');
$customer_id = $this->input->post('customer');
$biller_id = $this->input->post('biller');
$total_items = $this->input->post('total_items');
$sale_status = $this->input->post('sale_status');
$payment_status = $this->input->post('payment_status');
$payment_term = $this->input->post('payment_term');
$due_date = $payment_term ? date('Y-m-d', strtotime('+' . $payment_term . ' days', strtotime($date))) : null;
$shipping = $this->input->post('shipping') ? $this->input->post('shipping') : 0;
$customer_details = $this->site->getCompanyByID($customer_id);
$customer = $customer_details->company != '-' ? $customer_details->company : $customer_details->name;
$biller_details = $this->site->getCompanyByID($biller_id);
$biller = $biller_details->company != '-' ? $biller_details->company : $biller_details->name;
$note = $this->sma->clear_tags($this->input->post('note'));
$staff_note = $this->sma->clear_tags($this->input->post('staff_note'));
$quote_id = $this->input->post('quote_id') ? $this->input->post('quote_id') : null;
$total = 0;
$product_tax = 0;
$order_tax = 0;
$product_discount = 0;
$order_discount = 0;
$percentage = '%';
$digital = FALSE;
$i = isset($_POST['product_code']) ? sizeof($_POST['product_code']) : 0;
for ($r = 0; $r < $i; $r++) {
$item_id = $_POST['product_id'][$r];
$item_type = $_POST['product_type'][$r];
$item_code = $_POST['product_code'][$r];
$item_name = $_POST['product_name'][$r];
$item_option = isset($_POST['product_option'][$r]) && $_POST['product_option'][$r] != 'false' && $_POST['product_option'][$r] != 'null' ? $_POST['product_option'][$r] : null;
$real_unit_price = $this->sma->formatDecimal($_POST['real_unit_price'][$r]);
$unit_price = $this->sma->formatDecimal($_POST['unit_price'][$r]);
$item_unit_quantity = $_POST['quantity'][$r];
$item_serial = isset($_POST['serial'][$r]) ? $_POST['serial'][$r] : '';
$item_tax_rate = isset($_POST['product_tax'][$r]) ? $_POST['product_tax'][$r] : null;
$item_discount = isset($_POST['product_discount'][$r]) ? $_POST['product_discount'][$r] : null;
$item_unit = $_POST['product_unit'][$r];
$item_quantity = $_POST['product_base_quantity'][$r];
if (isset($item_code) && isset($real_unit_price) && isset($unit_price) && isset($item_quantity)) {
$product_details = $item_type != 'manual' ? $this->sales_model->getProductByCode($item_code) : null;
// $unit_price = $real_unit_price;
$pr_discount = 0;
if ($item_type == 'digital') {
$digital = TRUE;
}
if (isset($item_discount)) {
$discount = $item_discount;
$dpos = strpos($discount, $percentage);
if ($dpos !== false) {
$pds = explode("%", $discount);
$pr_discount = $this->sma->formatDecimal(((($this->sma->formatDecimal($unit_price)) * (Float) ($pds[0])) / 100), 4);
} else {
$pr_discount = $this->sma->formatDecimal($discount);
}
}
$unit_price = $this->sma->formatDecimal($unit_price - $pr_discount);
$item_net_price = $unit_price;
$pr_item_discount = $this->sma->formatDecimal($pr_discount * $item_unit_quantity);
$product_discount += $pr_item_discount;
$pr_tax = 0;
$pr_item_tax = 0;
$item_tax = 0;
$tax = "";
if (isset($item_tax_rate) && $item_tax_rate != 0) {
$pr_tax = $item_tax_rate;
$tax_details = $this->site->getTaxRateByID($pr_tax);
if ($tax_details->type == 1 && $tax_details->rate != 0) {
if ($product_details && $product_details->tax_method == 1) {
$item_tax = $this->sma->formatDecimal((($unit_price) * $tax_details->rate) / 100, 4);
$tax = $tax_details->rate . "%";
} else {
$item_tax = $this->sma->formatDecimal((($unit_price) * $tax_details->rate) / (100 + $tax_details->rate), 4);
$tax = $tax_details->rate . "%";
$item_net_price = $unit_price - $item_tax;
}
} elseif ($tax_details->type == 2) {
if ($product_details && $product_details->tax_method == 1) {
$item_tax = $this->sma->formatDecimal((($unit_price) * $tax_details->rate) / 100, 4);
$tax = $tax_details->rate . "%";
} else {
$item_tax = $this->sma->formatDecimal((($unit_price) * $tax_details->rate) / (100 + $tax_details->rate), 4);
$tax = $tax_details->rate . "%";
$item_net_price = $unit_price - $item_tax;
}
$item_tax = $this->sma->formatDecimal($tax_details->rate);
$tax = $tax_details->rate;
}
$pr_item_tax = $this->sma->formatDecimal($item_tax * $item_unit_quantity, 4);
}
$product_tax += $pr_item_tax;
$subtotal = (($item_net_price * $item_unit_quantity) + $pr_item_tax);
$unit = $this->site->getUnitByID($item_unit);
$products[] = array(
'product_id' => $item_id,
'product_code' => $item_code,
'product_name' => $item_name,
'product_type' => $item_type,
'option_id' => $item_option,
'net_unit_price' => $item_net_price,
'unit_price' => $this->sma->formatDecimal($item_net_price + $item_tax),
'quantity' => $item_quantity,
'product_unit_id' => $item_unit,
'product_unit_code' => $unit ? $unit->code : NULL,
'unit_quantity' => $item_unit_quantity,
'warehouse_id' => $warehouse_id,
'item_tax' => $pr_item_tax,
'tax_rate_id' => $pr_tax,
'tax' => $tax,
'discount' => $item_discount,
'item_discount' => $pr_item_discount,
'subtotal' => $this->sma->formatDecimal($subtotal),
'serial_no' => $item_serial,
'real_unit_price' => $real_unit_price,
);
$total += $this->sma->formatDecimal(($item_net_price * $item_unit_quantity), 4);
}
}
if (empty($products)) {
$this->form_validation->set_rules('product', lang("order_items"), 'required');
} else {
krsort($products);
}
if ($this->input->post('order_discount')) {
$order_discount_id = $this->input->post('order_discount');
$opos = strpos($order_discount_id, $percentage);
if ($opos !== false) {
$ods = explode("%", $order_discount_id);
$order_discount = $this->sma->formatDecimal(((($total + $product_tax) * (Float) ($ods[0])) / 100), 4);
} else {
$order_discount = $this->sma->formatDecimal($order_discount_id);
}
} else {
$order_discount_id = null;
}
$total_discount = $this->sma->formatDecimal($order_discount + $product_discount);
if ($this->Settings->tax2) {
$order_tax_id = $this->input->post('order_tax');
if ($order_tax_details = $this->site->getTaxRateByID($order_tax_id)) {
if ($order_tax_details->type == 2) {
$order_tax = $this->sma->formatDecimal($order_tax_details->rate);
} elseif ($order_tax_details->type == 1) {
$order_tax = $this->sma->formatDecimal(((($total + $product_tax - $order_discount) * $order_tax_details->rate) / 100), 4);
}
}
} else {
$order_tax_id = null;
}
$total_tax = $this->sma->formatDecimal(($product_tax + $order_tax), 4);
$grand_total = $this->sma->formatDecimal(($total + $total_tax + $this->sma->formatDecimal($shipping) - $order_discount), 4);
$data = array('date' => $date,
'reference_no' => $reference,
'customer_id' => $customer_id,
'customer' => $customer,
'biller_id' => $biller_id,
'biller' => $biller,
'warehouse_id' => $warehouse_id,
'note' => $note,
'staff_note' => $staff_note,
'total' => $total,
'product_discount' => $product_discount,
'order_discount_id' => $order_discount_id,
'order_discount' => $order_discount,
'total_discount' => $total_discount,
'product_tax' => $product_tax,
'order_tax_id' => $order_tax_id,
'order_tax' => $order_tax,
'total_tax' => $total_tax,
'shipping' => $this->sma->formatDecimal($shipping),
'grand_total' => $grand_total,
'total_items' => $total_items,
'sale_status' => $sale_status,
'payment_status' => $payment_status,
'payment_term' => $payment_term,
'due_date' => $due_date,
'paid' => 0,
'created_by' => $this->session->userdata('user_id'),
);
if ($payment_status == 'partial' || $payment_status == 'paid') {
if ($this->input->post('paid_by') == 'deposit') {
if ( ! $this->site->check_customer_deposit($customer_id, $this->input->post('amount-paid'))) {
$this->session->set_flashdata('error', lang("amount_greater_than_deposit"));
redirect($_SERVER["HTTP_REFERER"]);
}
}
if ($this->input->post('paid_by') == 'gift_card') {
$gc = $this->site->getGiftCardByNO($this->input->post('gift_card_no'));
$amount_paying = $grand_total >= $gc->balance ? $gc->balance : $grand_total;
$gc_balance = $gc->balance - $amount_paying;
$payment = array(
'date' => $date,
'reference_no' => $this->input->post('payment_reference_no'),
'amount' => $this->sma->formatDecimal($amount_paying),
'paid_by' => $this->input->post('paid_by'),
'cheque_no' => $this->input->post('cheque_no'),
'cc_no' => $this->input->post('gift_card_no'),
'cc_holder' => $this->input->post('pcc_holder'),
'cc_month' => $this->input->post('pcc_month'),
'cc_year' => $this->input->post('pcc_year'),
'cc_type' => $this->input->post('pcc_type'),
'created_by' => $this->session->userdata('user_id'),
'note' => $this->input->post('payment_note'),
'type' => 'received',
'gc_balance' => $gc_balance,
);
} else {
$payment = array(
'date' => $date,
'reference_no' => $this->input->post('payment_reference_no'),
'amount' => $this->sma->formatDecimal($this->input->post('amount-paid')),
'paid_by' => $this->input->post('paid_by'),
'cheque_no' => $this->input->post('cheque_no'),
'cc_no' => $this->input->post('pcc_no'),
'cc_holder' => $this->input->post('pcc_holder'),
'cc_month' => $this->input->post('pcc_month'),
'cc_year' => $this->input->post('pcc_year'),
'cc_type' => $this->input->post('pcc_type'),
'created_by' => $this->session->userdata('user_id'),
'note' => $this->input->post('payment_note'),
'type' => 'received',
);
}
} else {
$payment = array();
}
if ($_FILES['document']['size'] > 0) {
$this->load->library('upload');
$config['upload_path'] = $this->digital_upload_path;
$config['allowed_types'] = $this->digital_file_types;
$config['max_size'] = $this->allowed_file_size;
$config['overwrite'] = false;
$config['encrypt_name'] = true;
$this->upload->initialize($config);
if (!$this->upload->do_upload('document')) {
$error = $this->upload->display_errors();
$this->session->set_flashdata('error', $error);
redirect($_SERVER["HTTP_REFERER"]);
}
$photo = $this->upload->file_name;
$data['attachment'] = $photo;
}
// $this->sma->print_arrays($data, $products, $payment);
}
if ($this->form_validation->run() == true && $this->sales_model->addSale($data, $products, $payment)) {
$this->session->set_userdata('remove_slls', 1);
if ($quote_id) {
$this->db->update('quotes', array('status' => 'completed'), array('id' => $quote_id));
}
$this->session->set_flashdata('message', lang("sale_added"));
redirect("sales");
} else {
if ($quote_id || $sale_id) {
if ($quote_id) {
$this->data['quote'] = $this->sales_model->getQuoteByID($quote_id);
$items = $this->sales_model->getAllQuoteItems($quote_id);
} elseif ($sale_id) {
$this->data['quote'] = $this->sales_model->getInvoiceByID($sale_id);
$items = $this->sales_model->getAllInvoiceItems($sale_id);
}
krsort($items);
$c = rand(100000, 9999999);
foreach ($items as $item) {
$row = $this->site->getProductByID($item->product_id);
if (!$row) {
$row = json_decode('{}');
$row->tax_method = 0;
} else {
unset($row->cost, $row->details, $row->product_details, $row->image, $row->barcode_symbology, $row->cf1, $row->cf2, $row->cf3, $row->cf4, $row->cf5, $row->cf6, $row->supplier1price, $row->supplier2price, $row->cfsupplier3price, $row->supplier4price, $row->supplier5price, $row->supplier1, $row->supplier2, $row->supplier3, $row->supplier4, $row->supplier5, $row->supplier1_part_no, $row->supplier2_part_no, $row->supplier3_part_no, $row->supplier4_part_no, $row->supplier5_part_no);
}
$row->quantity = 0;
$pis = $this->site->getPurchasedItems($item->product_id, $item->warehouse_id, $item->option_id);
if ($pis) {
foreach ($pis as $pi) {
$row->quantity += $pi->quantity_balance;
}
}
$row->id = $item->product_id;
$row->code = $item->product_code;
$row->name = $item->product_name;
$row->type = $item->product_type;
$row->qty = $item->quantity;
$row->base_quantity = $item->quantity;
$row->base_unit = $row->unit ? $row->unit : $item->product_unit_id;
$row->base_unit_price = $row->price ? $row->price : $item->unit_price;
$row->unit = $item->product_unit_id;
$row->qty = $item->unit_quantity;
$row->discount = $item->discount ? $item->discount : '0';
$row->price = $this->sma->formatDecimal($item->net_unit_price + $this->sma->formatDecimal($item->item_discount / $item->quantity));
$row->unit_price = $row->tax_method ? $item->unit_price + $this->sma->formatDecimal($item->item_discount / $item->quantity) + $this->sma->formatDecimal($item->item_tax / $item->quantity) : $item->unit_price + ($item->item_discount / $item->quantity);
$row->real_unit_price = $item->real_unit_price;
$row->tax_rate = $item->tax_rate_id;
$row->serial = '';
$row->option = $item->option_id;
$options = $this->sales_model->getProductOptions($row->id, $item->warehouse_id);
if ($options) {
$option_quantity = 0;
foreach ($options as $option) {
$pis = $this->site->getPurchasedItems($row->id, $item->warehouse_id, $item->option_id);
if ($pis) {
foreach ($pis as $pi) {
$option_quantity += $pi->quantity_balance;
}
}
if ($option->quantity > $option_quantity) {
$option->quantity = $option_quantity;
}
}
}
$combo_items = false;
if ($row->type == 'combo') {
$combo_items = $this->sales_model->getProductComboItems($row->id, $item->warehouse_id);
}
$units = $this->site->getUnitsByBUID($row->base_unit);
$tax_rate = $this->site->getTaxRateByID($row->tax_rate);
$ri = $this->Settings->item_addition ? $row->id : $c;
$pr[$ri] = array('id' => $c, 'item_id' => $row->id, 'label' => $row->name . " (" . $row->code . ")",
'row' => $row, 'combo_items' => $combo_items, 'tax_rate' => $tax_rate, 'units' => $units, 'options' => $options);
$c++;
}
$this->data['quote_items'] = json_encode($pr);
}
$this->data['error'] = (validation_errors() ? validation_errors() : $this->session->flashdata('error'));
$this->data['quote_id'] = $quote_id ? $quote_id : $sale_id;
$this->data['billers'] = $this->site->getAllCompanies('biller');
$this->data['warehouses'] = $this->site->getAllWarehouses();
$this->data['tax_rates'] = $this->site->getAllTaxRates();
//$this->data['currencies'] = $this->sales_model->getAllCurrencies();
$this->data['slnumber'] = ''; //$this->site->getReference('so');
$this->data['payment_ref'] = ''; //$this->site->getReference('pay');
$bc = array(array('link' => base_url(), 'page' => lang('home')), array('link' => site_url('sales'), 'page' => lang('sales')), array('link' => '#', 'page' => lang('add_sale')));
$meta = array('page_title' => lang('add_sale'), 'bc' => $bc);
$this->page_construct('sales/add', $meta, $this->data);
}
}
public function calculateAVCost($product_id, $warehouse_id, $net_unit_price, $unit_price, $quantity, $product_name, $option_id, $item_quantity) {
$product = $this->getProductByID($product_id);
$real_item_qty = $quantity;
$wp_details = $this->getWarehouseProduct($warehouse_id, $product_id);
$avg_net_unit_cost = $wp_details ? $wp_details->avg_cost : $product->cost;
$avg_unit_cost = $wp_details ? $wp_details->avg_cost : $product->cost;
if ($pis = $this->getPurchasedItems($product_id, $warehouse_id, $option_id)) {
$cost_row = array();
$quantity = $item_quantity;
$balance_qty = $quantity;
foreach ($pis as $pi) {
if (!empty($pi) && $pi->quantity > 0 && $balance_qty <= $quantity && $quantity > 0) {
if ($pi->quantity_balance >= $quantity && $quantity > 0) {
$balance_qty = $pi->quantity_balance - $quantity;
$cost_row = array('date' => date('Y-m-d'), 'product_id' => $product_id, 'sale_item_id' => 'sale_items.id', 'purchase_item_id' => $pi->id, 'quantity' => $real_item_qty, 'purchase_net_unit_cost' => $avg_net_unit_cost, 'purchase_unit_cost' => $avg_unit_cost, 'sale_net_unit_price' => $net_unit_price, 'sale_unit_price' => $unit_price, 'quantity_balance' => $balance_qty, 'inventory' => 1, 'option_id' => $option_id);
$quantity = 0;
} elseif ($quantity > 0) {
$quantity = $quantity - $pi->quantity_balance;
$balance_qty = $quantity;
$cost_row = array('date' => date('Y-m-d'), 'product_id' => $product_id, 'sale_item_id' => 'sale_items.id', 'purchase_item_id' => $pi->id, 'quantity' => $pi->quantity_balance, 'purchase_net_unit_cost' => $avg_net_unit_cost, 'purchase_unit_cost' => $avg_unit_cost, 'sale_net_unit_price' => $net_unit_price, 'sale_unit_price' => $unit_price, 'quantity_balance' => 0, 'inventory' => 1, 'option_id' => $option_id);
}
}
if (empty($cost_row)) {
break;
}
$cost[] = $cost_row;
if ($quantity == 0) {
break;
}
}
}
if ($quantity > 0 && !$this->Settings->overselling) {
$this->session->set_flashdata('error', sprintf(lang("quantity_out_of_stock_for_%s"), ($pi->product_name ? $pi->product_name : $product_name)));
redirect($_SERVER["HTTP_REFERER"]);
} elseif ($quantity > 0) {
$cost[] = array('date' => date('Y-m-d'), 'product_id' => $product_id, 'sale_item_id' => 'sale_items.id', 'purchase_item_id' => NULL, 'quantity' => $real_item_qty, 'purchase_net_unit_cost' => $avg_net_unit_cost, 'purchase_unit_cost' => $avg_unit_cost, 'sale_net_unit_price' => $net_unit_price, 'sale_unit_price' => $unit_price, 'quantity_balance' => NULL, 'overselling' => 1, 'inventory' => 1);
$cost[] = array('pi_overselling' => 1, 'product_id' => $product_id, 'quantity_balance' => (0 - $quantity), 'warehouse_id' => $warehouse_id, 'option_id' => $option_id);
}
return $cost;
}
warehouse id 2
I am trying to sell the item from warehouse_id 2 where i have 43 products in stock where it shows of stock when i am selling 1 or 2 quantity from this warehouse i dont know which piece of code causing the issue.
Quantity issue is quite likely in this code as i have asked the tecdiary about the issue but they themselves dont know which piece of code is causing the issue
error when selling
This is PHP code I have so far:
https://gist.github.com/2eeba2ff31ebecb526e2
This is the result:
https://gist.github.com/cf07fe90922ac3dfcd22
Now say I need to get information that is referenced in this table:
object(ttfTableDirectoryEntry)#6 (4) {
["tag"]=>
string(4) "cmap"
["checksum"]=>
int(2553734765)
["offset"]=>
int(1556)
["length"]=>
int(1190)
}
How do I do that?
In general, I need to parse info for every of these tables.
This is what you get if you simply try to parse the data from offset with length.
object(ttfTableDirectoryEntry)#12 (4) {
["tag"]=>
string(4) "name"
["checksum"]=>
int(3955157420)
["offset"]=>
int(400)
["length"]=>
int(1153)
}
string(1153) "���>��������:����������:��������F�������"�L��������n�������
������������������5����������������� �#��������
�:������������������ ���t#�� ����� ����� ��D��� ��$��� ��#�� ��$��� ��j=�� ����� � �F��� �
�t#�� ��: �� ��: Copyright (c) 2010 by YouWorkForThem. All rights reserved.YWFT HLLVTKANormalYouWorkForThem: YWFT HLLVTKA: 2010YWFT HLLVTKA NormalVersion 1.000YWFTHLLVTKA-NormalYWFT HLLVTKA Normal is a trademark of YouWorkForThem.YouWorkForThemEric Carlson & Taechit Jiropaskosolhttp://www.youworkforthem.com�C�o�p�y�r�i�g�h�t� �(�c�)� �2�0�1�0� �b�y� �Y�o�u�W�o�r�k�F�o�r�T�h�e�m�.� �A�l�l� �r�i�g�h�t�s� �r�e�s�e�r�v�e�d�.�Y�W�F�T� �H�L�L�V�T�K�A�N�o�r�m�a�l�Y�o�u�W�o�r�k�F�o�r�T�h�e�m�:� �Y�W�F�T� �H�L�L�V�T�K�A�:� �2�0�1�0�Y�W�F�T�H�L�L�V�T�K�A�-�N�o�r�m�a�l�V�e�r�s�i�o�n� �1�.�0�0�0�Y�W�F�T� �H�L�L�V�T�K�A� �N�o�r�m�a�l� �i�s� �a� �t�r�a�d�e�m�a�r�k� �o�f� �Y�o�u�W�o�r�k�F�o�r�T�h�e�m�.�Y�o�u�W�o�r�k�F�o�r�T�h�e�m�E�r�i�c� �C�a�r�l�s�o�n� �&� �T�a�e�c�h�i�t� �J�i�r�o�p�a�s�k�o�s�o�l�h�t�t�p�:�/�/�w�w�w�.�y�o�u�w�o�r�k�f�o�r�t�h�e�m�.�c�o�m"
I tried to achieve this and went close to making it. However, at the end, I decided to use Python instead when parsing data. Anyway, if anyone decide that they want to go PHP way, here is what I have until this moment. It is one step close to getting glyph map. For a documentation on how to read the data, refer to http://developer.apple.com/fonts/ttrefman/RM06/Chap6.html.
<?php
$ttr = new TrueTypeReader;
$ttr->open('font.otf');
class TrueTypeReader
{
private $position = 0;
private $offset = 0;
private $file;
public function open($file)
{
$this->file = file_get_contents($file);
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6.html
// The offset subtable
$number_of_tables = $this->getUint16(4);
$this->tables = array();
for($i = 0; $i < $number_of_tables; $i++)
{
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6.html
// The table directory
$table = array();
$tag = $this->getTag(12 + $i * 16);
$table = array
(
'tag' => $tag,
'check_sum' => $this->getUint32(12 + $i * 16 + 4),
'offset' => $this->getUint32(12 + $i * 16 + 8),
'length' => $this->getUint32(12 + $i * 16 + 12),
);
if($tag == 'cmap')
{
$this->parseCmapTable($table);
}
$this->tables[] = $table;
}
}
private function getTag($pt = FALSE)
{
if($pt === FALSE)
{
$pt = $this->position;
$this->position += 4;
}
return substr($this->file, $pt, 4);
}
private function getUint32($pt = FALSE)
{
if($pt === FALSE)
{
$pt = $this->position;
$this->position += 4;
}
$r = unpack("N", substr($this->file, $pt, 4) );
return $r[1];
}
private function getUint16($pt = FALSE)
{
if ($pt === FALSE)
{
$pt = $this->position;
$this->position += 2;
}
$r = unpack("n", substr($this->file, $pt, 2) );
return $r[1];
}
private function parseCmapTable($table)
{
$this->position = $table['offset'];
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6cmap.html
// General table information
$data = array
(
'version' => $this->getUint16(),
'number_subtables' => $this->getUint16(),
);
$sub_tables = array();
for($i = 0; $i < $data['number_subtables']; $i++)
{
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6cmap.html
// The 'cmap' encoding subtables
$sub_tables[] = array
(
'platform_id' => $this->getUint16(),
'specific_id' => $this->getUint16(),
'offset' => $this->getUint32(),
);
}
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6cmap.html
// The 'cmap' formats
$formats = array();
foreach($sub_tables as $t)
{
// http://stackoverflow.com/questions/5322019/character-to-glyph-mapping-table/5322267#5322267
$this->position = $table['offset'] + $t['offset'];
$format = array
(
'format' => $this->getUint16(),
'length' => $this->getUint16(),
'language' => $this->getUint16(),
);
if($format['format'] == 4)
{
$format += array
(
'seg_count_X2' => $this->getUint16(),
'search_range' => $this->getUint16(),
'entry_selector' => $this->getUint16(),
'range_shift' => $this->getUint16(),
'end_code[segCount]' => $this->getUint16(),
'reserved_pad' => $this->getUint16(),
'start_code[segCount]' => $this->getUint16(),
'id_delta[segCount]' => $this->getUint16(),
'id_range_offset[segCount]' => $this->getUint16(),
'glyph_index_array[variable]' => $this->getUint16(),
);
$backup = $format;
$format['seg_count_X2'] = $backup['seg_count_X2']*2;
$format['search_range'] = 2 * (2 * floor(log($backup['seg_count_X2'], 2)));
$format['entry_selector'] = log($backup['search_range']/2, 2);
$format['range_shift'] = (2 * $backup['seg_count_X2']) - $backup['search_range'];
}
$formats[$t['offset']] = $format;
}
die(var_dump( $sub_tables, $formats ));
die(var_dump( $this->getUint16(), $this->getUint16(), $this->getUint16(), $this->getUint16(), $this->getUint16() ));
die(var_dump( $sub_tables[0] ));
$cmap = array
(
'format' => $this->getUint16(),
#'length' => $this->getUint16(),
#'language' => $this->getUint16(),
);
die(var_dump( $cmap ));
die(var_dump( $table, $data, $table, $cmap ));
}
private function parseNameTable($table)
{
// http://developer.apple.com/fonts/ttrefman/RM06/Chap6name.html
// Name Table Format
$data = array
(
'format' => $this->getUint16($table['offset']),
'count' => $this->getUint16($table['offset'] + 2), // $num_of_name_tables
'string_offset' => $this->getUint16($table['offset'] + 4),
);
$offset = $table['offset'] + $data['string_offset']; // $name_tables_offset
$name_tables = array();
for($i = 0; $i < $data['count']; $i ++)
{
$this->position = $table['offset'] + 6 + $i * 12;
$d = array
(
'platform_id' => $this->getUint16(),
'specific_id' => $this->getUint16(),
'lang_id' => $this->getUint16(),
'name_id' => $this->getUint16(),
'length' => $this->getUint16(),
'offset' => $this->getUint16() + $offset,
);
$key = "{$d['platform_id']}::{$d['specific_id']}::{$d['lang_id']}";
if(isset($d['name_id']) && empty($name_tables[$key][$d['name_id']]))
{
$text = substr($this->file, $d['offset'], $d['length']);
$name_tables[$key][$d['name_id']] = str_replace(chr(0), '', $text);
}
}
die(var_dump( $name_tables ));
}
}