Создание счета и счет-фактур в модуле 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; } }