<?php

/**
 * kataoPeriod actions.
 *
 * @package www.katao.fr
 * @subpackage kataoPeriod
 * @author Your name here
 * @version SVN: $Id: actions.class.php 8507 2008-04-17 17:32:20Z fabien $
 */
class kataoPeriodActions extends wpActions {
    public function executeIndex() {
        $criteria = new Criteria();

        $sort_method = $this->getCriteriaSortMethod();
        switch ($this->sort = $this->getRequestParameter('sort', 'name')) {
            case 'begin':
                $criteria->$sort_method(KataoPeriodPeer::BEGIN_AT);
                break;
            case 'end':
                $criteria->$sort_method(KataoPeriodPeer::FINISH_AT);
                break;
            case 'order':
                $criteria->$sort_method(KataoPeriodPeer::ORDER_ENDED_AT);
                break;
            case 'active':
                $criteria->$sort_method(KataoPeriodPeer::IS_ACTIVE);
                break;
            default:
                $criteria->$sort_method(KataoPeriodPeer::NAME);
        }

        if ('' != $this->filter_status = $this->getUser()->getAttribute('katao_period_status')) {
            $criteria->add(KataoPeriodPeer::STATUS, $this->filter_status);
        }

        $pager = new sfPropelPager('KataoPeriod', sfConfig::get('app_pager'));
        $pager->setCriteria($criteria);
        $pager->setPage($this->getRequestParameter('page', 1));
        $pager->init();
        $this->pager = $pager;

        $this->katao_periodList = $pager->getResults();
    }

    public function executeFilter($request) {
        $this->getUser()->setAttribute('katao_period_status', $request->getParameter('filter_status'));
        return $this->redirect('kataoPeriod/index');
    }

    public function executeFilterReset($request) {
        $this->getUser()->setAttribute('katao_period_status', '');
        return $this->redirect('kataoPeriod/index');
    }

    public function executeShow($request) {
        $this->katao_period = KataoPeriodPeer::retrieveByPk($request->getParameter('id'));
        $this->redirectWithErrorUnless($this->katao_period, 'Période #' . $request->getParameter('id') . ' inconnue.');
    }

    public function executeCreate() {
        $this->form = new KataoPeriodForm();

        $this->katao_suppliers = KataoSupplierPeer::getAllToSortArray();
        $this->products = KataoProductPeer::getSelectedProducts(array_keys($this->katao_suppliers['some_product']));

        $this->setTemplate('edit');
    }

    public function executeEdit($request) {
        $this->form = new KataoPeriodForm(KataoPeriodPeer::retrieveByPk($request->getParameter('id')));

        $this->katao_suppliers = KataoSupplierPeer::getAllToSortArray($request->getParameter('id'));
        $this->products = KataoProductPeer::getSelectedProducts(array_keys($this->katao_suppliers['some_product']), $request->getParameter('id'));
    }

    public function executeUpdate($request) {
        $this->redirectWithErrorUnless($request->isMethod('post'));

        $this->form = new KataoPeriodForm(KataoPeriodPeer::retrieveByPk($request->getParameter('id')));

        $this->form->bind($request->getParameter('katao_period'));
        if ($this->form->isValid()) {
            $katao_period = $this->form->save();

            wpFlashMessages::addConfirmation('Période "' . $katao_period->getName() . '" sauvée avec succès.');
            $this->redirect('kataoPeriod/index');
        }

        $this->katao_suppliers = KataoSupplierPeer::getAllToSortArray($request->getParameter('id'));
        $this->products = KataoProductPeer::getSelectedProducts(array_keys($this->katao_suppliers['some_product']), $request->getParameter('id'));

        $this->setTemplate('edit');
    }

    public function executeDelete($request) {
        $this->redirectWithErrorUnless($katao_period = KataoPeriodPeer::retrieveByPk($request->getParameter('id')), 'Période #' . $request->getParameter('id') . ' inconnue.');
        $this->redirectWithErrorIf(!$katao_period->isDeletable());

        $katao_period->delete();

        wpFlashMessages::addConfirmation('Période "' . $katao_period->getName() . '" supprimée avec succès.');
        $this->redirect('kataoPeriod/index');
    }

    public function executeDeleteMultiple($request) {
        if (!wpPersistenceManager::isEmpty('katao_period')) {
            foreach (KataoPeriodPeer::retrieveByPKs(array_keys(wpPersistenceManager::getSelectedItems('katao_period'))) as/*(KataoPeriod)*/ $katao_period) {
                if ($katao_period->isDeletable()) {
                    $katao_period->delete();
                }
            }

            wpPersistenceManager::cleanSelection('katao_period');
            wpFlashMessages::addConfirmation('Les périodes sélectionnées ont été supprimées avec succès.');
        } else {
            wpFlashMessages::addWarning('Merci de sélectionner au moins une période.');
        }

        $this->redirect('kataoPeriod/index');
    }

    public function executeRefreshProducts($request) {
        return $this->renderText('(' . Utils::array_to_json_string(KataoProductPeer::getSelectedProducts(explode(',', $request->getParameter('suppliers_ids')), $request->getParameter('id'))) . ')');
    }

    public function executeActivate($request) {
        $this->redirectWithErrorUnless($katao_period = KataoPeriodPeer::retrieveByPk($request->getParameter('id')), 'Période #' . $request->getParameter('id') . ' inconnue.');

        $katao_period->activate();

        wpFlashMessages::addConfirmation('Période "' . $katao_period->getName() . '" activée avec succès.');
        $this->redirect('kataoPeriod/index');
    }

    public function executeExportAccounting($request) {
        $katao_periods = KataoPeriodPeer::getAllWithDates();
        $export_date_from = date('Y-m-d 00:00:00', Utils::getDateFromInput($request->getParameter('date_from')));
        $export_date_to = date('Y-m-d 23:59:59', Utils::getDateFromInput($request->getParameter('date_to')));

        $content = array();

        /* Liste des dépôts validés de la période en question */
        $criteria = new Criteria();
        $criteria->add(KataoMemberDepositPeer::PAYMENT_MODE, KataoMemberDeposit::PAYMENT_MODE_TRANSFER_SOL, Criteria::NOT_EQUAL);
        $criteria->add(KataoMemberDepositPeer::STATUS, KataoMemberDeposit::STATUS_VALIDATED);
        $criterion = $criteria->getNewCriterion(KataoMemberDepositPeer::VALUED_AT, $export_date_from, Criteria::GREATER_EQUAL);
        $criterion->addAnd($criteria->getNewCriterion(KataoMemberDepositPeer::VALUED_AT, $export_date_to, Criteria::LESS_EQUAL));
        $criteria->addAnd($criterion);
        $criteria->addAscendingOrderByColumn(KataoMemberDepositPeer::VALUED_AT);
        foreach (KataoMemberDepositPeer::doSelectJoinKataoMember($criteria) as/*(KataoMemberDeposit)*/ $katao_member_deposit) {
            $katao_period_id = KataoPeriodPeer::getIdFromRangeDate($katao_member_deposit->getValuedAt('Y-m-d'), $katao_periods);
            $katao_member = $katao_member_deposit->getKataoMember();

            $date_ecriture = $katao_member_deposit->getValuedAt('Ymd');
            $date_echeance = $katao_member_deposit->getValuedAt('Ymd');
            $num_piece = sprintf('DE%04d', $katao_member_deposit->getId());
            if (KataoMemberDeposit::PAYMENT_MODE_CHECK == $katao_member_deposit->getPaymentMode()) {
                $libelle_ecriture = sprintf('%s%s%s - %s', $katao_member_deposit->getCheckDeposit()?sprintf('%s-', $katao_member_deposit->getCheckDeposit()):'', $katao_member_deposit->getCheckBank(), $katao_member_deposit->getCheckNumber(), $katao_member->getLastName());
            } else {
                $libelle_ecriture = sprintf('%s - %s', $katao_member_deposit->getPaymentModeStr(), $katao_member->getLastName());
            }
            $num_pointage = '';
            $code_analytique_budgetaire = '';
            $libelle_compte = $katao_member->getFullName();

            if (KataoMemberDeposit::CURRENCY_SOL == $katao_member_deposit->getCurrency()) {
                $journal = 'SO';
                $num_mouvement = $katao_period_id . '4';
                $montant = $katao_member_deposit->getAmount() / CONST_EURO_TO_SOL;

                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeSolDiscount(), $libelle_ecriture, $montant, (KataoMemberDeposit::PAYMENT_MODE_WITHDRAWAL != $katao_member_deposit->getPaymentMode())?'D':'C', $num_pointage, $code_analytique_budgetaire, 'REMISE SOL');
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $katao_member->getAccountingCodeSol(), $libelle_ecriture, $montant, (KataoMemberDeposit::PAYMENT_MODE_WITHDRAWAL != $katao_member_deposit->getPaymentMode())?'C':'D', $num_pointage, $code_analytique_budgetaire, $libelle_compte . '-' . wpConfig::getAdditionalCurrencyName());
            } else {
                $journal = 'BQ';
                $num_mouvement = $katao_period_id . '3';
                $montant = $katao_member_deposit->getAmount();

                $num_compte = (KataoMemberDeposit::PAYMENT_MODE_CREDIT == $katao_member_deposit->getPaymentMode())?wpConfig::getAccountingCodeCredit():wpConfig::getAccountingCodeBank();

                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $num_compte, $libelle_ecriture, $montant, (KataoMemberDeposit::PAYMENT_MODE_WITHDRAWAL != $katao_member_deposit->getPaymentMode())?'D':'C', $num_pointage, $code_analytique_budgetaire, 'CAISSE D\'EPARGNE');
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $katao_member->getAccountingCode(), $libelle_ecriture, $montant, (KataoMemberDeposit::PAYMENT_MODE_WITHDRAWAL != $katao_member_deposit->getPaymentMode())?'C':'D', $num_pointage, $code_analytique_budgetaire, $libelle_compte);
            }
        }

        /* Liste des factures fournisseurs de la période */
        $criteria = new Criteria();
        $criterion = $criteria->getNewCriterion(KataoSupplierInvoicePeer::INVOICE_DATE, $export_date_from, Criteria::GREATER_EQUAL);
        $criterion->addAnd($criteria->getNewCriterion(KataoSupplierInvoicePeer::INVOICE_DATE, $export_date_to, Criteria::LESS_EQUAL));
        $criteria->addAnd($criterion);
        $criteria->addAscendingOrderByColumn(KataoSupplierInvoicePeer::INVOICE_DATE);
        foreach (KataoSupplierInvoicePeer::doSelectJoinAll($criteria) as/*(KataoSupplierInvoice)*/ $katao_supplier_invoice) {
            $katao_period = $katao_supplier_invoice->getKataoPeriod();
            $katao_supplier = $katao_supplier_invoice->getKataoSupplier();

            $journal = 'HA';
            $num_mouvement = $katao_period->getId() . '2';
            $date_ecriture = $katao_supplier_invoice->getInvoiceDate('Ymd');
            $date_echeance = $katao_supplier_invoice->getDueDate('Ymd');
            $num_piece = $katao_supplier_invoice->getReference();
            $libelle_ecriture = $katao_period->getName();
            $num_pointage = '';
            $code_analytique_budgetaire = '';
            $libelle_compte = '';

            $total_sol = $katao_supplier_invoice->getPaymentAmountSol() / CONST_EURO_TO_SOL;
            // enlever la valeur en sol du montant total en €
            $total_euro = $katao_supplier_invoice->getTotalHT() + $katao_supplier_invoice->getTotalTva() - $total_sol;

            $total_credit = $total_euro;
            // pour vérifier que total débit = total crédit sans les sols
            $total_debit = - $total_sol;

            $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $katao_supplier->getAccountingCode(), $libelle_ecriture, $total_euro, 'C', $num_pointage, $code_analytique_budgetaire, $katao_supplier->getName());
            if ($total_sol) {
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $katao_supplier->getAccountingCodeSol(), $libelle_ecriture, $total_sol, 'C', $num_pointage, $code_analytique_budgetaire, $katao_supplier->getName() . '-' . wpConfig::getAdditionalCurrencyName());
            }

            $line_by_accounting_code = array();
            foreach ($katao_supplier_invoice->getKataoSupplierInvoiceProductsJoinKataoProduct() as/*(KataoSupplierInvoiceProduct)*/ $katao_supplier_invoice_product) {
                $katao_product = $katao_supplier_invoice_product->getKataoProduct();
                if (!isset($line_by_accounting_code[$katao_product->getAccountingCodePurchase()]['amount'])) {
                    $line_by_accounting_code[$katao_product->getAccountingCodePurchase()]['amount'] = 0;
                }
                $line_by_accounting_code[$katao_product->getAccountingCodePurchase()]['amount'] += $katao_supplier_invoice_product->getProductPriceTotal();
                $line_by_accounting_code[$katao_product->getAccountingCodePurchase()]['category'] = sprintf('Ach : %s', $katao_product->getKataoProductFamily()->getKataoProductCategory()->getName());
            }
            foreach ($line_by_accounting_code as $accounting_code => $data) {
                if (!empty($data['amount'])) {
                    $total_debit += $data['amount'];
                    $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $accounting_code, $libelle_ecriture, $data['amount'], 'D', $num_pointage, $code_analytique_budgetaire, $data['category']);
                }
            }

            $discount = $katao_supplier_invoice->getTaux0DiscountHt() + $katao_supplier_invoice->getTaux1DiscountHt() + $katao_supplier_invoice->getTaux2DiscountHt();

            $tva_rates = array('0.196' => 1, '0.055' => 2, '0' => 0);
            $tva_5_5 = $katao_supplier_invoice->getTaux2Amount();
            $tva_19_6 = $katao_supplier_invoice->getTaux1Amount();
            if ($katao_supplier_invoice->getFeesBillingTva() && !empty($tva_rates[(string)$katao_supplier_invoice->getFeesBillingRate()])) {
                switch ($tva_rates[(string)$katao_supplier_invoice->getFeesBillingRate()]) {
                    case 1:
                        $tva_19_6 += $katao_supplier_invoice->getFeesBillingTva();
                        break;
                    case 2:
                        $tva_5_5 += $katao_supplier_invoice->getFeesBillingTva();
                        break;
                }
            }
            if ($katao_supplier_invoice->getFeesShippingTva() && !empty($tva_rates[(string)$katao_supplier_invoice->getFeesShippingRate()])) {
                switch ($tva_rates[(string)$katao_supplier_invoice->getFeesShippingRate()]) {
                    case 1:
                        $tva_19_6 += $katao_supplier_invoice->getFeesShippingTva();
                        break;
                    case 2:
                        $tva_5_5 += $katao_supplier_invoice->getFeesShippingTva();
                        break;
                }
            }

            if ($tva_19_6) {
                $total_debit += $tva_19_6;
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, '445664', $libelle_ecriture, $tva_19_6, 'D', $num_pointage, $code_analytique_budgetaire, 'TVA 19.6%');
            }
            if ($tva_5_5) {
                $total_debit += $tva_5_5;
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, '445662', $libelle_ecriture, $tva_5_5, 'D', $num_pointage, $code_analytique_budgetaire, 'TVA 5.5%');
            }
            if ($katao_supplier_invoice->getFeesBillingHt()) {
                $total_debit += $katao_supplier_invoice->getFeesBillingHt();
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeFeesBilling(), sprintf('FRSDEFACT-%s', $katao_supplier->getName()), $katao_supplier_invoice->getFeesBillingHt(), 'D', $num_pointage, $code_analytique_budgetaire, $katao_supplier->getName());
            }

            if ($katao_supplier_invoice->getFeesShippingHt()) {
                $total_debit += $katao_supplier_invoice->getFeesShippingHt();
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeFeesShipping(), sprintf('FRSDEPORT-%s', $katao_supplier->getName()), $katao_supplier_invoice->getFeesShippingHt(), 'D', $num_pointage, $code_analytique_budgetaire, $katao_supplier->getName());
            }
            if ($discount) {
                $total_credit += $discount;
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeDiscount(), sprintf('REMISE-%s', $katao_supplier->getName()), $discount, 'C', $num_pointage, $code_analytique_budgetaire, $katao_supplier->getName());
            }

            if (round(abs($total_debit - $total_credit), 2)) {
                if ($total_debit > $total_credit) {
                    $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeErrorAdjustmentPositive(), $libelle_ecriture, $total_debit - $total_credit, 'C', $num_pointage, $code_analytique_budgetaire, 'Ecart de conversion');
                } elseif ($total_debit < $total_credit) {
                    $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeErrorAdjustmentNegative(), $libelle_ecriture, $total_credit - $total_debit, 'D', $num_pointage, $code_analytique_budgetaire, 'Ecart de conversion');
                }
            }
        }

        /* Liste des factures fournisseurs payées de la période */
        $criteria = new Criteria();
        $criterion = $criteria->getNewCriterion(KataoSupplierInvoicePeer::PAYMENT_DATE, $export_date_from, Criteria::GREATER_EQUAL);
        $criterion->addAnd($criteria->getNewCriterion(KataoSupplierInvoicePeer::PAYMENT_DATE, $export_date_to, Criteria::LESS_EQUAL));
        $criteria->addAnd($criterion);
        $criteria->addAscendingOrderByColumn(KataoSupplierInvoicePeer::INVOICE_DATE);
        foreach (KataoSupplierInvoicePeer::doSelectJoinAll($criteria) as/*(KataoSupplierInvoice)*/ $katao_supplier_invoice) {
            $katao_period = $katao_supplier_invoice->getKataoPeriod();
            $katao_supplier = $katao_supplier_invoice->getKataoSupplier();

            $num_mouvement = $katao_period->getId() . '5';
            $date_ecriture = $katao_supplier_invoice->getPaymentDate('Ymd');
            $date_echeance = $katao_supplier_invoice->getPaymentDate('Ymd');
            $num_piece = $katao_supplier_invoice->getReference();
            $libelle_ecriture = sprintf('%s - %s', (KataoMemberDeposit::PAYMENT_MODE_CHECK == $katao_supplier_invoice->getPaymentMode())?$katao_supplier_invoice->getPaymentDetails():$katao_supplier_invoice->getPaymentModeStr(), $katao_supplier->getName());
            $num_pointage = '';
            $code_analytique_budgetaire = '';
            $libelle_compte = '';

            $total_sol = $katao_supplier_invoice->getPaymentAmountSol() / CONST_EURO_TO_SOL;
            $total_euro = $katao_supplier_invoice->getTotalHT() + $katao_supplier_invoice->getTotalTva();

            $this->addAccountingLine($num_mouvement, 'BQ', $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeBank(), $libelle_ecriture, $total_euro, 'C', $num_pointage, $code_analytique_budgetaire, 'CAISSE D\'EPARGNE');
            if ($total_sol) {
                $this->addAccountingLine($num_mouvement, 'BQ', $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeBankSol(), $libelle_ecriture, $total_sol, 'C', $num_pointage, $code_analytique_budgetaire, 'COMPTE SOL');
            }
            $this->addAccountingLine($num_mouvement, 'BQ', $date_ecriture, $date_echeance, $num_piece, $katao_supplier->getAccountingCode(), $libelle_ecriture, $total_euro, 'D', $num_pointage, $code_analytique_budgetaire, $katao_supplier->getName());
            if ($total_sol) {
                $this->addAccountingLine($num_mouvement, 'BQ', $date_ecriture, $date_echeance, $num_piece, $katao_supplier->getAccountingCodeSol(), $libelle_ecriture, $total_sol, 'D', $num_pointage, $code_analytique_budgetaire, $katao_supplier->getName() . '-' . wpConfig::getAdditionalCurrencyName());
            }
        }

        /* Liste des factures adhérents envoyées de la période */
        $criteria = new Criteria();
        $criterion = $criteria->getNewCriterion(KataoInvoicePeer::CREATED_AT, $export_date_from, Criteria::GREATER_EQUAL);
        $criterion->addAnd($criteria->getNewCriterion(KataoInvoicePeer::CREATED_AT, $export_date_to, Criteria::LESS_EQUAL));
        $criteria->addAnd($criterion);
        $criteria->add(KataoInvoicePeer::STATUS, KataoInvoice::STATUS_SENT);
        $criteria->addAscendingOrderByColumn(KataoInvoicePeer::CREATED_AT);
        foreach (KataoInvoicePeer::doSelectJoinAllExceptKataoCart($criteria) as/*(KataoInvoice)*/ $katao_invoice) {
            $katao_period = $katao_invoice->getKataoPeriod();
            $katao_member = $katao_invoice->getKataoMember();

            $journal = 'VT';
            $num_mouvement = $katao_period->getId() . '1';
            $date_ecriture = $katao_invoice->getCreatedAt('Ymd');
            $date_echeance = $katao_invoice->getCreatedAt('Ymd');
            $num_piece = $katao_invoice->getNumber();
            $libelle_ecriture = sprintf('%s - %s', $katao_period->getName(), $katao_invoice->getKataoNode()->getCity());
            $num_pointage = '';
            $code_analytique_budgetaire = '';
            $libelle_compte = '';

            $total_by_tva_rate = array('0.196' => 0, '0.055' => 0, '0' => 0);

            $total_debit = $katao_invoice->sumProducts();
            $total_debit_sol = $katao_invoice->getSolAmount() / CONST_EURO_TO_SOL;
            $total_debit_euro = $total_debit - $total_debit_sol;

            $total_credit = 0;

            $libelle_compte = $katao_member->getFullName();
            $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $katao_member->getAccountingCode(), $libelle_ecriture, $total_debit_euro, 'D', $num_pointage, $code_analytique_budgetaire, $libelle_compte);
            if ($total_debit_sol) {
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $katao_member->getAccountingCodeSol(), $libelle_ecriture, $total_debit_sol, 'D', $num_pointage, $code_analytique_budgetaire, $libelle_compte . '-' . wpConfig::getAdditionalCurrencyName());
            }
            $libelle_compte = '';

            $amounts_by_accounting_code_and_tva = array();
            $line_by_accounting_code = array();
            foreach ($katao_invoice->getKataoInvoiceProductsJoinKataoProduct() as/*(KataoInvoiceProduct)*/ $katao_invoice_product) {
                $katao_product = $katao_invoice_product->getKataoProduct();

                $famille = $katao_product->getAccountingCodeSell();
                $tva = (string)$katao_invoice_product->getProductTvaRate();

                $amounts_by_accounting_code_and_tva[$famille]['name'] = $katao_product->getKataoProductFamily()->getKataoProductCategory()->getName();
                if (!isset($amounts_by_accounting_code_and_tva[$famille]['values'][$tva]['ttc'])) {
                    $amounts_by_accounting_code_and_tva[$famille]['values'][$tva]['ttc'] = 0;
                }
                $amounts_by_accounting_code_and_tva[$famille]['values'][$tva]['ttc'] += round($katao_invoice_product->getQuantityDelivered() * round($katao_invoice_product->getProductPriceWithTaxes(), 2), 2);

                $amount = $katao_invoice_product->getQuantityDelivered() * $katao_invoice_product->getProductPriceWithoutTaxes();
            }

            $total_by_tva_rate = array();
            foreach ($amounts_by_accounting_code_and_tva as $amount_accounting_code => $amount_accounting_code_tvas) {
                foreach ($amount_accounting_code_tvas['values'] as $amount_tva => $amount_tva_values) {
                    if (!isset($amount_tva_values['ttc'])) {
                        $amount_tva_values['ttc'] = 0;
                        $amounts_by_accounting_code_and_tva[$amount_accounting_code]['values'][$amount_tva]['ttc'] = 0;
                    }
                    $value = round($amount_tva_values['ttc'] / (1 + (float)$amount_tva), 2);
                    $amounts_by_accounting_code_and_tva[$amount_accounting_code]['values'][$amount_tva]['ht'] = $value;

                    if (!isset($total_by_tva_rate[$amount_tva])) {
                        $total_by_tva_rate[$amount_tva] = 0;
                    }
                    $total_by_tva_rate[$amount_tva] += max(0, $amounts_by_accounting_code_and_tva[$amount_accounting_code]['values'][$amount_tva]['ttc'] - $amounts_by_accounting_code_and_tva[$amount_accounting_code]['values'][$amount_tva]['ht']);
                }
            }

            foreach ($amounts_by_accounting_code_and_tva as $amount_accounting_code => $amount_accounting_code_tvas) {
                $amount = 0;
                foreach ($amount_accounting_code_tvas['values'] as $amount_tva => $amount_tva_values) {
                    $amount += $amount_tva_values['ht'];
                }
                $total_credit += round($amount, 2);

                $line_by_accounting_code[$amount_accounting_code]['amount'] = $amount;
                $line_by_accounting_code[$amount_accounting_code]['category'] = sprintf('Vts : %s', $amount_accounting_code_tvas['name']);
            }

            foreach ($line_by_accounting_code as $accounting_code => $data) {
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $accounting_code, $libelle_ecriture, $data['amount'], 'C', $num_pointage, $code_analytique_budgetaire, $data['category']);
            }

            if (!empty($total_by_tva_rate['0.196'])) {
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, '445714', $libelle_ecriture, $total_by_tva_rate['0.196'], 'C', $num_pointage, $code_analytique_budgetaire, 'TVA 19.6%');
                $total_credit += round($total_by_tva_rate['0.196'], 2);
            }
            if (!empty($total_by_tva_rate['0.055'])) {
                $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, '445712', $libelle_ecriture, $total_by_tva_rate['0.055'], 'C', $num_pointage, $code_analytique_budgetaire, 'TVA 5.5%');
                $total_credit += round($total_by_tva_rate['0.055'], 2);
            }

            if (round(abs($total_debit - $total_credit), 2)) {
                if ($total_debit > $total_credit) {
                    $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeErrorAdjustmentPositive(), $libelle_ecriture, $total_debit - $total_credit, 'C', $num_pointage, $code_analytique_budgetaire, 'Ecart de conversion');
                } elseif ($total_debit < $total_credit) {
                    $this->addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, wpConfig::getAccountingCodeErrorAdjustmentNegative(), $libelle_ecriture, $total_credit - $total_debit, 'D', $num_pointage, $code_analytique_budgetaire, 'Ecart de conversion');
                }
            }
        }

        $content = implode("\n", $this->accounting_lines);

        $response = $this->getResponse();
        $response->setContentType('application/octet-stream');
        $response->setHttpHeader('Content-disposition', 'attachment; filename="XIMPORT.TXT"');
        $response->setHttpHeader('Content-Length', strlen($content));
        $response->setHttpHeader('Pragma', 'public');
        $response->setHttpHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
        $response->setHttpHeader('Expires', '0');
        $response->setContent($content);
        return sfView::NONE;
    }

    protected $accounting_lines = array();
    protected function addAccountingLine($num_mouvement, $journal, $date_ecriture, $date_echeance, $num_piece, $num_compte, $libelle_ecriture, $montant, $sens_operation, $num_pointage, $code_analytique_budgetaire, $libelle_compte) {
        $libelle_ecriture = Utils::removeAccents(utf8_decode($libelle_ecriture));
        $libelle_compte = Utils::removeAccents(utf8_decode($libelle_compte));

        $this->accounting_lines[] = sprintf('%s%s%s%s%s%s%s%s%s%s%s%s02003', Utils::completeWithSpaces($num_mouvement, 5, true), $journal,
            $date_ecriture, $date_echeance,
            Utils::completeWithSpaces($num_piece, 12), Utils::completeWithSpaces($num_compte, 11),
            Utils::completeWithSpaces($libelle_ecriture, 25), Utils::completeWithSpaces(sprintf('%0.2f', $montant), 13, true), $sens_operation,
            Utils::completeWithSpaces($num_pointage, 12), Utils::completeWithSpaces('', 6),
            Utils::completeWithSpaces($libelle_compte, 34));
    }

    public function executeCopy($request) {
        $this->redirectWithErrorUnless($katao_period = KataoPeriodPeer::retrieveByPk($request->getParameter('id')), 'Période #' . $request->getParameter('id') . ' inconnue.');

        if ($katao_period_id = $katao_period->makePeriodCopy()) {
            wpFlashMessages::addConfirmation('Période "' . $katao_period->getName() . '" copiée avec succès.');
            $this->redirect('kataoPeriod/edit?id=' . $katao_period_id);
        }

        wpFlashMessages::addError('Impossible de copier la période "' . $katao_period->getName() . '".');
        $this->redirect('kataoPeriod/index');
    }
}