kb:artikli:optimizacija_po_vazecem_periodu_main

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
kb:artikli:optimizacija_po_vazecem_periodu_main [2019/05/12 18:15] – created milanokb:artikli:optimizacija_po_vazecem_periodu_main [2019/05/12 18:56] (current) – [Algoritam "važećeg perioda" (optmizacija)] milano
Line 1: Line 1:
 ====== Algoritam "važećeg perioda" (optmizacija) ====== ====== Algoritam "važećeg perioda" (optmizacija) ======
  
-Autor:  Milan Oparnica (14.07.2009)+Autor:  Milan Oparnica (14.07.2009)\\ 
 +Revizija: Milan Oparnica (06.08.2017) Od sada zapisi koji ne trebaju imati uticaj na važeći period imaju NULL u vazod/vazdo
  
 Algoritam iza zadatak da ukloni sledeća uska grla kod određivanja prodajne i cene koštanja: Algoritam iza zadatak da ukloni sledeća uska grla kod određivanja prodajne i cene koštanja:
Line 8: Line 9:
   - Određivanje početne vrednosti za potrebe ažuriranje cena   - Određivanje početne vrednosti za potrebe ažuriranje cena
   - Utvrđivanje otpremnica i računa sa netačnim srednjim cenama i njihova ispravka   - Utvrđivanje otpremnica i računa sa netačnim srednjim cenama i njihova ispravka
 +
  
 ===== Određivanje početnih vrednosti za ažuriranje cena ===== ===== Određivanje početnih vrednosti za ažuriranje cena =====
Line 34: Line 36:
  
 ^Polje^Tip^Svrha| ^Polje^Tip^Svrha|
-|VazOd|INTEGER|Celobrojno polje koje predstavlja **datum početka** perioda za koji srednja i prodajna cena u slogu **SasUlaz** važi.| +|vazod|INTEGER|Celobrojno polje koje predstavlja **datum početka** perioda za koji srednja i prodajna cena u slogu **SasUlaz** važi.| 
-|VazDo|INTEGER|Celobrojno polje koje predstavlja **datum kraja** perioda (ne uključujući dan unet u **VazDo**) od kog srednja i prodajna cena u slogu **SasUlaz** više ne važi.| +|vazdo|INTEGER|Celobrojno polje koje predstavlja **datum kraja** perioda (ne uključujući dan unet u **VazDo**) od kog srednja i prodajna cena u slogu **SasUlaz** više ne važi.| 
-|VazDTS|DOUBLE|Duplikat **DTStamp** polja iz **Ulaz** tabele kako bi se izbegao nepotreban **JOIN** u upitima koji će vraćati rezulate strukture.|+|vazdts|DOUBLE|Duplikat **DTStamp** polja iz **Ulaz** tabele kako bi se izbegao nepotreban **JOIN** u upitima koji će vraćati rezulate strukture.|
  
 ===== Validne vrednosti polja VazOd i VazDo (logička provera) ===== ===== Validne vrednosti polja VazOd i VazDo (logička provera) =====
  
-Primeri su dati nad sledećim vrednostima (#m/dd/yyyy#): \\  39875 - brojčana vrednost datuma #3/3/09# \\  39885 - brojčana vrednost datuma #3/13/09# \\  401769 - brojčana vrednost datuma #1/1/3000# \\   \\ Sledeće kombinacije vrednosti ovih polja za isti **ElID**  i **SklID**  sloga **SasUlaz**  su ispravne:+Primeri su dati nad sledećim vrednostima (#m/dd/yyyy#): \\ 39875 - brojčana vrednost datuma #3/3/09# \\ 39885 - brojčana vrednost datuma #3/13/09# \\ 401769 - brojčana vrednost datuma #1/1/3000# \\  \\ Sledeće kombinacije vrednosti ovih polja za isti **ElID**  i **SklID**  sloga **SasUlaz**  su ispravne: 
 + 
 +^vazod^vazdo^Opis situacije| 
 +|39875|401769|Ovo je normalno kod prvog i jedinog ulaza artikla koji tada važi od datuma ulaza do kraja (1/1/3000)| 
 +| | | | 
 +|39875|39885|vo je normalno za artikal koji je ponovo nabaljen za 10 dana, pri čemu bi drugi slog izgledao...| 
 +|39885|401769|...ovako| 
 +| | | | 
 +|39875|39875|Ovo je normalno za artikal koji je u toku jednog dana više puta ulazio. Mogući scenario sledećih polja je...| 
 +|39875|39875|...ponovo je ušao, ali ima još jedan ulaz od istog dana| 
 +|39875|39885|...sledeći ulaz od istog dana važi narednih 9 dana| 
 +|39885|401769|...a 10-tog dana je artikal ponovo ušao, i od tada se više nije pojavljivao| 
 + 
 +Iz ovih vrednosti mogu se izvući sledeći logički zaključci: 
 + 
 +  - Polja sa **vazod = vazdo**  ne uzimaju se u obzir prilikom odabira cena jer je pravilo Balansa da svi ulazi uvek ide pre bilo kog izlaza. Izuzetak je jedino popis, koji je zadnji dokument nekog dana.  Nama su dakle interesantni samo poslednji ulazi dana tj oni gde je** vazod < vazdo**. 
 +  - Ni jedan par **[elid, sklid]**  gde je  **vazod < vazdo**ne može da ima dva ista  **vazod**datuma. To bi značilo da postoji "preklapanje" perioda u okviru istorije promena cena. 
 +  - Ni jedan par **[elid, sklid]**  gde je ** vazod < vazdo**ne može da ima dva ista  **vazod**datuma. To bi značilo da postoji "preklapanje" perioda u okviru istorije promena cena. 
 +  - Ni jedan par **[elid, sklid]**  ne može da ima  **vazod**ili  **vazdo**između  **vazod**i  **vazdo** (**>**  ** vazodAND <  vazdo**) bilo kojeg drugog para istih**[elid, sklid]**.  \\ **Napomena ****!**  Upit koji bi ovo proveravao ne postoji, ali postoji pretpostavka da će takva situacija uvek dovesti do pojave duplikata u  **vazod**ili  **vazdo**. 
 +====== Popisi ====== 
 + 
 +Izuzetno je važno da se popisi više ne tretiraju kao poslednji dokumenti u danu, ako već nisu tako i snimljeni. Periodi **vazod**  i **vazdo**  ne smeju postati netačni. Ovo tretiranje popisi imaju samo u procedurama za obradu srednjih cena i nivelacija, i to zato što svi ulazi pomeraju **DTStamp**  svih otpremnica tako da ove **uvek**  dolaze iza njih. 
 + 
 +Popisima se na **DTStamp**  dodaje **20000**  tako da se oni veštački postave iza svih ulaznih dokumenata. Ovo je prvenstveno urađeno zbog uprošćavanja detekcije trenutnih količina u trenutku ulaza i formiranja srednje nabavne cene. 
 + 
 +Pošto su svi izlazi agregirani pod jednim danom i smešteni na njegov kraj, jedini podatak koji nam informaciju može pružiti jeste **TKol**  **prethodnog**  **ulaza**. Stvar, nažalost, nije nimalo jednostavna. **Ulazi**  pre popisa će u **TKol**  da smeste sve ulaze do tog momenta minus količinu robe prodatu do kraja prethodnog dana. **Popis**  će uzeti stanje u trenutku popisa i u svoj **TKol**  upisati stanje posle popisa uključujući izlaze do momenta popisa. \\ Ulazi napravljeni posle popisa će uzeti: 
 + 
 +<code> 
 +zbir svih ulaza do pre popisa + izmene po popisu – zbir izlaza do kraja prošlog dana. 
 +</code> 
 + 
 +Tablica koja demonstrira problem: 
 + 
 +{{:kb:artikli:ce1e8632f0242f42df5b0b9cfd9d31c5.png}} 
 + 
 +Iz ovoga se vidi da će prethodni **TKol**  biti isti kao i stanje lagera po obračunu **SC**  ali će se **razlikovati**  od stvarnog stanja koje je bilo u trenutku popisa. 
 + 
 +===== Rešenje ===== 
 + 
 +Razlog za usaglašavanje dokumenta Popis može biti samo promena u stanju (ili ceni, ali ako to nema veze sa količinom radi se o drugoj priči) pre popisa. Do promene stanja može doći samo izmenom tabele **Ulaz**  ili **Otpremnice**. 
 + 
 +U prvom slučaju, izmena će se odraziti na **TKol**  makar poslednjeg **Ulaza**  pre popisa.  U drugom slučaju desiće se isto sem ako je došlo do promene baš one otpremnice koja se nalazila između poslednjeg ulaza i popisa, odnosno popisa i prvog sledećeg ulaza, a to će se reflektovati tek na **TKol**-u prvog sledećeg Ulaza. 
 + 
 +Problem je kako razlikovati da li je do razlike u izlazima došlo pre ili posle popisa ? 
 + 
 +Jedino rešenje je ipak da popis u okviru zapisa u **Popis**  unese i podatak o** ukupnom ulazu i izlazu**  do trenutka izrade popisa. U tu svrhu su dodata polja **inkol**  i **outkol**.  Prilikom sakupljanja informacija o prometu artikala (**CS_UlaziSumIzlazi**  i sl.), dodat je podupit koji za slogove popisa testira trenutno važeći izlaz do momenta popisa i posle popisa (potonje za sada ne trebaju, ali pošto ne utiču na performanse ostavio sam ih). 
 + 
 +====  Implementacija u  BLSCNIV  biblioteci  ==== 
 + 
 +U strukturu **uMag**  dodaću dva nova polja **InKol**  i **OutKol**, ali i u matricu popisa isto to.  Slog u **SasUlaz**  će u polju **ExtLink**  pamtiti **PopID**  polje iz tabele **Popis**. 
 + 
 +=== Matrica popisa === 
 + 
 +Matrica popisa se formira prilikom prebacivanja podataka iz recordseta sa prometom artikala. Tada se za sve slogove, za koje se otkrije da predstavljaju slog popisa, umetne zapis u matricu popisa koja ima sledeći format: 
 + 
 +^Naziv polja^Vrsta^Opis| 
 +|iIndex|Long|Ovde se upisuje broj reda iz osnovne matrice gde se čuvaju svi podaci o slogu popisa. Pošto je taj broj unikatan poslužiće nam kao unikatan index.| 
 +|iElID|Long|ID artikla na koji se popis odnosi| 
 +|iSklID|Long|ID skladišta na kom je popis urađen| 
 +|dDatum|TDateTime|Datum i vreme izrade popisa| 
 +|nLoTKol|Double|Originalna TKol vrednost učitana iz baze| 
 +|nLoKol|Double|Količina uneta kroz popis| 
 +|nChTKol1|Double|Vrednost TKol-a iz poslednjeg Ulaza pre popisa| 
 +|nChTKol2|Double|Vrednost TKol-a iz Ulaza posle popisa| 
 +| | |//< ima još polja u ovoj matrici...potrebno je updateovati ovaj dokument >// | 
 + 
 +=== Implementacija === 
 + 
 +Izmene se dešavaju u modulu za obračun srednjih cena i nivelacija [[:l2:rob:b3:blscniv:index_main|BLSCNIV]]. \\ 
 +Koraci bitni za implementaciju: 
 + 
 +  - Sve izmene uMag.TKol (trenutna količina po faktičkom stanju) su preusmereni na jednu proceduru mSetNewTKol. \\ Izuzetak je jedino promena koja se dešava pod uicajem izlaza (Otpremnice) jer ona ne podleže analizi. 
 +  - TUlazRec strukturi dodato je novo polje LastUlDocTip. U to polje se smešta tip ulaznog dokumenta u trenutku izmene/potvrde TKol-a, kako bi u narednj izmeni mogao da posluži kao informacija o prethodnom tipu dokumenta. \\ Suština ovog polja je da ukaže da li je pre konkretnog Ulaza bio dokument Popisa. Tu je samo u cilju optimizacije, tj. da ne bi svaka izmena morala da traži unazad koji joj je bio prethodni dokument. Pošto nas samo zanima da li je to bio Popis, moguće je da se u ovom polju pojavi i 0. Otpremnice neće uticati na ovo polje. \\ Problem predstavljaju Ulazi po osnovu premeštaja. Tada se ne preduzima ništa, već se nit tekućeg obračuna prekida. Pošto će u budućnosti nit biti nastavljena pozivom mGetNeobradjen funkcije, logično je da ta funkcija postavi i koji je to dokument prethodio ovom koji će se obrađivati (za sve pozive, ne samo za ovaj slučaj). Pošto se u okviru ove funkcije poziva i mGetPrevMCen kako bi se utvrdila prethodna prodajna cena, proširio sam tu funkcija da setuje mbLastPrevDocTip u prvi prethodni DocTip. Vrednost mbLastPrevDocTip mora da se pročita odmah po izlasku iz  mGetPrevMCen funkcije. 
 + 
 +====== Izuzetci iz strukture "važećeg perioda" ====== 
 + 
 +===== Inetrni nalozi za prijem i prenos robe ===== 
 + 
 +U strukturu se ne unose slogovi iz **SasUlaz**  koji imaju **sklid = 0**. U Balansu jedino interni nalozi za prijem ili prenos robe snimaju u **Ulaz > SasUlaz**  pod **sklid = 0**. \\ Pošto ti podaci ionako ne učestvuju u formiranju cena i količina sasvim je ispravno da ne koriste strukturu važećeg perioda. 
 + 
 +===== Dokumenti koji ne utiču na obračun prodajne ili cene koštanja ===== 
 + 
 +Od **06.08.2017**  zapisi koji ne trebaju imati uticaj na važeći period (''defDocTip.FNivelTot = false i defDocTip.FSCObrac = false'') imaju **NULL**  u **vazod**/**vazdo** 
 + 
 +====== Važni upiti ======
  
-|  \\ <font 9pt/inherit;;inherit;;transparent>VazOd</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>VazDo</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>Opis situacije</font>  \\ +^Upit^Opis| 
- \\ <font 9pt/inherit;;inherit;;transparent>39875</font>  \\  \\ <font 9pt/inherit;;inherit;;transparent>401769</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>Ovo je normalno kod prvog jedinog ulaza artikla koji tada važi od datuma ulaza do kraja (1/1/3000)</font>  \\ +|CS_UlaziDDDoc|Novi upit za dobijanje obracunskog peroda sc nivel po predatom dokumentu
- \\ <font 9pt/inherit;;inherit;;transparent>*******</font>  \\ ||| +|CS_UlaziSumIzlazi_Tst|CS_UlaziSumIzlazi samo bez UNIONA po Ulaz tabelama
- \\ <font 9pt/inherit;;inherit;;transparent>39875</font>  \\  \\ <font 9pt/inherit;;inherit;;transparent>39885</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>Ovo je normalno za artikal koji je ponovo nabaljen za 10 dana, pri čemu bi drugi slog izgledao ovako:</font>  \\ +|zCalc_INKOLByDoc_xx|Upiti za dobijanje stanja svih lagera artikala predatog dokumenta na trenutak pre izrade predatog dokumenta
- \\ <font 9pt/inherit;;inherit;;transparent>39885</font>  \\  \\ <font 9pt/inherit;;inherit;;transparent>401769</font>  \\ |  \\   \\ +|CS2_GetPer4Del| | 
- \\ <font 9pt/inherit;;inherit;;transparent>*******</font>  \\ ||| +|CS2_GetPer4New| | 
- \\ <font 9pt/inherit;;inherit;;transparent>39875</font>  \\  \\ <font 9pt/inherit;;inherit;;transparent>39875</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>Ovo je normalno za artikal koji je u toku jednog dana više puta ulazio. Mogući scenario sledećih polja je:</font>  \\ | +|CS2_GetPerErr_1| |
-|  \\ <font 9pt/inherit;;inherit;;transparent>39875</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>39875</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>...ponovo je ušao, ali ima još jedan ulaz od istog dana</font>  \\ | +
-|  \\ <font 9pt/inherit;;inherit;;transparent>39875</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>39885</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>...sledeći ulaz od istog dana važi narednih 9 dana,</font>  \\ | +
-|  \\ <font 9pt/inherit;;inherit;;transparent>39885</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>401769</font>  \\ |  \\ <font 9pt/inherit;;inherit;;transparent>....a 10-tog dana je artikal ponovo ušao, i iza njega više se nije pojavljivao</font>  \\ |+
  
 \\ \\
  
  
  • kb/artikli/optimizacija_po_vazecem_periodu_main.1557684907.txt.gz
  • Last modified: 2019/05/12 18:15
  • by milano