Pirkimo operacijų apjungimas

MSCAN sprendimas, skirtas optimizuoti prekių priėmimą, kai vienu metu atvyksta prekės pagal kelis skirtingus pirkimo dokumentus (pvz., iš to paties tiekėjo).

Kelių pirkimo dokumentų apjungimas vienam priėmimui ir rezultatų paskirstymas

Numatyta galimybė kelis pirkimo dokumentus apjungti į vieną bendrą priėmimo operaciją, o ją pabaigus – nuskenuotus kiekius ir informaciją automatiškai paskirstyti atgal į originalius pirkimo dokumentus.

Visas procesas susideda iš trijų pagrindinių etapų: pirkimo op. apjungimo, skenavimo (kai skenavimo operacijoje keičiama lokacija) ir pabaigimo su serijų paskirstymu.

Sukurta lokacijų operacija neturės iš anksto užpildytų laukų „Lokacija iš“ ir „Lokacija į“. Jas darbuotojas priskirs skenavimo metu (prekių priėmimo atveju „Lokacija iš“ gali likti tuščia).

Paruošiamieji nustatymai

Prieš pradedant naudotis pirkimo operacijų apjungimu būtina atlikti šiuos sistemos konfigūravimo žingsnius:

1. Naujos būsenos sukūrimas. Reikia sukurti naują būseną, kuri indikuotų, jog operacija yra sėkmingai perduota atrinkimui į lokacijų modulį:

  • Sistemos parametre MSCAN_BUS sukuriamas naujas įrašas, kurio vartotojo kodas yra L.

    apj_01

  • Pirkimo operacijų sąraše sukuriama nauja operacijos būsena su identišku pavadinimu.

    apj_02

2. Naujo klavišo aprašymas. Pirkimų operacijų sąraše aprašomas naujas greitasis klavišas (pvz., CTRL + Q), kurį paspaudus bus iškviečiamas pirkimo dokumentų apjungimas ir perdavimas priėmimui.

rez_03

Pardavimuose:

mscan_po_0e("", "productCode, unitCode", "", 1, .f., 100, .f., .f.)

Funkcijoje mscan_po_0e naudojami parametrai:

Nr. Reikšmė Pavyzdys
1. Lokacija į - lokacija į kurią pajamuojamos prekės, pvz. atrinkimo zona, gali būti tuščia ""
2. Į lokacijų operacijas perduodami laukai (pavyzdyje be objektų ir serijų) "productCode, unitCode"
3. Rūšiavimo eiliškumas formuojant lokacijų operacijas, pvz.: nuo didžiausio lokacijos prioriteto "priority desc"
4. Lokacijos operacijos tipas (pagal nutylėjima 1 - lokacijų operacija) 1
5. Jei parametras užpildytas, priėmimo operacijos su pateiktu arba didesniu eilučių kiekiu siunčiamos tiesiai priėmimui jų neapjungiant. 70
6. Grupuoti operacijas, nurodoma kiek vienetų į vieną užsakymą, negrupuojama jei parametras tuščias arba neperduotas 100
7. Jei grupuojama, apatinė kiekio riba 90
8. Jei grupuojama, viršutinė kiekio riba 110

Sukurta lokacijų operacija gali neturėti iš anksto užpildytų laukų „Lokacija iš“ ir „Lokacija į“. Jos gali būti priskirtos skenavimo metu.

3. Formulė lokacijos ir serijos priskyrimui skenavimo metu.

Kadangi pradinėje Lokacijų operacijoje tikslios prekių padėjimo vietos nėra žinomos, jos nurodomos skenuojant. Kad sistema teisingai apdorotų šiuos pakeitimus, skenavimo metu turi būti vykdoma papildoma formulė.

Skenavimo formulės logika:

  1. Vartotojas nuskenuoja prekę ir nurodo lokaciją, į kurią ją padeda.
  2. Formulė programiškai pašalina pradines eilutes, kurios neturi nurodytų lokacijų.
  3. Vietoje jų sukuriamos naujos eilutės su vartotojo priskirtomis lokacijomis.
  4. Lankstumas: Tą pačią prekę (iš vienos pradinės eilutės) galima išskirstyti ir padėti į kelias skirtingas lokacijas – sistema sukurs atitinkamą kiekį naujų eilučių.
-- lokacijų op. prekės be serijų ir lokacijų, skenuojama su serijomis ir lokacijomis
-- kuriamos naujos eilutės su atitinkamomis serijomis ir lokacijomis ir mažinamas kiekis eilutėje be
-- lokacija būtina, neleidžiama vesti naujų eilučių ir viršyti užsakyto kiekio

-- parametrų nuskaitymas
declare @module char(2), @operationType char(20), @operationCode char(12), @mscanCode varchar(1000), @lot char(120), @objectCode char(120),
    @quantityApp numeric(14,3), @locale char(2), @mscanUser char(12), @ignoreWarnings int, @note varchar(300), @extraInfo1 varchar(1000),
    @extraInfo2 varchar(1000), @extraInfo3 varchar(1000), @extraInfo4 varchar(1000), @extraInfo5 varchar(1000), @rowNumber numeric(6),
    @departmentId char(12), @lot2 char(120), @objectCode2 char(1220), @expirationDate datetime, @id bigint, @warningId varchar(8000),
    @palOption int, @kodas_0l1 char(120), @kodas_0l2 char(120), @expirationDate2 datetime

declare @productCode char(12), @unitCode char(12), @barcode varchar(1000), @alt_bar_lenght int, @quantityDocument numeric(14,3),
    @quantityDocument2 numeric(14,3), @rowNumber2 numeric(6)

select @module = module, @operationType = operationType, @operationCode = operationCode, @mscanCode = mscanCode, @lot = lot, @objectCode = objectCode,
    @quantityApp = quantityApp, @locale = locale, @mscanUser = mscanUser, @ignoreWarnings = ignoreWarnings, @note = note, @extraInfo1 = extraInfo1,
    @extraInfo2 = extraInfo2, @extraInfo3 = extraInfo3, @extraInfo4 = extraInfo4, @extraInfo5 = extraInfo5, @rowNumber = rowNumber,
    @departmentId = departmentId, @lot2 = lot2, @objectCode2 = objectCode2, @expirationDate = expirationDate, @id = id, @warningId = warningId,
    @palOption = palOption, @kodas_0l1 = kodas_0l1, @kodas_0l2 = kodas_0l2, @expirationDate2 = expirationDate2
from #inParams

-- skirta tik lokacijų op.
if @module <> '0E'
    return

-- lokacijų kodai pagal barkodus
select @kodas_0l1 = upper(isnull(@kodas_0l1, ''))
select @kodas_0l2 = upper(isnull(@kodas_0l2, ''))
if @kodas_0l1 <> ''
    select @kodas_0l1 = kodas_0l from dbo.RGI_MSCAN_0L_S where barcode = @kodas_0l1
if @kodas_0l2 <> ''
    select @kodas_0l2 = kodas_0l from dbo.RGI_MSCAN_0L_S where barcode = @kodas_0l2

-- būtina lokaciją į
if isnull(@kodas_0l2, '') = ''
begin
    insert #appErrors (Tag, Err_Code, Expr2) values ('LOKACIJA', 0, 'Nenurodyta Lokacija į!')
    return
end

-- prekės kodas pagal pagrindinį barkodą
select @productCode = n37_kodas_ps, @unitCode = n37_kodas_us from dbo.n37_pmat
    where n37_bar_kodas = right('000000000000' + rtrim(left(@mscanCode, 12)), 12) and n37_bar_kodas <> '000000000000'

-- prekės kodas pagal alternatyvų barkodą
if @productCode is null 
begin
    select @alt_bar_lenght = col_length('dbo.n40_abar', 'n40_bar_kodas')
    select @barcode = substring(@mscanCode, 1, @alt_bar_lenght)
    select @productCode = n40_kodas_ps, @unitCode = n40_kodas_us from dbo.n40_abar where n40_bar_kodas = @barcode
end

if isnull(@productCode, '') = ''
begin
    insert into #appErrors (Tag, Err_Code, Expr1, Expr3) values ('BARCODE', 9009, @mscanCode, 'Nėra tokios prekės ' + rtrim(@mscanCode))
    return
end

if not exists (select 1 from dbo.RGI_MSCAN_0E_D where kodas_0e = @operationCode and productCode = @productCode and unitCode = @unitCode)
begin
    insert #appErrors (Tag, Err_Code, Expr2) values ('MSCANCODE', 0, 'Užsakyme nėra tokios prekės ' + rtrim(@productCode))
    return
end

select @rowNumber = rowNumber, @quantityDocument = quantity / fraction
    from dbo.RGI_MSCAN_0E_D where kodas_0e = @operationCode and productCode = @productCode and unitCode = @unitCode and lot = '' and kodas_0l2 = '' and (quantity / fraction) >= @quantityApp

-- tikrinama ar yra eilutė jau su lokacija / serija
if exists (select 1 from dbo.RGI_MSCAN_0E_D D0E left join dbo.RGI_MSCAN_D D on D0E.kodas_0e = D.operationCode and D.module = @module and D0E.rowNumber = D.rowNumber
        where D0E.kodas_0e = @operationCode and D0E.productCode = @productCode and D0E.unitCode = @unitCode and D0E.lot = @lot and D0E.kodas_0l1 = @kodas_0l1 and D0E.kodas_0l2 = @kodas_0l2
        having sum(D0E.quantity / D0E.fraction) - sum(isnull(D.quantityApp, 0)) >= @quantityApp) and @quantityApp > 0
    return

if isnull(@rowNumber, 0) = 0
begin
    insert #appErrors (Tag, Err_Code, Expr2) values ('QUANTITYAPP', 0, 'Viršytas užsakytas kiekis')
    return
end

-- sumažinamas kiekis eilutėje be lokacijos / serijos
select @quantityDocument = @quantityDocument - @quantityApp
exec dbo.RGI_MSCAN_0E_D_EDIT @Oper = 'U', @kodas_0e = @operationCode, @rowNumber = @rowNumber, @kiekis_u = @quantityDocument, @updateUser = @mscanUser, @response_type = 2
update #inParams set ignoreWarnings = 1

if not exists (select 1 from dbo.RGI_MSCAN_0E_D where kodas_0e = @operationCode and rowNumber = @rowNumber and (quantity / fraction) = @quantityDocument)
begin
    insert #appErrors (Tag, Err_Code, Expr2) values ('ERROR', 0, 'Klaida koreduojant kiekį be serijos')
    return
end

-- jei yra eilutė su serija ir lokacija - padidinamas kiekis joje
select @rowNumber2 = D0E.rowNumber, @quantityDocument2 = D0E.quantity / D0E.fraction
    from dbo.RGI_MSCAN_0E_D D0E left join dbo.RGI_MSCAN_D D on D0E.kodas_0e = D.operationCode and D.module = @module and D0E.rowNumber = D.rowNumber
    where D0E.kodas_0e = @operationCode and D0E.productCode = @productCode and D0E.unitCode = @unitCode and D0E.lot = @lot and D0E.kodas_0l1 = @kodas_0l1 and D0E.kodas_0l2 = @kodas_0l2

if isnull(@rowNumber2, 0) <> 0
begin
    select @quantityDocument2 = @quantityDocument2 + @quantityApp
    exec dbo.RGI_MSCAN_0E_D_EDIT @Oper = 'U', @kodas_0e = @operationCode, @rowNumber = @rowNumber2, @kiekis_u = @quantityDocument2, @updateUser = @mscanUser, @response_type = 2
    return
end

-- įterpiama nauja eilutė
exec dbo.RGI_MSCAN_0E_D_EDIT @Oper = 'I', @kodas_0e = @operationCode, @productCode = @productCode, @unitCode = @unitCode, @lot = @lot, @kodas_0l1 = @kodas_0l1,
    @kodas_0l2 = @kodas_0l2, @kiekis_u = @quantityApp, @updateUser = @mscanUser, @response_type = 2

if not exists (select 1 from dbo.RGI_MSCAN_0E_D where kodas_0e = @operationCode and productCode = @productCode and unitCode = @unitCode and lot = @lot
    and (quantity / fraction) = @quantityApp and kodas_0l1 = @kodas_0l1 and kodas_0l2 = @kodas_0l2)
begin
    insert #appErrors (Tag, Err_Code, Expr2) values ('ERROR', 0, 'Klaida įterpiant eilutę su lokacija ir serija')
    return
end

4. Operacijos pabaigimas ir rezultatų paskirstymas.

Užbaigus apjungtą Lokacijų operaciją, sistema atlieka atvirkštinį procesą – nuskenuotus kiekius perkelia ir paskirsto į pradines pirkimo operacijas.

Priklausomai nuo įmonės verslo logikos ir darbo su Serijomis, galimi du skirtingi pabaigimo scenarijai:

Scenarijus A: Pirkimai su serijomis, skenuojama be serijų

Šiuo atveju serijos (kaip tam tikras požymis) jau yra įvestos originaliuose pirkimo dokumentuose.

  • Darbuotojas skenuoja prekes MSCAN įrenginyje nevesdamas serijų.
  • Operacijos pabaigimo metu, sistema automatiškai paskirsto priimtą kiekį ant atitinkamų pirkimo eilučių, kurios jau turi priskirtas serijas.

Pabaigimo formulės pavyzdys (Scenarijus A):

declare @cikl_id int, @count int, @cikl_id2 int, @count2 int
declare @productCode char(12), @unitCode char(12), @quantityApp numeric(14, 0), @quantityTmp numeric(14, 0)
declare @mscan_koreguojama varchar(100), @mscan_koreguojama_busena numeric(3,0), @documentType numeric(2,0), @busena_be char(12)
declare @i07_kodas_po char(12), @i07_eil_nr numeric(6), @i07_kodas_os char(12), @i07_serija char(12),
    @i07_pav char(40), @i07_alt_kiekis numeric(14, 0), @i07_alt_frak numeric(4, 0)

-- pašalinami pirkimo operacijų RGI_MSCAN_D irašai
delete d from dbo.RGI_MSCAN_D d inner join dbo.I38_IRYS i on d.operationCode = i.i38_kodas1
    where i.i38_kodas2 = @operationCode and i.i38_modul2 = '0E' and d.module = 'PO'

-- prekės iš lokacijos op. susumuotos pagal prekės kodą ir mat.vnt.
if dbo.RGI_ver2_tmp_exists('#lok_sum') = 1 drop table #lok_sum
select row_number() over (order by productCode, unitCode) as num_row, productCode, unitCode, sum(quantityApp) as quantityApp
    into #lok_sum from dbo.RGI_MSCAN_D where module = '0E' and operationCode = @operationCode group by productCode, unitCode

select @count = count(*) from #lok_sum
select @cikl_id = 1
while @cikl_id <= @count
begin
    select @productCode = productCode, @unitCode = unitCode, @quantityApp = quantityApp from #lok_sum where num_row = @cikl_id
    select @cikl_id = @cikl_id + 1

    -- pirkimų eilutės pagal prekės kodą ir mat.vnt.
    if dbo.RGI_ver2_tmp_exists('#lok_det') = 1 drop table #lok_det
    select row_number() over (order by i07_kodas_po asc, i07_eil_nr asc) as num_row, * into #lok_det from (
        select i07_kodas_po, i07_eil_nr, i07_kodas_os, i07_serija, i07_pav, i07_alt_kiekis, i07_alt_frak
        from dbo.I07_PARD inner join dbo.I38_IRYS on i38_pav = 'Pirkimo op. apjungimas' and i07_kodas_po = i38_kodas1 and i38_modul2 = '0E' and i38_modul1 = 'PO'
        where i38_kodas2 = @operationCode and i07_kodas = @productCode and i07_kodas_us_p = @unitCode) scr

    select @count2 = count(*) from #lok_det
    select @cikl_id2 = 1
    while @cikl_id2 <= @count2
    begin
        select @i07_kodas_po = i07_kodas_po, @i07_eil_nr = i07_eil_nr, @i07_kodas_os = i07_kodas_os, @i07_serija = i07_serija, @i07_pav = i07_pav,
            @i07_alt_kiekis = i07_alt_kiekis, @i07_alt_frak = i07_alt_frak
            from #lok_det where num_row = @cikl_id2
        select @cikl_id2 = @cikl_id2 + 1

        select @quantityTmp = case when @quantityApp >= @i07_alt_kiekis then @i07_alt_kiekis else @quantityApp end
        select @quantityApp = @quantityApp - @quantityTmp

        -- paskutinė eilutė ir dar liko kiekio - pridedamas perteklius
        if @cikl_id2 > @count2 and @quantityApp > 0
            select @quantityTmp = @quantityTmp + @quantityApp, @quantityApp = 0

        insert into dbo.RGI_MSCAN_D (operationCode, module, operationType, rowNumber, productCode, productName, mscanCode, barcode, objectCode, lot,
            unitCode, quantityApp, quantityDoc, fraction, isFullyCollected, quantitiesModifiedSuccessfully, errorMessage, addUser, updateUser, updateDate,
            addDate, note, isInserted, extraInfo1, extraInfo2, extraInfo3, extraInfo4, extraInfo5, objectCode2, lot2, expDate)
        values (@i07_kodas_po, 'PO', 'PAJ', @i07_eil_nr, @productCode, @i07_pav, '', '', @i07_kodas_os, @i07_serija, @unitCode, @quantityTmp, @i07_alt_kiekis,
            @i07_alt_frak, 0, null, null, @user, @user, convert(char(30), getdate(), 20), convert(char(30), getdate(), 20),
            null, 0, null, null, null, null, null, null, null, null)

        if @quantityApp <= 0
            break
    end
end

-- pirkimo operacijoms priskiriama būsena ir inicijuojamas pabaigimas
if dbo.RGI_ver2_tmp_exists('#pabaig_op') = 1 drop table #pabaig_op
select row_number() over (order by i38_kodas1 asc) as num_row, i38_kodas1
    into #pabaig_op from dbo.I38_IRYS where i38_pav = 'Pirkimo op. apjungimas' and i38_kodas2 = @operationCode and i38_modul2 = '0E' and i38_modul1 = 'PO'

select @count = count(*) from #pabaig_op
select @cikl_id = 1
while @cikl_id <= @count
begin
    select @i07_kodas_po = i38_kodas1 from #pabaig_op where num_row = @cikl_id
    select @cikl_id = @cikl_id + 1

    select @documentType = i06_op_tip from dbo.I06_PARH where i06_kodas_po = @i07_kodas_po
    select @mscan_koreguojama = coalesce(nullif(dbo.RGI_uf_param_96('MSCAN_BUS', 'PO', 'K', 1), ''), 'MSCAN renkama')
    select @mscan_koreguojama_busena = L19_BUSENA from dbo.L19_BUS where L19_PAV = @mscan_koreguojama and L19_MODUL = 'PO' and (L19_TIPAS = 0 or L19_TIPAS = @documentType)
    select @busena_be = L19_KODAS_BE from dbo.I06_PARH, dbo.L19_BUS where I06_KODAS_PO = @i07_kodas_po and l19_busena = i06_busena and l19_modul = 'PO'

    execute dbo.RGI_MSCAN_CHANGE_STATE @modul = 'PO', @op = @i07_kodas_po, @user = @user, @veiksmas = 'P', @busena = @busena_be, @busena_nauja = @mscan_koreguojama_busena, @tyliai = 1
    execute dbo.RGI_OPK_EDIT @operationCode = @i07_kodas_po, @module = 'PO', @finalizeOption = 1, @tik_prekes = 1, @user = @user, @response_type = 2
end

Scenarijus B: Pirkimai be serijų, skenuojama su serijomis

Šiuo atveju pirkimo dokumentai įvedami be serijų numerių.

  • Prekių priėmimo metu skenuojamos ne tik prekės, bet ir jų serijiniai numeriai.
  • Operacijos pabaigimo metu, naujai įvestos serijos yra proporcingai ar pagal atitikimą paskirstomos ir įrašomos į originalias pirkimo operacijas.

Pabaigimo formulės pavyzdys (Scenarijus B):

declare @cikl_id int, @count int, @cikl_id2 int, @count2 int
declare @productCode char(12), @unitCode char(12), @quantityApp numeric(14, 0), @quantityTmp numeric(14, 0)
declare @mscan_koreguojama varchar(100), @mscan_koreguojama_busena numeric(3,0), @documentType numeric(2,0), @busena_be char(12)
declare @i07_kodas_po char(12), @i07_eil_nr numeric(6), @i07_kodas_os char(12), @lot char(12),
    @i07_pav char(40), @i07_alt_kiekis numeric(14, 0), @i07_alt_frak numeric(4, 0)
declare @likutis numeric(14, 0)

-- pašalinami pirkimo operacijų RGI_MSCAN_D įrašai
delete d from dbo.RGI_MSCAN_D d inner join dbo.I38_IRYS i on d.operationCode = i.i38_kodas1
    where i.i38_kodas2 = @operationCode and i.i38_modul2 = '0E' and d.module = 'PO'

-- paruošiamos originalių pirkimo operacijų eilutės (be serijų)
if dbo.RGI_ver2_tmp_exists('#po_eilutes') = 1 drop table #po_eilutes
select row_number() over (order by i07_kodas_po asc, i07_eil_nr asc) as num_row, 
       i07_kodas_po, i07_eil_nr, i07_kodas_os, i07_pav, i07_alt_kiekis, i07_alt_frak,
       i07_kodas as productCode, i07_kodas_us_p as unitCode
    into #po_eilutes 
    from dbo.I07_PARD 
    inner join dbo.I38_IRYS on i38_pav = 'Pirkimo op. apjungimas' and i07_kodas_po = i38_kodas1 and i38_modul2 = '0E' and i38_modul1 = 'PO'
    where i38_kodas2 = @operationCode

-- sugrupuojami nuskenuoti 0E kiekiai pagal prekę, mat. vnt. ir seriją (lot)
if dbo.RGI_ver2_tmp_exists('#scanned_serijos') = 1 drop table #scanned_serijos
select row_number() over (order by productCode, unitCode, lot) as scan_id,
       productCode, unitCode, lot, sum(quantityApp) as quantityApp, sum(quantityApp) as likutis
    into #scanned_serijos
    from dbo.RGI_MSCAN_D 
    where module = '0E' and operationCode = @operationCode 
    group by productCode, unitCode, lot

select @count = count(*) from #po_eilutes
select @cikl_id = 1

-- išorinis ciklas: einama per originalias pirkimų eilutes eilutes
while @cikl_id <= @count
begin
    select @i07_kodas_po = i07_kodas_po, @i07_eil_nr = i07_eil_nr, @i07_kodas_os = i07_kodas_os, @i07_pav = i07_pav,
           @i07_alt_kiekis = i07_alt_kiekis, @i07_alt_frak = i07_alt_frak,
           @productCode = productCode, @unitCode = unitCode 
        from #po_eilutes where num_row = @cikl_id
    select @cikl_id = @cikl_id + 1

    -- kiekis, kurį reikia užpildyti šioje pirkimų eilutėje
    select @quantityApp = @i07_alt_kiekis 

    -- vidinis ciklas: ieškome nuskenuotų serijų šiai prekei
    select @cikl_id2 = min(scan_id) from #scanned_serijos where productCode = @productCode and unitCode = @unitCode and likutis > 0

    while @cikl_id2 is not null and @quantityApp > 0
    begin
        select @lot = lot, @likutis = likutis from #scanned_serijos where scan_id = @cikl_id2

        select @quantityTmp = case when @quantityApp >= @likutis then @likutis else @quantityApp end

        -- sumažinamas poreikis ir nuskenuotos serijos likutis laikinoje lentelėje
        select @quantityApp = @quantityApp - @quantityTmp
        update #scanned_serijos set likutis = likutis - @quantityTmp where scan_id = @cikl_id2

        -- įterpiama eilutė į MSCAN_D su nuskenuota serija (@lot)
        insert into dbo.RGI_MSCAN_D (operationCode, module, operationType, rowNumber, productCode, productName, mscanCode, barcode, objectCode, lot,
            unitCode, quantityApp, quantityDoc, fraction, isFullyCollected, quantitiesModifiedSuccessfully, errorMessage, addUser, updateUser, updateDate,
            addDate, note, isInserted, extraInfo1, extraInfo2, extraInfo3, extraInfo4, extraInfo5, objectCode2, lot2, expDate)
        values (@i07_kodas_po, 'PO', 'PAJ', null, @productCode, @i07_pav, '', '', @i07_kodas_os, @lot, @unitCode, @quantityTmp, @i07_alt_kiekis,
            @i07_alt_frak, 0, null, null, @user, @user, convert(char(30), getdate(), 20), convert(char(30), getdate(), 20),
            null, 0, null, null, null, null, @i07_eil_nr, null, null, null)

        -- jei PO eilutei dar trūksta kiekio, imama kita nuskenuota serija
        if @quantityApp > 0
            select @cikl_id2 = min(scan_id) from #scanned_serijos where productCode = @productCode and unitCode = @unitCode and likutis > 0 and scan_id > @cikl_id2
        else
            break
    end
end

-- pertekliaus apdorojimas (jei nuskenuota daugiau prekių su serijomis, nei laukiama pirkimuose)
-- perteklius priskiriamas paskutinei pirkimų eilutei, kurioje egzistuoja tokia prekė
select @cikl_id2 = min(scan_id) from #scanned_serijos where likutis > 0
while @cikl_id2 is not null
begin
    select @lot = lot, @likutis = likutis, @productCode = productCode, @unitCode = unitCode from #scanned_serijos where scan_id = @cikl_id2

    -- randama paskutinė originali PO eilutė atitinkamai prekei
    select top 1 @i07_kodas_po = i07_kodas_po, @i07_eil_nr = i07_eil_nr, @i07_kodas_os = i07_kodas_os, @i07_pav = i07_pav,
           @i07_alt_kiekis = i07_alt_kiekis, @i07_alt_frak = i07_alt_frak
        from #po_eilutes where productCode = @productCode and unitCode = @unitCode order by num_row desc

    if @@rowcount > 0
    begin
        insert into dbo.RGI_MSCAN_D (operationCode, module, operationType, rowNumber, productCode, productName, mscanCode, barcode, objectCode, lot,
            unitCode, quantityApp, quantityDoc, fraction, isFullyCollected, quantitiesModifiedSuccessfully, errorMessage, addUser, updateUser, updateDate,
            addDate, note, isInserted, extraInfo1, extraInfo2, extraInfo3, extraInfo4, extraInfo5, objectCode2, lot2, expDate)
        values (@i07_kodas_po, 'PO', 'PAJ', null, @productCode, @i07_pav, '', '', @i07_kodas_os, @lot, @unitCode, @likutis, @i07_alt_kiekis,
            @i07_alt_frak, 0, null, null, @user, @user, convert(char(30), getdate(), 20), convert(char(30), getdate(), 20),
            null, 0, null, null, null, null, @i07_eil_nr, null, null, null)
    end

    update #scanned_serijos set likutis = 0 where scan_id = @cikl_id2
    select @cikl_id2 = min(scan_id) from #scanned_serijos where likutis > 0 and scan_id > @cikl_id2
end

-- pirkimo operacijoms priskiriama būsena ir inicijuojamas pabaigimas
if dbo.RGI_ver2_tmp_exists('#pabaig_op') = 1 drop table #pabaig_op
select row_number() over (order by i38_kodas1 asc) as num_row, i38_kodas1
    into #pabaig_op from dbo.I38_IRYS where i38_pav = 'Pirkimo op. apjungimas' and i38_kodas2 = @operationCode and i38_modul2 = '0E' and i38_modul1 = 'PO'

select @count = count(*) from #pabaig_op
select @cikl_id = 1
while @cikl_id <= @count
begin
    select @i07_kodas_po = i38_kodas1 from #pabaig_op where num_row = @cikl_id
    select @cikl_id = @cikl_id + 1

    select @documentType = i06_op_tip from dbo.I06_PARH where i06_kodas_po = @i07_kodas_po
    select @mscan_koreguojama = coalesce(nullif(dbo.RGI_uf_param_96('MSCAN_BUS', 'PO', 'K', 1), ''), 'MSCAN renkama')
    select @mscan_koreguojama_busena = L19_BUSENA from dbo.L19_BUS where L19_PAV = @mscan_koreguojama and L19_MODUL = 'PO' and (L19_TIPAS = 0 or L19_TIPAS = @documentType)
    select @busena_be = L19_KODAS_BE from dbo.I06_PARH, dbo.L19_BUS where I06_KODAS_PO = @i07_kodas_po and l19_busena = i06_busena and l19_modul = 'PO'

    execute dbo.RGI_MSCAN_CHANGE_STATE @modul = 'PO', @op = @i07_kodas_po, @user = @user, @veiksmas = 'P', @busena = @busena_be, @busena_nauja = @mscan_koreguojama_busena, @tyliai = 1
    execute dbo.RGI_OPK_EDIT @operationCode = @i07_kodas_po, @module = 'PO', @finalizeOption = 1, @tik_prekes = 1, @user = @user, @response_type = 2
end