Создание счета и счет-фактур в модуле Bill(выполнение тех же действий что и руками)

Материал из BiTel WiKi

Перейти к: навигация, поиск

Создает счета или счет-фактуры в зависимости от выставленных параметров:

счета

BillManager pbm = new BillManager( setup, con, mid, moduleSetup );

счет-фактуры

InvoiceManager pbm = new InvoiceManager( setup, con, mid, moduleSetup );

выполняет те же действия что и если их выставлять руками в соответствии с настройками модуля.

v 1.0 by skyb

import bitel.billing.server.util.*;
import ru.bitel.bgbilling.server.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.math.BigDecimal;
import bitel.billing.server.bill.bean.*;
import bitel.billing.server.contract.bean.*;
import bitel.billing.common.*;
import java.io.StringWriter;
import bitel.billing.server.bill.bean.BillManager;
 
 
public void main( setup, con, conSlave )
{
int mid = 65; //mid модуля Бухгалтерии
int accountId =1; // id счета банка
 
Calendar month = new GregorianCalendar();
int mm = month.get(Calendar.MONTH);
int yy = month.get(Calendar.YEAR);
month.set(Calendar.DAY_OF_MONTH,1);
 
BalanceUtils bu = new BalanceUtils( conSlave );   
ModuleSetup moduleSetup = setup.getModuleSetup( mid );
TemplateBillManager man = new TemplateBillManager( moduleSetup, conSlave, mid, false );
List templateBillList = man.getTemplatePayBillList( moduleSetup, yy, mm, null, null, null, null );
print("doc for create = "+templateBillList.size());
//делаем
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = dFactory.newDocumentBuilder();
Document doc = docBuilder.newDocument();
Element bills = doc.createElement("bills");
doc.appendChild(bills);
for( TemplateBill templateBill : templateBillList )
{
 
Element row = createElement( bills,"bill" );
BigDecimal subBillSumm = BigDecimal.ZERO;
row.setAttribute( "rest", Utils.formatBigDecimalSumm( bu.getBalance( month.getTime(), templateBill.getContractId() ) ) );
row.setAttribute( "account_id",String.valueOf(accountId ));
BigDecimal billSumm = fillBillData( row, templateBill );
if( templateBill.getSubBillList() != null )
{
for( TemplateBill templateSubBill : templateBill.getSubBillList() )
{
Element subBill = createElement( row, "sub_bill" );
subBillSumm = subBillSumm.add( fillBillData( subBill, templateSubBill ) );
}
}
row.setAttribute( "sub_bill_summ", Utils.formatBigDecimalSumm( subBillSumm ) );
row.setAttribute( "summ", Utils.formatBigDecimalSumm( billSumm.add( subBillSumm ) ) );
} 
//посомтрим что получилось
ByteArrayOutputStream sos = new ByteArrayOutputStream();
CommonUtils.serializeXML(doc , sos, "windows-1251");
String xml = sos.toString();
//print(xml);
InputStream is = new ByteArrayInputStream( xml.getBytes( "cp1251" ) );
BillManager pbm = new BillManager( setup, con, mid, moduleSetup );
pbm.addBillDocs( -1, is, yy, mm, new Date() );
 
 
}
private BigDecimal fillBillData( Element row, TemplateBill templateBill )
{
BigDecimal billSumm = BigDecimal.ZERO;
 
row.setAttribute( "id", String.valueOf( templateBill.getContractDocTypeId() ) );
row.setAttribute( "type", String.valueOf( templateBill.getDocTypeId() ) );
row.setAttribute( "cid", String.valueOf( templateBill.getContractId() ) );
 
row.setAttribute( "contract", templateBill.getContractTitle() );
row.setAttribute( "contract_comment", templateBill.getContractComment() );
 
for( PositionValue value : templateBill.getPositionList() )
{
BigDecimal summ = value.getSumma();
 
Element posEl = createElement( row, "pos" );
value.toElement( posEl );
 
Position pos = value.getPosition();
posEl.setAttribute( "insum", Utils.booleanToStringInt( pos.isInSum() ) );
posEl.setAttribute( "awlz", Utils.booleanToStringInt( pos.isAddWhenLessZero() ) );
 
java.util.Map params = pos.getParams();
if(null!=params){
	if("1".equals(params.get("param_awq")) && BigDecimal.ZERO.compareTo(Utils.maskNull(value.getQuantity()))<0){
		posEl.setAttribute( "awlz", "1");
	}
}
 
if( pos.isInSum() )
{
billSumm = billSumm.add( summ );
}
}
 
row.setAttribute( "summ", Utils.formatBigDecimalSumm( billSumm ) );
 
return billSumm;
}
 
protected Element createElement( Element element, String name )
{
Element newElement = null;
if( element == null )
{
newElement = null;
}
else
{
newElement = element.getOwnerDocument().createElement( name );
element.appendChild( newElement );
}
return newElement;
}

Для 5.2


package ru.skyb.scripts.global.schetfaktura;
 
import ru.bitel.bgbilling.kernel.script.server.dev.GlobalScriptBase;
import ru.bitel.bgbilling.server.util.Setup;
import ru.bitel.common.Utils;
import ru.bitel.common.sql.ConnectionSet;
 
 
import ru.bitel.bgbilling.server.util.*;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.math.BigDecimal;
import java.sql.Connection;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;
 
import ru.bitel.common.XMLUtils;
 
import bitel.billing.server.bill.bean.*;
import bitel.billing.server.contract.bean.*;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import bitel.billing.server.bill.bean.TemplateBill;
import bitel.billing.server.bill.bean.TemplateBillManager;
import bitel.billing.server.bill.bean.InvoiceManager;
 
public class faktur
	extends GlobalScriptBase
{
	@Override
	public void execute( Setup setup1, ConnectionSet connectionSet2 )
		throws Exception
	{
	Connection con = connectionSet2.getConnection();
	int mid = 8; //mid модуля Бухгалтерии
	int accountId =1; // id счета банка
	String gr ="12";//группа
 
	Calendar month = new GregorianCalendar();
	//корректировка времени
	month.add( Calendar.MONTH, -1 );
	month.set(Calendar.DATE,month.getActualMaximum(Calendar.DATE));
	int mm = month.get(Calendar.MONTH);
	int yy = month.get(Calendar.YEAR);
	print("date of create: "+month.getTime());
 
 
	BalanceUtils bu = new BalanceUtils( con );	  
	ModuleSetup moduleSetup = setup1.getModuleSetup( mid );
	TemplateBillManager man = new TemplateBillManager( moduleSetup, con, mid, true );
	List<TemplateBill> templateBillList = man.getTemplatePayBillList( moduleSetup, yy, mm, gr, null, null, null );
	print("doc for create = "+templateBillList.size());
	//делаем
	DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
	DocumentBuilder docBuilder = dFactory.newDocumentBuilder();
	Document doc = docBuilder.newDocument();
	Element bills = doc.createElement("bills");
	doc.appendChild(bills);
	for( TemplateBill templateBill : templateBillList )
	{
		Element row = createElement( bills,"bill" );
		BigDecimal subBillSumm = BigDecimal.ZERO;
		row.setAttribute( "rest", Utils.formatBigDecimalSumm( bu.getBalance( month.getTime(), templateBill.getContractId() ) ) );
		row.setAttribute( "account_id",String.valueOf(accountId ));
		BigDecimal billSumm = fillBillData( row, templateBill );
		if( templateBill.getSubBillList() != null )
		{
			for( TemplateBill templateSubBill : templateBill.getSubBillList() )
			{
				Element subBill = createElement( row, "sub_bill" );
				subBillSumm = subBillSumm.add( fillBillData( subBill, templateSubBill ) );
			}
		}
		row.setAttribute( "sub_bill_summ", Utils.formatBigDecimalSumm( subBillSumm ) );
		row.setAttribute( "summ", Utils.formatBigDecimalSumm( billSumm.add( subBillSumm ) ) );
	} 
//посомтрим что получилось 
	ByteArrayOutputStream sos = new ByteArrayOutputStream();
	XMLUtils.serialize(doc , sos, "utf-8");
	String xml = sos.toString();
//	print(xml);
	InputStream is = new ByteArrayInputStream( xml.getBytes( "windows-1251" ) );
	//BillManager pbm = new BillManager( setup, con, mid, moduleSetup );
	InvoiceManager pbm = new InvoiceManager( setup1, con, mid, moduleSetup );
	pbm.addBillDocs( -1, is, yy, mm, month.getTime() );
 
 
}
private BigDecimal fillBillData( Element row, TemplateBill templateBill )
{
BigDecimal billSumm = BigDecimal.ZERO;
 
row.setAttribute( "id", String.valueOf( templateBill.getContractDocTypeId() ) );
row.setAttribute( "type", String.valueOf( templateBill.getDocTypeId() ) );
row.setAttribute( "cid", String.valueOf( templateBill.getContractId() ) );
 
row.setAttribute( "contract", templateBill.getContractTitle() );
row.setAttribute( "contract_comment", templateBill.getContractComment() );
 
for( PositionValue value : templateBill.getPositionList() )
{ 
BigDecimal summ = value.getSumma();
 
Element posEl = createElement( row, "pos" );
value.toElement( posEl );
 
Position pos = value.getPosition();
posEl.setAttribute( "insum", Utils.booleanToStringInt( pos.isInSum() ) );
posEl.setAttribute( "awlz", Utils.booleanToStringInt( pos.isAddWhenLessZero() ) );
 
if( pos.isInSum() )
{
billSumm = billSumm.add( summ );
}
}
 
row.setAttribute( "summ", Utils.formatBigDecimalSumm( billSumm ) );
 
return billSumm;
}
 
protected Element createElement( Element element, String name )
{
Element newElement = null;
if( element == null )
{
newElement = null;
}
else
{
newElement = element.getOwnerDocument().createElement( name );
element.appendChild( newElement );
}
return newElement;
}
 
	}

--Skyb 05:42, 15 сентября 2011 (UTC)

v 1.1 edited by Cromeshnic

Версия биллинга: 5.1

Изменения:

  • Создание счетов для каждого договора отдельно, а не скопом (требует меньше памяти)
  • Логирование через log4j
  • Выбор групп, по которым будут выставляться счета
  • Выбор пользователя, от имени которого создаются счета
  • Исправлен вызов deprecated методов
  • Счета создаются за предыдущий месяц
  • Дата создания счета - текущее число

Примечание:

  • Для логирования в отдельный файл через log4j добавьте в /usr/local/BGBillingServer/data/log4j.xml :
<appender name="BILL" class="org.apache.log4j.RollingFileAppender">
                <param name="Threshold" value="ALL" />
                <param name="File" value="${log.dir.path}bill.log" />
                <param name="MaxFileSize" value="10MB" />
                <param name="MaxBackupIndex" value="5" />
                <param name="Append" value="true" />
                <layout class="org.apache.log4j.PatternLayout">
                        <param name="ConversionPattern" value="%X{nestedContext} %d{MM-dd/HH:mm:ss} %5p [%t] %c{1} - %m%n" />
                </layout>
        </appender>
<!-- Bill generation script log -->
        <logger name="Bill">
                <appender-ref ref="BILL" />
        </logger>

Код:

import ru.bitel.common.Utils;
import bitel.billing.common.TimeUtils;
import org.apache.log4j.Logger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Date;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.math.BigDecimal;
import bitel.billing.server.bill.bean.TemplateBill;
import bitel.billing.server.bill.bean.TemplateBillManager;
import bitel.billing.server.bill.bean.PositionValue;
import bitel.billing.server.bill.bean.Position;
import bitel.billing.server.contract.bean.BalanceUtils;
import ru.bitel.common.XMLUtils;
import java.io.StringWriter;
import bitel.billing.server.bill.bean.TemplateBillManager;
import bitel.billing.server.bill.bean.BillManager;
//import bitel.billing.server.bill.bean.InvoiceManager;
 
 
public void main( setup, con, conSlave )
{
	String groups = "22,26,27";
	int uid = 123; // пользователь, от имени которого создаются счета
	int mid = 6; //mid модуля Бухгалтерии
	int accountId = 1; // id счета банка
 
	Logger log = Logger.getLogger("Bill");
	int milestoneStep = 100; //Через каждые x договоров пишем в лог обработанное количество
 
	Calendar month = new GregorianCalendar();
	//корректировка времени
	month.add( Calendar.MONTH, -1 );
	month.set(Calendar.DATE,month.getActualMaximum(Calendar.DATE));
	int mm = month.get(Calendar.MONTH);
	int yy = month.get(Calendar.YEAR);
	print("Date of bills: " + month.getTime());
	long grMask = Utils.enumToMask(groups); //битовая маска групп договоров (205520896 = группы 22,26,27)
	log.info("Starting bill generation for yy="+yy+" mm="+mm+" groups="+Utils.maskToEnum(grMask)+" uid="+uid);
 
	int fetchSize = 0;
 
	BalanceUtils bu = new BalanceUtils( conSlave );
	ModuleSetup moduleSetup = setup.getModuleSetup( mid );
	TemplateBillManager man = new TemplateBillManager( moduleSetup, conSlave, mid, false ); // false если надо для счетов
	BillManager pbm = new BillManager( setup, con, mid, moduleSetup );//это если надо счета а не с-ф
	//InvoiceManager pbm = new InvoiceManager( setup, con, mid, moduleSetup );
 
	String query_part = " contract_module cm inner join contract c  on cm.cid=c.id where cm.mid=? AND (c.date1 IS NULL OR c.date1<=?) AND (c.date2 IS NULL OR c.date2>=?) AND (c.gr&" + grMask + ">0)";
	//Прикидываем размер выборки
	PreparedStatement ps = conSlave.prepareStatement("select count(*) from "+query_part);
	ps.setInt(1, mid);
	ps.setDate(2, TimeUtils.convertCalendarToSqlDate(month));
	ps.setDate(3, TimeUtils.convertCalendarToSqlDate(new GregorianCalendar(yy, mm, 1)));
	ResultSet rs = ps.executeQuery();
	if(rs.next()){fetchSize = rs.getInt(1);};	
 
	//Берем id договоров в группе grMask, с модулем mid и пересекающихся датой с нужным нам месяцем month
	String query = "select c.id from " + query_part;
	ps = conSlave.prepareStatement(query);
	ps.setInt(1, mid);
	ps.setDate(2, TimeUtils.convertCalendarToSqlDate(month));
	ps.setDate(3, TimeUtils.convertCalendarToSqlDate(new GregorianCalendar(yy, mm, 1)));
	rs = ps.executeQuery();
	log.info("Total "+fetchSize+ " contracts selected");
	int i=0;
	while(rs.next()){
		i++;
		if((i % milestoneStep)==0){log.info("Contract "+i+"\t of " + fetchSize );};
		List templateBillList = man.getTemplatePayBillList( moduleSetup, yy, mm, null, String.valueOf(rs.getInt(1)), null, null );
		//делаем
		DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = dFactory.newDocumentBuilder();
		Document doc = docBuilder.newDocument();
		Element bills = doc.createElement("bills");
		doc.appendChild(bills);
		for( TemplateBill templateBill : templateBillList )
		{
			Element row = createElement( bills,"bill" );
			BigDecimal subBillSumm = BigDecimal.ZERO;
			row.setAttribute( "rest", Utils.formatBigDecimalSumm( bu.getBalance( month.getTime(), templateBill.getContractId() ) ) );
			row.setAttribute( "account_id",String.valueOf(accountId ));
			BigDecimal billSumm = fillBillData( row, templateBill );
			if( templateBill.getSubBillList() != null )
			{
				for( TemplateBill templateSubBill : templateBill.getSubBillList() )
				{
					Element subBill = createElement( row, "sub_bill" );
					subBillSumm = subBillSumm.add( fillBillData( subBill, templateSubBill ) );
				}
			}
			row.setAttribute( "sub_bill_summ", Utils.formatBigDecimalSumm( subBillSumm ) );
			row.setAttribute( "summ", Utils.formatBigDecimalSumm( billSumm.add( subBillSumm ) ) );
		}
 
		//посомтрим что получилось
		ByteArrayOutputStream os = new ByteArrayOutputStream();
 
		XMLUtils.serialize(doc , os, "utf-8"); //для 5.1 
		//CommonUtils.serializeXML(doc , os, "utf-8"); //для 5.0
		String xml = os.toString();
		// print(xml);
		InputStream is = new ByteArrayInputStream( xml.getBytes( "windows-1251" ) );
 
		//Собственно создаём счета:
		pbm.addBillDocs( uid, is, yy, mm, new Date() ); //или month.getTime(), если дата создания счета должна быть последним числом месяца, а не текущим днем.
		is.close();
		os.close();
	}
	log.info("Done!");
}
 
private BigDecimal fillBillData( Element row, TemplateBill templateBill )
{
	BigDecimal billSumm = BigDecimal.ZERO;
 
	row.setAttribute( "id", String.valueOf( templateBill.getContractDocTypeId() ) );
	row.setAttribute( "type", String.valueOf( templateBill.getDocTypeId() ) );
	row.setAttribute( "cid", String.valueOf( templateBill.getContractId() ) );
 
	row.setAttribute( "contract", templateBill.getContractTitle() );
	row.setAttribute( "contract_comment", templateBill.getContractComment() );
 
	for( PositionValue value : templateBill.getPositionList() )
	{
		BigDecimal summ = value.getSumma();
 
		Element posEl = createElement( row, "pos" );
		value.toElement( posEl );
 
		Position pos = value.getPosition();
		posEl.setAttribute( "insum", Utils.booleanToStringInt( pos.isInSum() ) );
		posEl.setAttribute( "awlz", Utils.booleanToStringInt( pos.isAddWhenLessZero() ) );
 
		java.util.Map params = pos.getParams();
		if(null!=params){
			if("1".equals(params.get("param_awq")) && BigDecimal.ZERO.compareTo(Utils.maskNull(value.getQuantity()))<0){
				posEl.setAttribute( "awlz", "1");
			}
		}
 
 
		if( pos.isInSum() )
		{
			billSumm = billSumm.add( summ );
		}
	}
 
	row.setAttribute( "summ", Utils.formatBigDecimalSumm( billSumm ) );
 
	return billSumm;
}
 
private Element createElement( Element element, String name )
{
	Element newElement = null;
	if( element == null )
	{
		newElement = null;
	}
	else
	{
		newElement = element.getOwnerDocument().createElement( name );
		element.appendChild( newElement );
	}
	return newElement;
}

Пример лога:

server 04-05/10:32:10  INFO [Thread-4547] Bill - Starting bill generation for yy=2011 mm=2 groups=1 uid=123
server 04-05/10:32:10  INFO [Thread-4547] Bill - Total 50 contracts selected
server 04-05/10:32:20  INFO [Thread-4547] Bill - Contract 10     of 50
server 04-05/10:32:27  INFO [Thread-4547] Bill - Contract 20     of 50
server 04-05/10:32:37  INFO [Thread-4547] Bill - Contract 30     of 50
server 04-05/10:32:47  INFO [Thread-4547] Bill - Contract 40     of 50
server 04-05/10:32:53  INFO [Thread-4547] Bill - Contract 50     of 50
server 04-05/10:32:53  INFO [Thread-4547] Bill - Done!

v 1.2 Multithreaded

Счета создаются в несколько потоков. Количество потоков указывается в переменной thread_count. Потоки выполняются в контексте сервера, поэтому при большом их количестве BGBillingServer может заметно тормозить.

import ru.bitel.common.Utils;
import bitel.billing.common.TimeUtils;
import org.apache.log4j.Logger;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Connection;
import java.util.Date;
import java.util.ArrayList;
import java.util.List;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.math.BigDecimal;
import bitel.billing.server.bill.bean.TemplateBill;
import bitel.billing.server.bill.bean.TemplateBillManager;
import bitel.billing.server.bill.bean.PositionValue;
import bitel.billing.server.bill.bean.Position;
import bitel.billing.server.contract.bean.BalanceUtils;
import ru.bitel.common.XMLUtils;
import java.io.StringWriter;
import bitel.billing.server.bill.bean.BillManager;
//import bitel.billing.server.bill.bean.InvoiceManager;
import ru.bitel.bgbilling.server.util.ModuleSetup;
import ru.bitel.bgbilling.server.util.ServerUtils;
import ru.bitel.bgbilling.server.util.Setup;
 
public void main( setup, con, conSlave )
{
	String groups = "22,26,27";
	int uid = 160; // пользователь, от имени которого создаются счета
	int mid = 6; //mid модуля Бухгалтерии
	int accountId = 1; // id счета банка
	int thread_count = 4; //Количество потоков создания счетов
 
	Logger log = Logger.getLogger("Bill");
 
	Calendar month = new GregorianCalendar();
	//корректировка времени
	month.add( Calendar.MONTH, -1 );
	month.set(Calendar.DATE,month.getActualMaximum(Calendar.DATE));
	int mm = month.get(Calendar.MONTH);
	int yy = month.get(Calendar.YEAR);
	print("Date of bills: " + month.getTime());
	long grMask = Utils.enumToMask(groups); //битовая маска групп договоров (205520896 = группы 22,26,27)
	print("Starting bill generation for yy="+yy+" mm="+mm+" groups="+Utils.maskToEnum(grMask)+" uid="+uid);
	log.info("Starting bill generation for yy="+yy+" mm="+mm+" groups="+Utils.maskToEnum(grMask)+" uid="+uid);
 
	int fetchSize = 0;
 
	String query_part = " contract_module cm left join contract c  on cm.cid=c.id where cm.mid=? AND (c.date1 IS NULL OR c.date1<=?) AND (c.date2 IS NULL OR c.date2>=?) AND (c.gr&" + grMask + ">0) ";
	//Прикидываем размер выборки
	PreparedStatement ps = conSlave.prepareStatement("select count(*) from "+query_part);
	ps.setInt(1, mid);
	ps.setDate(2, TimeUtils.convertCalendarToSqlDate(month));
	ps.setDate(3, TimeUtils.convertCalendarToSqlDate(new GregorianCalendar(yy, mm, 1)));
	ResultSet rs = ps.executeQuery();
	if(rs.next()){fetchSize = rs.getInt(1);};	
 
	int thread_batch_size = fetchSize / thread_count;
	print("Thread count: " + thread_count);
	log.info("Thread count: " + thread_count);
	print("Total "+fetchSize+ " contracts selected");
	log.info("Total "+fetchSize+ " contracts selected");
	print(thread_batch_size+" contracts per thread");
	log.info(thread_batch_size+" contracts per thread");
 
	//Берем id договоров в группе grMask, с модулем mid и пересекающихся датой с нужным нам месяцем month
	String query = "select c.id from " + query_part;
	ps = conSlave.prepareStatement(query);
	ps.setInt(1, mid);
	ps.setDate(2, TimeUtils.convertCalendarToSqlDate(month));
	ps.setDate(3, TimeUtils.convertCalendarToSqlDate(new GregorianCalendar(yy, mm, 1)));
	rs = ps.executeQuery();
 
	ArrayList batch = new ArrayList();
	int i=0;
	int batchId=0;
	while(rs.next()){
		//Собираем id по thread_batch_size штук в массив и передаём его в task
		batch.add(rs.getInt(1));
		if(++i>=thread_batch_size){
			print("Добавляем задание: "+ i +" договоров");
			i=0;
			new Thread(new MyBillGenerator(batch, month, mid, uid, accountId, ++batchId)).start();
			batch = new ArrayList();
		}
	}
	//Обрабатываем последнюю (неполную) пачку, если есть
	if(i>0){
		print("Добавляем задание: "+ i +" договоров");
		i=0;
		new Thread(new MyBillGenerator(batch, month, mid, uid, accountId, ++batchId)).start();
		batch=null;
	}
 
}
 
 
private class MyBillGenerator implements Runnable{
	private int mid;
	private int uid;
	private int accountId;
	private List cidList;
	private int milestoneStep = 100; //Через каждые x договоров пишем в лог обработанное количество
	private Calendar month;
	private int yy;
	private int mm;
	private int batchId;
 
	public MyBillGenerator(List cidList, Calendar month, int mid, int uid, int accountId, int batchId){
		this.cidList = cidList;
		this.mid = mid;
		this.uid = uid;
		this.accountId = accountId;
		this.month = month;
		int mm = month.get(Calendar.MONTH);
		int yy = month.get(Calendar.YEAR);
		this.mm=mm;
		this.yy=yy;
		this.batchId = batchId;
		this.setup=Setup.getSetup();
	}
 
	public String getDescription(){
		return "Задача создания счетов id="+this.batchId+" [mm="+this.mm+" yy="+this.yy+" mid="+this.mid+" uid="+this.uid+"]";
	}
 
	public void run(){
		Logger myLog = Logger.getLogger("Bill");
		myLog.info("[task id="+batchId+"] Task started: "+this.getDescription());
		Connection conSlave = this.setup.getDBSlaveConnectionFromPool();
 
		try{
			BalanceUtils bu = new BalanceUtils( conSlave );
			ModuleSetup moduleSetup = setup.getModuleSetup( mid );
			TemplateBillManager man = new TemplateBillManager( moduleSetup, conSlave, mid, false ); // false если надо для счетов
			BillManager pbm = new BillManager( setup, conSlave, mid, moduleSetup );//это если надо счета а не с-ф
			//InvoiceManager pbm = new InvoiceManager( setup, con, mid, moduleSetup );
 
			int i=0;
			for(Integer cid : cidList){
				i++;
				if((i % milestoneStep)==0){myLog.info("[task id="+batchId+"] "+i+" contracts of \t"+cidList.size() );};
//				List templateBillList = man.getTemplatePayBillList( moduleSetup, yy, mm, null, String.valueOf(cid), null, null );
				//делаем
				DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
				DocumentBuilder docBuilder = dFactory.newDocumentBuilder();
				Document doc = docBuilder.newDocument();
				Element bills = doc.createElement("bills");
				doc.appendChild(bills);
				for( TemplateBill templateBill : man.getTemplatePayBillList( moduleSetup, yy, mm, null, String.valueOf(cid), null, null ))//templateBillList )
				{
					Element row = createElement( bills,"bill" );
					BigDecimal subBillSumm = BigDecimal.ZERO;
					row.setAttribute( "rest", Utils.formatBigDecimalSumm( bu.getBalance( month.getTime(), templateBill.getContractId() ) ) );
					row.setAttribute( "account_id",String.valueOf(accountId ));
					BigDecimal billSumm = fillBillData( row, templateBill );
					if( templateBill.getSubBillList() != null )
					{
						for( TemplateBill templateSubBill : templateBill.getSubBillList() )
						{
							Element subBill = createElement( row, "sub_bill" );
							subBillSumm = subBillSumm.add( fillBillData( subBill, templateSubBill ) );
						}
					}
					row.setAttribute( "sub_bill_summ", Utils.formatBigDecimalSumm( subBillSumm ) );
					row.setAttribute( "summ", Utils.formatBigDecimalSumm( billSumm.add( subBillSumm ) ) );
				}
 
				//посомтрим что получилось
				ByteArrayOutputStream os = new ByteArrayOutputStream();
 
				XMLUtils.serialize(doc , os, "utf-8"); //для 5.1 
				//CommonUtils.serializeXML(doc , os, "utf-8"); //для 5.0
				String xml = os.toString();
				InputStream is = new ByteArrayInputStream( xml.getBytes( "windows-1251" ) );
 
				//Собственно создаём счета:
				pbm.addBillDocs( uid, is, yy, mm, new Date() ); //или month.getTime(), если дата создания счета должна быть последним числом месяца, а не текущим днем.
				is.close();
				os.close();
			}
			if((i % milestoneStep)!=0){myLog.info("[task id="+batchId+"] "+i+" contracts of \t"+cidList.size());};
	    }
		catch (Exception ex){
			myLog.error(ex.getMessage(), ex);
		}
		finally{
			ServerUtils.closeConnection(new Connection[] { conSlave });
			myLog.info("[task id="+batchId+"] Task finished!");
		}
	}
 
	private BigDecimal fillBillData( Element row, TemplateBill templateBill )
	{
		BigDecimal billSumm = BigDecimal.ZERO;
 
		row.setAttribute( "id", String.valueOf( templateBill.getContractDocTypeId() ) );
		row.setAttribute( "type", String.valueOf( templateBill.getDocTypeId() ) );
		row.setAttribute( "cid", String.valueOf( templateBill.getContractId() ) );
 
		row.setAttribute( "contract", templateBill.getContractTitle() );
		row.setAttribute( "contract_comment", templateBill.getContractComment() );
 
		for( PositionValue value : templateBill.getPositionList() )
		{
			BigDecimal summ = value.getSumma();
 
			Element posEl = createElement( row, "pos" );
			value.toElement( posEl );
 
			Position pos = value.getPosition();
			posEl.setAttribute( "insum", Utils.booleanToStringInt( pos.isInSum() ) );
			posEl.setAttribute( "awlz", Utils.booleanToStringInt( pos.isAddWhenLessZero() ) );
 
			java.util.Map params = pos.getParams();
			if(null!=params){
				if("1".equals(params.get("param_awq")) && BigDecimal.ZERO.compareTo(Utils.maskNull(value.getQuantity()))<0){
					posEl.setAttribute( "awlz", "1");
				}
			}
 
			if( pos.isInSum() )
			{
				billSumm = billSumm.add( summ );
			}
		}
 
		row.setAttribute( "summ", Utils.formatBigDecimalSumm( billSumm ) );
 
		return billSumm;
	}
 
	private Element createElement( Element element, String name )
	{
		Element newElement = null;
		if( element == null )
		{
			newElement = null;
		}
		else
		{
			newElement = element.getOwnerDocument().createElement( name );
			element.appendChild( newElement );
		}
		return newElement;
	}
 
}
Личные инструменты