Arif

WFN Üye
Konular
638
Mesajlar
638
Çözüm
0
Ticaret Puanı
0
Üyelik
23 Gün
Konum
Bilecik
Web Sitesi
Var
Alanı
SEO Uzmanı
1/1
Konu sahibi
Alış faturası kaydedildiğinde stok miktarını artırmanın güvenli yolu, fatura başlığı ve satırlarıyla birlikte stok güncellemesini aynı veritabanı işlemi içinde yapmaktır. Her fatura satırındaki miktarı ilgili stok kartına ekleyin; işlem başarılı olursa tamamını onaylayın, herhangi bir satırda hata oluşursa faturayı ve stok değişikliğini birlikte geri alın. Böylece fatura kaydedilmiş görünüp stokun eksik artması veya aynı faturanın ikinci kez stoğa eklenmesi önlenir.

Stok artışı hangi aşamada yapılmalı?​


Stok güncellemesini yalnızca kullanıcı arayüzündeki “Kaydet” düğmesinin sonunda yapmak yerine, fatura kaydetme işleminin parçası olan tek bir yordamda gerçekleştirin. Bu yordamın sırası genel olarak şöyledir:
  1. Fatura başlığını ve satırlarını doğrulayın.
  2. Veritabanı işlemini başlatın.
  3. Fatura başlığını kaydedin ve fatura numarasını alın.
  4. Fatura satırlarını kaydedin.
  5. Her satırın miktarını ilgili stok kartına ekleyin.
  6. Gerekliyse stok hareketi kaydı oluşturun.
  7. Bütün adımlar başarılıysa işlemi onaylayın; hata oluşursa geri alın.
Buradaki kritik nokta, alış faturasının gerçekten stoğa alınmış bir belge olup olmadığını ayırmaktır. Taslak veya iptal edilmiş faturalar stok miktarını artırmamalıdır. Fatura sonradan iptal edilebiliyorsa iptal sırasında aynı miktarı tekrar eklemek yerine ters stok hareketi oluşturulmalıdır.

Gerekli veri yapısı​


Örnek olarak aşağıdaki alanların bulunduğu varsayılsın:
  • Stock tablosunda ID ve Quantity alanları bulunuyor.
  • PurchaseInvoice tablosu fatura başlığını, PurchaseInvoiceLine tablosu fatura satırlarını tutuyor.
  • Fatura satırında StockID ve Quantity alanları var.
  • Fatura türü alış faturası, belge durumu da kayda alınmış anlamına gelen bir değer taşıyor.
Gerçek tablo ve alan adlarınız farklı olabilir. Önemli olan, stok güncellemesinin kullanıcıdan alınan hazır SQL metniyle değil, parametreli sorguyla yapılması ve fatura satırındaki miktarın doğru stok kartına bağlanmasıdır.

Bir satırda 12 adet ürün varsa stok güncellemesi kavramsal olarak şu işlemdir:

SQL:
UPDATE Stock
SET Quantity = Quantity + :Quantity
WHERE ID = :StockID

Bu sorgu, mevcut stok miktarını silip yeni değer yazmaz; mevcut değerin üzerine satır miktarını ekler. Örneğin mevcut miktar 40, fatura miktarı 12 ise sonuç 52 olur. Ancak bu sonuç yalnızca sorgunun bir kez ve doğru belge için çalıştırıldığını gösterir; faturanın muhasebe açısından doğru olduğunu veya ürün maliyetinin güncellendiğini tek başına kanıtlamaz.

Delphi’de transaction ile uygulama​


Aşağıdaki örnek FireDAC kullanır. Tablo adları ve alanlar örnektir; kendi veritabanınızdaki adlarla değiştirilmelidir. Fatura satırlarının daha önce bellekte tutulduğu ve ALines listesindeki her kaydın stok kartı ile miktarı içerdiği varsayılmıştır.

Kod:
type
  TInvoiceLine = record
    StockID: Integer;
    Quantity: Double;
  end;

procedure TInvoiceService.SavePurchaseInvoice(
  const AInvoiceNo: string;
  const ALines: TArray<TInvoiceLine>);
var
  LInvoiceID: Integer;
  LLine: TInvoiceLine;
  Q: TFDQuery;
begin
  if Length(ALines) = 0 then
    raise Exception.Create('Fatura en az bir satır içermelidir.');

  for LLine in ALines do
  begin
    if LLine.StockID <= 0 then
      raise Exception.Create('Geçersiz stok kartı.');

    if LLine.Quantity <= 0 then
      raise Exception.Create('Stok miktarı sıfırdan büyük olmalıdır.');
  end;

  Q := TFDQuery.Create(nil);
  try
    Q.Connection := FDConnection1;

    FDConnection1.StartTransaction;
    try
      Q.SQL.Text :=
        'INSERT INTO PurchaseInvoice (InvoiceNo, InvoiceType, Status) ' +
        'VALUES (:InvoiceNo, :InvoiceType, :Status) ' +
        'RETURNING ID';
      Q.ParamByName('InvoiceNo').AsString := AInvoiceNo;
      Q.ParamByName('InvoiceType').AsString := 'PURCHASE';
      Q.ParamByName('Status').AsString := 'POSTED';
      Q.Open;
      LInvoiceID := Q.FieldByName('ID').AsInteger;
      Q.Close;

      for LLine in ALines do
      begin
        Q.SQL.Text :=
          'INSERT INTO PurchaseInvoiceLine ' +
          '(InvoiceID, StockID, Quantity) ' +
          'VALUES (:InvoiceID, :StockID, :Quantity)';
        Q.ParamByName('InvoiceID').AsInteger := LInvoiceID;
        Q.ParamByName('StockID').AsInteger := LLine.StockID;
        Q.ParamByName('Quantity').AsFloat := LLine.Quantity;
        Q.ExecSQL;

        Q.SQL.Text :=
          'UPDATE Stock ' +
          'SET Quantity = Quantity + :Quantity ' +
          'WHERE ID = :StockID';
        Q.ParamByName('Quantity').AsFloat := LLine.Quantity;
        Q.ParamByName('StockID').AsInteger := LLine.StockID;
        Q.ExecSQL;

        if Q.RowsAffected <> 1 then
          raise Exception.CreateFmt(
            'Stok kartı güncellenemedi. StokID: %d',
            [LLine.StockID]);
      end;

      FDConnection1.Commit;
    except
      FDConnection1.Rollback;
      raise;
    end;
  finally
    Q.Free;
  end;
end;

Bu örnekte StartTransaction ile başlayan işlem, fatura başlığını, fatura satırlarını ve stok güncellemelerini kapsar. Commit yalnızca bütün satırlar başarıyla işlendiğinde çalışır. Örneğin üçüncü satırda stok kartı bulunamazsa Rollback çağrılır; önceki iki satırın stok artışı da faturanın kendisi de kalıcı olmaz.

Kullandığınız veritabanı RETURNING ID sözdizimini desteklemiyorsa fatura kimliğini veritabanınıza uygun yöntemle alın. Bu ayrıntı veritabanına göre değişir; fatura numarasını metin olarak kullanıp satırları ona bağlamak da mümkündür, ancak benzersiz bir sayısal kimlik kullanmak yanlış faturaya satır eklenmesi riskini azaltır.

Stok hareketi kaydı neden ayrıca tutulmalı?​


Sadece Stock.Quantity alanını artırmak, güncel toplamı verir; fakat bu artışın hangi faturadan, hangi tarihte ve hangi miktarla geldiğini göstermez. ERP uygulamalarında genellikle stok hareketi tablosu da tutulur. Örnek bir hareket kaydında şu bilgiler bulunabilir:
  • Stok kartı kimliği
  • Hareket türü: alış
  • Miktar
  • Kaynak belge türü ve kimliği
  • Hareket tarihi
  • Kullanıcı veya işlem yapan uygulama
Stok toplamı hareketlerden hesaplanıyorsa ayrıca Stock.Quantity güncellemek yerine hareket kaydı eklenip toplamın bu hareketlerden üretilmesi tercih edilebilir. Mevcut sisteminiz toplam miktarı stok kartında saklıyorsa iki yöntemi aynı işlem içinde uygulayın: hem stok miktarını güncelleyin hem de stok hareketini ekleyin. Biri başarılı, diğeri başarısız kalmamalıdır.

Aynı faturanın iki kez stoğa eklenmesini önleme​


Kullanıcı faturayı yeniden açıp tekrar kaydettiğinde yukarıdaki yordam doğrudan çağrılırsa stok ikinci kez artar. Bunun önüne geçmek için faturada stok hareketinin uygulanıp uygulanmadığını belirten bir alan tutabilir veya kaynak belge kimliğini stok hareketi tablosunda benzersiz yapabilirsiniz.

Örneğin mantık şu şekilde kurulabilir:
  1. Faturanın durumu taslaksa stok artırılmaz.
  2. Fatura ilk kez kayda alınıp kesinleştiriliyorsa stok artırılır ve belge durumu “işlendi” yapılır.
  3. Belge durumu zaten “işlendi” ise stok güncellemesi tekrar çalıştırılmaz.
  4. Fatura iptal ediliyorsa alış miktarı yeniden eklenmez; ters yönde bir stok hareketi oluşturulur.
Bu kontrolün yalnızca Delphi formundaki bir değişkene bırakılması güvenli değildir. Aynı faturayı iki farklı kullanıcı veya iki ayrı istemci kaydedebileceği için kontrol veritabanı transaction'ı ve mümkünse benzersiz kısıtla desteklenmelidir.

Sonucu nasıl kontrol etmelisiniz?​


Fatura kaydedildikten sonra kontrolü yalnızca ekranda “kayıt başarılı” mesajı göstererek yapmayın. Fatura satırındaki miktarı, stok kartının önceki miktarını ve oluşan hareket kaydını birlikte karşılaştırın.

Örneğin stok miktarı 40 iken 12 adetlik alış faturası kaydedildiğinde beklenen yeni miktar 52'dir. Sonuç 40 ise stok güncelleme sorgusu çalışmamış veya yanlış stok kartını hedeflemiş olabilir. Sonuç 64 ise aynı fatura iki kez işlenmiş olma ihtimali vardır. Sonuç 52 olduğu hâlde hareket kaydı yoksa toplam miktar doğru görünür, fakat denetim izi eksiktir.
Görülen sonuçOlası anlamıİzlenecek yol
Stok beklenen miktar kadar arttıGüncelleme bir kez başarılı olmuş olabilirFatura durumu ve stok hareketi kaydını da doğrulayın
Stok hiç artmadıKod çalışmamış, transaction geri alınmış veya yanlış StockID kullanılmış olabilirFatura satırındaki StockID, miktar ve işlem hata kaydını inceleyin
Stok iki kez arttıAynı belge yeniden işlenmiş olabilirBelge durumu ile kaynak fatura kimliğine ait hareketleri kontrol edin; fazladan hareket için ters kayıt uygulayın
Fatura var, bazı satırlar yokTransaction kullanılmamış veya kayıtlar farklı işlemlerde yapılmış olabilirFatura ve stok kayıtlarını tek transaction altında birleştirin
Tablodaki beklenen miktar kontrolü, yalnızca aritmetik bir doğrulamadır. Miktarın doğru çıkması; alış fiyatının, KDV bilgilerinin, depo bilgisinin veya seri-lot takibinin de doğru işlendiği anlamına gelmez. Bu alanlar kullanılıyorsa aynı fatura işlemi içinde ayrıca doğrulanmalı ve kaydedilmelidir.

Depo, seri ve lot takibi varsa​


Tek bir Stock.Quantity alanı, birden fazla depoya veya seri-lot takibine sahip sistemler için yeterli olmayabilir. Bu durumda stok miktarı ürün kartında değil, en azından ürün-depo veya ürün-lot düzeyinde tutulmalıdır. Alış faturasında depo seçilmişse miktarı genel stok alanına değil, seçilen depoya ait kayda ekleyin.

Seri numaralı ürünlerde fatura miktarı 5 ise beş ayrı seri kaydı beklenebilir; lot takipli ürünlerde ise miktar lotlara dağıtılmalıdır. Bu bilgiler eksikse toplam stok artmış görünse bile hangi serinin veya lotun depoya girdiği belirlenemez. Dolayısıyla ana stok güncellemesinden önce ilgili takip bilgilerinin zorunlu olup olmadığını kontrol edin.

Uygulamada dikkat edilmesi gerekenler​

  • Miktar alanını Integer yerine küsuratlı ürünler için Double veya veritabanındaki uygun kesinlikte sayısal türle tutun.
  • Stok güncellemesini string birleştirmeyle değil, parametreli sorguyla yapın.
  • Fatura başlığı, satırları, stok toplamı ve stok hareketini aynı transaction içine alın.
  • Stok kartı bulunamazsa veya güncelleme beklenen satır sayısını etkilemezse işlemi hata kabul edin.
  • Kesinleşmemiş, iptal edilmiş veya iade niteliğindeki belgelerin yönünü alış faturasıyla aynı kabul etmeyin.
  • Faturayı tekrar kaydetme durumunda belge durumu veya benzersiz kaynak belge kontrolü kullanın.
En küçük doğru çözüm, her alış faturası satırı için Quantity = Quantity + fatura_miktarı güncellemesini transaction içinde çalıştırmaktır. ERP uygulamasında güvenilir çözüm ise buna fatura durumu, stok hareketi, tekrar işleme kontrolü ve gerekiyorsa depo-seri-lot ayrımını eklemektir.
 

Sende şimdi bize katılmak ister misin?

Kayıt ol

Bize katılım kolay ve ücretsizdir!

Foruma git ?

Bu konuyu görüntüleyen kullanıcılar

Bu konuyu şu anda görüntüleyen üye bulunmuyor.
Robotlar:
  • Anthropic