pindesk / openbravoposru

Automatically exported from code.google.com/p/openbravoposru
0 stars 0 forks source link

Возврат продажи через фискальный регистратор #175

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
Хотела поделиться со своим опытом в OpenBravo, в 
плане возвратного чека через фискальник. 
Как и думала, это нужно было реализовать с 
помощью команды возврата, протокола 
Атол(так как у меня фискальник АУРА-01ФР). 
Сначала добавила в ресурсы, в Printer.Ticket теги 
для возвратного чека:
<output>
...
#if (${ticket.ticketType} == 1)
    <fiscalrefund>
      #foreach ($ticketline in $ticket.getLines())

            #set ($newvalue = ${ticketline.getPrice()} * ${ticketline.getMultiply()})

            #if ($ticketline.isProductCom())
                <line price="${newvalue}" units="${ticketline.getMultiply()}" >*${ticketline.printName()}</line>
            #else
                <line price="${newvalue}" units="${ticketline.getMultiply()}" >${ticketline.printName()}</line>
            #end
      #end
      <message>========================================</message>
      <message>Кол-во возвратов: ${ticket.printArticlesCount()}</message>
      #foreach ($paymentline in $ticket.payments)
            #if ($paymentline.name == "cashrefund" )
                <total paid="0">Возврат по чеку:</total>
            #end
      #end

    </fiscalrefund>
    #end

</output>

Потом добавила новые функции для обработки 
команд:

1. DeviceAuraFrComm.java : 

public void sendRefundLine(int iFlag, double dProductPrice, double dSaleUnits) 
throws TicketPrinterException {
        sendMessage(m_FR.RefundLine(iFlag, dProductPrice, dSaleUnits), 1);
    }

2. AuraFr.java :

private static final byte REFUND = (byte) 0x57;
...

public byte[] RefundLine(int iFlag, double dProductPrice, double dProductUnit) {
        ByteArrayOutputStream lineout = new ByteArrayOutputStream();
        lineout.write(STX);
        for (int i = 0; i < PASS.length; i++) lineout.write(PASS[i]);
        lineout.write(REFUND);
        lineout.write(iFlag);
        byte[] MSG = new byte[5];
        MSG = convertDouble(dProductPrice,2);
        for (int i = 0; i < MSG.length; i++) lineout.write(MSG[i]);
        MSG = null;
        MSG = convertDouble(dProductUnit,3);
        for (int i = 0; i < MSG.length; i++) lineout.write(MSG[i]);
        byte[] bData = new byte[lineout.size()];
        bData = lineout.toByteArray();
        lineout.reset();
        for (int i = 0; i < 4; i++) lineout.write(bData[i]);;
        for (int i = 4; i < bData.length; i++) {
            if (bData[i] == ETX || bData[i] == DLE) {
                lineout.write(DLE);
            }
            lineout.write(bData[i]);
        }
        lineout.write(ETX);
        lineout.write(calcCheckSumCRC(lineout.toByteArray()));
        return lineout.toByteArray();
    }
3. TicketParser.java :

startElement(...){
...
case OUTPUT_NONE: ...
else if ("fiscalrefund".equals(qName)) {
                m_iOutputType = OUTPUT_FISCAL_REFUND;
                m_printer.getFiscalPrinter().beginReceipt(2);
            }
...
case OUTPUT_FISCAL_REFUND:
            if ("line".equals(qName)) {
                text = new StringBuffer();
                m_dValue1 = parseDouble(attributes.getValue("price"));
                m_dValue2 = parseDouble(attributes.getValue("units"), 1.0);

            } else if ("message".equals(qName)) {
                text = new StringBuffer();
            } else if ("total".equals(qName)) {
                text = new StringBuffer();
                m_dValue1 = parseDouble(attributes.getValue("paid"));
            }
            break;
}

endElement(...){
...
case OUTPUT_FISCAL_REFUND:
            if ("fiscalrefund".equals(qName)) {
                m_printer.getFiscalPrinter().endReceipt();
                m_iOutputType = OUTPUT_NONE;
            } else if ("line".equals(qName)) {
                m_printer.getFiscalPrinter().printLine(text.toString(), m_dValue1, m_dValue2);
                text = null;
            } else if ("message".equals(qName)) {
                m_printer.getFiscalPrinter().printMessage(text.toString());
                text = null;
            } else if ("total".equals(qName)) {
                m_printer.getFiscalPrinter().printTotal(text.toString(), m_dValue1);
                text = null;
            }
            break;
}

4. Функции m_printer.getFiscalPrinter().beginReceipt(2) и 
m_printer.getFiscalPrinter().printLine(text.toString(), m_dValue1, m_dValue2) 
перегрузила, beginReceipt(2) - для открытия чека 
возврата.

public void beginReceipt(int iType) {
        try {
            m_CommOutputFiscal.connectDevice();
//            m_CommOutputFiscal.sendInitMessage();
            m_CommOutputFiscal.sendSelectModeMessage(1);
            m_CommOutputFiscal.sendBeepMessage();
            m_CommOutputFiscal.sendOpenTicket(0,iType);
        } catch (TicketPrinterException e) {
        }

    }

public void printLine(String sproduct, double dprice, double dunits) {
        try {
            if (dprice >= 0 && dunits >= 0) {
                m_CommOutputFiscal.sendTextMessage(sproduct);
                m_CommOutputFiscal.sendRefundLine(0, dprice / dunits, dunits);
            } else {
                m_CommOutputFiscal.sendTextMessage("Error in ticket line for sale");
            }
        } catch (TicketPrinterException e) {
        }
    }

5. Цену, количество товаров изменила на 
положительные при возврате. Это в JRefundLines.java

Результат можно посмотреть на файле.

Original issue reported on code.google.com by m.makazh...@gmail.com on 20 Sep 2011 at 8:26

Attachments:

GoogleCodeExporter commented 8 years ago
Cпасибо за пост и за покупку.

Original comment by Nsaryb...@gmail.com on 20 Sep 2011 at 8:49

GoogleCodeExporter commented 8 years ago
Отлично!!! Спасибо что развиваете код 
нашего проекта. С удовольствием его 
добавлю в репозитарий. Но у меня есть 
предложение не создавать отдельный тег 
<fiscalrefund>, а разделить <fiscalreceipt> на два типа 
"sale" и "refund" в итоге шаблон фискального чека 
будет иметь вид:

    #if (${ticket.ticketType} == 0)
    <fiscalreceipt type="sale">
      #foreach ($ticketline in $ticket.getLines())
            #if (${ticketline.getTaxInfo().getRate()}==0.1)
                    #set ($vatinfo ="2")
            #elseif (${ticketline.getTaxInfo().getRate()}==0.15)
                    #set ($vatinfo ="3")
            #elseif (${ticketline.getTaxInfo().getRate()}==0.2)
                    #set ($vatinfo ="4")
            #else
                    #set ($vatinfo ="1")
            #end

            #set ($newvalue = ${ticketline.getPrice()} * ${ticketline.getMultiply()} + ${ticketline.getTax()})

            #if ($ticketline.isProductCom())
                <line price="${newvalue}" units="${ticketline.getMultiply()}" tax="${vatinfo}">*${ticketline.printName()}</line>
            #else
                <line price="${newvalue}" units="${ticketline.getMultiply()}" tax="${vatinfo}">${ticketline.printName()}</line>
            #end
      #end
      <message>========================================</message>
      <message>Кол-во продаж: ${ticket.printArticlesCount()}</message>
      #foreach ($paymentline in $ticket.payments)
            #if ($paymentline.name == "cash")
                <total paid="${paymentline.getPaid()}">К оплате по чеку:</total>
            #end
      #end
    </fiscalreceipt>
    #elseif (${ticket.ticketType} == 1) 
    <fiscalreceipt type="refund">
      #foreach ($ticketline in $ticket.getLines())

            #set ($newvalue = ${ticketline.getPrice()} * ${ticketline.getMultiply()})

            #if ($ticketline.isProductCom())
                <line price="${newvalue}" units="${ticketline.getMultiply()}" >*${ticketline.printName()}</line>
            #else
                <line price="${newvalue}" units="${ticketline.getMultiply()}" >${ticketline.printName()}</line>
            #end
      #end
      <message>========================================</message>
      <message>Кол-во возвратов: ${ticket.printArticlesCount()}</message>
      #foreach ($paymentline in $ticket.payments)
            #if ($paymentline.name == "cashrefund" )
                <total paid="0">Возврат по чеку:</total>
            #end
      #end
    </fiscalreceipt>    
    #end

Во вложении мой патч кода проекта для 
реализации такой возможности.

Original comment by svinin...@gmail.com on 20 Sep 2011 at 12:12

Attachments:

GoogleCodeExporter commented 8 years ago
Или даже такой вариант шаблона:

    #if (${ticket.ticketType} == 0)
       #set ($fiscaltickettype = "sale")
    #elseif (${ticket.ticketType} == 1)
       #set ($fiscaltickettype = "refund")    
    #end

    #if ($fiscaltickettype == "sale" || $fiscaltickettype == "refund")
    <fiscalreceipt type="${fiscaltickettype}">
      #foreach ($ticketline in $ticket.getLines())
            #if (${ticketline.getTaxInfo().getRate()}==0.1)
                    #set ($vatinfo ="2")
            #elseif (${ticketline.getTaxInfo().getRate()}==0.15)
                    #set ($vatinfo ="3")
            #elseif (${ticketline.getTaxInfo().getRate()}==0.2)
                    #set ($vatinfo ="4")
            #else
                    #set ($vatinfo ="1")
            #end

            #set ($newvalue = ${ticketline.getPrice()} * ${ticketline.getMultiply()} + ${ticketline.getTax()})

            #if ($ticketline.isProductCom())
                <line price="${newvalue}" units="${ticketline.getMultiply()}" tax="${vatinfo}">*${ticketline.printName()}</line>
            #else
                <line price="${newvalue}" units="${ticketline.getMultiply()}" tax="${vatinfo}">${ticketline.printName()}</line>
            #end
      #end
      <message>========================================</message>
      #if ($fiscaltickettype == "sale")
            <message>Кол-во продаж: ${ticket.printArticlesCount()}</message>
      #elseif ($fiscaltickettype == "refund")
            <message>Кол-во возвратов: ${ticket.printArticlesCount()}</message>
      #end
      #foreach ($paymentline in $ticket.payments)
            #if ($paymentline.name == "cash")
                <total paid="${paymentline.getPaid()}">К оплате по чеку:</total>
            #elseif ($paymentline.name == "cashrefund")
                <total paid="${paymentline.getTotal()}">Возврат по чеку:</total>            
            #end
      #end
    </fiscalreceipt>
    #end

Завтра залью в репозитарий свой вариант 
кода, попробуйте его в действии с этим 
шаблонов, а то у меня сейчас Ауры под руками 
нет. Если всё нормально оставлю его, если 
нет то вернусь на Ваш, хотя я не сторонник 
множества тегов, лучше их дополнительно 
описывать свойствами. Как закончим с 
атоловским протоколом буду пробовать 
реализовать этот функционал для штрихов, 
благо и у нас в Казахстане сейчас появились 
новые Штрихи.

Я Вас добавил в участники проекта, если 
будет интерес напрямую вносить изменения в 
проект свяжитесь со мной по почте или через 
скайп svininykh.

Original comment by svinin...@gmail.com on 20 Sep 2011 at 1:16

GoogleCodeExporter commented 8 years ago

Original comment by svinin...@gmail.com on 20 Sep 2011 at 1:30

GoogleCodeExporter commented 8 years ago
С последним вариантом тоже хорошо 
работает, так что можно добавлять!

Спасибо за ответ, и  за добавление в 
участники :)) 

Original comment by m.makazh...@gmail.com on 21 Sep 2011 at 4:02

GoogleCodeExporter commented 8 years ago
Всё залил изменения в r577, тестируем.

Original comment by svinin...@gmail.com on 21 Sep 2011 at 4:09

GoogleCodeExporter commented 8 years ago
Был баг с отрицательными цифрами и с 
отсутствием итоговой суммы для Ауры, решил 
добавлением Math.abs() в AuraFR.java. В шаблоне 
передачу суммы при возврате всё же оставлю, 
но тем у кого фискальники Штрих или JavaPOS 
надо посмотреть как там она обрабатывается.

Original comment by svinin...@gmail.com on 21 Sep 2011 at 6:30

GoogleCodeExporter commented 8 years ago
В Issue 177 посмотрите что у меня получилось.

Original comment by svinin...@gmail.com on 21 Sep 2011 at 12:11