<?php

$path_to_root = "../..";
include_once($path_to_root . "/purchasing/includes/po_class.inc");
include_once($path_to_root . "/purchasing/includes/purchasing_ui.inc");
include_once($path_to_root . "/purchasing/includes/db/suppliers_db.inc");

function purchase_add() {
    global $Refs, $systypes_array;
    $app = \Slim\Slim::getInstance('SASYS');
    $req = $app->request();
    $info = $req->post();
    unset($_SESSION['PO']);

    create_new_po($info['trans_type'], $info['trans_no'] ? $info['trans_no'] : 0);

    $can_process = check_data($info);
    if ($can_process['passed'] == false) {
        unset($_SESSION['PO']);
        api_error(200, $can_process['message']);
        return;
    }

    foreach ($info['line_items'] as $item) {
        $_SESSION['PO']->add_to_order(count($_SESSION['PO']->line_items), $item['stock_item']['stock_id'], $item['qty'],
                $item['item_description'], $item['price'], '', $_SESSION['PO']->trans_type == ST_PURCHORDER ? $item['req_del_date'] : '', 0, 0);
    }

    $can_process = can_commit($info);
    if ($can_process['passed'] == false) {
        unset($_SESSION['PO']);
        api_error(200, $can_process['message']);
        return;
    }

    $cart = &$_SESSION['PO'];
    $reference = $cart->reference;
    $cart->supplier_id = $info['supplier']['supplier_id'];
    get_supplier_details_to_order($cart, $cart->supplier_id);
    $cart->orig_order_date = $info['orig_order_date'];
    if ($cart->trans_type == ST_SUPPINVOICE) {
        $cart->due_date = $info['due_date'];
        $cart->cash_account = $info['cash_account'];
    }
    $cart->supp_ref = $info['supp_ref'];
    $cart->Comments = $info['Comments'];
    $cart->Location = $info['Location'];
    $cart->delivery_address = $info['delivery_address'];
    $cart->dimension = @$info['dimension']['id'];
    $cart->dimension2 = @$info['dimension2']['id'];
    $cart->prep_amount = 0;
    $cart->ex_rate = 1;

    if (isset($info['mantax'])) {
        foreach ($info['mantax'] as $id => $tax) {
            $cart->tax_overrides[$id] = user_numeric($info['mantax'][$id]);
        }
    }

    $trans_no = "";
    $feeback_response = "";
    new_doc_date($cart->orig_order_date);
    if ($cart->order_no == 0) { // new po/grn/invoice
        $trans_no = add_direct_supp_trans($cart);
        if (!$trans_no) {
            unset($_SESSION['PO']);
            api_error(200, 'Could Not Save to Database');
            return;
        }
    } else { // order modification
        if ($cart->trans_type == ST_PURCHORDER) {
            $trans_no = update_po($cart);
            if (!$trans_no) {
                unset($_SESSION['PO']);
                api_error(200, 'Could Not Save to Database');
                return;
            }
        } else {
            unset($_SESSION['PO']);
            api_error(200, 'Update not allowed here');
            return;
        }
    }

    $response['msg'] = $systypes_array[$cart->trans_type] . " has been saved";
    $response['reference'] = $reference;
    $response['type_no'] = $trans_no;
    unset($_SESSION['PO']);
    api_success_response(json_encode($response));
}

function purchase_edit($rest, $trans_no) {
    global $Refs, $systypes_array;
    $req = $rest->request();
    $info = $req->post();

    $supp_trans = new supp_trans(ST_SUPPINVOICE, $trans_no ? $trans_no : 0);

    $can_process = check_item_data($info);
    if ($can_process['passed'] == false) {
        unset($supp_trans);
        api_error(200, $can_process['message']);
        return;
    }

    foreach ($info['line_items'] as $item) {
        $supp_trans->add_grn_to_trans($item['grn_item_id'], $item['po_detail_item'],
                $item['item_code'], $item['item_description'], $item['qty_recd'],
                $item['prev_quantity_inv'], $item['this_quantity_inv'], $item['order_price'], $item['ChgPrice']);
    }

    $can_process = check_gl_codes_data($info);
    if ($can_process['passed'] == false) {
        unset($supp_trans);
        api_error(200, $can_process['message']);
        return;
    }

    foreach ($info['gl_codes'] as $item) {
        $result = get_gl_account_info($item['gl_code']);
        $myrow = db_fetch_row($result);
        $gl_act_name = $myrow[1];
        $supp_trans->add_gl_codes_to_trans($item['gl_code'], $gl_act_name,
                $item['dimension_id'], $item['dimension2_id'], $item['amount'], $item['memo_']);
    }

    $can_process = can_commit_supp_trans($supp_trans, $info);
    if ($can_process['passed'] == false) {
        unset($supp_trans);
        api_error(200, $can_process['message']);
        return;
    }

    $supp_trans->supplier_id = $info['supplier']['supplier_id'];
    read_supplier_details_to_trans($supp_trans, $supp_trans->supplier_id);
    if (trim($info['reference'])) {
        $supp_trans->reference = $info['reference'];
    } else {
        if (!trim($supp_trans->reference))
            $supp_trans->reference = $Refs->get_next($supp_trans->trans_type, null,
                    array('supplier_id' => $supp_trans->supplier_id, 'date' => $info['tran_date']));
    }
    $reference = $supp_trans->reference;
    $supp_trans->Comments = $info['Comments'];
    $supp_trans->tran_date = $info['tran_date'];
    $supp_trans->due_date = $info['due_date'];
    $supp_trans->supp_reference = $info['supp_ref'];
    $supp_trans->dimension = @$info['dimension']['id'];
    $supp_trans->dimension2 = @$info['dimension2']['id'];
    $supp_trans->ex_rate = 1;

    $supp_trans->ov_amount = $supp_trans->ov_discount = 0; /* for starters */
    if (isset($info['mantax'])) {
        foreach ($info['mantax'] as $id => $tax) {
            $supp_trans->tax_overrides[$id] = user_numeric($info['mantax'][$id]);
        }
    } else
        unset($supp_trans->tax_overrides);

    if (count($supp_trans->grn_items) > 0) {
        foreach ($supp_trans->grn_items as $grn) {
            $supp_trans->ov_amount += round2(($grn->this_quantity_inv * $grn->chg_price), user_price_dec());
        }
    }
    if (count($supp_trans->gl_codes) > 0) {
        foreach ($supp_trans->gl_codes as $gl_line) {
            if (!is_tax_account($gl_line->gl_code) || $supp_trans->tax_included)
                $supp_trans->ov_amount += $gl_line->amount;
        }
    }

    $trans_no = add_supp_invoice($supp_trans);
    $response['msg'] = $systypes_array[$supp_trans->trans_type] . " has been saved";
    $response['reference'] = $reference;
    $response['type_no'] = $trans_no;
    api_success_response(json_encode($response));
}

function check_data($info) {
    foreach ($info['line_items'] as $item) {
        $result = get_short_info($item['stock_item']['stock_id']);
        if (db_num_rows($result) == 0) {
            return array("passed" => false, "message" => _("Stock item code: " . $item['stock_item']['stock_id'] . " does not exist in the system."));
        }

        $dec = get_qty_dec($item['stock_item']['stock_id']);
        $min = 1 / pow(10, $dec);
        if (!$item['qty'] || $item['qty'] < $min) {
            $min = number_format2($min, $dec);
            return array("passed" => false, "message" => _("The quantity of the order item: " . $item['item_description'] . " must be numeric and not less than ") . $min);
        }

        if (!$item['price']) {
            return array("passed" => false, "message" => _("The price entered for: " . $item['item_description'] . " must be numeric and not less than zero."));
        }
        if ($_SESSION['PO']->trans_type == ST_PURCHORDER && !is_date($info['req_del_date'])) {
            return array("passed" => false, "message" => _("The delivery date entered for " . $item['item_description'] . " is in an invalid format."));
        }
    }

    return array("passed" => true, "message" => "");
}

function can_commit($info) {
    if (!$info['supplier']['supplier_id']) {
        return array("passed" => false, "message" => _("There is no supplier selected."));
    }

    if (!is_date($info['orig_order_date'])) {
        return array("passed" => false, "message" => _("The entered date is invalid."));
    }
    if (($_SESSION['PO']->trans_type == ST_SUPPRECEIVE || $_SESSION['PO']->trans_type == ST_SUPPINVOICE) && !is_date_in_fiscalyear($info['orig_order_date'])) {
        return array("passed" => false, "message" => _("The entered invoice date is invalid."));
    }

    if (($_SESSION['PO']->trans_type == ST_SUPPINVOICE) && !is_date($info['due_date'])) {
        return array("passed" => false, "message" => _("The entered due date is invalid."));
    }

//    if ($_SESSION['PO']->trans_type == ST_SUPPINVOICE && trim(get_post('supp_ref')) == false) {
//        return array("passed" => false, "message" => _("You must enter a supplier's invoice reference."));
//    }
    if ($_SESSION['PO']->trans_type == ST_SUPPINVOICE && is_reference_already_there($_SESSION['PO']->supplier_id, $info['supp_ref'], $_SESSION['PO']->order_no)) {
        return array("passed" => false, "message" => _("This invoice number has already been entered. It cannot be entered again.") . " (" . $info['supp_ref'] . ")");
    }
    if ($_SESSION['PO']->trans_type == ST_PURCHORDER && $info['delivery_address'] == '') {
        return array("passed" => false, "message" => _("There is no delivery address specified."));
    }
    if ($info['Location'] == '') {
        return array("passed" => false, "message" => _("There is no location specified to move any items into."));
    }
    if (!db_has_currency_rates($_SESSION['PO']->curr_code, $info['orig_order_date'], false))
        return array("passed" => false, "message" => _("Cannot retrieve exchange rate for currency %s as of %s. Please add exchange rate manually on Exchange Rates page."), $_SESSION['PO']->curr_code, $info['orig_order_date']);
    if ($_SESSION['PO']->order_has_items() == false) {
        return array("passed" => false, "message" => _("The order cannot be placed because there are no lines entered on this order."));
    }

    return array("passed" => true);
}

function check_gl_codes_data($info) {
    foreach ($info['gl_codes'] as $item) {
        $result = get_gl_account_info($item['gl_code']);
        if (db_num_rows($result) == 0) {
            return array("passed" => false, "message" => _("The account code: " . $item["gl_code"] . " is not a valid code, this line cannot be added to the transaction."));
        } else {
            $result = get_gl_account_info($item['gl_code']);
            $myrow = db_fetch_row($result);
            $gl_act_name = $myrow[1];
            if (!$item['amount']) {
                return array("passed" => false, "message" => _("The amount entered for: $gl_act_name is not numeric."));
            }
        }

        if (!is_tax_gl_unique($item['gl_code'])) {
            return array("passed" => false, "message" => _("Cannot post to GL account: $gl_act_name, used by more than one tax type."));
        }
    }
    return array("passed" => true);
}

function check_item_data($info) {
    global $SysPrefs;

    foreach ($info['line_items'] as $item) {
        if (!$item['this_quantity_inv'] || $item['this_quantity_inv'] == 0) {
            return array("passed" => false, "message" => _("The quantity to invoice must be numeric and greater than zero."));
        }

        if (!$item['ChgPrice']) {
            return array("passed" => false, "message" => _("The price is not numeric."));
        }

        $margin = $SysPrefs->over_charge_allowance();
        if ($SysPrefs->check_price_charged_vs_order_price == True) {
            if ($item['order_price'] != $item['ChgPrice']) {
                if ($item['order_price'] == 0 || $item['ChgPrice'] / $item['order_price'] > (1 + ($margin / 100))) {
                    return array("passed" => false, "message" => _("The price being invoiced is more than the purchase order price by more than the allowed over-charge percentage. The system is set up to prohibit this. See the system administrator to modify the set up parameters if necessary.") . _("The over-charge percentage allowance is :") . $margin . "%");
                }
            }
        }

        if ($SysPrefs->check_qty_charged_vs_del_qty == true && ($item['qty_recd'] != $item['prev_quantity_inv'])) {
            if ($item['this_quantity_inv'] / ($item['qty_recd'] - $item['prev_quantity_inv']) > (1 + ($margin / 100))) {
                return array("passed" => false, "message" => _("The quantity being invoiced is more than the outstanding quantity by more than the allowed over-charge percentage. The system is set up to prohibit this. See the system administrator to modify the set up parameters if necessary.") . _("The over-charge percentage allowance is :") . $margin . "%");
            }
        }
    }

    return array("passed" => true);
}

function can_commit_supp_trans($supp_trans, $info) {
    global $Refs;

    if (!$supp_trans->is_valid_trans_to_post()) {
        display_error(_(""));
        return array("passed" => false, "message" => _("The invoice cannot be processed because the there are no items or values on the invoice.  Invoices are expected to have a charge."));
    }
    if (!is_date($info['tran_date'])) {
        return array("passed" => false, "message" => _("The invoice as entered cannot be processed because the invoice date is in an incorrect format."));
    } elseif (!is_date_in_fiscalyear($info['tran_date'])) {
        return array("passed" => false, "message" => _("The entered date is out of fiscal year or is closed for further data entry."));
    }
    if (!is_date($info['due_date'])) {
        return array("passed" => false, "message" => _("The invoice as entered cannot be processed because the due date is in an incorrect format."));
    }

    if (trim($info['supp_ref']) == false) {
        return array("passed" => false, "message" => _("You must enter a supplier's invoice reference."));
    }


    return array("passed" => true);
}
