<?php

namespace FAAPI;

$path_to_root = "../..";

include_once ($path_to_root . "/inventory/includes/inventory_db.inc");
include_once ($path_to_root . "/inventory/includes/db/items_codes_db.inc");
include_once ($path_to_root . "/inventory/includes/db/items_locations_db.inc");
include_once ($path_to_root . "/gl/includes/gl_db.inc");
include_once ($path_to_root . "/includes/ui/items_cart.inc");
include_once ($path_to_root . "/modules/external/stock/items_prices_db.inc");
include_once($path_to_root . "/modules/external/stock/db.php");

include_once (API_ROOT . "/inventory.inc");

class Inventory {

    // Get Items
    public function get($rest) {
        $req = $rest->request();

        $page = $req->get("page");
        $from = isset($_GET["start"]) ? $_GET["start"] : null;
        $length = isset($_GET["length"]) ? $_GET["length"] : null;
        $term = isset($_GET["term"]) ? $_GET["term"] : '';
        $tax_group = isset($_GET["tax_group_id"]) ? $_GET["tax_group_id"] : '';
        if ($from == null) {
            $this->inventory_all();
        } else {
            // If page = 1 the value will be 0, if page = 2 the value will be 1, ...
            $from = --$page * RESULTS_PER_PAGE;
            $this->inventory_all($from, $length, $term, $tax_group);
        }
    }

    // Get Specific Item by Stock Id
    public function getById($rest, $id) {
        $this->inventory_get($id);
    }

    // Add Item
    public function post($rest) {
        $this->inventory_add();
    }

    // Edit Specific Item
    public function put($rest, $id) {
        $this->inventory_edit($id);
    }

    // Delete Specific Item
    public function delete($rest, $id) {
        $this->inventory_delete($id);
    }

    function inventory_all($from = null, $length = null, $term = null, $tax_group = "") {
        global $SysPrefs;
        if ($from == null)
            $from = 0;
        if ($length == null)
            $length = 1000;
        if ($term == null)
            $term = '';
        if ($tax_group == null)
            $tax_group = '';
        
        $comp_path = $SysPrefs->comp_path;
	if (!isset($comp))
		$comp = user_company();
	// if path is relative, set current path_to_root
	$company_path = ($comp_path[0]=='.' ? basename($comp_path) : $comp_path)
			. '/'.$comp;

        $where = "";
        if (!empty($_GET['category'])) {
            $where .= " and category_id='" . $_GET['category'] . "' ";
        }
        $sql = "SELECT * FROM " . TB_PREF . "stock_master where inactive!=1 $where AND mb_flag!='F' AND no_sale!=1 and description like " . db_escape("%" . $term . "%") . " LIMIT " . $from . ", " . $length;

        $query = db_query($sql, "error");

        $info = array();
        while ($data = db_fetch($query, "error")) {
            $info[] = array(
                'stock_id' => $data['stock_id'],
                'category_id' => $data['category_id'],
                'tax_type_id' => $data['tax_type_id'],
                'description' => html_entity_decode($data['description'], ENT_QUOTES | ENT_HTML5),
                'long_description' => html_entity_decode($data['long_description'], ENT_QUOTES | ENT_HTML5),
                'units' => $data['units'],
                'mb_flag' => $data['mb_flag'],
                'sales_account' => $data['sales_account'],
                'cogs_account' => $data['cogs_account'],
                'inventory_account' => $data['inventory_account'],
                'adjustment_account' => $data['adjustment_account'],
                'wip_account' => $data['wip_account'],
                'purchase_cost' => $data['purchase_cost'],
                'material_cost' => $data['material_cost'],
                'labour_cost' => $data['labour_cost'],
                'overhead_cost' => $data['overhead_cost'],
                'inactive' => $data['inactive'],
                'no_sale' => $data['no_sale'],
                'no_purchase' => $data['no_purchase'],
                'id' => $data['stock_id'],
                'image' => file_exists(company_path().'/images/'.item_img_name($data['stock_id']).".jpg") ? $company_path.'/images/'.item_img_name($data['stock_id']).".jpg":"",
                'text' => html_entity_decode($data['description'], ENT_QUOTES | ENT_HTML5),
                'sales_price' => get_price($data['stock_id'], get_company_currency(), "1"),
                'tax_rate' => get_item_tax($data['stock_id'], $tax_group),
                    //'tax_rate' => get_item_tax_type_for_item($stock_id)
            );
        }

        $response['items'] = $info;
        $response['incomplete_results'] = FALSE;
        $response['total_count'] = $length;
        api_success_response(json_encode($response));
    }

    function get_all_prices() {
        $where = "";
        $sql = "SELECT * FROM " . TB_PREF . "prices where 1=1 " . $where;
        $query = db_query($sql, "error");
        $info = array();
        $count = 0;
        while ($data = db_fetch($query, "error")) {
            $info[] = array(
                'stock_id' => $data['stock_id'],
                'curr_abrev' => $data['curr_abrev'],
                'lower_qty' => is_numeric($data['lower_qty']) ? $data['lower_qty'] : 0,
                'upper_qty' => is_numeric($data['upper_qty']) ? $data['upper_qty'] : 0,
                'sales_type_id' => $data['sales_type_id'],
                'price' => (is_numeric($data['price']) ? $data['price'] : 0),
                'id' => $data['id']
            );
            $count++;
        }

        $response['items'] = $info;
        $response['incomplete_results'] = FALSE;
        $response['total_count'] = $count;
        api_success_response(json_encode($response));
    }

    function get_price($stock_id, $currency, $qty) {
        api_error(200, "we are here");
        $price = get_qty_price($stock_id, $currency, $qty);
        $response['price'] = get_price($stock_id, $currency, $price['sales_type_id']);
        api_success_response(json_encode($response));
    }

    function inventory_get($id) {
        $item = get_item($id);
        api_success_response(json_encode(api_ensureAssociativeArray($item)));
    }

    function inventory_add() {
        $app = \Slim\Slim::getInstance('SASYS');
        $req = $app->request();
        $info = $req->post();

        // Validate Required Fields
        if (!isset($info['stock_id'])) {
            api_error(412, 'Stock Id is required');
        }
        if (!isset($info['description'])) {
            api_error(412, 'Description is required');
        }
        if (!isset($info['long_description'])) {
            $info['long_description'] = $info['description'];
        }
        if (!isset($info['category_id'])) {
            api_error(412, 'Category Id is required');
        }
        if (!isset($info['tax_type_id'])) {
            api_error(412, 'Tax Type is required');
        }
        if (!isset($info['units'])) {
            api_error(412, 'Units is required');
        }
        if (!isset($info['mb_flag'])) {
            api_error(412, 'MB Flag is required');
        }
        if (!isset($info['sales_account'])) {
            api_error(412, 'Sales Account is required');
        }
        if (!isset($info['cogs_account'])) {
            api_error(412, 'Cogs Account is required');
        }
        if (!isset($info['adjustment_account'])) {
            api_error(412, 'Adjustment Account is required');
        }
        if (!isset($info['wip_account'])) {
            api_error(412, 'Assembly Account is required');
        }

        // TODO Validate Stock Id is Unique

        /*
         * $stock_id, $description, $long_description, $category_id, $tax_type_id, $units, $mb_flag,	$sales_account,
         * $inventory_account, $cogs_account, $adjustment_account,	$wip_account, $dimension_id, $dimension2_id,
         * $no_sale, $editable
         */
        add_item(
                $info['stock_id'], $info['description'], $info['long_description'], $info['category_id'], $info['tax_type_id'], $info['units'], $info['mb_flag'], $info['sales_account'], $info['inventory_account'], $info['cogs_account'], $info['adjustment_account'], $info['wip_account'], 0, // dimension 1
                0, // dimension2
                0, // no sale
                1, // editable
                0  // no purchase
        );

        $itm = get_item($info['stock_id']);

        if ($itm != null) {
            api_create_response(json_encode($itm));
        } else {
            api_error(500, 'Could Not Save to Database');
        }
    }

    function inventory_edit($id) {
        $app = \Slim\Slim::getInstance('SASYS');
        $req = $app->request();
        $info = $req->post();

        $itm = get_item($id);
        if ($itm == null) {
            api_error(400, 'Invalid Stock Id');
        }

        // Validate Required Fields
        if (!isset($info['description'])) {
            api_error(412, 'Description is required');
        }
        if (!isset($info['long_description'])) {
            $info['long_description'] = $info['description'];
        }
        if (!isset($info['category_id'])) {
            api_error(412, 'Category Id is required');
        }
        if (!isset($info['tax_type_id'])) {
            api_error(412, 'Tax Type is required');
        }
        if (!isset($info['units'])) {
            api_error(412, 'Units is required');
        }
        if (!isset($info['mb_flag'])) {
            api_error(412, 'MB Flag is required');
        }
        if (!isset($info['sales_account'])) {
            api_error(412, 'Sales Account is required');
        }
        if (!isset($info['cogs_account'])) {
            api_error(412, 'Cogs Account is required');
        }
        if (!isset($info['adjustment_account'])) {
            api_error(412, 'Adjustment Account is required');
        }
        if (!isset($info['wip_account'])) {
            api_error(412, 'WIP Account is required');
        }

        /*
         * $stock_id, $description, $long_description, $category_id, $tax_type_id, $units='', $mb_flag='',
         * $sales_account, $inventory_account, $cogs_account, 	$adjustment_account, $wip_account, $dimension_id,
         * $dimension2_id, $no_sale, $editable
         */
        update_item(
                $info['stock_id'], $info['description'], $info['long_description'], $info['category_id'], $info['tax_type_id'], $info['units'], $info['mb_flag'], $info['sales_account'], $info['inventory_account'], $info['cogs_account'], $info['adjustment_account'], $info['wip_account'], 0, // dimension 1
                0, // dimension2
                0, // no sale
                1, // editable
                0  // no purchase
        );

        api_success_response("Item has been updated");
    }

    function inventory_delete($id) {
        $app = \Slim\Slim::getInstance('SASYS');
        $req = $app->request();
        $info = $req->post();

        $itm = get_item($id);
        if ($itm == null) {
            api_error(400, 'Invalid Stock Id');
        }

        delete_item($id);

        $itm = get_item($id);

        if ($itm != null) {
            api_error(500, 'Could Not Delete from Database');
        } else {
            api_success_response("Item has been deleted");
        }
    }

    function combo_search() {
        $name = get_post("name");
        $selected_id = get_post("selected_id");
        $valfield = get_post("valfield");
        $namefield = get_post("namefield");
        $type = get_post("type");
        $sql = $this->sales_items_list_sql($type);

        $opts = array(// default options
            'where' => get_post("where"), // additional constraints
            'order' => get_post("order"), // list sort order
            // special option parameters
            'spec_option' => get_post("spec_option"), // option text or false
            'spec_id' => get_post("spec_id"), // option id
            // submit on select parameters
            'default' => get_post("default"), // default value when $_POST is not set
            'multi' => get_post("multi"), // multiple select
            'select_submit' => get_post("select_submit"), //submit on select: true/false
            'async' => get_post("async"), // select update via ajax (true) vs _page_body reload
            // search box parameters
            'sel_hint' => get_post("sel_hint"),
            'search_box' => get_post("search_box"), // name or true/false
            'type' => get_post("type"), // type of extended selector:
            // 0 - with (optional) visible search box, search by fragment inside id
            // 1 - with hidden search box, search by option text
            // 2 - with (optional) visible search box, search by fragment at the start of id
            // 3 - TODO reverse: box with hidden selector available via enter; this
            // would be convenient for optional ad hoc adding of new item
            'search_submit' => get_post("search_submit"), //search submit button: true/false
            'size' => get_post("size"), // size and max of box tag
            'max' => get_post("max"),
            'height' => get_post("height"), // number of lines in select box
            'cells' => get_post("cells"), // combo displayed as 2 <td></td> cells
            'search' => get_post("search"), // sql field names to search
            'format' => get_post("format"), // format functions for regular options
            'disabled' => get_post("disabled"),
            'box_hint' => get_post("box_hint"), // box/selectors hints; null = std see below
            'category' => get_post("category"), // category column name or false
            'show_inactive' => get_post("show_inactive"), // show inactive records. 
            'editable' => get_post("editable"), // false, or length of editable entry field
            'editlink' => get_post("editlink") // link to entity entry/edit page (optional)
        );
// ------ merge options with defaults ----------

        if (!is_array($opts['where'])) {
            if (!empty($opts['where'])) {
                $opts['where'] = array($opts['where']);
            }
        }

        $limit = '';
        if (!empty($_POST['term'])) {
            $opts['where'][] = ' s.description like "%' . $_POST['term'] . '%" ';
        }



        // sql completion
        if (count($opts['where'])) {
            $where = strpos($sql, 'WHERE') == false ? ' WHERE ' : ' AND ';
            $where .= '(' . implode($opts['where'], ' AND ') . ')';
            $group_pos = strpos($sql, 'GROUP BY');
            if ($group_pos) {
                $group = substr($sql, $group_pos);
                $sql = substr($sql, 0, $group_pos) . $where . ' ' . $group;
            } else {
                $sql .= $where;
            }
        }
        if ($opts['order'] != false) {
            if (!is_array($opts['order']))
                $opts['order'] = array($opts['order']);
            $sql .= ' ORDER BY ' . implode(',', $opts['order']);
        }

        $sql .= $limit;
        //die('SQL : '.$sql);
        $query = db_query($sql, "error");

        $info = array();

        $length = 0;
        while ($data = db_fetch($query, "error")) {
            $info[] = array(
                'id' => $data['item_code'],
                'text' => $data['description']
            );
            $length++;
        }

        $response['items'] = $info;
        $response['incomplete_results'] = FALSE;
        $response['total_count'] = $length;
        api_success_response(json_encode($response));

        return $sql;
    }

    public function sales_items_list_sql($type = '') {
        $sql = "SELECT i.item_code, i.description,  count(*)>1 as kit,
                            i.inactive, if(count(*)>1, '0', s.editable) as editable
                           FROM
                           " . TB_PREF . "stock_master s,
                           " . TB_PREF . "item_codes i
                           LEFT JOIN
                           " . TB_PREF . "stock_category c
                           ON i.category_id=c.category_id
                           WHERE i.stock_id=s.stock_id
         AND mb_flag != 'F'";


        if ($type == 'local') { // exclude foreign codes
            $sql .= " AND !i.is_foreign";
        } elseif ($type == 'kits') { // sales kits
            $sql .= " AND !i.is_foreign AND i.item_code!=i.stock_id";
        }
        $sql .= " AND !i.inactive AND !s.inactive AND !s.no_sale ";
        $sql .= " GROUP BY i.item_code";
        return $sql;
    }

}
