SKT’li Ürünlerin Planlamasında MRP ile Uyarı Gösterilmesi ve MRP Tarafından Dikkate Alınması

Son kullanma tarihli ürünler, özellikle gıda sektöründe hizmet veren şirketler için önemli bir konu.

 SKT’li Ürünlerin Planlamasında MRP ile Uyarı Gösterilmesi ve MRP Tarafından Dikkate Alınması

Son kullanma tarihli ürünler, özellikle gıda sektöründe hizmet veren şirketler için önemli bir konu. Şirketlerin üretim planlama departmanlarıysa, planlama çalışmalarını yaparken son kullanma tarihi olan ürünlerin tarihinin ne zaman sonlandığını bilmek istiyorlar. Biz de bu şekilde bir ihtiyacı olan müşterimize, MD04 (Stok / İhtiyaç Listesi) işlem kodunda son kullanma tarihli partileri olan ürünlerin tarihinin bittiği zamana bu bilgiyi verecek negatif bir kayıt atacak ve MRP’nin de planlama yaparken bu negatif kaydı dikkate alacağı bir geliştirme yaptık. Aşağıda bu geliştirmenin detaylarını göreceksiniz.

İlk olarak bu geliştirmeyi nereye yapacağımızı seçmemiz gerekti. Tabi ki bu yer, MRP elemanlarına (planlı sipariş, ihtiyaç, vs. gibi öğeler) müdahale edilebildiğinden, akla ilk gelen “MD_ADD_ELEMENTS” badi’si içindeki “ADD_CHANGE_ELEMENTS” metodu. Az önce de söylediğim gibi bu badinin uygun görülmesinin sebebi, planlama esnasında ilgili malzeme üzerindeki MRP öğelerini rahat bir şekilde görülebiliyor ve müdahale edilebiliyor olmasından kaynaklanıyor.

Doğru yer seçildikten sonra geriye geliştirmelere başlamak kalıyor. Öncelikle, geliştirmeyi yaptığımız müşterinin son kullanma tarihi geliştirmesi ihtiyacı hammadde ve ambalaj ürünleri için olduğundan, metottaki im_mt61d structure’ının içinde bulunan MTART (Malzeme Türü) alanı için hammadde ve ambalaj malzeme türlerini içeren koşul koyuldu.

“IF im_mt61d-mtart EQ ‘1001’ or im_mt61d-mtart EQ ‘1004’.” Eğer ilgili kayıt bu koşullara uyuyor ise yapılan geliştirme kısmına girecektir.

Bu kısma girdikten sonra, badiye düşen malzeme için MRP öğelerini (üretim yeri stoku, planlı sipariş, ihtiyaç, vs.) içeren ch_copy_mdpsx tablosundaki PLUMI alanı “-“ olan yani stoka – şekilde etki edecek (birincil ihtiyaç, ikincil ihtiyaç, vs.) kayıtlar bir internal tabloya doldurulur. Bunun sebebi, son kullanma tarihiyle yönetilen partilerin, bu “-“ kayıtlar yani ihtiyaçlar giderildikten sonra stokunun kalıp kalmadığı, eğer kalıyorsa ne kadar kaldığını hesaplayabilmektir.

Sonrasında ilgili malzemenin partilerinin bilgilerinin elde edilebilmesi için MCHA, MCHB, MCH1 ve MARC tablolarının joinlendiği kapsamlı bir select atılır. Joinler aşağıdaki şekilde yapılmıştır:

MCHA – MCHB

  • MATNR
  • CHARG
  • WERKS

MCHA – MARC

  • MATNR
  • WERKS

MCHA – MCH1

  • MATNR
  • CHARG

Select’e koşul olarak MCHA’daki MATNR’ye badideki im_mt61d structure’ındaki MATNR, MCHA’daki WERKS’e im_mt61d’deki WERKS ve MCHA’daki LVORM alanı boş’a eşit (mcha~lvorm EQ ”) olacak şekilde verilir.

Alınacak alanlar ise, MCH1 tablosundaki VFDAT (Son kullanım tr) ve CHARG (Parti No) alanları, bir de partilerin stoklarını alabilmek için MCHB tablosundaki CLABS (Tahditsiz Stok) ve CINSM (Kalite Stoku) alanları toplanarak ilgili tablonun (lt_data) tek bir alanına yazılır. Tahditsiz ve kalite stoklarının toplanarak yazılmasının sebebi, müşterinin talebinin stok tahditsizde de olsa kalitede de olsa son kullanma tarihi geçtiyse iki stokun da kullanılamaz hale gelmesi yönünde olmasıdır. Burada önemli olan nokta, mal girişi yapılırken, ilgili partilerin VFDAT yani Son Kullanım Tarihi bilgisinin girilmesi gerekmektedir. Aksi halde VFDAT alanı 0 olan partilere, 31.12.8999 tarihi son kullanma tarihi olarak tanımlanacaktır.

Bu geliştirmede, tüm veriler çekildikten sonra son kullanma tarihi hesaplamalarının bir tablo mantığıyla yapılabilmesi için gerekli alanları içeren bir internal tablo tanımlanmıştır ve gerekli veriler veri tabanından çekildikten sonra bu tablo üzerinden yapılacaktır. Bu tabonun alanları şu şekildedir: VFDAT, CHARG, CLABS, REQUIRED_AMOUNT, REQUIRED_REST, STOCK_REST, USED, RECORD. Bu alanların ifade ettiği veriler aşağıdaki gibidir:

VFDAT: Son Kullanım Tarihi

CHARG: Parti No.

CLABS: Tablodan çekilen Tahditsiz Stok + Kalite Stoku değeri

REQUIRED_AMOUNT: ch_copy_mdpsx tablosundan gelen PLUMI alanı “-“ olan kayıtların MNG01 değeri

REQUIRED_REST: Eğer daha büyük ise, REQUIRED_AMOUNT değerinden CLABS değeri çıkarıldığında kalan miktar

STOCK_REST: Eğer CLABS değeri daha büyük ise, CLABS değerinden REQUIRED_AMOUNT değeri çıkarıldığında kalan miktar

USED: CLABS değerinden çıkarılan değer. Parti stokunun kullanılan miktarını ifade eder.

RECORD: Eğer parti stoku kaldıysa, son kullanma tarihi bitişinde “-“ kayıt atılacak olan kaydı ifade eden değer. “X” ya da “ “ değerlerini alabilir.

Parti bilgilerinin çekildiği select’ten alınan veriler ise, bu tablonun ilgili alanlarına yerleştirilir.

Sonrasında ise stok alanı boş olan kayıtlar, verilerin atıldığı tablodan silinir. Ardından, yukarıda da bahsedildiği üzere, VFDAT alanı boş olan kayıtlar için bu alanın değeri 31.12.8999 olarak tanımlanır. Tabi kod içerisinde bu değer 89991231 şeklinde verilmiştir. Bu işlemle birlikte tablodaki tüm kayıtların son kullanım tarihi alanı doldurulmuş oldu. Doldurulduktan sonra da tüm kayıtlar VFDAT alanına göre küçükten büyüğe doğru sıralanır.

Ardından partilerin olduğu internal tablonun (lt_data) içinde bir döngüye girilir. Bu döngünün içinde de ilk başta ch_copy_mdpsx tablosundaki PLUMI alanı “-“ olan kayıtların doldurulduğu internal tablo (lt_mdps) içinde bir döngüye girilir. Lt_mdps tablosu için olan döngüde şöyle bir koşul vardı: lt_mdps’deki “dat00” alanı lt_data’nın ilgili kaydındaki VFDAT’tan küçük eşit olan kayıtlar ve check alanı “X” olmayan kayıtlar için girilir. Daha iyi anlaşılması için kod görünümü şu şekildedir:

       LOOP AT lt_data ASSIGNING .          LOOP AT lt_mdps ASSIGNING FIELD-SYMBOL()           WHERE dat00 LE -vfdat             AND check NE 'X'.

Bu koşula uygun bir kayıt var ise, bu kaydın miktarı yani MNG01 alanı, hesaplama tablosunun (lt_data) içindeki required_amount (ihtiyaç miktarı) alanına yazılır ve “check” alanının değeri de “X” olarak güncellenir. Check alanı X’lendiği için de tekrar aynı kayıt okunacak olduğunda “check NE ‘X’.” koşulundan geçmez. Bu şekilde ihtiyaç miktarları hesaplama tablosuna doldurulmuş olur.

Artık hesaplamaların yapılmaya başlanacağı kısma gelmiş bulunuyoruz. İlk olarak, bir önceki döngüde (lt_mdps tablosunun içindeki döngü) işlem yapıldıysa, yani lt_mdps tablosunda kayıt var ise bundan sonraki hesaplama kısmına girecektir. Bunun kontrolü, hesaplama kısmının başına

IF sy-subrc EQ 0.  koşulu koyularak sağlanmıştır. Hesaplama kısmında gelindiğinde, öncelikle bir önceki kayıttan required_rest (yani kalan ihtiyaç) alanında bir değer var ise, mevcut satırdaki required_amount (ihtiyaç miktarı) alanına ekleniyor. Required_rest değeri olup olmadığı bilgisi, hesaplamalar yapıldıktan sonra required_rest alanının değerinin yazıldığı lv_required_rest adında bir değişken ile kontrol ediliyor. Bu ilk kayıt olduğu için bir şey ifade etmiyor ancak sonraki kayıtlar için required_rest alanı dolu olduğunda anlamlı bir hareket olacaktı. Sonrasında required_amount – clabs değerine bakılıyor. Daha önce de söylediğim gibi eğer required_amount değeri clabs değerinden büyükse, yani bu çıkarma işleminin sonucu 0’dan büyükse, sonuç required_rest alanına yazılıyor ancak 0’dan küçükse stock_rest (kalan stok) alanına yazılıyor. Bu bilgi doğrultusunda kodda şu şekilde bir eğer koşulu bulunmaktadır:

  IF ( -required_amount - -clabs ) LT 0.

Eğer 0’dan küçükse, çıkarma işlemi yapılıp sonucu –1 ile çarpılarak stock_rest alanına yazılıyor. İhtiyaç miktarı değeri ise kullanılan miktara eşit olduğu için direk used alanına yazılıyor. Tabi ihtiyaç miktarı, parti stokundan küçük olduğu ve ihtiyaç karşılandıktan sonra parti stoku kaldığı için, bu partinin son kullanma tarihi bitmeden karşılayabileceği başka ihtiyaç olmadığı anlamına geliyor. Bu sebeple bu parti, son kullanma tarihine –  kayıt atılacak kayıtlardan oluyor ve tablodaki record alanı değeri “X” yapılıyor. Kalan bir ihtiyaç olmadığı için de lv_required_rest değeri 0’a eşitleniyor.

ELSE.

Eğer required_amount – clabs sonucu 0’dan büyük ise, ihtiyaç miktarı parti stoku kadar karşılandıktan sonra geriye bir miktar ihtiyaç kalıyor anlamına gelmektedir. Bu doğrultuda çıkarma işleminin sonucu required_rest alanına yazılır. Parti stoku da (clabs) kullanılan stok miktarına eşit olduğu için direk used alanına clabs değeri yazılır. Required_rest değeri de bir sonraki kayıtta ihtiyaç miktarına eklenebilmesi için lv_required_rest değişkenine atılır.

Lt_mdps tablosunda olan döngüden sonra sy-subrc değeri 0 değilse, yani lt_mdps tablosunda bir kayıt yoksa, kod üstte anlatılan hesaplama kısmına girmeyecektir. Dolayısıyla şimdi anlatacağım kısım, bu durumlarda nasıl bir yol izlediğimizi gösterecek.

Lt_mdps tablosunun boş olması, parti stoklarını kullanabileceğimiz bir ihtiyaç olmadığı anlamına gelmektedir. Dolayısıyla bu durumda stock_rest alanına clabs alanını (parti stokunu) direkt olarak yazıp, record alanının değerini de “X” yapıyoruz. Bu da parti stokunun komple çöpe gittiği senaryo oluyor. Bu vesileyle tüm hesaplamalar tamamlanmış oluyor.

Yukarıda anlatılan tüm hesaplama işleminin örnek verilerini, daha net anlaşılması açısından yapılan işlemlerle birlikte aşağıdaki tablolardan kontrol edebilirsiniz. İhtiyaç tablosundaki ve parti tablosundaki renk eşleştirmeleri, hangi partinin hangi ihtiyaçları kapsayabileceğini göstermektedir.

CH_COPY_MDPSX tablosundan alınan, PLUMI alanı “-“ olan kayıtlar (Tarihleri ve Miktarları ile):

Parti Verileri ve Hesaplama Tablosu:

Hesaplamalar tamamlandıktan sonra, son kullanma tarihi bittiği gün stoku kalan partiler için eksi kayıt atma kısmı kalıyor. Öncelikle bu partileri ayırabilmek için hesaplama tablosunun (lt_data) son hali üzerinden record alanı “X” olan kayıtlar okunuyor. Sonrasında bu işlem için de MRP öğelerinin (Stok / İhtiyaç Kayıtları) bulunduğu ch_copy_mdpsx isimli tabloya, son kullanma tarihi biten partiler için alanları ve değerleri aşağıdaki gibi olan kayıtlar atılıyor.

 mng01 = stock_rest. à - Kayıt atılacak parti kaydının miktarı, kalan parti stoku kadar dat00 = vfdat. à Kayıt tarihi son kullanma tarihine eşit plumi = '-'.   à Atılacak kaydın – değerli bir kayıt olduğu belirtiliyor delnr = charg. à MRP öğesi numarasına, hangi partinin son kullanma tarihinin geçtiğinin anlaşılabilmesi için Parti No. değeri yazılıyor delkz = 'WA'.  à MRP öğesi türüne, sistemsel olarak kullanılmayan bir tür olan “WA – Mal Çıkışı” veriliyor plaab = '2'.   à Burada verilen 2 değeri, net planlama olduğunu belirtiyor vrfkz = 'X'.   à Bu alana verilen “X” değeri ise, bu kaydın MRP planlaması tarafından dikkate alınacağını ifade ediyor.

Bu kayıtlar tek tek tüm partiler için ch_copy_mdpsx tablosuna eklendikten sonra, son olarak bu badi’de değişiklik yapıldığını sistemin anlaması ve yeni durumu dikkate alması için, metodun içinde bulunan ve bu işe yarayan “ch_changed” değişkeninin değerinin “X” olarak güncellenmesi gerekiyor. Bu değişkenin değeri de “X” olarak güncellendikten sonra, geliştirme tamamlanmış oluyor ve son kullanma tarihine kadar stoku kullanılamayan partilerin, kullanılamayan stokunu, parti bilgisini ve hangi tarihte sona erdiğini gösteriyor ve MRP tarafından da dikkate alınır hale gelmiş oluyor.

Aşağıda SKT’si bitmiş bir partinin örnek kaydının görüntüsünü görebilirsiniz:

Ayrıca, görselde gözüktüğü gibi, ilgili kaydın başında SKT yazması için de MRP öğelerinin metninin revize edilebildiği uyarlama adımında bir revizyon yaptık. Uyarlama adımlarını ve yapılan uyarlamayı da aşağıda görebilirsiniz.