<?php

namespace App\Http\Controllers;

use App\Http\Controllers\InvLibController;
use App\Http\Controllers\PdfB2CController;
use App\Models\BitImage;
use App\Models\Customer;
use App\Models\InvbHead;
use App\Models\InvBody;
use App\Models\InvHead;
use App\Models\InvPay;
use App\Models\Param;
use App\Models\Pay;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\Session;
use Intervention\Image\Facades\Image;
use Mike42\Escpos\EscposImage;
use Mike42\Escpos\PrintConnectors\FilePrintConnector;
use Mike42\Escpos\PrintConnectors\NetworkPrintConnector;
use Mike42\Escpos\PrintConnectors\WindowsPrintConnector;
use Mike42\Escpos\Printer;
use Milon\Barcode\Facades\DNS2DFacade;

class PrtInvAobController extends Controller
{
    public static $Param = [];

    public function __construct()
    {
        //self::middleware('admin');
        self::$Param = Param::orderBy('id')->get()->keyBy('id');
    }

    //列印一張發票
    public function index($id)
    {
        if (self::$Param['51']['param_value'] != '') {
            $invtmp = InvHead::where('InvoiceNumber', $id)->First();
            $inv = $invtmp->toArray();
            $inv['reprt'] = 'N';
            if (isset($_GET['onlybody'])) {
                $inv['RandomNumber'] .= 'B';
            }
            $inv['back'] = self::$Param['20']['param_value'];
            $inv['store_id'] = Session::get('Store')->StoreId;
            if (isset($_GET['phone'])) {
                switch ($_GET['phone']) {
                    case ('3'):
                        $inv['back'] = 'phone_quick';
                        break;
                }
            }
            return view('prtlocal', compact('inv'));
        }

        $invtmp = InvHead::where('InvoiceNumber', $id)->First();
        $inv = $invtmp->toArray();
        $inv['body'] = [];
        foreach ($invtmp->invbody as $key => $value) {
            $inv['body'][] = $value->toarray();
        }
        if ($invtmp->invpay != null) {
            $inv['pay'] = $invtmp->invpay->toarray();
        }
        if (isset($_GET['reprt']) and $_GET['reprt'] == 'Y') {
            $inv['reprt'] = 'Y';
        } else {
            $inv['reprt'] = 'N';
        }
        $inv['customer'] = '';
        $inv['cust_addr'] = '';
        if ($inv['Identifier'] != '0000000000') {
            $customer = new Customer;
            switch (env('APP_CUSTNO')) {
                case ('7'): //小馬
                    $customer->setTable('einv_22928539.customers');
                    break;
            }
            $cust = $customer->where('Identifier', $inv['Identifier'])->get()->toArray();
            if ($cust != []) {
                $inv['customer'] = $cust['0']['Name'];
                $inv['cust_addr'] = $cust['0']['Address'];
                $inv['cust_tel'] = $cust['0']['TelephoneNumber'];
            }
        } else {
            $inv['Identifier'] = '';
        }
        //dd($inv);
        self::aob($inv);

        if (self::$Param['40']['param_value'] == '0') {
            return redirect('/' . config('admin.prefix') . '/' . self::$Param['20']['param_value']);
        } else {
            return redirect('/' . config('admin.prefix') . '/uploadxml');
        }
    }

    //列印多張發票
    public function prtmulti(Request $request)
    {
        if (null == session('prtmulti')) {
            $request->session()->forget('reprt');
            if (self::$Param['40']['param_value'] == '0') {
                return redirect(env('APP_URL') . '/' . config('admin.prefix') . '/message?' . '批次開立完成');
            } else {
                return redirect('/' . config('admin.prefix') . '/uploadxml');
            }
        }

        $prttime = session('prttime');
        $prttime++;
        session(['prttime' => $prttime]);
        $id = session('prtmulti.' . array_keys(session('prtmulti'))[0]);

        if (self::$Param['51']['param_value'] != '') {
            $invtmp = InvHead::where('InvoiceNumber', $id)->First();
            $inv = $invtmp->toArray();
            $inv['reprt'] = 'N';
            $inv['store_id'] = self::getstore();
            //列印明細設定
            if (self::$Param['13']['param_value'] == 0) {
                $inv['RandomNumber'] .= 'B';
            }
            $request->session()->forget('prtmulti.' . array_keys(session('prtmulti'))[0]);
            return view('prtlocal', compact('inv'));
        }

        $invtmp = InvHead::where('InvoiceNumber', $id)->First();
        $inv = $invtmp->toArray();
        $inv['body'] = [];
        foreach ($invtmp->invbody as $key => $value) {
            $inv['body'][] = $value->toarray();
        }
        if ($invtmp->invpay != null) {
            $inv['pay'] = $invtmp->invpay->toarray();
        }
        $inv['customer'] = '';
        $inv['cust_addr'] = '';
        $inv['reprt'] = 'N';
        //列印明細設定
        if (self::$Param['13']['param_value'] == 0) {
            $inv['onlybody'] = 'Y';
        } else {
            $inv['onlybody'] = 'N';
        }
        if ($inv['Identifier'] != '0000000000') {
            $customer = new Customer;
            switch (env('APP_CUSTNO')) {
                case ('7'): //小馬
                    $customer->setTable('einv_22928539.customers');
                    break;
            }
            $cust = $customer->where('Identifier', $inv['Identifier'])->get()->toArray();
            if ($cust != []) {
                $inv['customer'] = $cust['0']['Name'];
                $inv['cust_addr'] = $cust['0']['Address'];
            }
        } else {
            $inv['Identifier'] = '';
            if (null != session('reprt')) {
                $inv['reprt'] = 'Y';
            }
        }
        $printer = self::aob_open();
        self::aob_data($printer, $inv);
        self::aob_close($printer);
        sleep(3);
        if (session('prttime') % 10 == 0) {
            sleep(12);
            //return redirect('/'.config('admin.prefix').'/message?' . '批次');
        }
        $request->session()->forget('prtmulti.' . array_keys(session('prtmulti'))[0]);
        return redirect("/prtmulti?" . time() . '-' . session('prttime'));
    }

    public function prtmultiset($id, $id1)
    {
        if (strlen($id) != 10) {
            echo '發票號碼長度錯誤' . $id;
            exit;
        }
        if (strlen($id1) != 10) {
            echo '發票號碼長度錯誤' . $id1;
            exit;
        }
        $head = substr($id, 0, 2);
        $start = substr($id, -8);
        $end = substr($id1, -8);
        //產生發票
        $invstr = [];
        for ($i = $start; $i <= $end; $i++) {
            $invstr[] = $head . sprintf("%'.08d", $i);
        }
        session(['prtmulti' => $invstr]);
        session(['prttime' => 0]);
        return redirect("/prtmulti");
    }

    //補印一張發票
    public function reprt($id)
    {
        if (self::$Param['51']['param_value'] != '') {
            $invtmp = InvHead::where('InvoiceNumber', $id)->First();
            $inv = $invtmp->toArray();
            $inv['reprt'] = 'Y';
            $inv['back'] = 'phone_invhead';
            $inv['store_id'] = self::getstore();
            return view('prtlocal', compact('inv'));
        }

        $invtmp = InvHead::where('InvoiceNumber', $id)->First();
        $inv = $invtmp->toArray();
        $inv['body'] = [];
        foreach ($invtmp->invbody as $key => $value) {
            $inv['body'][] = $value->toarray();
        }
        if ($invtmp->invpay != null) {
            $inv['pay'] = $invtmp->invpay->toarray();
        }
        //列印明細設定
        if (self::$Param['13']['param_value'] == 0) {
            $inv['onlybody'] = 'Y';
        } else {
            $inv['onlybody'] = 'N';
        }
        $inv['reprt'] = 'Y';
        $inv['customer'] = '';
        $inv['cust_addr'] = '';
        if ($inv['Identifier'] != '0000000000') {
            $customer = new Customer;
            switch (env('APP_CUSTNO')) {
                case ('7'): //小馬
                    $customer->setTable('einv_22928539.customers');
                    break;
            }
            $cust = $customer->where('Identifier', $inv['Identifier'])->get()->toArray();
            if ($cust != []) {
                $inv['customer'] = $cust['0']['Name'];
                $inv['cust_addr'] = $cust['0']['Address'];
            }
        } else {
            $inv['Identifier'] = '';
        }
        //dd($inv);
        self::aob($inv);
        return redirect('/' . config('admin.prefix') . '/invhead');
    }

    //開啟印表機
    public static function aob_open()
    {
        $invlib = new InvLibController;
        $invlib->checkprt();
        if (self::$Param['16']['param_value'] != '') {
            $connector = new NetworkPrintConnector(self::$Param['16']['param_value'], 9100);
        } else {
            if (PHP_OS == 'WINNT') {
                if ($invlib->getwinver() < 22000) {
                    $connector = new WindowsPrintConnector(self::$Param['17']['param_value']);
                } else {
                    $connector = new FilePrintConnector(storage_path('inv.data'));
                }
            } else {
                $connector = new FilePrintConnector(self::$Param['17']['param_value']);
            }
        }
        return $printer = new Printer($connector);
    }

    //列印發票+明細
    public static function aob_data($printer, $data)
    {
        if (!isset($data['onlybody'])) {
            $data['onlybody'] = 'N';
        }
        if ($data['Identifier'] != '' or ($data['CarrierType'] == '' and $data['NPOBAN'] == '')) {
            self::aob_head($printer, $data);
        }
        if ($data['Identifier'] != '' or $data['onlybody'] == 'Y' or isset($_GET['onlybody'])) {
            self::aob_body($printer, $data);
        }
        //印完發票開錢櫃
        if (self::$Param['83']['param_value'] != '0') {
            $escpos = explode(',', self::$Param['83']['param_value']);
            $code = '';
            foreach ($escpos as $key => $value) {
                $code .= chr($value);
            }
            $printer->getPrintConnector()->write($code);
        }
    }

    //列印發票
    public static function aob_head($printer, $data)
    {
        $invlib = new InvLibController;
        //$invlib->checkprt();
        $data['seller_id'] = self::$Param['2']['param_value'];
        $data['77'] = $invlib->qr_code_77($data);
        $qrcodetmp = $invlib->qr_code($data);
        $data['qrcode1'] = $qrcodetmp['0'];
        $data['qrcode2'] = $qrcodetmp['1'];

        $br = self::setChr("10"); //換行
        $printer->initialize();
        $printer->getPrintConnector()->write(self::setChr("1B,74,FE", 'hex')); // AOB 指令打印繁体 ESC指令 切换 繁体字库 0x1b 0x74 0xfe

        if (self::$Param['71']['param_value'] == '1' and $data['customer'] != '') {
            //印地址條
            $printer->getPrintConnector()->write(self::setChr("29,33,17"));
            $printer->text(mb_convert_encoding($data['customer'] . "\n", 'big5', 'utf-8'));
            $printer->getPrintConnector()->write($br);
            $printer->getPrintConnector()->write($br);
            $printer->text(mb_convert_encoding($data['cust_addr'] . "\n", 'big5', 'utf-8'));
            if (isset($data['cust_tel'])) {
                $printer->text(mb_convert_encoding($data['cust_tel'] . "\n", 'big5', 'utf-8'));
            }
            $printer->getPrintConnector()->write($br);
            $printer->getPrintConnector()->write($br);
            $printer->getPrintConnector()->write($br);
            $printer->getPrintConnector()->write(self::setChr("29") . 'V1');
        }

        $printer->setJustification(Printer::JUSTIFY_CENTER);
        //營業人企業標章
        if (self::$Param['24']['param_value'] == '') {
            //LOGO
            $printer->getPrintConnector()->write(self::setChr("27,97,1"));
            $printer->getPrintConnector()->write(self::setChr("28,112,1,0") . $br); //Print the specified NV graphics data
            $printer->getPrintConnector()->write(self::setChr("27,97,0"));
        } else {
            //TITLE
            if (mb_strwidth(self::$Param['24']['param_value']) > 16) {
                $printer->getPrintConnector()->write(self::setChr("1D,21,01", 'hex')); //Select character size倍高倍寬
            } else {
                $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex')); //Select character size倍高倍寬
            }
            $printer->text(mb_convert_encoding(self::$Param['24']['param_value'], 'big5', 'utf-8'));
            $printer->getPrintConnector()->write($br);
            $printer->getPrintConnector()->write(self::setChr("27,51,10") . $br);
        }
        $printer->getPrintConnector()->write(self::setChr("27,97,1")); //Select justification 0 Left justification 1 Centered 2 Right justification
        // 電子發票證明聯
        if ($data['reprt'] == 'Y') {
            $printer->getPrintConnector()->write(self::setChr("1D,21,01", 'hex')); //Select character size倍高倍寬
            $printer->text(mb_convert_encoding("電子發票證明聯", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding(" 補印", 'big5', 'utf-8'));
        } else {
            $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex')); //Select character size倍高倍寬
            $printer->text(mb_convert_encoding(" 電子發票證明聯", 'big5', 'utf-8'));
        }
        if (!in_array($data['MessageType'], ['C0401', 'A0401', 'A0101'])) {
            $printer->text(mb_convert_encoding("作廢", 'big5', 'utf-8'));
        }
        $printer->getPrintConnector()->write($br);
        $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex')); //Select character size倍高倍寬
        // 發票年月
        $printer->text(mb_convert_encoding($invlib->getInvMonth($data['InvoiceDate']), 'big5', 'utf-8'));
        $printer->getPrintConnector()->write($br);
        //發票號碼
        $printer->text(mb_convert_encoding(substr($data['InvoiceNumber'], 0, 2) . "-" . substr($data['InvoiceNumber'], -8), 'big5', 'utf-8'));
        $printer->getPrintConnector()->write($br);
        $printer->setJustification();
        $printer->selectPrintMode();
        //時間
        $printer->text(mb_convert_encoding($data['InvoiceDate'] . " " . $data['InvoiceTime'], 'big5', 'utf-8'));
        if ($data['Identifier'] != '') {
            $printer->text(mb_convert_encoding(" 格式:25", 'big5', 'utf-8'));
        }
        $printer->getPrintConnector()->write($br);
        //隨機碼
        $printer->text(mb_convert_encoding("隨機碼:" . $data['RandomNumber'] . " 總計:" . $data['TotalAmount'], 'big5', 'utf-8'));
        $printer->getPrintConnector()->write($br);
        //賣方、買方
        $printer->text(mb_convert_encoding("賣方:" . $data['seller_id'], 'big5', 'utf-8'));
        if ($data['Identifier'] != '') {
            $printer->text(mb_convert_encoding(" 買方:" . $data['Identifier'], 'big5', 'utf-8'));
        }
        $printer->getPrintConnector()->write($br);
        //一維條碼
        $printer->getPrintConnector()->write(self::setChr("27,51,2") . $br);
        $printer->getPrintConnector()->write(self::setChr("27,97,0")); //Select justification 0 Left justification 1 Centered 2 Right justification
        $printer->getPrintConnector()->write(self::setChr("29,104,50"));
        $printer->getPrintConnector()->write(self::setChr("29,119,1") . self::setChr("29,107,69,19"));
        $printer->text($invlib->barcode_19($data));
        $printer->getPrintConnector()->write($br);

        //QRCODE圖片大小
        $img = Image::canvas(280, 130, '#ffffff'); //W 5.7 H 9CM
        $qrCode1png = DNS2DFacade::getBarcodePNG($data['qrcode1'], 'QRCODE', 3, 3);
        //右側QRCODE倍數
        if (strlen($data['qrcode2']) < 100) {
            $qrcodex = 3.5;
        } else {
            $qrcodex = 3;
        }
        $qrCode2png = DNS2DFacade::getBarcodePNG($data['qrcode2'], 'QRCODE', $qrcodex, $qrcodex);
        //比對2個QRCODE大小
        if (Image::make($qrCode1png)->height() != Image::make($qrCode2png)->height()) {
            $qrcodex = 3.5;
            $qrCode2png = DNS2DFacade::getBarcodePNG($data['qrcode2'], 'QRCODE', $qrcodex, $qrcodex);
        }
        //QRCODE
        $img->insert($qrCode1png, 'bottom-left', 5, 5);
        $img->insert($qrCode2png, 'bottom-right', 5, 5);
        $file = public_path('upload/file/' . $data['InvoiceNumber'] . '.png');
        $img->save($file);

        $pic = EscposImage::load($file, false);
        $printer->bitImage($pic);

        $printer->setJustification();
        $printer->selectPrintMode();
        //memo1
        $printer->text(mb_convert_encoding("備註:" . str_replace('&&', "\n", $data['MainRemark']), 'big5', 'utf-8'));
        $printer->getPrintConnector()->write($br);
        //memo2
        $printer->text(mb_convert_encoding("說明:" . self::$Param['25']['param_value'], 'big5', 'utf-8'));
        $printer->getPrintConnector()->write($br);
        $printer->text('PRT AT:' . date('Y-m-d H:i:s'));
        $printer->text('                             ');
        $printer->getPrintConnector()->write($br);
        $printer->text('                             ');
        $printer->getPrintConnector()->write($br);
        $printer->text('                             ');
        $printer->getPrintConnector()->write($br);
    }

    //列印明細
    public static function aob_body($printer, $data)
    {
        $br = self::setChr("10"); //換行
        //明細
        $printer->initialize();
        $printer->getPrintConnector()->write(self::setChr("1B,74,FE", 'hex')); // AOB 指令打印繁体 ESC指令 切换 繁体字库 0x1b 0x74 0xfe
        $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex')); //Select character size倍高倍寬
        $printer->text(mb_convert_encoding("    交易明細\n", 'big5', 'utf-8'));
        $printer->getPrintConnector()->write(self::setChr("1D,21,00", 'hex')); //Select character size倍高倍寬
        //列印客戶資料
        if (self::$Param['72']['param_value'] == '1') {
            if ($data['Address'] != '' or $data['Name'] != '0000') {
                $printer->text(str_repeat("=", 32) . "\n");
                ($data['CustomerNumber'] != '') ? $printer->text(mb_convert_encoding($data['CustomerNumber'] . "\n", 'big5', 'utf-8')) : '';
                ($data['Name'] != '0000') ? $printer->text(mb_convert_encoding($data['Name'] . "\n", 'big5', 'utf-8')) : '';
                ($data['PersonInCharge'] != '') ? $printer->text(mb_convert_encoding($data['PersonInCharge'] . "\n", 'big5', 'utf-8')) : '';
                ($data['TelephoneNumber'] != '') ? $printer->text(mb_convert_encoding($data['TelephoneNumber'] . "\n", 'big5', 'utf-8')) : '';
                ($data['Address'] != '') ? $printer->text(mb_convert_encoding($data['Address'] . "\n", 'big5', 'utf-8')) : '';
            }
        }
        //列印載具資料
        if ($data['CarrierType'] != '' and $data['CarrierId1'] != '') {
            $printer->getPrintConnector()->write($br);
            $printer->text(mb_convert_encoding('發票號碼:' . $data['InvoiceNumber'] . "\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding('載具類別:', 'big5', 'utf-8'));
            switch ($data['CarrierType']) {
                case ('3J002'):
                    $printer->text(mb_convert_encoding('手機條碼' . "\n", 'big5', 'utf-8'));
                    break;
                case ('GQ001'):
                    $printer->text(mb_convert_encoding('自然人憑證' . "\n", 'big5', 'utf-8'));
                    break;
                case ('EG0524'):
                    $printer->text(mb_convert_encoding('趁錢' . "\n", 'big5', 'utf-8'));
                    break;
                case ('EJ0080'):
                    $printer->text(mb_convert_encoding('伊愛恩米會員 ' . "\n", 'big5', 'utf-8'));
                    break;
                case ('EG0528'):
                    $printer->text(mb_convert_encoding('鴻奕會員' . "\n", 'big5', 'utf-8'));
                    break;
                default:
                    $printer->text(mb_convert_encoding($data['CarrierType'] . "\n", 'big5', 'utf-8'));
                    break;
            }
            $printer->text(mb_convert_encoding('載具號碼:' . $data['CarrierId1'] . "\n", 'big5', 'utf-8'));
        }
        //列印愛心碼
        if ($data['NPOBAN'] != '') {
            $printer->getPrintConnector()->write($br);
            $printer->text(mb_convert_encoding('發票號碼:' . $data['InvoiceNumber'] . "\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding('發票捐贈對象:' . $data['NPOBAN'] . "\n", 'big5', 'utf-8'));
        }
        $detailtotal = 0;
        $printer->text(str_repeat("=", 32) . "\n");
        //取得小數設定
        $cc = self::$Param['43']->param_value;
        $point = (strlen($cc) == 1) ? 0 : strlen($cc) - 2; //算出位數
        foreach ($data['body'] as $key => $value) {
            if (self::$Param['89']['param_value'] == 1) {
                $left = strlen(mb_convert_encoding($value['Description'] . round($value['Quantity'], $point) . $value['Unit'] . '*' . round($value['UnitPrice'], $point), 'big5', 'utf-8'));
                $right = strlen(mb_convert_encoding(round($value['Amount'], $point) . $value['TaxType'], 'big5', 'utf-8'));
                if (($left + $right) < 32) {
                    $printer->text(mb_convert_encoding($value['Description'] . round($value['Quantity'], $point) . $value['Unit'] . '*' . round($value['UnitPrice'], $point) . str_repeat(" ", 32 - $left - $right) . round($value['Amount'], $point) . $value['TaxType'] . "\n", 'big5', 'utf-8'));
                } else {
                    $printer->text(mb_convert_encoding($value['Description'] . round($value['Quantity'], $point) . $value['Unit'] . '*' . round($value['UnitPrice'], $point) . round($value['Amount'], $point) . $value['TaxType'] . "\n", 'big5', 'utf-8'));
                }                
            } else {
                $printer->text(mb_convert_encoding($value['Description'] . "\n", 'big5', 'utf-8'));
                $printer->text(iconv('UTF-8', 'BIG5//IGNORE', self::addspace1(round($value['Quantity'], $point) . $value['Unit'] . '*' . round($value['UnitPrice'], $point), round($value['Amount'], $point), $value['TaxType']) . "\n"));
            }
            $detailtotal += round($value['Amount'], $point);
        }
        //列印C12資料
        if ($data['C12'] != '' and self::$Param['46']['param_value'] == '1') {
            $printer->text(str_repeat("=", 32) . "\n");
            $printer->text(mb_convert_encoding(self::addspace('明細合計', $detailtotal), 'big5', 'utf-8'));
            $C12 = explode(',', $data['C12']);
            foreach ($C12 as $key => $value) {
                if ($value != '') {
                    $printer->text(mb_convert_encoding($value . "\n", 'big5', 'utf-8'));
                }
            }
        }
        if ($data['C13'] != '' and self::$Param['67']['param_value'] == '1') {
            $printer->text(mb_convert_encoding(str_replace('&&', "\n", $data['C13']) . "\n", 'big5', 'utf-8'));
        }

        if ($data['C14'] != '' and self::$Param['68']['param_value'] == '1') {
            $printer->text(mb_convert_encoding($data['C14'] . "\n", 'big5', 'utf-8'));
        }
        if ($data['C15'] != '' and self::$Param['69']['param_value'] == '1') {
            $printer->text(mb_convert_encoding($data['C15'] . "\n", 'big5', 'utf-8'));
        }
        //列印稅額資料
        $printer->text(str_repeat("=", 32) . "\n");
        if ($data['Identifier'] == '') {
            if (self::$Param['77']->param_value == 2) {
                $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex'));
                $printer->text(mb_convert_encoding(self::addspace('總計', $data['TotalAmount'], 16), 'big5', 'utf-8'));
                $printer->getPrintConnector()->write(self::setChr("1D,21,00", 'hex'));
            } else {
                $printer->text(mb_convert_encoding(self::addspace('總計', $data['TotalAmount']), 'big5', 'utf-8'));
            }
        } else {
            if ($data['SalesAmount'] != 0) {
                $printer->text(mb_convert_encoding(self::addspace('銷售額(應稅)', $data['SalesAmount']), 'big5', 'utf-8'));
            }
            if ($data['ZeroTaxSalesAmount'] != 0) {
                $printer->text(mb_convert_encoding(self::addspace('銷售額(零稅)', $data['ZeroTaxSalesAmount']), 'big5', 'utf-8'));
            }
            if ($data['FreeTaxSalesAmount'] != 0) {
                $printer->text(mb_convert_encoding(self::addspace('銷售額(免稅)', $data['FreeTaxSalesAmount']), 'big5', 'utf-8'));
            }
            $printer->text(mb_convert_encoding(self::addspace('稅額', $data['TaxAmount']), 'big5', 'utf-8'));
            if (self::$Param['77']->param_value == 2) {
                $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex'));
                $printer->text(mb_convert_encoding(self::addspace('總計', $data['TotalAmount'], 16), 'big5', 'utf-8'));
                $printer->getPrintConnector()->write(self::setChr("1D,21,00", 'hex'));
            } else {
                $printer->text(mb_convert_encoding(self::addspace('總計', $data['TotalAmount']), 'big5', 'utf-8'));
            }
        }
        if (self::$Param['94']->param_value == 1 and isset($data['pay'])) {
            $pays = Pay::all()->keyby('id');
            $printer->text(mb_convert_encoding("\n付款方式\n", 'big5', 'utf-8'));
            foreach ($data['pay'] as $key => $value) {
                $printer->text(mb_convert_encoding($pays[$value['pay_id']]->pay . ' ' . $value['Amount'] . "\n\n", 'big5', 'utf-8'));
            }
        }
        if (self::$Param['29']->param_value != "") {
            $printer->text(mb_convert_encoding(self::$Param['29']->param_value . "\n", 'big5', 'utf-8'));
        }
        //列印交易明細營業人資訊
        if (self::$Param['98']['param_value'] != '') {
            $printer->getPrintConnector()->write($br);
            $p98 = explode('#', self::$Param['98']['param_value']);
            foreach ($p98 as $key => $value) {
                $printer->text(mb_convert_encoding($value . "\n", 'big5', 'utf-8'));
            }
        }
        $printer->cut(Printer::CUT_FULL);
    }

    //列印庿告
    public static function aob_bitimage($printer, $data)
    {
        $bitimage = new BitImage;
        switch (env('APP_CUSTNO')) {
            case ('7'): //小馬
                $bitimage->setTable('einv_22928539.bitimages');
                break;
        }
        $pics = $bitimage::where('start_date', '<=', date('Y-m-d H:i:s'))->where('end_date', '>=', date('Y-m-d H:i:s'))->Get();
        if (count($pics)) {
            foreach ($pics as $key => $value) {
                if (($value->amount_min == 0 and $value->amount_max == 0) or ($value->amount_min <= $data['TotalAmount'] and $value->amount_max >= $data['TotalAmount'])) {
                    for ($i = 0; $i < $pics[$key]->quantity; $i++) {
                        if ($pics[$key]->pic_file != '') {
                            $pic = EscposImage::load(public_path('upload/') . $pics[$key]->pic_file, false);
                            $printer->bitImageColumnFormat($pic);
                        } else {
                            $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex'));
                            $printer->text(mb_convert_encoding($pics[$key]->message . "\n", 'big5', 'utf-8'));
                        }
                        $printer->cut(Printer::CUT_FULL);
                    }
                }
            }
        }
    }

    //測試庿告
    public static function bitimage_test($id)
    {
        $printer = self::aob_open();
        $bitimage = new BitImage;
        switch (env('APP_CUSTNO')) {
            case ('7'): //小馬
                $bitimage->setTable('einv_22928539.bitimages');
                break;
        }
        $pic = $bitimage::find($id);
        if ($pic->pic_file != '') {
            $pic = EscposImage::load(public_path('upload/') . $pic->pic_file, false);
            $printer->bitImageColumnFormat($pic);
        } else {
            $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex'));
            $printer->text(mb_convert_encoding($pic->message . "\n", 'big5', 'utf-8'));
        }
        $printer->cut(Printer::CUT_FULL);
        self::aob_close($printer);
    }

    //關閉印表機
    public static function aob_close($printer)
    {
        $printer->close();
        if (PHP_OS == 'WINNT') {
            $invlib = new InvLibController;
            if ($invlib->getwinver() >= 22000) {
                exec('type ' . storage_path('inv.data') . ' > ' . self::$Param['17']['param_value']);
            }
        }
    }

    //列印發票
    public function aob($data)
    {
        $printer = self::aob_open();
        self::aob_data($printer, $data);
        self::aob_bitimage($printer, $data);
        self::aob_close($printer);
    }

    // chr()
    public static function setChr($str, $type = 'dec')
    {
        $ReVal = "";
        $tmp = str_replace(' ', ',', $str);
        $obj = array();
        $obj = preg_split("/,/", $str);
        if (count($obj) > 0) {
            foreach ($obj as $elmt) {
                $cmd = trim($elmt);
                if ($type == 'dec') {
                    $ReVal .= ($cmd != "") ? chr($cmd) : "";
                } else {
                    $ReVal .= ($cmd != "") ? chr(hexdec($cmd)) : "";
                }
            }
        }
        return $ReVal;
    }

    // XY
    public static function setXy($x, $y)
    {
        $xL = $x % 256;
        $xH = floor($x / 256);
        $yL = $y % 256;
        $yH = floor($y / 256);
        $Reval = chr(29) . "$" . chr($yL) . chr($yH);
        $Reval .= chr(27) . "$" . chr($xL) . chr($xH);
        return $Reval;
    }

    //列印測試
    public function printtest()
    {
        if (self::$Param['51']['param_value'] != '') {
            $inv['InvoiceNumber'] = 'test';
            $inv['RandomNumber'] = '1689';
            $inv['reprt'] = 'N';
            $inv['back'] = self::$Param['20']['param_value'];
            $inv['store_id'] = self::getstore();
            return view('prtlocal', compact('inv'));
        }

        $invlib = new InvLibController;
        $invlib->checkprt();

        if (self::$Param['16']->param_value != '') {
            $connector = new NetworkPrintConnector(self::$Param['16']->param_value, 9100);
        } else {
            if (PHP_OS == 'WINNT') {
                if ($invlib->getwinver() < 22000) {
                    $connector = new WindowsPrintConnector(self::$Param['17']['param_value']);
                } else {
                    $connector = new FilePrintConnector(storage_path('inv.data'));
                }
            } else {
                $connector = new FilePrintConnector(self::$Param['17']['param_value']);
            }
        }

        $printer = new Printer($connector);
        try {
            $printer->initialize();
            $printer->getPrintConnector()->write(self::setChr("1B,74,FE", 'hex')); // AOB 指令打印繁体 ESC指令 切换 繁体字库 0x1b 0x74 0xfe
            //明細
            $printer->getPrintConnector()->write(self::setChr("1D,21,11", 'hex')); //Select character size倍高倍寬
            $printer->text(mb_convert_encoding("印表列印測試成功\n", 'big5', 'utf-8'));
            $printer->getPrintConnector()->write(self::setChr("1D,21,00", 'hex')); //Select character size倍高倍寬
            $printer->text(mb_convert_encoding("測試時間:" . date('Y-m-d H:i:s') . "\n", 'big5', 'utf-8', 'big5', 'utf-8'));
            //BARCODE
            $printer->setBarcodeHeight(40);
            $printer->setBarcodeWidth(1);
            $printer->barcode(date('YmdHis'), Printer::BARCODE_CODE39);
            $printer->cut(Printer::CUT_FULL);
        } finally {
            $printer->close();
            if (PHP_OS == 'WINNT') {
                $invlib = new InvLibController;
                if ($invlib->getwinver() >= 22000) {
                    exec('type ' . storage_path('inv.data') . ' > ' . self::$Param['17']['param_value']);
                }
            }
        }
        return redirect('/' . config('admin.prefix') . '');
    }

    //加入空白
    public static function addspace($data1, $data2, $len = 32)
    {
        $data2 = number_format($data2);
        if (mb_strlen($data1) == 7) {
            $add1 = 6;
        } else {
            $add1 = mb_strlen($data1);
        }
        return $data1 . str_repeat(" ", $len - $add1 * 2 - strlen($data2) - 1) . '$' . $data2 . "\n";
    }

    //加入空白英文字
    public static function addspace1($data1, $data2, $taxtype, $len = 32)
    {
        $data2 = number_format($data2);
        return '  ' . $data1 . str_repeat(" ", $len - strlen($data1) - strlen($data2) - 5) . '$' . $data2 . $taxtype;
    }

    //列印一張四聯單
    public function indexback($id)
    {
        if (self::$Param['51']['param_value'] != '') {
            $invtmp = InvbHead::where('AllowanceNumber', $id)->First();
            $inv = $invtmp->toArray();
            $inv['reprt'] = 'N';
            $inv['InvoiceNumber'] = $id;
            $inv['RandomNumber'] = 'INVB';
            $inv['back'] = self::$Param['20']['param_value'];
            $inv['store_id'] = self::getstore()();
            return view('prtlocal', compact('inv'));
        }

        $invtmp = InvbHead::where('AllowanceNumber', $id)->First();
        $inv = $invtmp->toArray();
        $inv['body'] = [];
        foreach ($invtmp->invbbody as $key => $value) {
            $inv['body'][] = $value->toarray();
        }
        $inv['customer'] = '';
        $inv['cust_addr'] = '';
        if ($inv['Identifier'] != '0000000000') {
            $customer = new Customer;
            switch (env('APP_CUSTNO')) {
                case ('7'): //小馬
                    $customer->setTable('einv_22928539.customers');
                    break;
            }
            $cust = $customer->where('Identifier', $inv['Identifier'])->get()->toArray();
            if ($cust != []) {
                $inv['customer'] = $cust['0']['Name'];
                $inv['cust_addr'] = $cust['0']['Address'];
            }
        } else {
            $inv['Identifier'] = '';
        }
        //dd($inv);
        $printer = self::aob_open();
        self::aobback($printer, $inv);
        self::aob_close($printer);

        if (self::$Param['40']['param_value'] == '0') {
            return redirect('/' . config('admin.prefix') . '/' . self::$Param['20']['param_value']);
        } else {
            return redirect('/' . config('admin.prefix') . '/uploadxml');
        }
    }

    //列印折讓單
    public static function aobback($printer, $data)
    {
        try {
            //明細
            $printer->initialize();
            $printer->getPrintConnector()->write(self::setChr("1B,74,FE", 'hex')); // AOB 指令打印繁体 ESC指令 切换 繁体字库 0x1b 0x74 0xfe
            $printer->text(mb_convert_encoding("  電子發票銷貨退回、進貨退出\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding("      或折讓證明單證明聯\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding("          " . substr($data['AllowanceDate'], 0, 10) . "\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding("折讓單號:" . trim($data['AllowanceNumber']) . "\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding('賣方統編:' . self::$Param['2']['param_value'] . "\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding('賣方名稱:' . self::$Param['24']['param_value'] . "\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding('買方統編:' . $data['Identifier'] . "\n", 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding('買方名稱:' . $data['Name'] . "\n", 'big5', 'utf-8'));
            $printer->text("\n");
            $InvoiceNumber = '';
            foreach ($data['body'] as $key => $value) {
                if ($value['OriginalInvoiceNumber'] != $InvoiceNumber) {
                    $printer->text(mb_convert_encoding('原發票開立日期:' . $value['OriginalInvoiceDate'] . "\n", 'big5', 'utf-8'));
                    $printer->text(mb_convert_encoding('原發票號碼 :' . $value['OriginalInvoiceNumber'] . "\n", 'big5', 'utf-8'));
                    $InvoiceNumber = $value['OriginalInvoiceNumber'];
                }
                $printer->text(mb_convert_encoding($value['OriginalDescription'] . '$' . $value['UnitPrice'] . '*' . $value['Quantity'] . "\n", 'big5', 'utf-8'));
            }
            //列印稅額資料
            $printer->text(str_repeat("=", 32) . "\n");
            $printer->text(mb_convert_encoding(self::addspace('稅額', $data['TaxAmount']), 'big5', 'utf-8'));
            $printer->text(mb_convert_encoding(self::addspace('總計', $data['TotalAmount']), 'big5', 'utf-8'));
            if (self::$Param['29']['param_value'] != "") {
                $printer->text(mb_convert_encoding(self::$Param['29']['param_value'] . "\n", 'big5', 'utf-8'));
            }
            $printer->text(mb_convert_encoding('簽收人：' . "\n", 'big5', 'utf-8'));
            $printer->cut(Printer::CUT_FULL);
        } finally {
        }
    }

    //手動開錢櫃
    public function opendrawer()
    {
        $printer = self::aob_open();
        $escpos = explode(',', self::$Param['83']['param_value']);
        $code = '';
        foreach ($escpos as $key => $value) {
            $code .= chr($value);
        }
        $printer->getPrintConnector()->write($code);
        self::aob_close($printer);
        return redirect('/' . config('admin.prefix') . '/' . self::$Param['20']['param_value']);
    }

    //列印發票主檔圖檔
    public static function prtpng($id, $cut = 'Y')
    {
        $pdf = new PdfB2CController;
        $pdf->pngb2c($id);
        $file = public_path('upload/file/' . $id . '.png');
        $printer = self::aob_open();
        $pic = EscposImage::load($file, false);
        // $printer->bitImage($pic);
        $printer->bitImageColumnFormat($pic);
        unlink($file);
        if ($cut == 'Y') {
            $printer->cut(Printer::CUT_FULL);
            self::aob_close($printer);
        }
    }

    //取得門市
    public function getstore()
    {
        if (Session::has('Store')) {
            if (Session::get('Store')->id != 1 and Session::get('Store')->StoreId != substr($this->table, 0 - strlen(Session::get('Store')->StoreId))) {
                return Session::get('Store')->StoreId;
            }
        } else {
            if (Config::get("app.store_id") != '') {
                if (Config::get("app.store_id") != substr($this->table, 0 - strlen(Config::get("app.store_id")))) {
                    return Config::get("app.store_id");
                }
            }
        }
        return '';
    }

}
