Name('Inventura z umístění');
Designed('SKL_MAN#1');

WnsType(1)

NewWNS('SklSys03.WNS');

DeclareRec('Program');
DeclareRec('Sklad');
DeclareRec('KeySklad10');
DeclareRec('SkladovySystem');
DeclareRec('KeySkladovySystem2');
DeclareRec('SerioveCislo')
DeclareRec('KeySerioveCislo1')
DeclareRec('SkupinovaOperace')
DeclareRec('Pohyb')
DeclareRec('PohybSeriovehoCisla')

CheckSklad:Word=Val(GetIni('Settings','SklSys03.WNS'))
if(CheckSklad=0)
  CheckSklad=Program.Sklad
Datum:Word=GetDate()
Rozdilne:Boolean
Generovat:Boolean

;DlgFollowMouse(True)

DefDialog('Volby',256,204);

DlgShade(-1,,4,4,244,130);
DlgStatic(-1,'&Sklad',16,20,64);
DlgEdit(,CheckSklad,80,16,48,,4,ES_LEFT,'0123456789')
DlgStatic(-1,'&Datum',16,50,64);
DlgEditDate(,Datum,80,46)
DlgCheckBox(,Rozdilne,16,80,212,,'Pouze položky s rozdílem');
DlgCheckBox(,Generovat,16,104,212,,'Generovat rozdílové doklady');
DlgButton(id_OK,,96,140);
DlgButton(id_Cancel,,176,140);

if(DlgExecute(True)<>id_OK)
  Halt;

SetIni('Settings','SklSys03.WNS',CheckSklad);

ModifyMode(Generovat)

Record DataRec
  dummy     :LongInt;
  adresa    :LongInt;
  sklad     :Word;
  CisMat    :LongInt;
  Material  :String[14]
  Nazev     :String[35]
  MJ        :String[7]
  CisSN     :LongInt;
  SN        :String[22]
  Mnozstvi  :Double;
  MnozstviSN:Double;
  Zustatek  :Double;
end;

DataRec2:DataRec

Record DataKey
  Length    :Byte;
  adresa    :LongInt
  CisMat    :LongInt
  CisSN     :LongInt
end;

Record DataKey2
  Length    :Byte;
  Material  :Array[1..14] of Char;
  CisMat    :LongInt
  SN        :Array[1..22] of Char;
  CisSN     :LongInt
end;

Veta:LongInt;
VetaS:LongInt;
VetaN:LongInt;
VetaL:LongInt
Pozice:LongInt;
LocStr:String
Mnozstvi:Double
LocBo:Boolean
Rozdil:Double
SklRozdil:Double
Exclamation:String
VetaManka:LongInt;
VetaPrebytky:LongInt;
Manka:SkupinovaOperace
Prebytky:SkupinovaOperace

LastAddr:LongInt=-1
LastMat:LongInt=-1
LastSN:LongInt=-1

Procedure UlozData
  if(LastAddr<>-1)
    begin
      if(RoundQuantity(Mnozstvi)<>0)
        begin
          KeySklad10.Length=4
          KeySklad10.Cislo=SwapL(LastMat)
          if(FindKey(KeySklad10,VetaS))
            begin
              ReadRec(Sklad,VetaS)
            end else
            begin
              ClearRec(Sklad)
            end;
          if((Sklad.Sklad=CheckSklad)and(Length(Sklad.Material)>4)and(InFilter(Sklad)))
            begin
              ClearRec(DataRec);
              DataRec.adresa=LastAddr
              DataRec.Sklad=Sklad.Sklad
              DataRec.CisMat=LastMat
              DataRec.CisSN=LastSN
              DataRec.Material=Sklad.Material
              DataRec.Nazev=Sklad.Nazev
              DataRec.MJ=Sklad.MJ
              DataRec.Zustatek=RoundQuantity(Sklad.PocStav+Sklad.Prijmy-Sklad.Vydaje)
              KeySerioveCislo1.Length=4
              KeySerioveCislo1.Cislo=SwapL(LastSN)
              if(FindKey(KeySerioveCislo1,VetaN))
                begin
                  ReadRec(SerioveCislo,VetaN)
                end else
                begin
                  ClearRec(SerioveCislo)
                end;
              DataRec.SN=SerioveCislo.Number
              DataRec.Mnozstvi=RoundQuantity(Mnozstvi);
              DataKey.Length=SizeOf(DataKey)-1
              DataKey.Adresa=SwapL(DataRec.Adresa)
              DataKey.CisMat=SwapL(DataRec.CisMat)
              DataKey.CisSN=SwapL(DataRec.CisSN)
              AddKey(DataKey,AddRec(DataRec))
            end;
        end;
    end;
  LastSN=SkladovySystem.CisSN
  LastMat=SkladovySystem.CisMat
  LastAddr=SkladovySystem.adresa
  Mnozstvi=0
end

Procedure Soucty(Finish:Boolean,Inventuruj:Boolean)
  if((LastMat<>DataRec2.CisMat)or(Finish))
    begin
      if((LastMat<>0)and((LocBo)or(Mnozstvi<>DataRec.Zustatek)))
        begin
          Rozdil=RoundQuantity(Mnozstvi-DataRec.Zustatek);
          if(Inventuruj)
            begin
              KeySklad10.Length=4
              KeySklad10.Cislo=SwapL(DataRec.CisMat)
              if(FindKey(KeySklad10,VetaS))
                begin
                  ReadRec(Sklad,VetaS)
                  Sklad.Flags2=Sklad.Flags2|$20;
                  Sklad.InvStav=RoundQuantity(Mnozstvi);
                  ModifyRec(Sklad,VetaS);
                end else
                begin
                  Error('Problém !!!\rNenalezena skladova karta !\r'+DataRec.Material,mb_IconExclamation)
                end;
            end else
          if((Rozdil<>0)or(not Rozdilne))
            begin
              if(Rozdil<>0)
                Exclamation='!'
              else
                Exclamation=''
              SetSumLine($87);
              AddLine(Str(DataRec.Sklad),DataRec.Material,DataRec.Nazev,'KARTA CELKEM',StrQuantity(Mnozstvi),StrQuantity(DataRec.Zustatek),StrQuantity(Rozdil),Exclamation,DataRec.MJ);
            end;
        end;
      LocBo=False;
      LastMat=DataRec2.CisMat;
      Mnozstvi=0
      CopyRec(DataRec2,DataRec);
    end;
end;

InitStatus(UsedKeys(KeySkladovySystem2),'Třídím umístění ...')

MakeTempFile(DataRec,DataKey,False)

KeySkladovySystem2.Length=1
KeySkladovySystem2.Operative=true

LocBo=SearchKey(KeySkladovySystem2,Veta);

While(LocBo)
  begin
    ReadRec(SkladovySystem,Veta)
    if((LastSN<>SkladovySystem.CisSN)or(LastMat<>SkladovySystem.CisMat)or(LastAddr<>SkladovySystem.Adresa))
      begin
        UlozData;
      end;
    if(SkladovySystem.CisHrom=-1)
      begin
        Mnozstvi=SkladovySystem.Mnozstvi
      end else
      begin
        Mnozstvi=Mnozstvi+SkladovySystem.Mnozstvi
      end
    Inc(Pozice)
    SetStatus(Pozice)
    LocBo=NextKey(KeySkladovySystem2,Veta)
  end;

UlozData;

InitStatus(UsedKeys(DataKey),'Sumarizuji umístění ...')
Pozice=0

MakeTempFile(DataRec2,DataKey2,False)

ClearKey(DataKey);

While(NextKey(DataKey,Veta))
  begin
    ReadRec(DataRec,Veta);
    DataKey2.Length=SizeOf(DataKey2)-1
    StrToChars(DataKey2.Material,DataRec.Material);
    StrToChars(DataKey2.SN,DataRec.SN);
    DataKey2.CisMat=SwapL(DataRec.CisMat)
    DataKey2.CisSN=SwapL(DataRec.CisSN)
    if(FindKey(DataKey2,VetaN))
      begin
        ReadRec(DataRec2,VetaN);
        DataRec2.Mnozstvi=RoundQuantity(DataRec2.Mnozstvi+DataRec.Mnozstvi);
        ModifyRec(DataRec2,VetaN)
      end else
      begin
        CopyRec(DataRec,DataRec2);
        AddKey(DataKey2,AddRec(DataRec2));
      end;
    Inc(Pozice)
    SetStatus(Pozice)
  end;

InitStatus(UsedKeys(KeySerioveCislo1),'Třídím sériová čísla ...');
Pozice=0

ClearKey(KeySerioveCislo1)
while(NextKey(KeySerioveCislo1,Veta))
  begin
    ReadRec(SerioveCislo,Veta);
    KeySklad10.Length=4
    KeySklad10.Cislo=SwapL(SerioveCislo.CisloMat)
    if(FindKey(KeySklad10,VetaS))
      begin
        ReadRec(Sklad,VetaS)
      end else
      begin
        ClearRec(Sklad)
      end;
    if((Sklad.Sklad=CheckSklad)and(Length(Sklad.Material)>4))
      begin
        DataKey2.Length=SizeOf(DataKey2)-1
        StrToChars(DataKey2.Material,Sklad.Material);
        StrToChars(DataKey2.SN,SerioveCislo.Number);
        DataKey2.CisMat=SwapL(SerioveCislo.CisloMat)
        DataKey2.CisSN=SwapL(SerioveCislo.Cislo)
        if(FindKey(DataKey2,VetaL))
          begin
            ReadRec(DataRec2,VetaL);
            DataRec2.MnozstviSN=RoundQuantity(DataRec2.MnozstviSN+SerioveCislo.Mnozstvi)
            ModifyRec(DataRec2,VetaL);
          end else
          begin
            ClearRec(DataRec2);
            DataRec2.Sklad=Sklad.Sklad
            DataRec2.CisMat=SerioveCislo.CisloMat
            DataRec2.CisSN=SerioveCislo.Cislo
            DataRec2.Material=Sklad.Material
            DataRec2.Nazev=Sklad.Nazev
            DataRec2.MJ=Sklad.MJ
            DataRec2.SN=SerioveCislo.Number
            DataRec2.MnozstviSN=SerioveCislo.Mnozstvi;
            DataRec2.Zustatek=RoundQuantity(Sklad.PocStav+Sklad.Prijmy-Sklad.Vydaje)
            AddKey(DataKey2,AddRec(DataRec2))
          end
      end
    Inc(Pozice)
    SetStatus(Pozice)
  end;

if(Generovat)
  begin
    InitStatus(UsedKeys(DataKey),'Dosazuji inventurní stavy')
    ClearKey(DataKey2)
    Pozice=0
    LastMat=0;
    LocBo=false
    Mnozstvi=0
    ClearRec(DataRec)
    While(NextKey(DataKey2,Veta))
      begin
        ReadRec(DataRec2,Veta);
        Soucty(false,true);
        Mnozstvi=RoundQuantity(Mnozstvi+DataRec2.Mnozstvi);
        if((RoundQuantity(DataRec2.Mnozstvi)<>0)or(RoundQuantity(DataRec2.MnozstviSN)<>0))
          begin
            LocBo=true;
          end;
        Inc(Pozice);
        SetStatus(Pozice);
      end;
    Soucty(true,true);
  end;

InitStatus(UsedKeys(DataKey),'Vytvářím sestavu')

if(Rozdilne)
  LocStr=' (pouze položky s rozdílem)')
else
  LocStr=''

SetDescr(0,0,TA_Right|descr_PageNum,'Strana: ');
SetDescr(1,0,TA_Center,'Inventura z umístění'+LocStr);
SetDescr(2,0,TA_Left|descr_Date,'Datum: ');

SetColumn(0,TA_RIGHT,4);                Sklad
SetColumn(1,TA_LEFT,14);                Material
SetColumn(2,TA_Left,35);                Nazev
SetColumn(3,TA_LEFT,22);                Seriove cislo
SetColumn(4,TA_RIGHT,12);               Mnozstvi
SetColumn(5,TA_RIGHT,12);               Mnozstvi
SetColumn(6,TA_RIGHT,12);               Rozdil
SetColumn(7,TA_CENTER,2);               !
SetColumn(8,TA_LEFT,7);                 MJ

SetHead('Sklad\tMateriál\tNázev\tSériové číslo\tUmístěno\tna kartě\trozdíl\t!\tMJ')

ClearKey(DataKey2)

Pozice=0

LastMat=0;
LocBo=false
Mnozstvi=0
ClearRec(DataRec)

if(Generovat)
  begin
    ClearRec(Pohyb)
    ClearRec(Manka)
    ClearRec(Prebytky)
    Manka.dt_create=GetDate()*65536+GetTime()
    Manka.create=GetUserName()
    Manka.cislo=GetNewIdent()
    Manka.datum=Datum
    Manka.obdobi=Month(Datum)*100+Year(Datum)%100;
    Manka.doklad='MANKA'
    Manka.popis='Manka zjištěna na základě umístění'
    Manka.vydaj=true
    Prebytky.dt_create=Manka.dt_create
    Prebytky.create=Manka.create
    Prebytky.cislo=GetNewIdent()
    Prebytky.datum=Datum
    Prebytky.obdobi=Manka.obdobi
    Prebytky.doklad='PREBYTKY'
    Prebytky.popis='Přebytky na základě umístění'
    Prebytky.vydaj=false
    VyssiDPH:Byte=SazbaDPH(true,Manka.datum)
    NizsiDPH:Byte=SazbaDPH(false,Manka.datum)
  end


While(NextKey(DataKey2,Veta))
  begin
    ReadRec(DataRec2,Veta);
    Soucty(false,false);
    Mnozstvi=RoundQuantity(Mnozstvi+DataRec2.Mnozstvi);
    if((RoundQuantity(DataRec2.Mnozstvi)<>0)or(RoundQuantity(DataRec2.MnozstviSN)<>0))
      begin
        Rozdil=RoundQuantity(DataRec2.Mnozstvi-DataRec2.MnozstviSN)
        if((Rozdil<>0)or(not Rozdilne))
          begin
            if(Rozdil<>0)
              begin
                if(Generovat)
                  begin
                    if(VetaManka=0)
                      begin
                        VetaManka=AddRec(Manka);
                      end;
                    if(VetaPrebytky=0)
                      begin
                        VetaPrebytky=AddRec(Prebytky);
                      end;
                    if(Pohyb.CisloMat<>DataRec2.CisMat)
                      begin
                        KeySklad10.Length=4
                        KeySklad10.Cislo=SwapL(DataRec2.CisMat)
                        if(FindKey(KeySklad10,VetaS))
                          begin
                            ReadRec(Sklad,VetaS)
                          end else
                          begin
                            Error('Problém !!!\rNenalezena skladova karta !\r'+DataRec.Material,mb_IconExclamation)
                          end;
                        ClearRec(Pohyb);
                        Pohyb.dt_create=Manka.dt_create;
                        Pohyb.create=Manka.create;
                        Pohyb.obdobi=Manka.obdobi
                        Pohyb.datum=Manka.datum
                        Pohyb.SklCena=Sklad.AktPNC
                        Pohyb.material=Sklad.material
                        Pohyb.CisloCeny=1
                        Pohyb.JednCena=RoundPrice(Sklad.AktPNC)
                        if(Sklad.SazbaDPH=0)
                          begin
                            Pohyb.DPH=VyssiDPH;
                          end else
                        if(Sklad.SazbaDPH=1)
                          begin
                            Pohyb.DPH=NizsiDPH;
                          end;
                        Pohyb.CisloMat=DataRec2.CisMat;
                        SklRozdil=RoundQuantity(Sklad.InvStav-DataRec2.Zustatek)
                        Pohyb.mnozstvi=SklRozdil;
                        if((SklRozdil>0)or((SklRozdil=0)and(Rozdil>0)))
                          begin
                            Pohyb.doklad=Prebytky.doklad
                            Pohyb.vydaj=false
                            if(SklRozdil=0)
                              begin
                                Pohyb.JednCena=0;
                              end;
                            Pohyb.Castka=RoundFloat(Pohyb.Mnozstvi*Pohyb.JednCena,-2)
                            Prebytky.Castka=Prebytky.Castka+Pohyb.Castka;
                            Pohyb.Hrom=Prebytky.cislo
                            Pohyb.SubHrom=Prebytky.PolCount
                            Inc(Prebytky.PolCount)
                            Pohyb.popis=Prebytky.popis
                          end else
                          begin
                            Pohyb.mnozstvi=RoundQuantity(-Pohyb.Mnozstvi);
                            Pohyb.doklad=Manka.doklad
                            Pohyb.vydaj=true
                            Pohyb.Castka=RoundFloat(Pohyb.Mnozstvi*Pohyb.JednCena,-2)
                            Manka.Castka=Manka.Castka+Pohyb.Castka;
                            Pohyb.Hrom=Manka.cislo
                            Pohyb.SubHrom=Manka.PolCount
                            Inc(Manka.PolCount)
                            Pohyb.popis=Manka.popis
                          end;

                        Pohyb.JednCenaBS=Pohyb.JednCena
                        Pohyb.JednCenaS=Pohyb.JednCena
                        Pohyb.CastkaBS=Pohyb.Castka
                        Pohyb.CastkaS=Pohyb.Castka

                        if(not AddStock(Pohyb))
                          begin
                            Error('Nelze přidat pohyb pro\r'+DataRec2.material+'\r'+Sklad.Nazev+'\rna skladě '+Str(Sklad.Sklad),mb_IconExclamation);
                          end;
                      end;
                    ClearRec(PohybSeriovehoCisla);
                    PohybSeriovehoCisla.Datum=Pohyb.Datum
                    PohybSeriovehoCisla.CisloPH=Pohyb.Cislo
                    PohybSeriovehoCisla.CisloMat=Pohyb.CisloMat
                    PohybSeriovehoCisla.CisloHP=Pohyb.Hrom
                    PohybSeriovehoCisla.CisloSN=DataRec2.CisSN
                    PohybSeriovehoCisla.Vydaj=Pohyb.Vydaj
                    PohybSeriovehoCisla.Mnozstvi=Rozdil;
                    if(Pohyb.Vydaj)
                      begin
                        PohybSeriovehoCisla.Mnozstvi=RoundQuantity(-PohybSeriovehoCisla.Mnozstvi);
                      end;
                    AddRec(PohybSeriovehoCisla);
                  end;
                Exclamation='!'
              end else
              begin
                Exclamation=''
              end;
            AddLine(Str(DataRec2.Sklad),DataRec2.Material,DataRec2.Nazev,DataRec2.SN,StrQuantity(DataRec2.Mnozstvi),StrQuantity(DataRec2.MnozstviSN),StrQuantity(Rozdil),Exclamation,DataRec2.MJ);
          end
        LocBo=true;
      end;
    Inc(Pozice);
    SetStatus(Pozice);
  end;
Soucty(true,false);
if(Generovat)
  begin
    if(VetaManka<>0)
      begin
        ModifyRec(Manka,VetaManka);
      end;
    if(VetaPrebytky<>0)
      begin
        ModifyRec(Prebytky,VetaPrebytky);
      end;
    Message('Pro dokončení je bezpodmínečně nutné spustit výpočet\r''Přepočet a kontrola stavu sériových čísel''',mb_IconExclamation)
  end;
END