//"join_tw.sc","Połączenie towarów","\System\Pomocnicze\",0,1.0.2,SYSTEM
//////////////////////////////////////////////////////////////////////
// Połączenie towarów
// join_tw.sc

#define OK 2
#define ANULUJ -1
#define KOMPLET   3
dispatch xPr=xFactory.GetObject("BProgram")
if xPr.liczbaUzytkownikow>1 then error "Nie można wykonać raportu.Przed wykonaniem raportu prosimy wylogować pozostałych użytkowników programu."

#include "Wydruki - include"
//Symfonia Mobilny Magazyn - start
#include "MobileWarehouse - include"
//Symfonia Mobilny Magazyn - end


int bTwRead
int bKomplet = 0

string sTW_edit(2)
string sTW_Src,sTW_Dst,sTW_DstNazwa,sTW_DstSubtyp,sTW_DstKodpaskowy,slTW_Src,slTW_dst,sNadaw,stTW_dst,stTW_src
long lTW_Src,lTW_Dst,lTW_tmp,nTW,lTemp, lRodzaj,lKatalog,lNumer,lLongName
int err,i,bUpdate,btn_choose(2)
int bOK,iZast,bUsun
int btn_setFocus(2)
int nTyp
float fIloscDosp, fWartoscDosp

int idx,KolTab(2)=130,220

dispatch connAdo=GetAdoConnection()
dispatch cmdAdo="ADODB.Command"
cmdAdo.ActiveConnection=connAdo
dispatch recAdo="ADODB.RecordSet"
recAdo.CursorType=1
recAdo.LockType=3
dispatch xTw
string sUPDATE="UPDATE %s SET %s=%s WHERE %s"
string sDELETE="DELETE FROM %s WHERE %s"
string sSELECT="SELECT %s FROM %s WHERE %s"
string sINSERT="INSERT INTO %s (%s) VALUES (%s)"

string sFrom
string sWhat
int sub UpdateFieldOffer(string sTable,string sField, string sData, string sWhere)
	sTable = "CM." + sTable
	cmdAdo.CommandText=(using sUPDATE,sTable,sField,sData,sWhere)
	cmdAdo.Execute()
endsub
int sub UpdateField(string sTable,string sField, string sData, string sWhere)
	sTable = "HM." + sTable
	cmdAdo.CommandText=(using sUPDATE,sTable,sField,sData,sWhere)
	cmdAdo.Execute()
endsub
int sub DeleteRecord(string sTable,string sWhere)
	sTable = "HM." + sTable
	cmdAdo.CommandText=using sDELETE,sTable,sWhere
	cmdAdo.Execute()
endsub
int sub InsertRecord(string sTable,string sFields,string sValues)
	sTable = "HM." + sTable
	cmdAdo.CommandText=using sINSERT,sTable,sFields,sValues
	cmdAdo.Execute()
endsub
int sub SelectRecord(string sFields,string sTable,string sWhere)
	sTable = "HM." + sTable
	recAdo.Open((using sSELECT,sFields,sTable,sWhere),connAdo)
endsub




MapValue mIloscDosp
MapValue mStan
MapValue mIloscDospIl
MapValue mWartoscSt
MapValue mIdDw


dispatch xParams = xFactory.NewObject("XParams")
dispatch xMg
//******************************





#include "Wybór obiektu - include"
int sub WyborTowaru(int n)
	Enable(btn_choose(n),0)
	save
//	string kod = ChooseObject(sTW_edit(n),"BTw","BKartParamsTw","towaru")
	string kod = WybierzTW(sTW_edit(n))
	if kod != "" then sTW_edit(n) = kod :load
	Enable(btn_choose(n),1)
	SetActive( btn_setFocus(n) )
endsub

int sub Check( int n )
	Check=1
		if !(xTw=GetObjByKod("BTw",sTW_edit(n))) then Message "Towar o kodzie '"+sTW_edit(n)+"' nie istnieje." : exit
	Check=0
endsub


int sub CheckData()
	CheckData=1
	Save
	sTW_edit(1)=NormalizeStr(sTW_edit(1))
	sTW_edit(2)=NormalizeStr(sTW_edit(2))
	if Len(sTW_edit(1))>40 then sTW_edit(1)=mid(sTW_edit(1),1,40)
	if Len(sTW_edit(2))>40 then sTW_edit(2)=mid(sTW_edit(2),1,40)
	Load
	if !sTW_edit(1) || !sTW_edit(2) then Message "Nie podano kodu towaru" : exit
	if lcase(sTW_edit(1))==lcase(sTW_edit(2)) then message "Nie można połączyć tych samych towarów." : exit
	if Check(1) || Check(2) then exit
	CheckData=2
endsub




//***********************************


mIloscDosp.Type(float)
mIloscDospIl.Type(float)
mStan.Type(float)
mWartoscSt.Type(float)
mIdDw.Type(long)


int sub CheckType(string subtypSrc, string subtypDst)
int bXt
string sNazwaTypSrc, sNAzwaTypDst
SelectRecord("kod","XT","subtyp="+subTypSrc+"AND typ=35 AND super=8200")
if recAdo.RecordCount() then
	sNazwaTypSrc=recAdo.Fields("kod").Value
endif
recAdo.Close()
SelectRecord("kod","XT","subtyp="+subTypDst+"AND typ=35 AND super=8200")
if recAdo.RecordCount() then
	sNazwaTypDst=recAdo.Fields("kod").Value
endif
recAdo.Close()
Message "Połączenie towarów niemożliwe. Nie można łączyć towarów o różnych typach. Towar '"+sTw_Src+"' jest typu '"+sNazwaTypSrc+"' a towar '"+sTW_DSt+"' to '"+sNazwaTypDst +"'."
endsub



form "  " +GetReportName(),300,175

	Group "",10,5,275,105
	Text "Połącz &towar : ",20,20,100,20
	btn_setFocus(1) = Edit "",sTW_edit(1),20,35,180,18

	Text "&z towarem : ",20,65,100,20
	btn_setFocus(2) = Edit "",sTW_edit(2),20,80,180,18

	button "&OK",130,120,70,23,CheckData()
	button "&Anuluj",210,120,70,23,-1

	btn_choose(1) = Button "&Wybierz...",210,33,60,22,WyborTowaru(1)
	btn_choose(2) = Button "Wy&bierz...",210,78,60,22,WyborTowaru(2)

if execform==-1 then Error ""

Check(1)
lTW_src = xTw.id
sTW_src = xTw.kod
stTW_src = (using "%d",xTw.typ)
Check(2)
lTW_dst = xTw.id
sTW_dst = xTw.kod
stTw_Dst=(using "%d",xTw.typ)
sTW_DstNazwa = xTW.nazwa
sTW_DstSubtyp = (using "%d",xTw.Typ)
sTW_DstKodPaskowy = xTW.kodpaskowy
//zabezpieczenie przed apostrofami
Arg "'","''"
buf=sTW_src
Replace Arg
sTW_src=buf
buf=sTW_dst
Replace Arg
sTW_dst=buf
Delete Arg
//zamiana long na string
slTW_dst=using "%l",lTW_dst
slTW_src=using "%l",lTW_src
//dodanie apostrofów
string sTW_dstOld=sTW_dst
string sTW_srcOld=sTW_src
sTW_src="'"+sTW_src+"'"
sTW_dst="'"+sTW_dst+"'"





int sub OnCommand(int id,int msg)
endsub



if stTW_Dst!= stTW_Src then
	CheckType(stTW_src,stTW_Dst) : error ""
endif


//Symfonia Mobilny Magazyn - start
int canMergeProductsRes = CanMergeProducts(lTW_Src, lTW_Dst)
if(canMergeProductsRes > 0) then
	Message "Połączenie towarów niemożliwe. Towary znajdują się w aktywnej operacji w module Mobilnego Magazynu." 
	error ""
endif
//Symfonia Mobilny Magazyn - end

connAdo.BeginTrans()
//**********ADO rezerwacje
UpdateField("RZ","idtw",slTW_dst,"idtw="+slTW_src)


//wyszukujemy idkh które mają iduz zarówno src jak i dst
SelectRecord("iduz, idkh","UZ","iduz="+slTW_dst+" ORDER BY idkh")
//i kasujemy te uzgodnienia które są dla obu towarów
While !recAdo.EOF && recAdo.RecordCount()
	DeleteRecord("UZ","idkh="+(using "%l",recAdo.Fields("idkh").Value)+" AND iduz="+slTW_src)
	recAdo.MoveNext()
wend
recAdo.Close()
//następnie przepisujemy te pozostałe iduz z src na dst
UpdateField("UZ","iduz",slTW_dst,"iduz="+slTW_src)

// połączenie towaru o id=lTW_src do lTW_dst
// czyli zamiana wszyskich kodów i idów towaru lTW_src na lTW_dst

// pozycje handlowe
UpdateField("DP","kod",sTW_dst,"idtw="+slTW_src)
UpdateField("DP","idtw",slTW_dst,"idtw="+slTW_src)

// pozycje zamowien
UpdateField("ZP","kod",sTW_dst,"idtw="+slTW_src)
UpdateField("ZP","idtw",slTW_dst,"idtw="+slTW_src)


// pozycje magazynowe
UpdateField("MZ","kod",sTW_dst,"idtw="+slTW_src)
UpdateField("MZ","idtw",slTW_dst,"idtw="+slTW_src)
// pozycje ofert
UpdateFieldOffer("OfferArticles","ArticleCode",sTW_dst,"ArticleId="+slTW_src)
UpdateFieldOffer("OfferArticles","ArticleId",slTW_dst,"ArticleId="+slTW_src)
//receptury


sWhat=using "idtw=%s AND super IN(SELECT super FROM RE WHERE idtw=%s)",slTW_src,slTW_dst
SelectRecord("super,ilosc","RE",sWhat)
While !recAdo.EOF
	sFrom=using "idtw=%s AND super=%l",slTW_dst,recAdo.Fields("super").Value
	UpdateField("RE","ilosc",(using "ilosc+%f",recAdo.Fields("ilosc").Value),sFrom)
	recAdo.MoveNext()
wend
DeleteRecord("RE",sWhat)
recAdo.Close()
UpdateField("RN","idtw",slTW_dst,"idtw="+slTW_src)
UpdateField("RE","idtw",slTW_dst,"idtw="+slTW_src)

//zlecenia
sWhat=using "idtw=%s AND idzl IN(SELECT idzl FROM ZR WHERE idtw=%s)",slTW_src,slTW_dst
SelectRecord("idzl,ilosc,wspolczynnik AS wsp,wartosc AS wart","ZR",sWhat)
While !recAdo.EOF
	sFrom="wspolczynnik=wspolczynnik+%f,wartosc=wartosc+%f,ilosc"
	sFrom=using sFrom,recAdo.Fields("wsp").Value,recAdo.Fields("wart").Value
	UpdateField("ZR",sFrom,(using "ilosc+%f",recAdo.Fields("ilosc").Value),using "idtw=%s AND idzl=%l",slTW_dst,recAdo.Fields("idzl").Value)
	recAdo.MoveNext()
wend
DeleteRecord("ZR",sWhat)
recAdo.Close()
UpdateField("ZR","idtw",slTW_dst,"idtw="+slTW_src)
UpdateField("ZL","idtw",slTW_dst,"idtw="+slTW_src)
//	OpenBase(bas,"BZ")
//	Pozycje()
//	bas.Close()




SelectRecord("id1","ZZ","typ=69 AND baza1=22 AND id2="+slTW_dst)
While !recAdo.EOF
	DeleteRecord("ZZ","id2="+slTW_src+" AND id1="+(using "%l",recAdo.Fields("id1").Value))
	recAdo.MoveNext()
Wend
recAdo.Close()
//update dla pozostałych przypadków
UpdateField("ZZ","kod2",sTW_dst,"id2="+slTW_src+" AND baza2=22")
UpdateField("ZZ","id2",slTW_dst,"id2="+slTW_src+" AND baza2=22")
bOK=1
//baza rozliczeń magazynowych
UpdateField("PW","idtw",slTW_dst,"idtw="+slTW_src)




//*****************************dostawy




PopUp(1,"Zmiana towarów w bazie dostaw")
// baza dostaw
//lNumer - kolejny numerek dostawy dla danego towaru jeśłi jest ujemny tylko to tylko były ilośćiowe
//rezerwacje z wynorem dostaw
SelectRecord("numer","DW","idtw="+slTW_dst+" ORDER BY numer DESC")
If recAdo.RecordCount() && !recAdo.EOF then
	recAdo.MoveFirst()
	lNumer=recAdo.Fields("numer").Value
endif
recAdo.Close()
lNumer=IIF(lNumer>0,lNumer+1,16777216)
SelectRecord("numer, iloscDosp, WartoscSt, stan, idtw, magazyn","DW","idtw="+slTW_src+" AND numer>0 AND bufor=0 ORDER BY numer ASC")
While !recAdo.EOF && recAdo.RecordCount()
	recAdo.Update("idtw",lTW_dst)
	recAdo.Update("numer",lNumer)
	buf = using "%d",recAdo.Fields("magazyn").Value
	mIloscDosp.Set(buf, mIloscDosp.Get(buf,0)+recAdo.Fields("iloscDosp").Value)
	mStan.Set(buf,mStan.Get(buf,0)+recAdo.Fields("stan").Value)
	mWartoscSt.Set(buf,mWartoscSt.Get(buf,0)+recAdo.Fields("WartoscSt").Value)
//	fIloscDosp += recAdo.Fields("iloscDosp").Value
//	fWartoscDosp += recAdo.Fields("WartoscDosp").Value
	lNumer+=1
	recAdo.MoveNext()
wend
recAdo.Close()
//rezerwacja ilościowa zliczyć oraz dodać należy ilości oraz pozamieniać iddw i idtw w bazie PW
//a gdy nie ma takiej rezerwacji towar dst to zamieniamy tylko idtw w DW i idtw w bazie PW
SelectRecord("id,numer,magazyn,iloscDosp,idtw","DW","idtw="+slTW_src+" AND numer<0 ORDER BY magazyn")
While !recAdo.EOF && recAdo.RecordCount()
		buf = using "%d",recAdo.Fields("magazyn").Value
		mIloscDospIl.Set(buf, mIloscDospIl.Get(buf,0)+recAdo.Fields("iloscDosp").Value)
		mIdDw.Set(buf,recAdo.Fields("id").Value)
		recAdo.MoveNext()
Wend

long iddw
recAdo.Close()

if mIloscDospIl.size() then
	for i=1 to i>mIloscDospIl.Size()
	SelectRecord("numer,magazyn,IloscDosp,idtw,id","DW","idtw="+slTW_dst+" AND magazyn="+mIloscDospIl.GetKey(i)+" AND numer<0")
	if recAdo.RecordCount() && !recAdo.EOF then
		iddw=recAdo.Fields("id").Value
		recAdo.Update("iloscDosp",recAdo.Fields("iloscDosp").Value+mIloscDospIl.Get(i))
		recAdo.Close()
		SelectRecord("iddw,idtw","PW","iddw="+(using "%l",mIdDw.Get(i)))
		While !recAdo.EOF
		recAdo.Update("iddw",iddw)
		recAdo.Update("idtw",lTW_dst)
		recAdo.MoveNext()
		Wend
	else
		recAdo.Close()
		SelectRecord("idtw","DW","id="+(using "%l",mIdDw.Get(i)))
		recAdo.Update("idtw",lTW_dst)
	endif
	recAdo.Close()
	next i
endif
////////// Wyzerowanie rezerwacji ilosciowych dla src
UpdateField("DW","iloscDosp","0","idtw="+slTW_src+" AND numer<0")
//////////



//baza SM
for i=1 to i>mIloscDosp.Size()
	buf= mIloscDosp.GetKey(i)
	SelectRecord("stan,stanHandl,wartosc","SM","idtw="+slTW_src+" AND magazyn="+buf)
	if recAdo.RecordCount() then
		recAdo.Update("stan",recAdo.Fields("stan").Value-mStan.Get(buf))
		recAdo.Update("stanHandl",recAdo.Fields("stanHandl").Value-mIloscDosp.Get(buf)-IIF(mIloscDospIl.Index(buf),mIloscDospIl.Get(buf),0))
		recAdo.Update("wartosc",recAdo.Fields("wartosc").Value-mWartoscSt.Get(buf))
		if Sign(recAdo.Fields("stan").Value) || Sign(recAdo.Fields("stanHandl").Value) || Sign(recAdo.Fields("wartosc").Value) then
			xMg = GetObjById("BMg",Val(buf))
			Message(using "Błąd w danych - stan magazynowy towaru '%s' lub jego wartosc w magazynie '%s' po przeniesieniu powinien wynosić zero.",sTW_SrcOld,xMg.kod)
		endif
	else
		bOK=0
		xMg = GetObjById("BMg",val(buf))
		Message( using "Brak rekordu stanu magazynowego towaru '%s' w magazynie %s.",sTW_SrcOld,xMg.kod)
	endif
	recAdo.Close()
	SelectRecord("stan,stanHandl,wartosc","SM","idtw="+slTW_dst+" AND magazyn="+buf)
	if recAdo.RecordCount() && !recAdo.EOF then
		recAdo.Update("stan",recAdo.Fields("stan").Value+mStan.Get(buf))
		recAdo.Update("stanHandl",recAdo.Fields("stanHandl").Value+mIloscDosp.Get(buf)+IIF(mIloscDospIl.Index(buf),mIloscDospIl.Get(buf),0))
		recAdo.Update("wartosc",recAdo.Fields("wartosc").Value+mWartoscSt.Get(buf))
	else
		//brak rekordu stanu w tym magazynie -> dodajemy
		InsertRecord("SM","flag,typ,subtyp,stan,stanHandl,wartosc,idtw,magazyn",(using "%d,%d,%s,%f,%f,%f,%l,%s",0,0,sTW_DstSubtyp,mStan.Get(buf),mIloscDosp.Get(buf)+IIF(mIloscDospIl.Index(buf),mIloscDospIl.Get(buf),0),mWartoscSt.Get(buf),lTW_dst,buf))
	endif
	recAdo.Close()
next i

//uaktualnienie dla magazynu 0

// uaktualnianie stanów magazynowych w magazynach


//uzgodnienia
SelectRecord("typ, idkh, iduz","UZ","iduz="+slTW_dst)
while recAdo.RecordCount() && !recAdo.EOF
	DeleteRecord("UZ","typ="+(using "%d",recAdo.Fields("typ").Value)+" AND iduz="+slTW_src+" AND idkh="+(using "%l",recAdo.Fields("idkh").Value))
	recAdo.MoveNext()
wend
recAdo.Close()
UpdateField("UZ","iduz",slTW_dst,"iduz="+slTW_src)

//atkulizacja bazy OP
UpdateField("OP","kod",sTW_dst,"id_co="+slTW_src)
UpdateField("OP","id_co",slTW_dst,"id_co="+slTW_src)

//atkulizacja bazy ZE
UpdateField("ZE","idTw",slTW_dst,"idTW="+slTW_src)


// przepięcie notatki
SelectRecord("id","NT","super="+slTW_dst+" AND typ=0 AND baza=22")
if !recAdo.RecordCount() || recAdo.EOF then
	recAdo.Close()
	SelectRecord("super","NT","super="+slTW_src+" AND typ=0 AND baza=22")
	if recAdo.RecordCount() && !recAdo.EOF then
		recAdo.Update("super",lTW_dst)
	endif
endif
recAdo.Close()

// rekord w bazie TW
connAdo.CommitTrans()

//Symfonia Mobilny Magazyn - start
cmdAdo.CommandText=(using "exec [emm].[essp_Products_UpdateAfterMerge] %s, %s",slTW_dst,slTW_src)
cmdAdo.Execute()
//Symfonia Mobilny Magazyn - end

if bOK then
	err = Message(using "Towar '%s' został połączony z towarem '%s'. Czy usunąć towar '%s'?{{icon=? buttons=(&Usuń:o)[&Nie usuwaj:a]}}",sTW_SrcOld,sTW_dstOld,sTW_SrcOld)
else
	Message(using "Towar '%s' został połączony z towarem '%s'.",sTW_SrcOld,sTW_dstOld)
	err=0
endif

if err==1 then
	Check(1)
	err = xTw.Delete()
	if err != 0 then
		message("Nie usunięto towaru '"+sTW_SrcOld+"' - wystąpił błąd. Usuń towar z kartoteki towarów ręcznie.")
	endif
endif


message "Aby zaktualizować dane należy zakończyć pracę z Firmą i otworzyć ją ponownie."
NoOutput()
