<?php

use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\Attributes\DataProvider;
/**
 * Generated by PHPUnit_SkeletonGenerator on 2014-11-07 at 23:05:36.
 * @backupGlobals enabled
 */
require DIRTEST.'/global.php';

class FicheTest extends TestCase
{

    /**
     * @var Fiche
     */
    protected $object;
    private $g_connection;
   

    /**
     * Sets up the fixture, for example, opens a network connection.
     * This method is called before a test is executed.
     */
    protected function setUp():void
    {
        $g_connection=Dossier::connect();
        $this->object = new Fiche($g_connection);
        $this->g_connection=$g_connection;
        $this->g_connection->exec_sql("delete from tmp_pcmn where  id > 1194");
        $this->g_connection->exec_sql("delete from fiche_detail where f_id > 47  ");
        $this->g_connection->exec_sql("delete from fiche where f_id > 47  ");
        $this->g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('N','MY_ALPHANUM'));
    }

    /**
     * Tears down the fixture, for example, closes a network connection.
     * This method is called after a test is executed.
     */
    protected function tearDown():void
    {

    }

    static function tearDownAfterClass():void
    {
        $g_connection=Dossier::connect();
          $fiche_def = new Fiche_Def($g_connection, 5);
        // prepare test , clean 
        $fiche_def->RemoveAttribut([20, 21, 22, 51, 52, 53]);
        $g_connection->exec_sql("delete from tmp_pcmn  where  id > 1194");
        $g_connection->exec_sql("delete from fiche_detail where f_id > 47  ");
        $g_connection->exec_sql("delete from fiche where f_id > 47  ");
        $g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('N','MY_ALPHANUM'));
    }

    /**
     * @covers Fiche::cmp_name
     */
    public function testCmp_name()
    {

        $fiche = new \Fiche($this->g_connection, 21);
        $fiche_2 = new \Fiche($this->g_connection, 25);
        $this->assertGreaterThan(\Fiche::cmp_name($fiche, $fiche_2), 0);
    }

    /**
     * @covers Fiche::get_bk_account
     * @backupGlobals enabled
     */
    public function testGet_bk_account()
    {
        require DIRTEST.'/global.php';
        $result = $this->object->get_bk_account();
        $this->assertEquals(gettype($result), 'array');
        $count = count($result);
        $this->assertEquals(3, $count,'number of FIN ledgers');
    }

    /**
     * @covers Fiche::get_row
     */
    public function testGet_row()
    {

        $card_count = $this->g_connection->get_array("select count(*),f_id " .
            " from jrnx " .
            " where " .
            " f_id is not null " .
            "group by f_id order by count(*) desc");
        $a = new Fiche($this->g_connection, $card_count[0]['f_id']);
        try {
            $a->get_row(235, 238);
            $this->assertFalse(TRUE, "Exception periode invalide");
        } catch (\Exception $e) {
            $this->assertTrue(TRUE);
        }
        $a_result = $a->get_row(92, 131);
        // Size == 25

        $nb_result = count($a_result);
        $this->assertEquals($nb_result, 3, "Size array not correct ");
        $this->assertEquals(198.74, $a_result[0][13]["deb_montant"], "Debit from operation 12");
    }

    /**
     * @covers Fiche::count_by_modele()
     */
    public function testCount_by_modele()
    {

        $nb = $this->object->count_by_modele(1, "", "");
        $this->assertEquals(4, $nb, "number of Sales Card ");
        $nb = $this->object->count_by_modele(3, "eau", "");
        $this->assertEquals(1, $nb, "Purchase card water ");
        $nb = $this->object->count_by_modele(3, "EAU", "");
        $this->assertEquals(1, $nb, "Purchase card water ");
        $nb = $this->object->count_by_modele(3, "ZZ", "");
        $this->assertEquals(0, $nb, "no  card  found");
        $nb = $this->object->count_by_modele(3000, "", "");
        $this->assertEquals(0, $nb, "no  card found");
        $nb = $this->object->count_by_modele(3, "", "");
        $this->assertEquals(7, $nb, "Purchase cards ");
        // attempt to inject SQL command, you must get an error
        try {
            $nb = @$this->object->count_by_modele(3, "", " ;delete from jrn;");
            $this->assertFalse(true, "Inject SQL command not found");
        } catch (Exception $e) {
            $this->assertTrue(true, "Inject SQL command found");
        }
    }

    /**
     * @covers Fiche::Summary
     * @covers Fiche::get_by_category
     * @covers Fiche::GetByDef
     */
    public function testSummary()
    {
        require DIRTEST.'/global.php';
        $_REQUEST['ac'] = "CARD";
        $this->object->fiche_def_ref = -1;
        $r = $this->object->summary();
        $this->assertEquals('', $r);
        $this->object->fiche_def_ref = 9;
        $r = $this->object->summary();
        $this->assertStringContainsString('</TABLE>', $r);
    }

    /**
     *
     *
     */
    function testFicheDefInsertAttribut()
    {

        $fiche_def = new Fiche_Def($this->g_connection, 5);
        // prepare test , clean 
        $fiche_def->RemoveAttribut([20, 21, 22, 51, 52, 53]);
        $this->assertEquals(35,
            $this->g_connection->get_value("select count(*) from fiche_detail join fiche using (f_id)
                where fd_id=5"), "Efface 6 attributs");

        // percent deductible
        $fiche_def->InsertAttribut(20);
        $fiche_def->InsertAttribut(21);
        $fiche_def->InsertAttribut(22);

        // accouting for not deductible
        $fiche_def->InsertAttribut(51);
        $fiche_def->InsertAttribut(52);
        $fiche_def->InsertAttribut(53);

        // check that all card has these attributes
        $this->assertEquals(77,
            $this->g_connection->get_value("select count(*) from fiche_detail join fiche using (f_id)
                where fd_id=5"), "Ajout 6 attributs");
    }

    /**
     * @covers  Fiche_Def::RemoveAttribut
     * @depends testFicheDefInsertAttribut
     */
    function testFicheDefRemoveAttribut()
    {
        $fiche_def = new Fiche_Def($this->g_connection, 5);

        // prepare test , clean 
        $fiche_def->RemoveAttribut([20, 21, 22, 51, 52, 53]);

        $this->assertEquals(35,
            $this->g_connection->get_value("select count(*) from fiche_detail join fiche using (f_id)
                where fd_id=5"), "Efface 6 attributs");
    }

    /**
     * @testdox update attribute , remove them , Fiche->update and Card_Property::update
     *
     */
    public function testUpdateAttribut()
    {
        $this->testFicheDefRemoveAttribut();
        $this->testFicheDefInsertAttribut();

        // modify attribute for card category , add VAT non ded, Tax non ded , VAT completely non ded 0%
        // category Misc Services & goods (5)
        //-- modify card 29 : ELECTR
        $fiche = new Fiche($this->g_connection, 29);
        $fiche->set_f_enable("1");
        $fiche->set_attribute(20, "33.33");
        $a_attribut = $fiche->to_array();
        $this->assertEquals($a_attribut['av_text20'], 33.33, "Attribut 20 set to 33%");

        $fiche->update($a_attribut);

        $this->assertEquals("33.33",
            $this->g_connection->get_value("select ad_value from fiche_detail where f_id=$1 and ad_id=$2", [29, 20]),
            "Attribut ad_id 20 inserted");

        $this->assertEquals("33.33", $fiche->get_attribute(20), "retrieve attribute 20");
        $fiche->set_attribute(20, "0.05");
        Card_Property::update($fiche);
        $this->assertEquals("0.05",
            $this->g_connection->get_value("select ad_value from fiche_detail where f_id=$1 and ad_id=$2", [29, 20]),
            "Attribut ad_id 20 updated");
    }

    function testInexistantCard()
    {

        $last_card = $this->g_connection->get_next_seq('s_fiche');
        $last_card = $this->g_connection->get_next_seq('s_fiche');
        $inexistant_fiche = new Fiche($this->g_connection, $last_card + 2000);
        $_POST['av_text1'] = 'not exist';
        try {
            $inexistant_fiche->update();
            $this->assertTrue(false, 'Inexistant card not detected');
        } catch (Exception $e) {
            $this->assertTrue(true, "Inexistant card properly detected");
        }
    }

    /**
     * @covers Fiche::get_by_qcode
     */
    public function testQueryAttribute()
    {
        $fiche_goods = new Fiche($this->g_connection);
        $fiche_goods->get_by_qcode("MARCHA");
        $this->assertEquals($fiche_goods->id, 23, "retrieve card by qcode");
        $this->assertEquals($fiche_goods->get_attribute(ATTR_DEF_NAME), "Marchandise1", "Retrieve name");
        $this->assertEquals($fiche_goods->getName(), "Marchandise1", "Retrieve name from db");
        $fiche_2 = new Fiche($this->g_connection);
        $fiche_2->get_by_qcode("marcha ");
        $this->assertEquals($fiche_2->id, 23, "retrieve card by qcode");
        $this->assertEquals($fiche_2->get_attribute(ATTR_DEF_NAME), "Marchandise1", "Retrieve name");
        $this->assertEquals($fiche_2->getName(), "Marchandise1", "Retrieve name from db");
    }

    /**
     * @covers Fiche::insert
     */
    public function testInsertAndRemoveCard()
    {
        $last_card = $this->g_connection->get_next_seq('s_fiche');
        $nb_fiche = $this->g_connection->get_value("select count(*) from fiche");
        $new_fiche = new Fiche($this->g_connection);
        $aProperty = array('av_text1' => 'Nom', 'av_text23' => 'ZZZTEST');
        $new_fiche->insert(5, $aProperty);
        $this->assertFalse(empty($new_fiche->attribut), " attributes array is empty");

        $this->assertGreaterThan($last_card, $new_fiche->id, 'card created');
        $nb_fiche_after = $this->g_connection->get_value("select count(*) from fiche");
        $this->assertGreaterThan($nb_fiche, $nb_fiche_after, 'card created');
        $this->assertEquals("1", $new_fiche->get_f_enable(), "By default enable");
        $new_fiche->remove();
        $nb_fiche_after = $this->g_connection->get_value("select count(*) from fiche");
        $this->assertEquals($nb_fiche, $nb_fiche_after, 'card removed');
    }

    /**
     * @testdox fiche->display
     */
    public function testDisplay()
    {
        $last_card = $this->g_connection->get_next_seq('s_fiche');
        $nb_fiche = $this->g_connection->get_value("select count(*) from fiche");

        $new_fiche = new Fiche($this->g_connection);
        $aProperty = array('av_text1' => 'Nom', 'av_text23' => 'ZZZTEST2');
        $new_fiche->insert(5, $aProperty);

        $this->assertFalse(empty($new_fiche->attribut), " attributes array is empty");
        $this->assertGreaterThan($last_card, $new_fiche->id, 'card  not created');
        $result = $new_fiche->display(true);

        \Noalyss\Facility::save_file(__DIR__ . '/file', 'testDisplay.txt', $result);
        $this->assertNotEquals('FNT', $result, 'card not found ' . print_r($new_fiche, true));

        $new_fiche->remove();

        $nb_fiche_after = $this->g_connection->get_value("select count(*) from fiche");
        $this->assertEquals($nb_fiche, $nb_fiche_after, 'card not removed');
    }

    public static function dataEmptyQuickCode()
    {
        return array(
            array("none", ""),
            array("", ""),
            array(",,,,", ""),
            array("####", ""),
            array("àz-5","AZ-5"),
            array("àz-5&é","AZ-5E"),
            array("é####àz-5","EAZ-5"),
        );
    }

    /**
     * @testdox testInsertEmptyQuickCode Test if it is possible to insert an  empty quickcode
     * @dataProvider dataEmptyQuickCode
     */
     #[DataProvider('dataEmptyQuickCode')]
    public function testInsertEmptyQuickCode($name, $quick_code)
    {
        //insert
        $fiche = new Fiche($this->g_connection);
        $fiche->insert(2, ['av_text13' => $quick_code, "av_text1" => $name]);
        $fiche->load();
        $this->assertTrue($fiche->id > 0 && !empty(trim($fiche->get_attribute(23))), 'error : card created with empty quickcode');
        $fiche->remove();

    }
    static function dataUpdateQuickCode()
    {
        return array(
            array('a+z+1-5', 'AZ1-5'),
            array('///a+z+1-5', 'AZ1-5'),
            array('/*/a+z+1-5', 'AZ1-5'),
            array('.2a+z+1-5', '.2AZ1-5'),
            array('a+z+1-5', 'AZ1-5'),
            array('ÀÉ@Ê', 'AE@E'),
            array('ça&"', 'CA'),
            array("", "QC"),
            array(",,,,", "QC"),
            array("####", "QC")
        );
    }

    /**
     * @testdox testUpdateEmptyQuickCode Test if it is possible to update an empty quickcode
     * @dataProvider dataUpdateQuickCode
     */
     #[DataProvider('dataUpdateQuickCode')]
    public function testUpdateEmptyQuickCode($name, $quick_code)
    {
        $aCardId=[];
        //insert
        $fiche = new Fiche($this->g_connection);
        $fiche->insert(2, ['av_text23' => 'QC', "av_text1" => $name]);
        $this->assertTrue($fiche->id > 0 && !empty($fiche->get_attribute(23)), 'error : card created with empty quickcode');
        $aCardId[]=$fiche->get_id();

        // add attributes of type card , and for another card, set it to this quickcode
        $fiche_def_id=$this->g_connection->get_value("select fd_id from fiche where f_id=$1 ",[$fiche->id]);
        $fiche_def=new Fiche_Def($this->g_connection,$fiche_def_id);
        $aAttribute=$this->g_connection->get_array("
select ad_id from attr_def a1
where 
      a1.ad_id not 
            in (select j1.ad_id from jnt_fic_attr j1 where j1.fd_id=$1)
    and a1.ad_type = $2",[$fiche_def_id,'card']);
        foreach ($aAttribute as $nAttribute) {
            $fiche_def->insertAttribut($nAttribute['ad_id']);
        }
        // related cards
        $fiche_related1=new Fiche($this->g_connection);
        $aAttributeRelated=array(
            "av_text23"=>"FR1",
            'av_text1'=>'Fiche reliée'
        );
        foreach ($aAttribute as $nAttribute) {
            $aAttributeRelated['av_text'.$nAttribute['ad_id']]='QC';
        }
        $fiche_related1->insert(2,$aAttributeRelated);
        $aAttributeRelated['av_text1']='Fiche reliée 2';
        $aAttributeRelated['av_text23']='FR2';
        $fiche_related2=new Fiche($this->g_connection);
        $fiche_related2->insert(2,$aAttributeRelated);
        $aCardId[]=$fiche_related1->get_id();
        $aCardId[]=$fiche_related2->get_id();

        // ----
        // check that related cards are properly created
        // ----
        $fiche_related1->load();
        $fiche_related2->load();
        $this->assertTrue($fiche_related1->id > 0 &&  !empty($fiche_related1->get_attribute(23)),'error related card 
        not created properly');
        $this->assertTrue($fiche_related2->id > 0 &&  !empty($fiche_related2->get_attribute(23)),'error related card 
        not created properly');
        // ----
        // check card attribute
        // ----
        foreach ($aAttribute as $nAttribute) {
            $this->assertEquals('QC',$fiche_related1->get_attribute($nAttribute['ad_id']),'Attribute QC is not set');
            $this->assertEquals('QC',$fiche_related2->get_attribute($nAttribute['ad_id']),'Attribute QC is not set');
        }

        $fiche->set_attribute(23, $name);


        $fiche->update($fiche->to_array());
        $compare = new Fiche($this->g_connection, $fiche->id);
        $this->assertEquals($quick_code, $compare->get_quick_code(), 'Error : quickcode not correct');

        // check that the other attributes of type card have been updated
        foreach ($aAttribute as $nAttribute) {
            $this->assertEquals($fiche->get_quick_code(),$fiche_related1->get_attribute($nAttribute['ad_id']),'Attribute QC is not set');
            $this->assertEquals($fiche->get_quick_code(),$fiche_related2->get_attribute($nAttribute['ad_id']),'Attribute QC is not set');
        }

        if ($fiche->is_used()) {
            $this->assertEquals($fiche->remove(),1,"Cannot remove {$fiche->id}");
            $aCardId[]=$fiche->get_id();
        } else {
            $this->assertEquals($fiche->remove(),0,"Cannot remove {$fiche->id}");
        }
        $this->assertEquals($fiche_related1->remove(),0,"Cannot remove {$fiche_related1->id}");
        $this->assertEquals($fiche_related2->remove(),0,"Cannot remove {$fiche_related2->id}");
        foreach ($aAttribute as $nAttribute) {
            $fiche_def->removeAttribut($nAttribute['ad_id']);
        }
    }

    static function dataFormat_QuickCode()
    {
        return array(
            array('a+z+1-5','AZ1-5'),
            array('///a+z+1-5','AZ1-5'),
            array('/*/a+z+1-5','AZ1-5'),
            array('.2a+z+1-5','.2AZ1-5'),
            array('a+z+1-5','AZ1-5'),
            array('ÀÉ@Ê','AE@E'),
            array('ça&"','CA'),
              array("", ""),
            array(",,,,", ""),
            array("####", ""),
        );
    }
    /**
     * @testdox test comptaproc.format_quickcode
     * @dataProvider dataFormat_Quickcode
     */
     #[DataProvider('dataFormat_Quickcode')]
    public function testFormat_QuickCode($p_qcode,$p_result)
    {
        $this->assertEquals($p_result,$this->g_connection->get_value( "select comptaproc.format_quickcode($1)",
        [$p_result]),'quickcode is not transformed correctly');
    }
    static function dataInsertName()
    {
        return array(
            ['',"Nom vide"],
            ['Eléphant','Eléphant'],
            ["L'alphabet","L'alphabet"]
        );
    }
    /**
     * @testdox Test if it is possible to insert an empty  name
     * @dataProvider dataInsertName
     */
     #[DataProvider('dataInsertName')]
    public function testInsertName($p_name,$p_result)
    {

        //insert
        $fiche = new Fiche($this->g_connection);
        $fiche->insert(2, ['av_text23' => 'QC', "av_text1" => $p_name]);
        $fiche->load();
        $this->assertEquals($p_result,$fiche->get_attribute(ATTR_DEF_NAME),'incorrect name');
        $fiche->remove();

    }
    /**
     * @testdox Test if it is possible to insert or update a empty  name
     * @dataProvider dataInsertName
     */
     #[DataProvider('dataInsertName')]
    public function testUpdateName($p_name,$p_result)
    {

        //insert
        $fiche = new Fiche($this->g_connection);
        $fiche->insert(2, ['av_text23' => 'QC', "av_text1" => $p_name]);
        $fiche->load();
        $this->assertEquals($p_result,$fiche->get_attribute(ATTR_DEF_NAME),'incorrect name');
        $fiche->remove();
    }
    /**
     * @testdox testQuickCodeNumbering quickcode is generated with number if duplicate
     */
    public function testQuickCodeNumbering()
    {
        $fiche=new Fiche($this->g_connection);
        $fiche->insert(2,array("av_text1"=>'Card for PHPUNIT','av_text23'=>'DUP'));
        $this->assertTrue($fiche->id > 0 && 'DUP'==$fiche->get_attribute(23),
            'error : card created with wrong quickcode'.$fiche->get_attribute(23));
        for ($i=0;$i<100;$i++) {
            $fiche_duplicate = new Fiche($this->g_connection);
            $fiche_duplicate->insert(2, array("av_text1" => 'Base Card' . $i, 'av_text23' => 'DUP'));
            
            $this->assertTrue($fiche_duplicate->id > $fiche->id && 'DUP' . $i == $fiche_duplicate->get_attribute(23),
                " error : card created with  quickcode {$fiche_duplicate->get_attribute(23)} expected DUP{$i}");
         
        }
        $a_fiche_clean=$this->g_connection->get_array("select f_id from fiche where f_id >= $1",
                    [$fiche->id]);
        foreach($a_fiche_clean as $fiche_clean) {
            $fiche=new Fiche($this->g_connection,$fiche_clean['f_id']);
            $fiche->remove();
            $this->assertEquals(0,
                $this->g_connection->get_value("select count(*) from fiche where f_id=$1",
                    array($fiche_clean['f_id']))
                ,"Card not removed");
        }
    }
    /**
     * @brief Create a card
     * @param type $p_qcode
     * @returns \Fiche
     */
    public function build_fiche($p_category,$p_qcode)
    {
                // insert a card in category 2 with automatic set 
        $fiche=new Fiche($this->g_connection);
        if ( $fiche->get_by_qcode($p_qcode) == 0 ) 
        {
            $fiche->remove();
        }
        $fiche->insert($p_category,array("av_text1"=>'Card for PHPUNIT','av_text23'=>$p_qcode));
        $this->assertTrue($fiche->id > 0 && $p_qcode==$fiche->get_attribute(23),
            'error : card created with wrong quickcode'.$fiche->get_attribute(23));
        return $fiche;
    }
    /**
     * @testdox testAutomaticAccountingUpdate test accounting automatic compute(update)
     */
    public function testAutomaticAccountingUpdate()
    {
        $this->g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('N','MY_ALPHANUM'));
        $fiche_def=new Fiche_Def($this->g_connection,2);
        $fiche_def->set_autocreate(true);
        $fiche_def->save_class_base('600');
        $fiche=$this->build_fiche(2,'TESTACCOUNT');
        // $start=$fiche->id;
        $this->assertEquals('6000001',$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');
        for ( $i=6000002; $i < 6000999;$i++) {
           $fiche->set_attribute(ATTR_DEF_ACCOUNT, "");
           Card_Property::update($fiche);
           $fiche->load();

           $this->assertEquals($i,$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');

        }

    }
    /**
     * @testdox testAutomaticAccountingUpdate test accounting automatic compute(update)
     */
    public function testAutomaticAccounting620Update()
    {
        $this->g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('N','MY_ALPHANUM'));
        $fiche_def=new Fiche_Def($this->g_connection,2);
        $fiche_def->set_autocreate(true);
        $fiche_def->save_class_base('620');
        $fiche=$this->build_fiche(2,'TESTACCOUNT');
        // $start=$fiche->id;
        $this->assertEquals('6200001',$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');
        for ( $i=6200002; $i < 6200999;$i++) {
           $fiche->set_attribute(ATTR_DEF_ACCOUNT, "");
           Card_Property::update($fiche);
           $fiche->load();

           $this->assertEquals($i,$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');

        }

    }
    /**
     * @testdox testAutomaticAccountingInsert test accounting automatic compute (insert)
     */
    public function testAutomaticAccountingInsert()
    {
        $this->g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('N','MY_ALPHANUM'));
        $fiche_def=new Fiche_Def($this->g_connection,2);
        $fiche_def->set_autocreate(true);
        $fiche_def->save_class_base('600');
        $first=true;
        for ( $i=6000001; $i <  6000999;$i++) {
            $fiche=new Fiche($this->g_connection);
            $fiche->insert(2,['av_text1'=>'PHPUNIT '.__FUNCTION__]);
            if ( $first ) { 
                $first=false;
            }
           $fiche->load();
           $this->assertEquals($i,$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');
        }
    }
    public static function dataAccount()
    {
        return array(
            ['600002','600002'],
            ['600100','600100'],
            ['6500','6500']
        );
    }
    /**
     * @brief test insert of the accounting
     * @testdox testAccountInsert Set  of the accounting while inserting, numeric with automatic
     * @dataProvider dataAccount
     */
     #[DataProvider('dataAccount')]
    public function testAccountInsert($p_value,$p_expected)
    {
      $fiche=$this->build_fiche(2, 'PHPUNIT.ACCOUNT.INSERT');
        $fiche->set_attribute(ATTR_DEF_ACCOUNT, $p_value);
        Card_Property::update($fiche);
        $this->assertEquals($p_expected,$fiche->get_attribute(ATTR_DEF_ACCOUNT)," cannot SET accounting");
        $this->assertTrue($this->g_connection->get_value("select count(*) from tmp_pcmn where pcm_val = $1",[$p_expected])==1
                ," accounting not created in TMP_PCMN");
        $this->g_connection->exec_sql("delete from tmp_pcmn where pcm_val=$1",[$p_expected]);
        $fiche->remove();
    }

    /**
     * @testdox testAutomaticAccountingUpdateAlpha test accounting automatic compute(update) with alphanumeric enable
     */
    public function testAlphaAutomaticAccountingUpdate()
    {
     
        $this->g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('Y','MY_ALPHANUM'));
        $fiche_def=new Fiche_Def($this->g_connection,2);
        $fiche_def->set_autocreate(true);
        $fiche_def->save_class_base('600');
        $fiche=$this->build_fiche(2,'TESTACCOUNT');
        $fiche->set_attribute(ATTR_DEF_ACCOUNT, "");
        Card_Property::update($fiche);
        $fiche->load();
        $this->assertEquals('600CARDF1',$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');

        for ( $i=600002; $i < 600099;$i++) {
            $fiche->set_attribute(ATTR_DEF_NAME,'Card for testing '.$i);
            $fiche->set_attribute(ATTR_DEF_ACCOUNT, "");
            Card_Property::update($fiche);
            $fiche->load();

            $idx=$i-600000;
            $this->assertEquals("600CARDF".$idx,$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');


        }

	}
    /**
     * @testdox testAutomaticAccountingInsertAlpha test accounting automatic compute (insert) with alphanumeric enable
     */
    public function testAlphaAutomaticAccountingInsert()
    {

        $this->g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('Y','MY_ALPHANUM'));
        $fiche_def=new Fiche_Def($this->g_connection,2);
        $fiche_def->set_autocreate(true);
        $fiche_def->save_class_base('600');
        $first=true;

        for ( $i=1; $i <  100;$i++) {
            $fiche=new Fiche($this->g_connection);
            $fiche->insert(2,['av_text1'=>substr($i.' PHPUNIT '.__FUNCTION__,0,35)],);

            $fiche->load();
            $expected="600".substr($i."PHPU",0,5);
            $this->assertEquals($expected,$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');

        }

     }
     /**
     * @brief test update of the accounting
     * @testdox testAccountUpdate et  of the accounting while updating
     * @dataProvider dataAccount
     */
      #[DataProvider('dataAccount')]
    public function testAccountUpdate($p_value,$p_expected)
    {
        $this->g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('N','MY_ALPHANUM'));
        $fiche=$this->build_fiche(2, 'PHPUNIT.ACCOUNT.UPDATE');
        $fiche->set_attribute(ATTR_DEF_ACCOUNT, $p_value);
        $fiche->update($fiche->to_array());
        $this->assertEquals($p_expected,$fiche->get_attribute(ATTR_DEF_ACCOUNT)," cannot SET accounting");
        $this->assertTrue($this->g_connection->get_value("select count(*) from tmp_pcmn where pcm_val = $1",[$p_expected])==1
                ," accounting not created in TMP_PCMN");
        $this->g_connection->exec_sql("delete from tmp_pcmn where pcm_val=$1",[$p_expected]);
        $fiche->remove();
    }
    /**
     * @testdox testSameAccountingUpdate UPDATE test all the same accounting 
     */
    public function testSameAccountingUpdate()
    {
        $this->g_connection->exec_sql("update public.parameter set pr_value = $1 where pr_id=$2",
            array('N','MY_ALPHANUM'));
        // insert a card in category 2 with always the same account
        $fiche_def=new Fiche_Def($this->g_connection,2);
        $fiche_def->set_autocreate(false);
        $fiche_def->save_class_base('600');
        $fiche=$this->build_fiche(2,'TESTACCOUNT');
        $this->assertEquals('600',$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');
        for ( $i=600003; $i < 600025;$i++) {
            $fiche->set_attribute(ATTR_DEF_ACCOUNT, "");
           Card_Property::update($fiche);
           $fiche->load();
            $this->assertEquals(600,$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');
            
        }
        $fiche->remove();
    }
     /**
     * @testdox testSameAccountingInsert INSERT test all the same accounting 
     */
    public function testSameAccountingInsert()
    {
        // insert a card in category 2 with always the same account
        $fiche_def=new Fiche_Def($this->g_connection,2);
        $fiche_def->set_autocreate(false);
        $fiche_def->save_class_base('600');
        
        for ( $i=600002; $i < 600025;$i++) {
            $fiche=new Fiche($this->g_connection);
            $fiche->insert(2,['av_text1'=>'PHPUNIT test Same accounting','av_text5'=>""]);
            $fiche->load();
            $this->assertEquals(600,$fiche->get_attribute(ATTR_DEF_ACCOUNT),'Account not properly created');
            $fiche->remove();
        }
        
    }
    /**
     * @testdox testUpdateEnable card enable and disable
     */
    public function testUpdateEnable()
    {
        $fiche= $fiche=$this->build_fiche(2,'PHPUNIT-ENABLE');
        $fiche->update($fiche->to_array());
        $this->assertEquals(1,$this->g_connection->get_value("select f_enable from fiche where f_id=$1",[$fiche->id])," Fiche::update card is not enabled" );
        $fiche->set_f_enable(0);
        $fiche->update($fiche->to_array());
        $this->assertEquals(0,$this->g_connection->get_value("select f_enable from fiche where f_id=$1",[$fiche->id])," Fiche::update  card is not disabled" );
        $fiche->set_f_enable(1);
        Card_Property::update($fiche);
        $this->assertEquals(1,$this->g_connection->get_value("select f_enable from fiche where f_id=$1",[$fiche->id]),"Card_Property:update card is not enabled" );
        $fiche->set_f_enable(0);
        Card_Property::update($fiche);
        $this->assertEquals(0,$this->g_connection->get_value("select f_enable from fiche where f_id=$1",[$fiche->id]),"Card_Property:update card is not disabled" );
        $fiche->remove();
           
    }
    /**
     * @testdox test the formating of quick-code : upper-case and some charater removed
     */
    public function testQuickCodeFormat()
    {
        // create a new card
        $fiche=new Fiche($this->g_connection);
        $fiche->set_fiche_def(5);
        Card_Property::load($fiche);
        $fiche->set_attribute(1, "Inserted by PHPUNIT");
        $fiche->set_attribute(23, " a a a a");
        $fiche->insert("5", $fiche->to_array());
        $this->assertGreaterThan (0,$fiche->id, "Card no created");
        $fiche_target=new Fiche($this->g_connection,$fiche->id);
        $this->assertTrue("AAAA"==$fiche_target->get_attribute(23),"Insert Quick code format not correct");
        $fiche_target->set_attribute(ATTR_DEF_QUICKCODE, " a a a a a a ");
        $fiche_target->update($fiche_target->to_array());
        
        // reload the card !!
        $fiche_target->load();
        
        $this->assertTrue("AAAAAA"==$fiche_target->get_attribute(23),"Update Quick code format not correct");
        
        $fiche->delete();
    }

    /**
     * @brief  test if it is possible to generate an accounting if there is a mix of alpha numeric and numeric
     * @testdox  test if it is possible to generate an accounting if there is a mix of alpha numeric and numeric
     * accounting
     * @return void
     */
    public function testMixedAlphaAccounting()
    {


        // set category : enable automatic compute + base = 600
        $fiche_def=new Fiche_Def($this->g_connection,2);
        $fiche_def->set_autocreate(true);
        $fiche_def->save_class_base('600');

        // insert a accounting 600TESTALPHA
        $this->g_connection->exec_sql("insert into tmp_pcmn (pcm_val,pcm_lib,pcm_val_parent,pcm_type,pcm_direct_use) 
                                          values('600TESTALPHA','Test Alpha','600','CHA','Y')");


        $fiche=$this->build_fiche(2,'TESTACCOUNT');

        // Try to generate an account
        $fiche->set_attribute(ATTR_DEF_ACCOUNT, null);
        $fiche->load();

        Card_Property::update($fiche);
        $fiche_updated=new Fiche($this->g_connection,$fiche->id);
        $fiche_updated->load();
        $this->assertEquals('6000001',$fiche_updated->get_attribute(ATTR_DEF_ACCOUNT),'account not computed properly');
        $this->g_connection->exec_sql('delete from tmp_pcmn where pcm_val=$1',['600TESTALPHA']);
      
    }

    /**
     * @testdox test Fiche::get_fiche_def
     * @covers Fiche::get_fiche_def
     * @return void
     */
    public function testGetFicheDef()
    {
        $res=Fiche::get_fiche_def($this->g_connection, 5);
        $this->assertEquals(7,count($res),"number of all cards incorrect ");
        $this->g_connection->exec_sql ('update fiche set f_enable=$1 where f_id = $2 or f_id=$3',[0,34,35]);
        $res=Fiche::get_fiche_def($this->g_connection, 5);
        $this->assertEquals(7,count($res),"number of all cards incorrect ");
        $res=Fiche::get_fiche_def($this->g_connection, 5,inactive:0);
        $this->assertEquals(5,count($res),"number of all cards incorrect ");


        $this->g_connection->exec_sql ('update fiche set f_enable=$1 where f_id = $2 or f_id=$3',[1,34,35]);
    }
    

}
