<?php

/**
 * Subclass for representing a row from the 'katao_order' table.
 *
 * @package lib.model
 */
class KataoOrder extends BaseKataoOrder {
    const STATUS_GENERATED = 1;
    const STATUS_ADJUSTED = 2;
    const STATUS_SENT = 3;
    const STATUS_RECEIVED = 4;
    const STATUS_DELIVERED = 5;

    public function __toString() {
        return $this->getNumber();
    }

    public function getNumber() {
        return sprintf('CO%04d', $this->getId());
    }

    public function getStatusStr() {
        return KataoOrderPeer::getStatusStr($this->getStatus());
    }

    public function getSupplierName() {
        return $this->getKataoSupplier()->getName();
    }
    public function getSupplierLink() {
        $result = '';
        if (null != $katao_supplier = $this->getKataoSupplier()) {
            $result = link_to($katao_supplier->getName(), '@katao_supplier_show?id=' . $katao_supplier->getId());
        }
        return $result;
    }

    /**
     * KataoOrder::sumProducts()
     *
     * @return float
     */
    public function sumProducts() {
        $return = 0;

        $criteria = new Criteria();
        $criteria->addSelectColumn(KataoOrderProductPeer::KATAO_ORDER_ID);
        $criteria->addAsColumn('sum_products', sprintf('SUM(ROUND(%s * (1 + %s), 2) * %s)', KataoOrderProductPeer::PRODUCT_PRICE_EURO, KataoOrderProductPeer::PRODUCT_TVA_RATE, KataoOrderProductPeer::QUANTITY));
        $criteria->add(KataoOrderProductPeer::KATAO_ORDER_ID, $this->getId());
        $criteria->addGroupByColumn(KataoOrderProductPeer::KATAO_ORDER_ID);

        $rs = KataoOrderProductPeer::doSelectRS($criteria);
        if ($rs->next()) {
            $return = $rs->getFloat(2);
        }

        return $return;
    }
    public function sumProductsStr() {
        return Utils::formatCurrencyEuro($this->sumProducts());
    }

    /**
     * KataoOrder::updateProductQuantity()
     *
     * @param int $katao_product_id
     * @param int $katao_order_product_quantity
     * @return
     */
    public function updateProductQuantity($katao_product_id, $katao_order_product_quantity) {
        $criteria_update = new Criteria();
        $criteria_update->add(KataoOrderProductPeer::QUANTITY, $katao_order_product_quantity);
        $criteria_where = new Criteria();
        $criteria_where->add(KataoOrderProductPeer::KATAO_ORDER_ID, $this->getId());
        $criteria_where->add(KataoOrderProductPeer::KATAO_PRODUCT_ID, $katao_product_id);
        BasePeer::doUpdate($criteria_where, $criteria_update, Propel::getConnection());
    }

    public function getCreatedAtStr() {
        return CatalyzDate::formatShort($this->getCreatedAt(null));
    }

    public function getNodeLink($with_link = false) {
        if ($with_link) {
            return link_to($this->getKataoNode()->getCity(), '@katao_node_show?id=' . $this->getKataoNodeId());
        }
        return $this->getKataoNode()->getCity();
    }

    public function getPeriodLink($with_link = false) {
        if ($with_link) {
            return link_to($this->getKataoPeriod()->getName(), '@katao_node_show?id=' . $this->getKataoPeriodId());
        }
        return $this->getKataoPeriod()->getName();
    }

    /**
     * KataoOrder::addProductToUser()
     *
     * @param int $katao_user_id
     * @param int $katao_product_id
     * @param int $quantity
     * @return
     */
    public function addProductToUser($katao_user_id, $katao_product_id, $quantity) {
        if (null != $katao_order_product = $this->getKataoOrderProductByProductId($katao_product_id)) {
            $katao_order_product->addProductToUser($katao_user_id, $quantity);
        }
    }

    /**
     * KataoOrder::updateProductQuantity()
     *
     * @param int $katao_product_id
     * @param int $katao_order_product_quantity
     * @return KataoOrderProduct
     */
    public function getKataoOrderProductByProductId($katao_product_id) {
        $criteria = new Criteria();
        $criteria->add(KataoOrderProductPeer::KATAO_ORDER_ID, $this->getId());
        $criteria->add(KataoOrderProductPeer::KATAO_PRODUCT_ID, $katao_product_id);
        return KataoOrderProductPeer::doSelectOne($criteria);
    }

    public function generatePDF() {
        $katao_supplier = $this->getKataoSupplier();

        $tva_rates = array('0.055' => '2', '0.2' => '1');
    	$tva_rates_map = array(2 => 0.055, 1 => 0.2);

        $pdf = new PDF_Invoice('P', 'mm', 'A4');

        $page = $pdf->addPageHeaderOrder(1, $this, $katao_supplier);
        $y = 109;

        $used_sol_by_product = $this->getUsedSolByProduct();

        $total_by_tva_rate = array(1 => 0, 2 => 0);

    	$criteria = new Criteria();
    	$criteria->addAscendingOrderByColumn(KataoOrderProductPeer::PRODUCT_NAME);
        foreach ($this->getKataoOrderProductsJoinKataoProduct($criteria) as/*(KataoOrderProduct)*/ $katao_order_product) {
            if ($y > 244) {
                $page = $pdf->addPageHeaderOrder($page, $this, $katao_supplier);
                $y = 109;
            }

            $tva_rate = !empty($tva_rates[(string)$katao_order_product->getProductTvaRate()])?$tva_rates[(string)$katao_order_product->getProductTvaRate()]:0;

            $quantity_adjusted = $katao_order_product->getQuantity();
            $quantity_received = $katao_order_product->getHasBeenReceived()?$katao_order_product->getQuantityReceived():CONST_N_A;
            $quantity_delivered = $katao_order_product->getHasBeenDelivered()?$katao_order_product->getQuantityDelivered():CONST_N_A;

            $quantity = $quantity_delivered;
            if (CONST_N_A === $quantity) {
                $quantity = $quantity_received;
            }
            if (CONST_N_A === $quantity) {
                $quantity = $quantity_adjusted;
            }

            $unit_price = round($katao_order_product->getProductPriceEuro() * (1 + $katao_order_product->getProductTvaRate()), 2);
            $amount = $quantity * $unit_price;

            if ($tva_rate) {
                $total_by_tva_rate[$tva_rate] += $amount;
            }

            $designation = utf8_decode($katao_order_product->getProductName());
            if (null != $katao_product = $katao_order_product->getKataoProduct()) {
                $designation .= utf8_decode(sprintf(' (UC : %d)', $katao_product->getMinOrderNumber()));
            }
            // $designation .= "\n" . utf8_decode(sprintf('Aju. : %s / Réc. : %s / Fac. : %s', $quantity_adjusted , strip_tags($quantity_delivered), strip_tags($quantity_invoiced)));
            $line = array("REFERENCE" => $katao_order_product->getProductReference(),
                "DESIGNATION" => $designation,
                "QUANTITE" => $quantity,
                "P.U. TTC" => Utils::formatCurrency($unit_price),
                "MONTANT TTC" => Utils::formatCurrency($amount),
                "TVA" => $tva_rate);
            $size = $pdf->addLine($y, $line);
            $y += $size + 2;
        }

        $pdf->addCadreTVAs();

        $tot_prods = array();
        foreach ($total_by_tva_rate as $tva_rate => $amount) {
            $tot_prods[] = array ("px_unit" => round($amount / (1 + $tva_rates_map[$tva_rate]), 2), "qte" => 1, "tva" => $tva_rate);
        }
        $tab_tva = array("1" => 20,
            "2" => 5.5);
        $params = array("RemiseGlobale" => 1,
            "remise_tva" => 0, // {la remise s'applique sur ce code TVA}
            "remise" => 0, // {montant de la remise}
            "remise_percent" => 0, // {pourcentage de remise sur ce montant de TVA}
            "FraisPort" => 0,
            "portTTC" => 0, // montant des frais de ports TTC
            // par defaut la TVA = 20 %
            "portHT" => 0, // montant des frais de ports HT
            "portTVA" => 20, // valeur de la TVA a appliquer sur le montant HT
            "AccompteExige" => 0,
            "accompte" => 0, // montant de l'acompte (TTC)
            "accompte_percent" => 0, // pourcentage d'acompte (TTC)
            "Remarque" => "");

        $pdf->addTVAs($params, $tab_tva, $tot_prods, null);

        $pdf->addCadreEurosFrancs();
        return $pdf->Output('', 'S');
    }

    public function checkIfAllProductsHaveBeenDelivered() {
        $return = false;

        $criteria = new Criteria();
        $criteria->addSelectColumn(KataoOrderProductPeer::KATAO_ORDER_ID);
        $criteria->addAsColumn('sum_has_been_delivered', sprintf('SUM(%s)', KataoOrderProductPeer::HAS_BEEN_DELIVERED));
        $criteria->add(KataoOrderProductPeer::KATAO_ORDER_ID, $this->getId());
        $criteria->addGroupByColumn(KataoOrderProductPeer::KATAO_ORDER_ID);

        $rs = KataoOrderProductPeer::doSelectRS($criteria);
        if ($rs->next()) {
            $return = $rs->getInt(2) == $this->countKataoOrderProducts();
        }

        return $return;
    }

    public function getUsedSolByProduct() {
        $return = array();

        $criteria = new Criteria();
        $criteria->addSelectColumn(KataoInvoiceProductPeer::KATAO_PRODUCT_ID);
        $criteria->addSelectColumn(KataoInvoiceProductPeer::SOL_AMOUNT);
        $criteria->addJoin(KataoInvoicePeer::ID, KataoInvoiceProductPeer::KATAO_INVOICE_ID);
        $criteria->add(KataoInvoicePeer::KATAO_PERIOD_ID, $this->getKataoPeriodId());
        $criteria->add(KataoInvoicePeer::KATAO_NODE_ID, $this->getKataoNodeId());
        $criteria->add(KataoInvoicePeer::STATUS, KataoInvoice::STATUS_SENT);

        $rs = KataoInvoiceProductPeer::doSelectRS($criteria);
        while ($rs->next()) {
            $return[$rs->getInt(1)] = $rs->getInt(2);
        }

        return $return;
    }
    public function getUsedSolTotal() {
        $return = 0;

        $criteria = new Criteria();
        $criteria->addAsColumn('sum_products', sprintf('SUM(%s)', KataoInvoiceProductPeer::SOL_AMOUNT));
        $criteria->addJoin(KataoInvoicePeer::ID, KataoInvoiceProductPeer::KATAO_INVOICE_ID);
        $criteria->add(KataoInvoicePeer::KATAO_PERIOD_ID, $this->getKataoPeriodId());
        $criteria->add(KataoInvoicePeer::KATAO_NODE_ID, $this->getKataoNodeId());
        $criteria->add(KataoInvoicePeer::STATUS, KataoInvoice::STATUS_SENT);
        $criteria->addGroupByColumn(KataoInvoicePeer::ID);

        $rs = KataoInvoiceProductPeer::doSelectRS($criteria);
        while ($rs->next()) {
            $return += $rs->getInt(1);
        }

        return $return;
    }

    public function notifyMembersWithModifiedAdjustedQuantities() {
        $criteria = new Criteria();
        $criteria->addJoin(KataoCartPeer::ID, KataoCartProductPeer::KATAO_CART_ID);
        $criteria->addJoin(KataoCartProductPeer::KATAO_ORDER_PRODUCT_ID, KataoOrderProductPeer::ID);
        $criteria->add(KataoOrderProductPeer::KATAO_ORDER_ID, $this->getId());
        $criteria->add(KataoCartProductPeer::HAS_BEEN_ADJUSTED, true);
        $criteria->add(KataoCartProductPeer::QUANTITY, sprintf('%s <> %s', KataoCartProductPeer::QUANTITY, KataoCartProductPeer::QUANTITY_ADJUSTED), Criteria::CUSTOM);
        $criteria->setDistinct();

        $katao_carts = KataoCartPeer::doSelectJoinKataoUser($criteria);
        if (0 < count($katao_carts)) {
            $mailer = new wpMail();
            foreach ($katao_carts as/*(KataoCart)*/ $katao_cart) {
                $katao_user = $katao_cart->getKataoUser();
                $katao_member = $katao_user->getKataoMember();

                try {
                    $mailer->send(new Swift_Message('Les demandes ont été ajustées et la vôtre modifiée', sprintf('%s,

Suite à l\'ajustement des demandes pour atteindre les minimun de commande fournisseur,
la quantité d\'un ou plusieurs produits que tu avais demandé
dans ta demande N° %s du %s a changé.

Tu peux en pendre connaissance via ton panier :
%smon-panier
%s', $katao_member->getFirstName(), $katao_cart->getNumber(), $katao_cart->getCreatedAtStr(), sfConfig::get('app_katao_frontend_url'), Utils::getKataoEmailFooter())), new Swift_Address($katao_user->getEmail(), $katao_member->getFullName()), sfConfig::get('app_mail_from'));
                }
                catch (Exception $e) {
                    $mailer->disconnect();
                }
            }
            $mailer->disconnect();
        }
    }

    public function notifyMembersWithModifiedDeliveredQuantities() {
        $criteria = new Criteria();
        $criteria->addJoin(KataoCartPeer::ID, KataoCartProductPeer::KATAO_CART_ID);
        $criteria->addJoin(KataoCartProductPeer::KATAO_ORDER_PRODUCT_ID, KataoOrderProductPeer::ID);
        $criteria->add(KataoOrderProductPeer::KATAO_ORDER_ID, $this->getId());
        $criteria->add(KataoOrderProductPeer::HAS_BEEN_DELIVERED, true);
        $criteria->add(KataoOrderProductPeer::QUANTITY, sprintf('%s <> %s', KataoOrderProductPeer::QUANTITY, KataoOrderProductPeer::QUANTITY_DELIVERED), Criteria::CUSTOM);
        $criteria->setDistinct();

        $katao_carts = KataoCartPeer::doSelectJoinKataoUser($criteria);
        if (0 < count($katao_carts)) {
            $mailer = new wpMail();
            foreach ($katao_carts as/*(KataoCart)*/ $katao_cart) {
                $katao_user = $katao_cart->getKataoUser();
                $katao_member = $katao_user->getKataoMember();

                try {
                    $mailer->send(new Swift_Message('La commande des fournisseurs a été réceptionnée et votre demande modifiée', sprintf('%s,

Suite à la recepton des commandes de nos fournisseurs la quantité d\'un ou plusieurs produits que tu avais demandé
dans ta demande N° %s du %s a changé.

Merci d\'en prendre connaissance en suivant le Lien vers ton panier :
%smon-panier
%s', $katao_member->getFirstName(), $katao_cart->getNumber(), $katao_cart->getCreatedAtStr(), sfConfig::get('app_katao_frontend_url'), Utils::getKataoEmailFooter())), new Swift_Address($katao_user->getEmail(), $katao_member->getFullName()), sfConfig::get('app_mail_from'));
                }
                catch (Exception $e) {
                    $mailer->disconnect();
                }
            }
            $mailer->disconnect();
        }
    }

    public function notifiySeoWithAdjustment() {
        try {
            $katao_member_seo = wpConfig::getInstance()->getKataoMember();
            $katao_user_seo = $katao_member_seo->getFirstKataoUser();

            $mailer = new wpMail();
            $mailer->send(new Swift_Message('Une commande a été justifiée', sprintf('%s,
le %s, le Délégué %s du noeud %s
a fini d\'ajuster la commande de la période %s pour le fournisseur %s

Pour approfondir cette information, suivre le Lien ci-dessous :
%s

Système katao.fr', $katao_member_seo->getFirstName(), CatalyzDate::formatShort(time()), $this->getKataoNode()->getKataoUser()->getKataoMember()->getFirstName(), $this->getKataoNode()->getCity(), $this->getKataoPeriod()->getName(), $this->getSupplierName(), sfConfig::get('app_katao_backend_url'))), new Swift_Address($katao_user->getEmail(), $katao_member->getFullName()), sfConfig::get('app_mail_from'));
            $mailer->disconnect();
        }
        catch (Exception $e) {
            $mailer->disconnect();
        }
    }

    public function notifiySeoWithReceive() {
        try {
            $katao_member_seo = wpConfig::getInstance()->getKataoMember();
            $katao_user_seo = $katao_member_seo->getFirstKataoUser();

            $mailer = new wpMail();
            $mailer->send(new Swift_Message('Une commande a été réceptionnée', sprintf('%s,
le %s, le Délégué %s du noeud %s
a fini de réceptionner la commande de la période %s pour le fournisseur %s

Pour approfondir cette information, suivre le Lien ci-dessous :
%s

Système katao.fr', $katao_member_seo->getFirstName(), CatalyzDate::formatShort(time()), $this->getKataoNode()->getKataoUser()->getKataoMember()->getFirstName(), $this->getKataoNode()->getCity(), $this->getKataoPeriod()->getName(), $this->getSupplierName(), sfConfig::get('app_katao_backend_url'))), new Swift_Address($katao_user->getEmail(), $katao_member->getFullName()), sfConfig::get('app_mail_from'));
            $mailer->disconnect();
        }
        catch (Exception $e) {
            $mailer->disconnect();
        }
    }

    public function notifiySeoWithDeliver() {
        try {
            $katao_member_seo = wpConfig::getInstance()->getKataoMember();
            $katao_user_seo = $katao_member_seo->getFirstKataoUser();

            $mailer = new wpMail();
            $mailer->send(new Swift_Message('Les demandes ont été distribuées', sprintf('%s,
le %s, le Délégué %s du noeud %s
a fini de distribuer les demandes de période %s

Pour approfondir cette information, suivre le Lien ci-dessous :
%s

Système katao.fr', $katao_member_seo->getFirstName(), CatalyzDate::formatShort(time()), $this->getKataoNode()->getKataoUser()->getKataoMember()->getFirstName(), $this->getKataoNode()->getCity(), $this->getKataoPeriod()->getName(), sfConfig::get('app_katao_backend_url'))), new Swift_Address($katao_user->getEmail(), $katao_member->getFullName()), sfConfig::get('app_mail_from'));
            $mailer->disconnect();
        }
        catch (Exception $e) {
            $mailer->disconnect();
        }
    }

    public function adjust($sf_user) {
        $this->setStatus(KataoOrder::STATUS_ADJUSTED);
        $this->save();

        $this->notifyMembersWithModifiedAdjustedQuantities();
        if ($sf_user->isJustDelegate()) {
            $this->notifiySeoWithAdjustment();
        }
    }

    public function getOtherProducts() {
        $return = array();

        $product_ids = array();

        $criteria = new Criteria();
        $criteria->addSelectColumn(KataoOrderProductPeer::KATAO_PRODUCT_ID);
        $criteria->add(KataoOrderProductPeer::KATAO_ORDER_ID, $this->getId());

        $rs = KataoOrderProductPeer::doSelectRS($criteria);
        while ($rs->next()) {
            $product_ids[$rs->getInt(1)] = true;
        }

        $criteria = new Criteria();
        $criteria->addSelectColumn(KataoProductPeer::ID);
        $criteria->addSelectColumn(KataoProductPeer::NAME);
        $criteria->add(KataoProductPeer::KATAO_SUPPLIER_ID, $this->getKataoSupplierId());
        $criteria->add(KataoProductPeer::ID, array_keys($product_ids), Criteria::NOT_IN);
        $criteria->addAscendingOrderByColumn(KataoProductPeer::NAME);

        $rs = KataoProductPeer::doSelectRS($criteria);
        while ($rs->next()) {
            $return[$rs->getInt(1)] = $rs->getString(2);
        }

        return $return;
    }
}
