//"diag_pw.sci","PW: diagnostyka funkcje","\System\",0,1.0.6,SYSTEM
////////////////////////////
// PW: diagnostyka funkcje
// diag_pw.sci
////////////////////////////

int sub funIlosc()
float dPrzel
	TextOutFun("Sprawdzenie ilości")
	PopUp(1,"Sprawdzenie ilości")

// naprawa powiązań z dokumentami WZ, RW, PZ, PW, MMM, MMP
// powiązania powinny odpowiadać ilości w pozycji magazynowej
// może  być wiele powiązań do jednej pozycji, ale powinno być co najmniej jedno powiązanie
// naprawa polega na modyfikacji ilości istniejących rekordów powiązań
// wykrywa ale nie naprawia braku rekordu powiązania
// bez pozycji kompletów

	lLastId = 0
	sSQL  = "select top 1 id as lastid from MZ order by id desc"
	rsMZ.Open(sSQL,xConn)
	if !rsMZ.EOF() then
		lLastId = rsMZ.Fields("lastid").Value
	endif
	rsMZ.Close()

	lCurrId = 0
	while (lCurrId < lLastId)

		xCmdAdo.CommandText = "create table #MGD (id int primary key, ilosc float, lp smallint, super int, kod varchar(40), subtyp smallint)"
		xCmdAdo.Execute()

		sSQLId = using " (MZ.id > %l and MZ.id <= %l) ", lCurrId, lCurrId + 10000

		sSQL  = " insert into #MGD "
		sSQL += " select MZ.id, MZ.ilosc, MZ.lp, MZ.super, MG.kod, MG.subtyp "
		sSQL += " from MZ join MG on MZ.super = MG.id "
		sSQL += " where "
		sSQL +=   sSQLId
		sSQL += " and MZ.bufor = 0 and (MZ.flag & 0x1000) = 0 and MG.anulowany = 0 and MG.subtyp in (74,131,89,76,129,78,84,82) "
		xCmdAdo.CommandText = sSQL
		xCmdAdo.Execute()

		sSQL =  "select MZP.id as idmz, MZP.lp, MZP.kod as mgkod, case when MZP.subtyp in (74,131,89,82) then 1 else 0 end as przyj , ROUND(MZP.ilosc, 6) as mzilosc, ROUND(ISNULL(PWP.ilosc, 0.0),6) as pwilosc, ISNULL(PWP.pwc, 0) as pwc, ISNULL(PWP.idpw, 0) as idpw, ISNULL(PW.ilosc, 0.0) as ilosc1 "
		sSQL += "from #MGD as MZP "
		sSQL += "left join "
		sSQL += " (select PW.idmg, SUM(PW.ilosc) as ilosc, count(*) as pwc, MAX(PW.id) as idpw "
		sSQL += "  from PW where PW.typ = 37 and PW.iddkmg in (select super from #MGD) "
		sSQL += "  group by PW.idmg) as PWP on PWP.idmg = MZP.id "
		sSQL += "left join PW on PW.id = PWP.idpw "
		sSQL += "where CAST((MZP.ilosc - ISNULL(PWP.ilosc, 0.0)) as decimal(24,6)) <> 0.0"

		rsPW.Open(sSQL,xConn)
		xCmdAdo.ActiveConnection = xConnTmp2
		while !rsPW.EOF()
			WriteStatusBar(using "Sprawdzenie ilości w pozycjach magazynowych...=%d%%%%,255",lCurrId/lLastId*100)
			if rsPW.Fields("pwc").Value == 0 then
				sAsk = using "Brak powiązania pozycji %d dokumentu '%s'.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value
				TextOut(sAsk)
			else
				dPrzel = 1.0
				if rsPW.Fields("przyj").Value then dPrzel = -1.0

				sAsk = using "Ilość w powiązaniach pozycji %d dokumentu '%s' jest wynosi %.6f, a powinna %.6f.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value, (dPrzel * rsPW.Fields("pwilosc").Value), (dPrzel * rsPW.Fields("mzilosc").Value)
				if TextOutAndAsk(15, sAsk," Czy naprawić?") then
					dIlosc = rsPW.Fields("mzilosc").Value - rsPW.Fields("pwilosc").Value
					if rsPW.Fields("pwc").Value == 1 || ((rsPW.Fields("ilosc1").Value + dIlosc) * dPrzel) > 0.0 then
						if rsPW.Fields("pwc").Value == 1 then
							// aktualizacja jedynego powiązania
							sSQL = using "update PW set ilosc = %.6f where id = %l", rsPW.Fields("mzilosc").Value, rsPW.Fields("idpw").Value
						else
							// aktualizacja ostatniego powiązania
							sSQL = using "update PW set ilosc = %.6f where id = %l", rsPW.Fields("ilosc1").Value + dIlosc, rsPW.Fields("idpw").Value
						endif
						xCmdAdo.CommandText = sSQL
						xCmdAdo.Execute()
					else
						// aktualizacja wielu powiązań, usuwane zerowe
						idmz = rsPW.Fields("idmz").Value

						if rsPW.Fields("przyj").Value then
							sSQL = using "select PW.id as idpw, ROUND(PW.ilosc, 6) as ilosc from PW where PW.typ = 37 and PW.subtyp in (74,131,89,82) and PW.idmg = %l order by PW.id desc", idmz
						else
							sSQL = using "select PW.id as idpw, ROUND(PW.ilosc, 6) as ilosc from PW where PW.typ = 37 and PW.subtyp in (76,129,78,84) and PW.idmg = %l order by PW.id desc", idmz
						endif

						rsPW1.Open(sSQL,xConnTmp)
						if rsPW1.RecordCount() then
							while !rsPW1.EOF() && (dPrzel * dIlosc) < 0.0
								if ((rsPW1.Fields("ilosc").Value + dIlosc) * dPrzel) > 0.0 then
									sSQL = using "update PW set ilosc = %.6f where id = %l", rsPW1.Fields("ilosc").Value + dIlosc, rsPW1.Fields("idpw").Value
									dIlosc = 0.0
								else
									sSQL = using "delete PW where id = %l", rsPW1.Fields("idpw").Value
									dIlosc = dIlosc + rsPW1.Fields("ilosc").Value
									dIlosc = Round(dIlosc,6)
								endif
								xCmdAdo.CommandText = sSQL
								xCmdAdo.Execute()
								rsPW1.MoveNext()
							wend
						endif
						rsPW1.Close()

					endif
					TextOut(using "Uaktualniono powiązanią z pozycją %d dokumentu magazynowego '%s' .\n",rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value)
					TextOut(sRepaired)
				else
					TextOut(sNoRepair)
				endif
			endif
			rsPW.MoveNext()
		wend
		xCmdAdo.ActiveConnection = xConn
		rsPW.Close()

		xCmdAdo.CommandText = "drop table #MGD"
		xCmdAdo.Execute()

		lCurrId += 10000
	wend

// naprawa powiązań z dokumentami WZK, RWK, PZK, PWZ, MKM, MKP
// ilość w pozycji magazynowej (korekta + kompensata) powinna odpowiadać ilości w powiązaniach
// może  być wiele powiązań do jednej pozycji, ale powinno być co najmniej jedno powiązanie
// naprawa polega na modyfikacji ilości istniejących rekordów powiązań
// wykrywa ale nie naprawia braku rekordu powiązania

	lCurrId = 0
	while (lCurrId < lLastId)

		xCmdAdo.CommandText = "create table #MGD (id int primary key, ilosc float, lp smallint, super int, kod varchar(40), subtyp smallint)"
		xCmdAdo.Execute()

		sSQLId = using " (MZ.id > %l and MZ.id <= %l) ", lCurrId, lCurrId + 10000

		sSQL  = " insert into #MGD "
		sSQL += " select MZ.id, MZ.ilosc, MZ.lp, MZ.super, MG.kod, MG.subtyp "
		sSQL += " from MZ join MG on MZ.super = MG.id "
		sSQL += " where "
		sSQL +=   sSQLId
		sSQL += " and MZ.bufor = 0 and (MZ.flag & 0x1000) = 0 and MZ.kompensata = 0 and MG.anulowany = 0 and MG.subtyp in (75,132,81,77,130,88,85,83) "
		xCmdAdo.CommandText = sSQL
		xCmdAdo.Execute()

		sSQL =  "select MZP.id as idmz, MZP.lp, MZP.kod as mgkod, case when MZP.subtyp in (75,132,81,83) then 1 else 0 end as przyj , ROUND(MZK.ilosc, 6) as mkilosc, ROUND(MZP.ilosc, 6) as mzilosc, ROUND(ISNULL(PWP.ilosc, 0.0),6) as pwilosc, ISNULL(PWP.pwc, 0) as pwc, ISNULL(PWP.idpw, 0) as idpw, ISNULL(PW.ilosc, 0.0) as ilosc1 "
		sSQL += "from #MGD as MZP "
		sSQL += "join "
		sSQL += " (select MZ.ilosc, MZ.lp, MZ.super "
		sSQL += "  from MZ where MZ.bufor = 0 and MZ.kompensata = 1) as MZK on MZP.lp = MZK.lp and MZP.super = MZK.super "
		sSQL += "left join "
		sSQL += " (select PW.idmg, SUM(PW.ilosc) as ilosc, count(*) as pwc, MAX(PW.id) as idpw "
		sSQL += "  from PW where PW.typ = 37 and PW.iddkmg in (select super from #MGD) "
		sSQL += "  group by PW.idmg) as PWP on PWP.idmg = MZP.id "
		sSQL += "left join PW on PW.id = PWP.idpw "
		sSQL += "where CAST((MZP.ilosc + MZK.ilosc - ISNULL(PWP.ilosc, 0.0)) as decimal(24,6)) <> 0.0"

		rsPW.Open(sSQL,xConn)
		xCmdAdo.ActiveConnection = xConnTmp
		while !rsPW.EOF()
			WriteStatusBar(using "Sprawdzenie ilości w pozycjach magazynowych korekty...=%d%%%%,255",lCurrId/lLastId*100)
			if rsPW.Fields("pwc").Value == 0 then
				sAsk = using "Brak powiązania pozycji %d dokumentu '%s'.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value
				TextOut(sAsk)
			else
				dPrzel = 1.0
				if rsPW.Fields("przyj").Value then dPrzel = -1.0

				sAsk = using "Ilość w powiązaniach pozycji %d dokumentu '%s' jest wynosi %.6f, a powinna %.6f.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value, (dPrzel * rsPW.Fields("pwilosc").Value), (dPrzel * (rsPW.Fields("mzilosc").Value + rsPW.Fields("mkilosc").Value))
				if TextOutAndAsk(16, sAsk," Czy naprawić?") then
					dIlosc = rsPW.Fields("mzilosc").Value + rsPW.Fields("mkilosc").Value - rsPW.Fields("pwilosc").Value
					if rsPW.Fields("pwc").Value == 1 then
						// aktualizacja jedynego powiązania
						sSQL = using "update PW set ilosc = %.6f where id = %l", (rsPW.Fields("mzilosc").Value + rsPW.Fields("mkilosc").Value), rsPW.Fields("idpw").Value
					else
						// aktualizacja ostatniego powiązania
						sSQL = using "update PW set ilosc = %.6f where id = %l", rsPW.Fields("ilosc1").Value + dIlosc, rsPW.Fields("idpw").Value
					endif
					xCmdAdo.CommandText = sSQL
					xCmdAdo.Execute()
					TextOut(using "Uaktualniono powiązanią z pozycją %d dokumentu magazynowego '%s' .\n",rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value)
					TextOut(sRepaired)
				else
					TextOut(sNoRepair)
				endif
			endif
			rsPW.MoveNext()
		wend
		xCmdAdo.ActiveConnection = xConn
		rsPW.Close()

		xCmdAdo.CommandText = "drop table #MGD"
		xCmdAdo.Execute()

		lCurrId += 10000
	wend

endsub

int sub funDoklWartosc()
	TextOutFun("Sprawdzenie dokładności wartości")
	PopUp(1,"Sprawdzenie dokładności wartości")

	sSQL =  "select count(*) as liczba from PW where Round(PW.wartosc,6) <> Round(PW.wartosc,2) "

	rsPW.Open(sSQL,xConn)
	if rsPW.RecordCount() then
		xCmdAdo.ActiveConnection = xConnTmp
		if rsPW.Fields("liczba").Value != 0 then
			sAsk = using "Znaleziono %l rekordów powiązań z wartością nie zaokrągloną do 1 gr.", rsPW.Fields("liczba").Value
			if TextOutAndAsk(17, sAsk," Czy naprawić?") then
				xCmdAdo.CommandText = "update PW set wartosc = Round(PW.wartosc,2) where Round(PW.wartosc,6) <> Round(PW.wartosc,2)"
				xCmdAdo.Execute()
				TextOut(using "Zaokrąglono wartości %l powiązań.\n",rsPW.Fields("liczba").Value)
				TextOut(sRepaired)
			else
				TextOut(sNoRepair)
			endif
		endif
		xCmdAdo.ActiveConnection = xConn
	endif
	rsPW.Close() : lCount=0
endsub

int sub funWartoscMM()
	TextOutFun("Sprawdzenie wartości MM")
	PopUp(1,"Sprawdzenie wartości MM")

// naprawa MM-ki z kilkoma dostawami, dostawa w dostawę
// wartość odpowiednich powiązań na MM- i MM+ powinna być ta sama
// jeszcze trzeba uwzględnić KWM-y na MM-:
//    1. MM- MM+ KWM
//    2. MM- KWM MM+
//    3. MM- KWM MM+ KWM (nie weryfikuje tego przypadku bo jeszcze nie ma kolejności zatwierdzania PW)

	sSQL =  " select ZZMM.id as idzz, PWM.wartosc, PWM.id as idpw, PWM.iddw, DW.iddw as iddwo, MZM.id as idmg, MZM.lp, MZM.flag "
	sSQL += " into #tblPWM "
	sSQL += " from (select ZZ.id, ZZ.id1, ZZ.id2 from ZZ where ZZ.typ = 114) as ZZMM "
	sSQL += " join PW as PWM on PWM.iddkmg = ZZMM.id2 "
	sSQL += " join MZ as MZM on PWM.idmg = MZM.id "
	sSQL += " join DW on DW.id = PWM.iddw"

	xCmdAdo.CommandText = sSQL
	xCmdAdo.Execute()

	sSQL =  " select ZZMM.id as idzz, PWP.wartosc, PWP.id as idpw, PWP.iddw, DW.iddw as iddwo, MZP.id as idmg, MZP.lp, MZP.flag "
	sSQL += " into #tblPWP "
	sSQL += " from (select ZZ.id, ZZ.id1, ZZ.id2 from ZZ where ZZ.typ = 114) as ZZMM "
	sSQL += " join PW as PWP on PWP.iddkmg = ZZMM.id1 "
	sSQL += " join MZ as MZP on PWP.idmg = MZP.id "
	sSQL += " join DW on DW.id = PWP.iddw"

	xCmdAdo.CommandText = sSQL
	xCmdAdo.Execute()

	// nie weryfikujemy skorygowanych wartosciowo MK+ (do jednej pozycji korekty dołączone wiele rekordów PW na tę samą dostawę)  
	sSQL =  " delete from #tblPWP where idpw in "
	sSQL += " (select idpw from #tblPWP join (select idmg, iddw from #tblPWP group by idmg, iddw having COUNT(*) > 1) as MKW "
	sSQL += " on #tblPWP.idmg = MKW.idmg and #tblPWP.iddw = MKW.iddw) "

	xCmdAdo.CommandText = sSQL
	xCmdAdo.Execute()

	sSQL =  " select PW.idkoryg, SUM(PW.wartosc) as wartosc "
	sSQL += " into #tblPWK "
	sSQL += " from PW where PW.idkoryg IS NOT NULL and PW.subtyp = 90 group by PW.idkoryg "

	xCmdAdo.CommandText = sSQL
	xCmdAdo.Execute()

	lLastId = 0
	sSQL  = "select top 1 idzz as lastid from #tblPWP order by idzz desc"
	rsMZ.Open(sSQL,xConn)
	if !rsMZ.EOF() then
		lLastId = rsMZ.Fields("lastid").Value
	endif
	rsMZ.Close()

	lCurrId = 0
	while (lCurrId < lLastId)
		sSQLId = using " (PWP.idzz > %l and PWP.idzz <= %l) ", lCurrId, lCurrId + 10000

		// doatawa w dostawę
		sSQL =  " select round(PWM.wartosc + case when (PWKP.idkoryg IS NULL) then ISNULL(PWKM.wartosc, 0.0) else 0.0 end,2) as wartosc, "
		sSQL += "        PWP.idpw, PWP.lp, MGP.id, MGP.kod as mgkod "
		sSQL += " from #tblPWM as PWM "
		sSQL += " join #tblPWP as PWP on PWM.idzz = PWP.idzz "
		sSQL += " left join #tblPWK as PWKM on PWM.idpw = PWKM.idkoryg " 
		sSQL += " left join #tblPWK as PWKP on PWP.idpw = PWKP.idkoryg "
		sSQL += " join MZ as MZP on PWP.idmg = MZP.id "
		sSQL += " join MG as MGP on MGP.id = MZP.super "
		sSQL += " where PWM.lp = PWP.lp and "
		sSQL +=         sSQLId
		sSQL += "       and (PWM.iddwo = PWP.iddwo or PWP.iddw = PWM.iddwo or PWM.iddw = PWP.iddwo or PWM.iddw = PWP.iddw) "
		sSQL += "       and (PWP.flag & 0x0800) <> 0 "
		sSQL += "       and (PWKP.idkoryg IS NULL or cast((ISNULL(PWKM.wartosc, 0.0) + ISNULL(PWKP.wartosc, 0.0)) as decimal (24,2)) = 0.0) " 
		sSQL += "       and cast((PWM.wartosc + ISNULL(PWKM.wartosc, 0.0) + PWP.wartosc + ISNULL(PWKP.wartosc, 0.0)) as decimal(24,2)) <> 0.0 "

		rsPW.Open(sSQL,xConn)
		xCmdAdo.ActiveConnection = xConnTmp
		while !rsPW.EOF()
			WriteStatusBar(using "Sprawdzenie wartości w powiązaniach MM- i MM+...=%d%%%%,255",lCurrId/lLastId*100)
			sAsk = using "Wartość w powiązaniu pozycji %d przesunięcia magazynowego %s powinna wynosić %.6f.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value, rsPW.Fields("wartosc").Value
			if TextOutAndAsk(18, sAsk," Czy naprawić?") then
				sSQL = using "update PW set wartosc = %.6f where id = %l", -rsPW.Fields("wartosc").Value, rsPW.Fields("idpw").Value
				xCmdAdo.CommandText = sSQL
				xCmdAdo.Execute()
				TextOut(sRepaired)
			else
				TextOut(sNoRepair)
			endif
			rsPW.MoveNext()
		wend
		xCmdAdo.ActiveConnection = xConn
		rsPW.Close()

		lCurrId += 10000
	wend
/* //Symfonia Mobilny Magazyn - start
	lCurrId = 0
	while (lCurrId < lLastId)
		sSQLId = using " (PWP.idzz > %l and PWP.idzz <= %l) ", lCurrId, lCurrId + 10000

		// MM+ tworzy nową dostawę
		sSQL =  " select round(PWMS.wartosc + case when (PWKP.idkoryg IS NULL) then PWMS.wartk else 0.0 end,2) as wartosc, PWP.idpw, PWP.lp, MGP.id, MGP.kod as mgkod "
		sSQL += " from #tblPWP as PWP "
		sSQL += " left join #tblPWK as PWKP on PWP.idpw = PWKP.idkoryg "
		sSQL += " join "
		sSQL += " (select SUM(PWM.wartosc) as wartosc, SUM(ISNULL(PWKM.wartosc, 0.0)) as wartk, PWM.idzz, PWM.idmg, PWM.lp "
 		sSQL += "  from #tblPWM as PWM "
		sSQL += "  left join #tblPWK as PWKM on PWM.idpw = PWKM.idkoryg " 
		sSQL += "  group by PWM.idzz, PWM.idmg, PWM.lp) as PWMS on PWMS.idzz = PWP.idzz "
		sSQL += " join MZ as MZP on PWP.idmg = MZP.id "
		sSQL += " join MG as MGP on MGP.id = MZP.super "
		sSQL += " where PWMS.lp = PWP.lp and "
		sSQL +=         sSQLId
		sSQL += "       and (PWP.flag & 0x0800) = 0 "
		sSQL += "       and (PWKP.idkoryg IS NULL or cast((ISNULL(PWMS.wartk, 0.0) + ISNULL(PWKP.wartosc, 0.0)) as decimal (24,2)) = 0.0) " 
		sSQL += "       and cast((PWMS.wartosc + PWMS.wartk + PWP.wartosc + ISNULL(PWKP.wartosc, 0.0)) as decimal(24,2)) <> 0.0 "

		rsPW.Open(sSQL,xConn)
		if rsPW.RecordCount() then
			xCmdAdo.ActiveConnection = xConnTmp
			while !rsPW.EOF()
				lCount+=1
				WriteStatusBar(using "Sprawdzenie wartości w powiązaniach MM- i MM+...=%d%%%%,255",lCount/rsPW.RecordCount()*100)
				sAsk = using "Wartość w powiązaniu pozycji %d przesunięcia magazynowego %s powinna wynosić %.6f.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value, rsPW.Fields("wartosc").Value
				if TextOutAndAsk(19, sAsk," Czy naprawić?") then
					sSQL = using "update PW set wartosc = %.6f where id = %l", -rsPW.Fields("wartosc").Value, rsPW.Fields("idpw").Value
					xCmdAdo.CommandText = sSQL
					xCmdAdo.Execute()
					TextOut(sRepaired)
				else
					TextOut(sNoRepair)
				endif
				rsPW.MoveNext()
			wend
			xCmdAdo.ActiveConnection = xConn
		endif
		rsPW.Close() : lCount=0

		lCurrId += 10000
	wend
*/ //Symfonia Mobilny Magazyn - start
	xCmdAdo.CommandText = "drop table #tblPWM"
	xCmdAdo.Execute()
	xCmdAdo.CommandText = "drop table #tblPWP"
	xCmdAdo.Execute()
	xCmdAdo.CommandText = "drop table #tblPWK"
	xCmdAdo.Execute()

endsub

int sub funWartosc()
	TextOutFun("Sprawdzenie wartości")
	PopUp(1,"Sprawdzenie wartości")

// naprawa wartości może działać w dwie strony
// albo modyfikować wartość pozycji magazynowej (czego nie robi ta diagnostyka, a powinna robić diagnostyka MZ),
// albo modyfikować wartość powiązania (to robimy poniżej)

// naprawa powiązań z dokumentami WZ, RW, PZ, PW, MMM, MMP
// powiązania powinny odpowiadać wartości w pozycji magazynowej
// może  być wiele powiązań do jednej pozycji, ale powinno być co najmniej jedno powiązanie
// naprawa polega na modyfikacji wartości istniejących rekordów powiązań
// wykrywa ale nie naprawia braku rekordu powiązania

// naprawa powiązań z dokumentami KWM, PWM
// wykrywa niezgodności wartości ale nie naprawia rekordów powiązań

	lLastId = 0
	sSQL  = "select top 1 id as lastid from MZ order by id desc"
	rsMZ.Open(sSQL,xConn)
	if !rsMZ.EOF() then
		lLastId = rsMZ.Fields("lastid").Value
	endif
	rsMZ.Close()

	lCurrId = 0
	while (lCurrId < lLastId)

		xCmdAdo.CommandText = "create table #MGD (id int primary key, wartosc float, lp smallint, super int, kod varchar(40), subtyp smallint) "
		xCmdAdo.Execute()

		sSQLId = using " (MZ.id > %l and MZ.id <= %l) ", lCurrId, lCurrId + 10000

		sSQL  = " insert into #MGD "
		sSQL += " select MZ.id, MZ.wartNetto as wartosc, MZ.lp, MZ.super, MG.kod, MG.subtyp "
		sSQL += " from MZ join MG on MZ.super = MG.id "
		sSQL += " where "
		sSQL +=   sSQLId
		sSQL += " and MZ.bufor = 0 and (MZ.flag & 0x1000) = 0 and MG.anulowany = 0 and MG.subtyp in (74,131,89,76,129,78,84,82,90,91) "
		xCmdAdo.CommandText = sSQL
		xCmdAdo.Execute()

		sSQL =  "select MZP.id as idmz, MZP.lp, MZP.kod as mgkod, case when MZP.subtyp in (90,91) then 1 else 0 end as kwm, case when MZP.subtyp in (74,131,89,82) then 1 else 0 end as przyj, ROUND(MZP.wartosc, 2) as mzwartosc, ROUND(ISNULL(PWP.wartosc, 0.0),2) as pwwartosc, ISNULL(PWP.pwc, 0) as pwc, ISNULL(PWP.idpw, 0) as idpw, ISNULL(PW.wartosc, 0.0) as wartosc1 "
		sSQL += "from #MGD as MZP "
		sSQL += "left join "
		sSQL += " (select PW.idmg, SUM(PW.wartosc) as wartosc, count(*) as pwc, MAX(PW.id) as idpw "
		sSQL += "  from PW where PW.typ = 37 and PW.iddkmg in (select super from #MGD) "
		sSQL += "  group by PW.idmg) as PWP on PWP.idmg = MZP.id "
		sSQL += "left join PW on PW.id = PWP.idpw "
		sSQL += "where CAST((MZP.wartosc - ISNULL(PWP.wartosc, 0.0)) as decimal(24,2)) <> 0.0"

		rsPW.Open(sSQL,xConn)
		if rsPW.RecordCount() then
			xCmdAdo.ActiveConnection = xConnTmp2
			while !rsPW.EOF()
				WriteStatusBar(using "Sprawdzenie wartości w pozycjach magazynowych...=%d%%%%,255",lCurrId/lLastId*100)
				if rsPW.Fields("pwc").Value == 0 then
					sAsk = using "Brak powiązania pozycji %d dokumentu '%s'.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value
					TextOut(sAsk)
				else
					dPrzel = 1.0
					if rsPW.Fields("przyj").Value then dPrzel = -1.0

					sAsk = using "Wartość w powiązaniach pozycji %d dokumentu '%s' wynosi %.6f i różni się od wartości pozycji magazynowej, która wynosi %.6f.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value, (dPrzel * rsPW.Fields("pwwartosc").Value), (dPrzel * rsPW.Fields("mzwartosc").Value)
					if rsPW.Fields("kwm").Value then
						// nie naprawiane powiązania KWM i PWM
						TextOut(sAsk)
					else
						if TextOutAndAsk(20, sAsk," Czy naprawić powiązania na podstawie wartości pozycji magazynowej?") then
							dWartosc = rsPW.Fields("mzwartosc").Value - rsPW.Fields("pwwartosc").Value
							if rsPW.Fields("pwc").Value == 1 || ((rsPW.Fields("wartosc1").Value + dWartosc) * dPrzel) > 0.0 then
								if rsPW.Fields("pwc").Value == 1 then
									// aktualizacja jedynego powiązania
									sSQL = using "update PW set wartosc = %.2f where id = %l", rsPW.Fields("mzwartosc").Value, rsPW.Fields("idpw").Value
								else
									// aktualizacja ostatniego powiązania
									sSQL = using "update PW set wartosc = %.2f where id = %l", rsPW.Fields("wartosc1").Value + dWartosc, rsPW.Fields("idpw").Value
								endif
								xCmdAdo.CommandText = sSQL
								xCmdAdo.Execute()
							else
								// aktualizacja wielu powiązań, usuwane zerowe
								idmz = rsPW.Fields("idmz").Value

								if rsPW.Fields("przyj").Value then
									sSQL = using "select PW.id as idpw, ROUND(PW.wartosc, 2) as wartosc from PW where PW.typ = 37 and PW.subtyp in (74,131,89,82) and PW.idmg = %l order by PW.id desc", idmz
								else
									sSQL = using "select PW.id as idpw, ROUND(PW.wartosc, 2) as wartosc from PW where PW.typ = 37 and PW.subtyp in (76,129,78,84) and PW.idmg = %l order by PW.id desc", idmz
								endif

								rsPW1.Open(sSQL,xConnTmp)
								if rsPW1.RecordCount() then
									while !rsPW1.EOF() && (dPrzel * dWartosc) < 0.0
										if ((rsPW1.Fields("wartosc").Value + dWartosc) * dPrzel) > 0.0 then
											sSQL = using "update PW set wartosc = %.2f where id = %l", rsPW1.Fields("wartosc").Value + dWartosc, rsPW1.Fields("idpw").Value
											dWartosc = 0.0
										else
											sSQL = using "delete PW where id = %l", rsPW1.Fields("idpw").Value
											dWartosc = dWartosc + rsPW1.Fields("wartosc").Value
											dWartosc = Round(dWartosc,2)
										endif
										xCmdAdo.CommandText = sSQL
										xCmdAdo.Execute()
										rsPW1.MoveNext()
									wend
								endif
								rsPW1.Close()

							endif
							TextOut(using "Uaktualniono powiązanią z pozycją %d dokumentu magazynowego '%s' .\n",rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value)
							TextOut(sRepaired)
						else
							TextOut(sNoRepair)
						endif
					endif
				endif
				rsPW.MoveNext()
			wend
			xCmdAdo.ActiveConnection = xConn
		endif
		rsPW.Close()

		xCmdAdo.CommandText = "drop table #MGD"
		xCmdAdo.Execute()

		lCurrId += 10000
	wend

// naprawa powiązań z dokumentami WZK, RWK, PZK, PWZ, MKM, MKP
// wartość w pozycji magazynowej (korekta + kompensata) powinna odpowiadać ilości w powiązaniach
// może  być wiele powiązań do jednej pozycji, ale powinno być co najmniej jedno powiązanie
// naprawa polega na modyfikacji wartości istniejących rekordów powiązań
// wykrywa ale nie naprawia braku rekordu powiązania

	lCurrId = 0
	while (lCurrId < lLastId)

		xCmdAdo.CommandText = "create table #MGD (id int primary key, wartosc float, lp smallint, super int, kod varchar(40), subtyp smallint)"
		xCmdAdo.Execute()

		sSQLId = using " (MZ.id > %l and MZ.id <= %l) ", lCurrId, lCurrId + 10000

		sSQL  = " insert into #MGD "
		sSQL += " select MZ.id, MZ.wartNetto as wartosc, MZ.lp, MZ.super, MG.kod, MG.subtyp "
		sSQL += " from MZ join MG on MZ.super = MG.id "
		sSQL += " where "
		sSQL +=   sSQLId
		sSQL += " and MZ.bufor = 0 and (MZ.flag & 0x1000) = 0 and MZ.kompensata = 0 and MG.anulowany = 0 and MG.subtyp in (75,132,81,77,130,88,85,83) "
		xCmdAdo.CommandText = sSQL
		xCmdAdo.Execute()

		sSQL =  "select MZP.id as idmz, MZP.lp, MZP.kod as mgkod, case when MZP.subtyp in (75,132,81,83) then 1 else 0 end as przyj , ROUND(MZK.wartosc, 2) as mkwartosc, ROUND(MZP.wartosc, 2) as mzwartosc, ROUND(ISNULL(PWP.wartosc, 0.0),2) as pwwartosc, ISNULL(PWP.pwc, 0) as pwc, ISNULL(PWP.idpw, 0) as idpw, ISNULL(PW.wartosc, 0.0) as wartosc1 "
		sSQL += "from #MGD as MZP "
		sSQL += "join "
		sSQL += " (select MZ.wartNetto as wartosc, MZ.lp, MZ.super "
		sSQL += "  from MZ where MZ.bufor = 0 and MZ.kompensata = 1) as MZK on MZP.lp = MZK.lp and MZP.super = MZK.super "
		sSQL += "left join "
		sSQL += " (select PW.idmg, SUM(PW.wartosc) as wartosc, count(*) as pwc, MAX(PW.id) as idpw "
		sSQL += "  from PW where PW.typ = 37 and PW.iddkmg in (select super from #MGD) "
		sSQL += "  group by PW.idmg) as PWP on PWP.idmg = MZP.id "
		sSQL += "left join PW on PW.id = PWP.idpw "
		sSQL += "where CAST((MZP.wartosc + MZK.wartosc - ISNULL(PWP.wartosc, 0.0)) as decimal(24,2)) <> 0.0"

		rsPW.Open(sSQL,xConn)
		if rsPW.RecordCount() then
			xCmdAdo.ActiveConnection = xConnTmp
			while !rsPW.EOF()
				WriteStatusBar(using "Sprawdzenie wartości w pozycjach magazynowych korekty...=%d%%%%,255",lCurrId/lLastId*100)
				if rsPW.Fields("pwc").Value == 0 then
					sAsk = using "Brak powiązania pozycji %d dokumentu '%s'.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value
					TextOut(sAsk)
				else
					dPrzel = 1.0
					if rsPW.Fields("przyj").Value then dPrzel = -1.0

					sAsk = using "Wartość w powiązaniach pozycji %d dokumentu '%s' wynosi %.2f i różni się od wartości pozycji magazynowej, która wynosi %.2f.", rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value, (dPrzel * rsPW.Fields("pwwartosc").Value), (dPrzel * (rsPW.Fields("mzwartosc").Value + rsPW.Fields("mkwartosc").Value))
					if TextOutAndAsk(21, sAsk," Czy naprawić powiązania na podstawie wartości pozycji magazynowej?") then
						dWartosc = rsPW.Fields("mzwartosc").Value + rsPW.Fields("mkwartosc").Value - rsPW.Fields("pwwartosc").Value
						if rsPW.Fields("pwc").Value == 1 then
							// aktualizacja jedynego powiązania
							sSQL = using "update PW set wartosc = %.2f where id = %l", (rsPW.Fields("mzwartosc").Value + rsPW.Fields("mkwartosc").Value), rsPW.Fields("idpw").Value
						else
							// aktualizacja ostatniego powiązania
							sSQL = using "update PW set wartosc = %.2f where id = %l", rsPW.Fields("wartosc1").Value + dWartosc, rsPW.Fields("idpw").Value
						endif
						xCmdAdo.CommandText = sSQL
						xCmdAdo.Execute()
						TextOut(using "Uaktualniono powiązanią z pozycją %d dokumentu magazynowego '%s' .\n",rsPW.Fields("lp").Value, rsPW.Fields("mgkod").Value)
						TextOut(sRepaired)
					else
						TextOut(sNoRepair)
					endif
				endif
				rsPW.MoveNext()
			wend
			xCmdAdo.ActiveConnection = xConn
		endif
		rsPW.Close()

		xCmdAdo.CommandText = "drop table #MGD"
		xCmdAdo.Execute()

		lCurrId += 10000
	wend

endsub

int sub funCenaPW()
	TextOutFun("Sprawdzenie wartości")
	PopUp(1,"Sprawdzenie wartości")

	sSQL  = " select DW.id, DW.iddw "
	sSQL += " into #tblDWP "
	sSQL += " from DW left join (select iddw from PW where subtyp = 90 or subtyp = 91 or subtyp = 81 group by iddw) as PWK on DW.id = PWK.iddw "
	sSQL += " where DW.numer > 0 and DW.typ <> 0 and PWK.iddw is NULL "

	xCmdAdo.CommandText = sSQL
	xCmdAdo.Execute()

	lLastId = 0
	sSQL  = "select top 1 id as lastid from #tblDWP order by id desc"
	rsDW.Open(sSQL,xConn)
	if !rsDW.EOF() then
		lLastId = rsMZ.Fields("lastid").Value
	endif
	rsDW.Close() 

	lCurrId = 0
	while (lCurrId < lLastId)
		sSQLId = using " (DWP.id > %l and DWP.id <= %l) ", lCurrId, lCurrId + 10000

		// podejrzane ceny na powiązaniach 
		// porównywana wartość PW liczona na podstawie ceny przyjęcia do dostawy z wartością w rekordzie PW
		// sparwdzenie tylko dla niewyczerpanych dostaw
		sSQL =  " select PW.id, PW.idtw, PW.ilosc, PW.wartosc, PW.data, MG.kod, MZ.lp, "
		sSQL += "         case when cast(PW.ilosc as decimal (24,6)) <> 0.0 then PW.wartosc/PW.ilosc else 0.0 end cenapw, "
		sSQL += "         case when cast(PWC.ilosc as decimal (24,6)) <> 0.0 then PWC.wartosc/PWC.ilosc else 0.0 end cenadw, DWW.id "
		sSQL += " from PW "
		sSQL += " join (select id, iddw from #tblDWP as DWP where "
		sSQL +=         sSQLId
		sSQL += "       ) as DWP on PW.iddw = DWP.id "
		sSQL += " join (select id from #tblDWP where iddw is null) as DWW on DWP.id = DWW.id or DWP.iddw = DWW.id "
		sSQL += " join PW as PWC on PWC.iddw = DWW.id "
		sSQL += " join MZ on MZ.id = PW.idmg "
		sSQL += " join MG on MG.id = MZ.super "
		sSQL += " where (PWC.flag & 0x08) <> 0 and PW.subtyp <> 90 and PW.ilosc <> 0.0 and "
		sSQL += " and cast (abs(abs(PW.wartosc) - case when (PWC.ilosc <> 0.0) then abs(PW.ilosc * PWC.wartosc / PWC.ilosc) else 0.0 end) as decimal (24,6)) > 0.01 "
		sSQL += " order by DWW.id "

		sAsk = "Znaleziono niezgodności ceny powiązania z ceną dostawy źródłowej."

		rsPW.Open(sSQL,xConn)
		if !rsPW.EOF() then
			TextOut(sAsk)
			while !rsPW.EOF()
				WriteStatusBar(using "Sprawdzenie zgodności ceny z dostawa źródłową ...=%d%%%%,255",lCurrId/lLastId*100)

				sOut = using "Pozycja lp=%d na dokumencie %s, powiązanie na ilość %.6f. Cena %.6f zamiast %.6f.", rsPW.Fields("lp").Value, rsPW.Fields("kod").Value, rsPW.Fields("ilosc").Value, rsPW.Fields("cenapw").Value, rsPW.Fields("cenadw").Value
				TextOut(sOut)
				rsPW.MoveNext()
			wend
		endif
		rsPW.Close()

		lCurrId += 10000
	wend

	xCmdAdo.CommandText = "drop table #tblDWP"
	xCmdAdo.Execute()

endsub

long aDWR(1)

record RowPWR
	long idpw
	float iloscpw
	float wartoscpw
	string datapw[30]
endrec

RowPWR aPWR(1)

int sub funWartoscRezerwacjiDostawy( long idDostawy )
float fWartoscDw, fIloscDw, fIloscSum, fWartoscNew
long lPwr, sizePwr, lZle
string sKodDw, sAsk, sOut, sCmd

	// stan magazynowy dostawy na podstawie zatwierdzonych operacji PW (wartość w DW może być niewłaściwa)
	sCmd  = " SELECT DW.kod, PWS.ilosc, PWS.wartosc "
	sCmd += " FROM DW join (SELECT iddw, -SUM(ilosc) AS ilosc, -SUM(wartosc) AS wartosc "
	sCmd += "               FROM PW WHERE typ = 37 GROUP BY iddw) AS PWS ON DW.id = PWS.iddw "
	sCmd += " WHERE DW.id = %l "
	sSQL  = using sCmd, idDostawy

	rsDW.Open(sSQL,xConn)
	if  !rsDW.EOF() then
		sKodDw     = rsDW.Fields("kod").Value
		fIloscDw   = rsDW.Fields("ilosc").Value
		fWartoscDw = rsDW.Fields("wartosc").Value
	endif
	rsDW.Close()

	shrink aPWR,-1
	
	// lista rekordów powiązan rezerwacji posortowanych w kolejności tworzenia
	sSQL  = using " SELECT PW.id, PW.ilosc, PW.wartosc, PW.data FROM PW WHERE PW.typ = 26 AND CAST(PW.ilosc AS DECIMAL(24,6)) <> 0 AND PW.iddw = %l ORDER BY id ", idDostawy
	rsDW.Open(sSQL,xConn)
	while !rsDW.EOF()
		lPwr+=1
		if lPwr > 1 then grow aPWR,1
		aPWR(lPwr).idpw      = rsDW.Fields("id").Value
		aPWR(lPwr).iloscpw   = rsDW.Fields("ilosc").Value
		aPWR(lPwr).wartoscpw = rsDW.Fields("wartosc").Value
		aPWR(lPwr).datapw    = rsDW.Fields("data").Value
		fIloscSum += aPWR(lPwr).iloscpw
		rsDW.MoveNext()
	wend
	rsDW.Close()

	if lPwr then
		if Round( (fIloscDw - fIloscSum),6 ) < 0.0 then
			sAsk = using "Brakuje ilości w dostawie %s id=%l.", sKodDw, idDostawy
			TextOut(sAsk)
		else
			sizePwr = size(aPWR)
			for lPwr = 1 to lPwr > sizePwr 
				fWartoscNew = Round( (fWartoscDw / fIloscDw * aPWR(lPwr).iloscpw),2 )
				fWartoscDw -= fWartoscNew
				fIloscDw   -= aPWR(lPwr).iloscpw

				if fWartoscNew != aPWR(lPwr).wartoscpw then
					lZle += 1
					if lZle == 1 then 
						sAsk = using "Znaleziono niezgodności wartości rezerwacji dostawy %s id=%l.", sKodDw, idDostawy
						TextOut(sAsk)
					endif
					sOut = using "Powiązanie id=%l z dnia %s na ilość %.6f. Wartość %.2f zamiast %.2f.", aPWR(lPwr).idpw, aPWR(lPwr).datapw, aPWR(lPwr).iloscpw, aPWR(lPwr).wartoscpw, fWartoscNew
					TextOut(sOut)
				endif
			next lPwr
		endif
	endif

endsub

int sub funWartoscRezerwacji()
long lDwr, sizeDwr

	TextOutFun("Sprawdzenie wartości rezerwacji")
	PopUp(1,"Sprawdzenie wartości rezerwacji")

	sSQL  = " select distinct DW.id from PW join DW on PW.iddw = DW.id "
	sSQL += " where DW.numer > 0 and (DW.flag & 0x02) = 0 and PW.typ = 26 "

	rsDW.Open(sSQL,xConn)
	while !rsDW.EOF()
		lDwr+=1
		if lDwr > 1 then grow aDWR,1
		aDWR(lDwr) = rsDW.Fields("id").Value
		rsDW.MoveNext()
	wend
	rsDW.Close()

	if lDwr then
		sizeDwr = size(aDWR)
		for lDwr = 1 to lDwr > sizeDwr
			WriteStatusBar(using "Sprawdzenie rezerwacji z dostaw...=%d%%%%,255",lDwr/sizeDwr*100)
			funWartoscRezerwacjiDostawy( aDWR(lDwr) )
		next lDwr
	endif

endsub
