창고 및 매장 관리 시스템 구축 - Pt. 4 - 최종




그럼 어떻게 하면 진짜로 작동하게 할 수 있을까요? ️😎

자, 자세히 설명하겠습니다(bismillah). 첫 번째 단계는 위의 흐름으로 작업하는 데 필요한 라이브러리를 준비하는 것입니다.
  • Michael Billington의 ESCPOS PHP
  • 워커의 노동자
  • 그리고 ☕ 한잔

  • ESCPOS PHP 설치




    composer require mike42/escpos-php
    


    This library implements a subset of Epson's ESC/POS protocols for thermal receipt printers. It allows you to create and print receipts in basic, cut, and barcode formats on a compatible printer.



    Workerman 설치




    composer require workerman/workerman
    


    This library is used to create a websocket server which will later provide a bridge between the browser and the client computer. So that the website application can trigger the printer.



    웹소켓 서버 생성


    workerman를 사용하여 websocket 서버를 매우 쉽게 만들 수 있습니다. 다음은 websocket을 만드는 코드입니다.

    <?php
    
    use Workerman\Worker;
    
    require_once __DIR__ . '/vendor/autoload.php';
    
    // Create a Websocket server
    $ws_worker = new Worker('websocket://0.0.0.0:8889');
    
    // Emitted when new connection come
    $ws_worker->onConnect = function ($connection) {
        echo "New connection open" . PHP_EOL;
    };
    
    // Emitted when data received
    $ws_worker->onMessage = function ($connection, $message) {
        // Send hallo $data
        $connection->send('Hallo ' . $message);
    };
    
    // Emitted when connection closed
    $ws_worker->onClose = function ($connection) {
        echo "Connection closed" . PHP_EOL;
    };
    
    // Run worker
    Worker::runAll();
    


    위의 코드는 github의 workerman/workerman 페이지에 있는 사용법 예제에서 websocket 서버를 생성한 예제입니다.

    websocket 서버 예제에서 벗어나 브라우저에서 온라인 웹 사이트 애플리케이션과 통신하기 위한 프린터 서버를 쉽게 만들 수 있습니다.

    물론 수행해야 하는 몇 가지 조정이 있습니다. 즉, 프린터를 사용할 때 필요한 사항입니다.
  • 프린터가 영수증을 인쇄하는 데 사용됩니다.
  • 데이터베이스에서 영수증까지 구매 데이터 표시
  • 영수증이 인쇄되면 브라우저에 신호를 보냅니다
  • .
  • 프린터 서버와 웹 사이트 응용 프로그램 간에 연결 표시 신호 전송

  • Websocket으로 프린터 서버 만들기




    <?php
    
    use Workerman\Worker;
    
    require_once __DIR__ . '/vendor/autoload.php';
    
    // Functions
    function sendToAll( $connection, $message )
    {
        $connection->send($message);
    }
    
    function createMessage( $type = 'info', $message )
    {
        $timestamps = date('Y/m/d H:i:s');
        $log = strtoupper($type);
        return "[$timestamps][$log] $message";
    }
    // End Functions
    
    echo createMessage("info", "Waiting connection...") . PHP_EOL;
    
    // Create a Websocket server
    $ws_worker = new Worker('websocket://0.0.0.0:8182');
    
    // Emitted when new connection come
    $ws_worker->onConnect = function ($connection) {
            $message = createMessage("info", "New connection open") . PHP_EOL;
            echo $message;
            sendToAll($connection, $message);
    };
    
    // Emitted when data received
    $ws_worker->onMessage = function ($connection, $message) {
        // Send hello $data
        $connection->send('Hello ' . $message);
    };
    
    // Emitted when connection closed
    $ws_worker->onClose = function ($connection) {
        echo "Connection closed" . PHP_EOL;
    };
    
    // Run worker
    Worker::runAll();
    


    이름workerman-printer.php으로 저장하고 터미널에서 다음 명령으로 실행합니다.

    php workerman-printer.php start
    




    터미널 콘솔 보기

    그리고 Simple WebSocket Client을 사용하여 websocket 연결을 테스트하십시오.
  • 서버 위치를 주소에 연결ws://127.0.0.1:PORT
  • Workerman 메시지를 사용하여 WebSocket 서버로 데이터를 보내려고 합니다.
  • 메시지 로그에서 결과 보기



  • 단순 WebSocket 클라이언트 표시Fenjin Wang

    프린터용 WebSocket 서버 생성이 순조롭게 진행되어 이제 브라우저의 온라인 애플리케이션에서 인쇄할 영업 노트 형식으로 이동합니다.

    인쇄 시 영수증 형식 만들기



    ESCPOS-PHP에서 영수증 형식의 예를 들어 보겠습니다. 먼저 우리가 만들어야 하는 것은 항목 이름과 가격을 열로 설정하는 래퍼 클래스입니다.

    <?php
    /* A wrapper to do organise item names & prices into columns */
    class item
    {
        private $name;
        private $price;
        private $dollarSign;
    
        public function __construct($name = '', $price = '', $dollarSign = false)
        {
            $this -> name = $name;
            $this -> price = $price;
            $this -> dollarSign = $dollarSign;
        }
    
        public function __toString()
        {
            $rightCols = 10;
            $leftCols = 38;
            if ($this -> dollarSign) {
                $leftCols = $leftCols / 2 - $rightCols / 2;
            }
            $left = str_pad($this -> name, $leftCols) ;
    
            $sign = ($this -> dollarSign ? '$ ' : '');
            $right = str_pad($sign . $this -> price, $rightCols, ' ', STR_PAD_LEFT);
            return "$left$right\n";
        }
    }
    


    그런 다음 ESCPOS-PHP 명령을 래핑하는 함수를 만듭니다.

    <?php
    
    function print_receipt($arrData) {
        switch (strtolower(php_uname('s'))) {
         case "linux":
                    // Make sure if using /dev/usb/lp0 you have access permissions
            $connector = new Mike42\Escpos\PrintConnectors\FilePrintConnector("/dev/usb/lp0");
         break;
         default:
                    // Dynamic printer name
            $connector = new Mike42\Escpos\PrintConnectors\WindowsPrintConnector($arrData['printer_name']);
         break;
      }
    
        $printer = new Mike42\Escpos\Printer($connector);
    
        /* Name of shop */
        $printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH);
        $printer -> text("ExampleMart Ltd.\n");
        $printer -> selectPrintMode();
        $printer -> text("Shop No. 42.\n");
        $printer -> feed();
    
        /* Title of receipt */
        $printer -> setEmphasis(true);
        $printer -> text("SALES INVOICE\n");
        $printer -> setEmphasis(false);
    
        /* Items */
        $printer -> setJustification(Printer::JUSTIFY_LEFT);
        $printer -> setEmphasis(true);
        $printer -> text(new item('', '$'));
        $printer -> setEmphasis(false);
        $subtotal = [];
        foreach ($arrData['items'] as $item) {
            $printer -> text(new Item($item['name'], $item['price']));
                array_push($subtotal, $item['price']);
        }
        $printer -> setEmphasis(true);
        $printer -> text(new Item('Subtotal', array_sum($subtotal)));
        $printer -> setEmphasis(false);
        $printer -> feed();
    
        /* Tax and total */
        $total = array_sum($subtotal) + $arrData['tax'];
        $printer -> text(new Item('A Local Tax', $arrData['tax']));
        $printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH);
        $printer -> text(new Item('Total', $total));
        $printer -> selectPrintMode();
    
        /* Footer */
        $date = date('l jS \of F Y h:i:s A');
        $printer -> feed(2);
        $printer -> setJustification(Printer::JUSTIFY_CENTER);
        $printer -> text("Thank you for shopping at ExampleMart\n");
        $printer -> text("For trading hours, please visit example.com\n");
        $printer -> feed(2);
        $printer -> text($date . "\n");
    
        /* Cut the receipt and open the cash drawer */
        $printer -> cut();
        $printer -> pulse();
    
        $printer -> close();
    }
    


    인쇄할 영수증 형식만 만들어도 충분하고 workerman-printer.php 파일에서 하나로 합치면 코드를 볼 수 있습니다. 이와 같이:

    <?php
    
    use Workerman\Worker;
    use Mike42\Escpos\Printer;
    use Mike42\Escpos\PrintConnectors\FilePrintConnector;
    use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
    
    require_once __DIR__ . '/vendor/autoload.php';
    
    // Functions
    function sendToAll( $connection, $message )
    {
        $connection->send($message);
    }
    
    function createMessage( $type = 'info', $message )
    {
        $timestamps = date('Y/m/d H:i:s');
        $log = strtoupper($type);
        return "[$timestamps][$log] $message";
    }
    
    function print_receipt($arrData) {
        switch (strtolower(php_uname('s'))) {
         case "linux":
                    // Make sure if using /dev/usb/lp0 you have access permissions
            $connector = new FilePrintConnector("/dev/usb/lp0");
         break;
         default:
                    // Dynamic printer name
            $connector = new WindowsPrintConnector($arrData['printer_name']);
         break;
      }
    
        $printer = new Printer($connector);
    
        /* Name of shop */
        $printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH);
        $printer -> text("ExampleMart Ltd.\n");
        $printer -> selectPrintMode();
        $printer -> text("Shop No. 42.\n");
        $printer -> feed();
    
        /* Title of receipt */
        $printer -> setEmphasis(true);
        $printer -> text("SALES INVOICE\n");
        $printer -> setEmphasis(false);
    
        /* Items */
        $printer -> setJustification(Printer::JUSTIFY_LEFT);
        $printer -> setEmphasis(true);
        $printer -> text(new item('', '$'));
        $printer -> setEmphasis(false);
        $subtotal = [];
        foreach ($arrData['items'] as $item) {
            $printer -> text(new Item($item['name'], $item['price']));
                array_push($subtotal, $item['price']);
        }
        $printer -> setEmphasis(true);
        $printer -> text(new Item('Subtotal', array_sum($subtotal)));
        $printer -> setEmphasis(false);
        $printer -> feed();
    
        /* Tax and total */
        $total = array_sum($subtotal) + $arrData['tax'];
        $printer -> text(new Item('A Local Tax', $arrData['tax']));
        $printer -> selectPrintMode(Printer::MODE_DOUBLE_WIDTH);
        $printer -> text(new Item('Total', $total));
        $printer -> selectPrintMode();
    
        /* Footer */
        $date = date('l jS \of F Y h:i:s A');
        $printer -> feed(2);
        $printer -> setJustification(Printer::JUSTIFY_CENTER);
        $printer -> text("Thank you for shopping at ExampleMart\n");
        $printer -> text("For trading hours, please visit example.com\n");
        $printer -> feed(2);
        $printer -> text($date . "\n");
    
        /* Cut the receipt and open the cash drawer */
        $printer -> cut();
        $printer -> pulse();
    
        $printer -> close();
    }
    // End Functions
    
    /* A wrapper to do organise item names & prices into columns */
    class item
    {
        private $name;
        private $price;
        private $dollarSign;
    
        public function __construct($name = '', $price = '', $dollarSign = false)
        {
            $this -> name = $name;
            $this -> price = $price;
            $this -> dollarSign = $dollarSign;
        }
    
        public function __toString()
        {
            $rightCols = 10;
            $leftCols = 38;
            if ($this -> dollarSign) {
                $leftCols = $leftCols / 2 - $rightCols / 2;
            }
            $left = str_pad($this -> name, $leftCols) ;
    
            $sign = ($this -> dollarSign ? '$ ' : '');
            $right = str_pad($sign . $this -> price, $rightCols, ' ', STR_PAD_LEFT);
            return "$left$right\n";
        }
    }
    
    echo createMessage("info", "Waiting connection...") . PHP_EOL;
    
    // Create a Websocket server
    $ws_worker = new Worker('websocket://0.0.0.0:8182');
    
    // Emitted when new connection come
    $ws_worker->onConnect = function ($connection) {
            $message = createMessage("info", "New connection open") . PHP_EOL;
            echo $message;
            sendToAll($connection, $message);
    };
    
    // Emitted when data received
    $ws_worker->onMessage = function ($connection, $message) {
        $data = json_decode($message, true);
        echo '> printing from: ' . $data['from'] . PHP_EOL; // to console
        sendToAll( $connection, createMessage('info', 'printing_from: ' . $data['from']) ); // to browser
      echo '> activer_printer: ' . $data['printer_name'] . PHP_EOL; // to console
      sendToAll( $connection, createMessage('info', 'active_printer: ' . $data['printer_name']) ); // to browser
      echo '< echo', "\n"; // to console
      try {
         print_receipt($data);
         echo "[INFO][" . date('Y-m-d h:i:s') . "] Staff " . $data['staff_fullname'] . " print transaction number " . $data['trx_number'] . PHP_EOL; // to console
         sendToAll( $connection, createMessage('info', "notifiy: Kasir " . $data['staff_fullname'] . " print transaction number " . $data['trx_number']) ); // to browser
      } catch (Exception $e) {
         echo "Couldn't print to this printer: " . $e->getMessage() . "\n"; // to console
         sendToAll( $connection, createMessage('error', "Couldn't print to this printer: " . $e->getMessage()) ); // to browser
      }
    };
    
    // Emitted when connection closed
    $ws_worker->onClose = function ($connection) {
        echo "Connection closed" . PHP_EOL;// to console
    };
    
    // Run worker
    Worker::runAll();
    

    workerman-printer.php 파일을 사용하여 위에서 설명한 도구로 테스트할 수 있습니다. WebSocket 클라이언트에서 서버로 보내는 데이터 형식은 다음과 같습니다.

    {
        "trx_number": "TRX-00017845",
        "items": [
            {"name": "An Example Item #1", "price": 1.45},
            {"name": "Another Item", "price": 3.45},
            {"name": "Something else", "price": 2.45},
            {"name": "Final Item", "price": 1.50}
        ],
        "tax": 1.30,
        "from": "Application Name",
        "printer_name": "ESPON TM-U220",
        "staff_fullname": "Ryan Oz"
    }
    


    잊지 마세요! WebSocket은 String만 전송하므로 JavaScript를 사용하는 경우 JSON.strigify(data)를 사용하십시오.

    다음 명령을 사용하여 터미널에서 workerman-printer.php 파일을 실행합니다.

    # run with DEBUG
    php workerman-printer.php start
    
    # or run in background
    php workerman-printer.php start -d
    


    창고 및 매장 관리 시스템 구축 시리즈의 마지막 글입니다. 읽어 주셔서 감사합니다.

    이 게시물이 유용하다고 생각되면 저를 위해 기부할 수 있습니다.
    경유 Saweria (인도네시아) 또는 경유 BuyMeCoffee , PayPal

    좋은 웹페이지 즐겨찾기