<?php

/*
 *  This file is part of open3A.

 *  open3A is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 3 of the License, or
 *  (at your option) any later version.

 *  open3A is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.

 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  2007 - 2020, open3A GmbH - Support@open3A.de

 *   JahrMonat2Nummer.class.php by www.hc-media.org / office@hc-media.org
 */

class BelegnummernEditor2 extends Auftrag implements iReNr {

	function getLabel() {
		return "Belegnummerneditor Mandanten";
	}

	public static function rewind(GRLBM $GRLBM, Auftrag $Auftrag, Stammdaten $Stammdaten){
		$type = $GRLBM->getMyPrefix();
		
		$next = mUserdata::getGlobalSettingValue("belegNummerNext$type".$Stammdaten->getID(), 1);
		if($next == 1)
			return;
		
		$current = $GRLBM->A("nummer");
		
		$nummer = self::replace($Stammdaten, $next - 1, false, $Auftrag);

		if($current != $nummer)
			return;
		
		mUserdata::setUserdataS("belegNummerNext$type".$Stammdaten->getID(), --$next, "belegNummer".$Stammdaten->getID(), -1);
	}
	
	private static function exists($type, $nummer, $StammdatenID){
		$is = array("R", "L", "G", "B", "M", "A");
		
		$AC = anyC::get("GRLBM", "TRIM(nummer)", $nummer);
		$AC->addJoinV3("Auftrag", "AuftragID", "=", "AuftragID");
		$AC->addAssocV3("AuftragStammdatenID", "=", $StammdatenID);
		
		if(in_array($type, $is)){
			$AC->addAssocV3("is$type", "=", "1", "AND", "2");
			
			if($type == "A" AND !in_array("B", Auftrag::getBelegArten()))
				$AC->addAssocV3("isB", "=", "1", "OR", "2");
		} else
			$AC->addAssocV3 ("isWhat", "=", $type);

		$F = $AC->n();
		#print_r($F->A("nummer").";".$F->getID()."\n");
		return $F !== null;
	}
	
	private static $counter = 0;
	public static function getNextNumber($type, Auftrag $Auftrag = null) {
		do {
			if(self::$counter > 200)
				break;
			
			$nummer = self::getNext($type, $Auftrag);
			self::$counter++;
		} while($nummer !== null AND self::exists($type, $nummer, $Auftrag->A("AuftragStammdatenID")));
		
		return $nummer;
	}
	
	private static function getNext($type, Auftrag $Auftrag = null){
		if($Auftrag != null AND $Auftrag->A("AuftragStammdatenID") != "0")
			$S = new Stammdaten($Auftrag->A("AuftragStammdatenID"));
		else
			$S = Stammdaten::getActiveStammdaten();
		#$P = new anyC();
		
		switch ($S->A("belegNummerResetR")) {
			case "":
				#$P->setTableLock("Userdata", true);
				#$next = mUserdata::getGlobalSettingValue("belegNummerNext$type".$S->getID(), 1);
				$next = 1;
				$U = new mUserdata();
				$UD = $U->getUserdata("belegNummerNext$type".$S->getID(), -1, "belegNummer".$S->getID());
				if($UD != null)
					$next = $UD->A("wert");
				
				$nummer = self::replace($S, $next, false, $Auftrag);
				
				mUserdata::setUserdataS("belegNummerNext$type".$S->getID(), ++$next, "belegNummer".$S->getID(), -1);
				#$P->setTableLock("Userdata", false);
				
				return $nummer;
			break;
			
			case "yearly":
			case "monthly":
				$next = 1;
				$U = new mUserdata();
				$UD = $U->getUserdata("belegNummerNext$type".$S->getID(), -1, "belegNummer".$S->getID());
				if($UD != null)
					$next = $UD->A("wert");
				
				$test = self::replace($S, 1, $S->A("belegNummerResetR") == "yearly", $Auftrag);
				if(!self::exists($type, $test, $Auftrag->A("AuftragStammdatenID"))) { 
					$nummer = $test;
					$next = 1;
				} else
					$nummer = self::replace($S, $next, false, $Auftrag);
				
				#$next = mUserdata::getGlobalSettingValue("belegNummerNext$type".$S->getID(), 1);
				
				
				/*$test = self::replace($S, $next > 1 ? $next - 1 : 1, $S->A("belegNummerResetR") == "yearly", $Auftrag);
				$AC = anyC::get("GRLBM");
				if(strpos("RLGBMA", $type) !== false)
					$AC->addAssocV3("is$type", "=", "1");
				else
					$AC->addAssocV3("isWhat", "=", $type);
				
				if($type == "A" AND !in_array("B", Auftrag::getBelegArten()))
					$AC->addAssocV3("isB", "=", "1", "OR");
					
				$AC->addAssocV3("nummer", "LIKE", $test);
				$AC->setFieldsV3(array("nummer"));
				
				
				$E = $AC->getNextEntry();*/
				#if(self::exists($type, $test, $Auftrag->A("AuftragStammdatenID")))
				#	$next = 1;
				
				#$nummer = self::replace($S, $next, false, $Auftrag);
				
				
				mUserdata::setUserdataS("belegNummerNext$type".$S->getID(), ++$next, "belegNummer".$S->getID(), -1);
				#$P->setTableLock("Userdata", false);
				
				return $nummer;
			break;
			
			case "daily":
				$next = 1;
				$U = new mUserdata();
				$UD = $U->getUserdata("belegNummerNext$type".$S->getID(), -1, "belegNummer".$S->getID());
				if($UD != null)
					$next = $UD->A("wert");
				
				$test = self::replace($S, 1, false, $Auftrag);
				if(!self::exists($type, $test, $Auftrag->A("AuftragStammdatenID"))) { 
					$nummer = $test;
					$next = 1;
				} else
					$nummer = self::replace($S, $next, false, $Auftrag);
				
				mUserdata::setUserdataS("belegNummerNext$type".$S->getID(), ++$next, "belegNummer".$S->getID(), -1);
				
				return $nummer;
			break;
			
		}
		
		return null;
	}
	
	private static function replace($S, $next, $wildcardMonth = false, Auftrag $Auftrag = null){
		$replace = array(
			"{J}" => date("Y"),
			"{J2}" => date("y"),
			"{T}" => str_pad(date("z"), 3, "0", STR_PAD_LEFT),
			"{TM}" => str_pad(date("d"), 2, "0", STR_PAD_LEFT),
			"{M}" => $wildcardMonth ? "%" : date("m"),
			"{M1}" => $wildcardMonth ? "%" : date("m") * 1
		);

		if($Auftrag != null)
			$replace["{K}"] = $Auftrag->A("kundennummer") > 0 ? $Auftrag->A("kundennummer") : 0;

		$nummer = $S->A("belegNummerFormatR");
		if($nummer == "")
			$nummer = "{J}{N:3}";
		foreach($replace AS $k => $v)
			$nummer = str_replace($k, $v, $nummer);

		$useNext = $next;
		preg_match("/\{N:([0-9]+)\}/", $nummer, $matches);
		if(isset($matches[1])){
			$useNext = str_pad($next, $matches[1], "0", STR_PAD_LEFT);
			$nummer = str_replace($matches[0], $useNext, $nummer);
		}
		
		return $nummer;
	}

}

?>