EAN13 - automatyczne generowanie unikalnego kodu podczas zapisu do bazy

Witam!
Czy ktoś z Was wykorzystywał może gem barby?

Chciałbym mieć możliwość automatycznego generowania kodu EAN13 podczas tworzenia nowego wpisu. Np:
Wpisuje nazwę w nazwie a barcode jest automatycznie generowany podczas zapisu do bazy sprawdza też swoją unikalność z danymi z bazy.

barcode = Barby::UPCA.new(data)

Proszę o wskazówki

Mozesz dodac callback w modelu before_save. W metodzie wywolanej callbackiem mozesz zawrzeć self.barcode = Barby::UPCA.new(data) i w momencie wykonania zapisu modelu bedziesz mial wygenerowany kod kreskowy. Co do unikalnosci dodaj do modelu:
validates :barcode, presence: true, uniqueness: true.

Callbcki nie zawsze sa najlepszym rozwiazaniem wiec radzilbym używać z rozsądkiem.

Dzięki za odpowiedź
Dodałem:

class Barcode < ApplicationRecord

validates :barcode, uniqueness: true

before_save :save_barcode

private
def save_barcode
self.barcode = Barby::UPCA.new(data)
end

end

Co ma być w data? ponieważ mam błąd
undefined local variable or method `data’ for #Barcode:0x007f788e6c2718
Czy gdzieś w kontrolerze trzeba to określić?
Pozdrawiam

@nikos nie używaj before_...

Barcode raczej dostajesz w requeście,

tak, wyciągnij ten kod w kontrolerze z paramsów.

klasa Barby::UPCA dziedziczy po klasie EAN13

Twoje data to 12 cyfr kodu kreskowego EAN13

taki format sprawdza dla pola data konstruktor klasy z której dziedziczy UPCA. - upca dokleja zero z przodu kodu co czyni z EAN13 standard UPC-A (stąd nazwa klasy)

proponuje jakieś poprawne kody wygenerować do testów

Pozdrawiam

ops najważniejsze pozostawiłem bez komentarza :slight_smile:

to co robisz w

To można nazwać automatycznym generowaniem kodu UPC-A z kodu EAN13

Raczej trudno automatycznie generować EAN13 chyba że już wstępną procedurę przeszedłeś i teraz to już tylko dogadanie czytnika z aplikacją i masz tabelę słownik id_produktu, kod_ean13

W moim poprzednim poście zakładałem że masz formę w której oprócz danych produktu wprowadzasz EAN13 i chcesz zrobić z niego UPC-A :confused:

Dzięki za odpowiedz!
Chodziło mi właśnie o losowe generowanie takiego kodu EAN.
Tzn
Tworze nowy produkt i kod EAN13 generuje się sam losowo i bez powtórzeń i zapisać to w bazie danych.

Później chciałbym np mieć możliwość wyświetlenia takiego kodu przerobionego już na kod kreskowy.

A więc poszukując w internecie znalazłem kilka rzeczy które pomogły mi sklecić część kodu:
Chcę aby początek kodu był:
590173
A następnie kolejne 6 cyfr generowane są automatycznie za pomocą:

rand(999999).to_s.center(6, rand(9).to_s)

Więc mój model wygląda tak:

class Barcode < ApplicationRecord

validates :barcode, uniqueness: true, length: { minimum: 12 }
before_validation:save_generate_code

private
def save_generate_code
poczatek = 590173
koniec = rand(999999).to_s.center(6, rand(9).to_s)
self.barcode = [poczatek,koniec].join.to_i
end

end

Teraz muszę w jakiś sposób rozdzielić połączony numer i cyfry nieparzyste mnożymy razy 1 a parzyste razy 3 następnie suma iloczynów dzielona jest przez 10
tutaj np:

10 - sumailoczynow % 10).

Następnie 10 - reszta z dzielenia z tej liczby to nasza suma kontrolna.

Muszę jeszcze dorobić sumę kontrolną i zmienić 12 na 13 cyfr.

Poszukaj w dokumentacji metod takich jak chars, reduce i partition. Jeśli masz mnożenie przez 1 to chyba nie musisz wykonywać takiego działania :wink:

Jak dobrze rozumiem to Twój początek

To jest system numerowy + kod wytwórcy ?

kod produktu

nie musisz :slight_smile: masz metodę data_with_checksum

wystarczy wywołać

barcode.data_with_checksum

lub jeszcz prościej :slight_smile:

barcode.to_s

by dostać kod + cyfrę kontrolną


Twoje data ma 12 cyfr. Zero z przodu dodawane jest tylko przez reader w klasie UPCA, do wyświetlania EAN13 w formacie UPC-A a cyrfra kotrnolna jest obliczana przez sam obiekt, do tego początek jest stały proponuje:

class Barcode < ApplicationRecord

  validates :barcode, uniqueness: true, length: { is: 12 }
  before_validation:save_generate_code

  # stała zamiast zmiennej
  POCZATEK = 590173

  def upca
     # reader wtłaczający 12 cyfr z tabelki w obiekt Barby::UPCA
    @upca = ::Barby::UPCA.new(barcode)
  end  

  def ean13
     # reader wtłaczający 12 cyfr z tabelki w obiekt Barby::EAN13
    @ean13 = ::Barby::EAN13.new(barcode)
  end  

  private

  def save_generate_code
    # barcode zapisujesz zawsze jako 12 cyfr
    # a odczytujesz do widoku metodą ean13 lub utca zależnie od tego który typ
    # można by barcode reader zastąpić przez ean13 lub utca jako Twój default
    koniec = rand(999999).to_s.center(6, rand(9).to_s)
    self.barcode = [POCZATEK,koniec].join.to_i
  end

end

Porównując ze schematem koniec wygląda dziwnie a początek ma nietypową długość

pierwsze 3 cyfry EAN13 to oznaczenie systemu numerowego

dalej numer wytwórcy który może mieć 4,5,6 lub 7 cyfr, odpowiednio wtedy numer produktu może mieć długość 5,4,3 lub 2 cyfry

A Twój początek ma 6 cyfr 3 cyfry systemu numerowego i 3 cyfry kodu wytwórcy ? Tak jakby o 1 za mało?

Pozdrawiam

p.s.

OO w Barby jest trochę… w krzywym zwierciadle :slight_smile:

Hej dzięki za kody! Szkoda, że dopiero odczytałem.
Ten schemat pierwszych 6 ciu cyfr dostałem od koleżanki która tworzyła sobie takie kody w excel i chciała taki schemat zachować.
Wiem, że 12 cyfr powinno być jednak ona potrzebuje cały kod więc moje rozwiązanie było takie:

def save_generate_code
poczatek = 590173
koniec = rand(999999).to_s.center(6, rand(9).to_s)
polaczone = [poczatek,koniec].join.to_s
pociete = polaczone.to_s.split(//).map(&:to_i)
sum = pociete[0] + pociete[1]*3 + pociete[2] + pociete[3]*3 + pociete[4] + pociete[5]*3 + pociete[6] + pociete[7]*3 + pociete[8] + pociete[9]*3 + pociete[10] + pociete[11]*3
if (sum % 10 == 0)
check_code = 0;
else
check_code = 10 - (sum % 10)
end
self.barcode = [polaczone, check_code].join.to_i
end

Oczywiście trzeba będzie je jeszcze uprościć i zmienić.
Jak napisałeś nic nie trzeba było liczyć … :frowning: program sam może w widoku generować ten numer np:

Pozdrawiam

Na pewno skorzystam z Twoich wskazówek dzięki!

W momencie gdy mamy już kody w bazie czy wiesz może jak je wyświetlić w widoku tak aby był widoczny kod kreskowy?

Coś chyba nie bardzo szukałeś :wink:

1 Like

Oj jest. Próbuje wygenerować sobie plik pdf z wybranych kodów ale nie rozumiem tego Barby wcale a wcale.

Wyświetlam pojedynczy kod np tak:

<%= @barcode_for_html.to_html.html_safe %>

W kontrolerze mam

def show
@order_items = current_order.order_items
@barcode1 = Barby::EAN13.new(‘000000000000’)
@barcode_for_html = Barby::HtmlOutputter.new(@barcode1)
end

Próbowałem też innych opcji tzn wykorzystanie skryptu jQuery https://github.com/joushx/jQuery.EAN13 (generuje kreskowy ean13 z liczby) i tu udało mi się wygenerować całą listę. Skryp jQuery generuje png.

Wydruk na drukarce Zebra na wielkości 30x20mm niestety jakość b. kiepska wprost z przeglądarki nie drukuje całego kodu.