Код:
import bitel.billing.server.util.*;
import ru.bitel.bgbilling.kernel.contract.balance.server.event.PaymentEvent;
import bitel.billing.server.contract.bean.Payment;
import bitel.billing.server.contract.bean.*;
import ru.bitel.bgbilling.plugins.cashcheck.server.bean.*;
import ru.bitel.bgbilling.plugins.cashcheck.common.Printer;
import ru.bitel.bgbilling.kernel.plugin.server.*;
import ru.bitel.bgbilling.common.BGMessageException;
import bitel.billing.common.BGException;
import ru.bitel.bgbilling.kernel.plugin.server.BGPluginServer;
import ru.bitel.billing.server.script.bean.ScriptMachineManager;
import org.w3c.dom.*;
import javax.servlet.http.HttpSession;
import java.math.BigDecimal;
import ru.bitel.frk.client.CmdProtocolClient;
import java.util.Arrays;
import java.util.List;
import java.sql.Connection;
import ru.bitel.billing.server.admin.bean.AddressUtils;
/*
Скрипт печати чека при добавлении платежа.
Вешается на событие PaymentEvent ("приход платежа").
В данной версии отслеживается тип платежа и реакция происходит на какой-то из них.
В зависимости от типа платежа печатается на определённый регистратор и определённого вида чек.
Используется настройка регистратора из конфига плагина CashCheck.
Также печатается только для определённых групп юзеров биллинга.
Внимание:
1) очередь печати чеков игнорируется.
2) настройки маппинга платежей на принтеры из конфига плагина игнорируются.
Это означает, что ОЧЕНЬ ЖЕЛАТЕЛЬНО, чтобы на тот тип платежей, которые здесь печатаются автоматом
в конфиге плагина НЕ БЫЛО маппинга на принтер. Иначе все эти платежи помимо распечатки тут попадут
также и в очередь, будут мешаться и смогут быть повторно распечатаны. Также при добавлении прихода
в клиенте биллинга нельзя ставить галочку "печатать чек", иначе печать чека будет инициирована ДВАЖДЫ.
Отсутствие маппинга спасёт и в этом случае - напечатать чек по галочке (как и из очереди) станет невозможно.
Скрипт написан для версии 5.0
*/
/**
* Здесь список всех юзеров, для которых сработает автопечать при приходе платежа.
*/
final static int[] USERS ={1,21};
/**
* Здесь выборка принтера по типу платежа. Берутся настройки из конфига плагина.
*/
// параметры регистратора: номер (из конфига плагина) и пароль, заполняются в методе
int FR_ID;
String FR_PASS;
private boolean changePrinter( int paymentTypeId )
{
switch( paymentTypeId )
{
case 13:
FR_ID = 1;
FR_PASS = "03";
return true;
default:
return false;
}
}
/**
* формируем объект-чек.
* Добавляются сколько-то строк и одна только addPayment, ведь платёж у нас тут всегда один
* и позиция, стало быть, тоже всегда одна
*/
private Check makeCheck( Payment payment, int paymentTypeId, Connection con )
{
switch( paymentTypeId )
{
case 13:
BigDecimal summa = payment.getSumma();
int cid = payment.getContractID();
Check check = new Check();
check.addString( " " );
int paycode = (1000000000 + cid);
//check.addString( "Телематические услуги связи(Интернет)" );
//check.addString( "Договор №: " + payment.getContractTitle() );
// догогор вытаскиваем
Contract contract = new ContractManager( con ).getContractById( cid );
if( contract != null )
{
check.addString( "Договор №: " + contract.getTitle() );
check.addString( "Код для оплаты в терминалах: " + paycode );
}
else
{
check.addString( "Договор неизвестный (ошибка)" );
}
// параметр вытаскиваем
int PARAM_ID = 3;
//ContractParameterManager bgParamMan = new ContractParameterManager( con );
//String paramVal = bgParamMan.getStringParam( cid, PARAM_ID );
//check.addString( "ФИО/Организация: ");
//check.addString( paramVal );
//check.addString( " " );
check.addString(
"Ваш текущий баланс: " +
(new BalanceUtils( con )).getBalance( new Date(), cid ).toPlainString()
);
check.setPaymentType(2);
check.addPayment( summa.floatValue(), "Оплата услуг ТК Фиалка через POS-терминал", 0 );
return check;
default:
return null;
}
}
public void onEvent( event, setup, con, conSlave )
{
PaymentEvent paymentEvent = (PaymentEvent)event;
Payment payment = paymentEvent.getPayment();
Arrays.sort( USERS );
if( Arrays.binarySearch( USERS, payment.getUserID() ) >=0 )
{
print( "CashCheck Autoprint: user id="+payment.getUserID()+", payment should be automatically printed!" );
int paymentTypeId = payment.getPaymentTypeID();
if( changePrinter( paymentTypeId ) )
{
print( "CashCheck Autoprint: paymentTypeId="+paymentTypeId+", payment should be automatically printed!" );
// Получаем плагин, принтер менеджер и сам принтер пытаемся получить
BGPluginServer plugin = BGPluginManagerServer.getManager().getPlugin( "ru.bitel.bgbilling.plugins.cashcheck" );
Element rootNode = null;
HttpSession session = null;
PrinterManager printerManager = new PrinterManager( plugin, rootNode );
Map printers = printerManager.getPrinterMap();
Printer printer = printers.get( FR_ID );
if ( printer == null )
{
error( "CashCheck Autoprint: ККМ не настроен" );
return;
}
// код похож на тот, что в экшене печати чека, но в отличие от него тут мы
// ничего не чекаем в очереди. надо озаботиться, чтобы в очередь не попадало.
Check check = makeCheck( payment, paymentTypeId, con );
if( check != null )
{
String clientsumma = check.getPaymentsum().toPlainString();
// запрос к серверу печати
CmdProtocolClient client = new CmdProtocolClient( printer.getAddress(), printer.getPort() );
try
{
client.connect();
boolean result = client.send( "check", new Object[]{FR_PASS, clientsumma, check.getPlines()} );
if( result == false )
{
error( "CashCheck Autoprint: Ошибка! ККМ сказала: " + client.getReply() );
return;
}
print( "CashCheck Autoprint: check was printed!" );
}
catch( ConnectException e )
{
error( "CashCheck Autoprint: Ошибка обмена с сервером печати ККМ: " + e.getMessage() );
}
finally
{
try{client.disconnect();}catch( ConnectException e ){}
}
}
else
{
print( "CashCheck Autoprint: makeCheck: paymentTypeId="+paymentTypeId+", payment NOT printed!" );
}
}
else
{
print( "CashCheck Autoprint: changePrinter: paymentTypeId="+paymentTypeId+", payment NOT printed!" );
}
}
else
{
print( "CashCheck Autoprint: user id="+payment.getUserID()+", payment NOT printed!" );
}
}
висит на событии приход платежа