You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

365 lines
20 KiB

11 years ago
  1. # -*- encoding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. #
  6. # Copyright (c) 2013 Noviat nv/sa (www.noviat.com). All rights reserved.
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU Affero General Public License as
  10. # published by the Free Software Foundation, either version 3 of the
  11. # License, or (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU Affero General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU Affero General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. #
  21. ##############################################################################
  22. import xlwt
  23. import time
  24. from datetime import datetime
  25. from openerp.report import report_sxw
  26. from openerp.addons.report_xls.report_xls import report_xls
  27. from openerp.addons.report_xls.utils import rowcol_to_cell
  28. from openerp.addons.account_financial_report_webkit.report.partners_ledger import PartnersLedgerWebkit
  29. from openerp.tools.translate import _
  30. #import logging
  31. #_logger = logging.getLogger(__name__)
  32. _column_sizes = [
  33. ('date', 12),
  34. ('period', 12),
  35. ('move', 20),
  36. ('journal', 12),
  37. ('partner', 30),
  38. ('label', 58),
  39. ('rec', 12),
  40. ('debit', 15),
  41. ('credit', 15),
  42. ('cumul_bal', 15),
  43. ('curr_bal', 15),
  44. ('curr_code', 7),
  45. ]
  46. class partner_ledger_xls(report_xls):
  47. column_sizes = [x[1] for x in _column_sizes]
  48. def generate_xls_report(self, _p, _xs, data, objects, wb):
  49. ws = wb.add_sheet(_p.report_name[:31])
  50. ws.panes_frozen = True
  51. ws.remove_splits = True
  52. ws.portrait = 0 # Landscape
  53. ws.fit_width_to_pages = 1
  54. row_pos = 0
  55. # set print header/footer
  56. ws.header_str = self.xls_headers['standard']
  57. ws.footer_str = self.xls_footers['standard']
  58. # cf. account_report_partner_ledger.mako
  59. initial_balance_text = {'initial_balance': _('Computed'), 'opening_balance': _('Opening Entries'), False: _('No')}
  60. # Title
  61. cell_style = xlwt.easyxf(_xs['xls_title'])
  62. report_name = ' - '.join([_p.report_name.upper(), _p.company.partner_id.name, _p.company.currency_id.name])
  63. c_specs = [
  64. ('report_name', 1, 0, 'text', report_name),
  65. ]
  66. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  67. row_pos = self.xls_write_row(ws, row_pos, row_data, row_style=cell_style)
  68. # write empty row to define column sizes
  69. c_sizes = self.column_sizes
  70. c_specs = [('empty%s'%i, 1, c_sizes[i], 'text', None) for i in range(0,len(c_sizes))]
  71. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  72. row_pos = self.xls_write_row(ws, row_pos, row_data, set_column_size=True)
  73. # Header Table
  74. nbr_columns = 10
  75. if _p.amount_currency(data):
  76. nbr_columns = 12
  77. cell_format = _xs['bold'] + _xs['fill_blue'] + _xs['borders_all']
  78. cell_style = xlwt.easyxf(cell_format)
  79. cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  80. c_specs = [
  81. ('coa', 2, 0, 'text', _('Chart of Account')),
  82. ('fy', 1, 0, 'text', _('Fiscal Year')),
  83. ('df', 2, 0, 'text', _p.filter_form(data) == 'filter_date' and _('Dates Filter') or _('Periods Filter')),
  84. ('af', 1, 0, 'text', _('Accounts Filter')),
  85. ('tm', 2, 0, 'text', _('Target Moves')),
  86. ('ib', nbr_columns-8, 0, 'text', _('Initial Balance')),
  87. ]
  88. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  89. row_pos = self.xls_write_row(ws, row_pos, row_data, row_style=cell_style_center)
  90. cell_format = _xs['borders_all']
  91. cell_style = xlwt.easyxf(cell_format)
  92. cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  93. c_specs = [
  94. ('coa', 2, 0, 'text', _p.chart_account.name),
  95. ('fy', 1, 0, 'text', _p.fiscalyear.name if _p.fiscalyear else '-'),
  96. ]
  97. df = _('From') + ': '
  98. if _p.filter_form(data) == 'filter_date':
  99. df += _p.start_date if _p.start_date else u''
  100. else:
  101. df += _p.start_period.name if _p.start_period else u''
  102. df += ' ' + _('To') + ': '
  103. if _p.filter_form(data) == 'filter_date':
  104. df += _p.stop_date if _p.stop_date else u''
  105. else:
  106. df += _p.stop_period.name if _p.stop_period else u''
  107. c_specs += [
  108. ('df', 2, 0, 'text', df),
  109. ('af', 1, 0, 'text', _('Custom Filter') if _p.partner_ids else _p.display_partner_account(data)),
  110. ('tm', 2, 0, 'text', _p.display_target_move(data)),
  111. ('ib', nbr_columns-8, 0, 'text', initial_balance_text[_p.initial_balance_mode]),
  112. ]
  113. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  114. row_pos = self.xls_write_row(ws, row_pos, row_data, row_style=cell_style_center)
  115. ws.set_horz_split_pos(row_pos)
  116. row_pos += 1
  117. # Account Title Row
  118. cell_format = _xs['xls_title'] + _xs['bold'] + _xs['fill'] + _xs['borders_all']
  119. account_cell_style = xlwt.easyxf(cell_format)
  120. account_cell_style_right = xlwt.easyxf(cell_format + _xs['right'])
  121. account_cell_style_decimal = xlwt.easyxf(cell_format + _xs['right'], num_format_str = report_xls.decimal_format)
  122. # Column Title Row
  123. cell_format = _xs['bold']
  124. c_title_cell_style = xlwt.easyxf(cell_format)
  125. # Column Header Row
  126. cell_format = _xs['bold'] + _xs['fill'] + _xs['borders_all']
  127. c_hdr_cell_style = xlwt.easyxf(cell_format)
  128. c_hdr_cell_style_right = xlwt.easyxf(cell_format + _xs['right'])
  129. c_hdr_cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  130. c_hdr_cell_style_decimal = xlwt.easyxf(cell_format + _xs['right'], num_format_str = report_xls.decimal_format)
  131. # Column Initial Balance Row
  132. cell_format = _xs['italic'] + _xs['borders_all']
  133. c_init_cell_style = xlwt.easyxf(cell_format)
  134. c_init_cell_style_right = xlwt.easyxf(cell_format + _xs['right'])
  135. c_init_cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  136. c_init_cell_style_decimal = xlwt.easyxf(cell_format + _xs['right'], num_format_str = report_xls.decimal_format)
  137. # Column Cumulated balance Row
  138. cell_format = _xs['bold'] + _xs['fill'] + _xs['borders_all']
  139. c_cumul_cell_style = xlwt.easyxf(cell_format)
  140. c_cumul_cell_style_right = xlwt.easyxf(cell_format + _xs['right'])
  141. c_cumul_cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  142. c_cumul_cell_style_decimal = xlwt.easyxf(cell_format + _xs['right'], num_format_str = report_xls.decimal_format)
  143. # Column Partner Row
  144. cell_format = _xs['bold']
  145. c_part_cell_style = xlwt.easyxf(cell_format)
  146. c_specs = [
  147. ('date', 1, 0, 'text', _('Date'), None, c_hdr_cell_style),
  148. ('period', 1, 0, 'text', _('Period'), None, c_hdr_cell_style),
  149. ('move', 1, 0, 'text', _('Entry'), None, c_hdr_cell_style),
  150. ('journal', 1, 0, 'text', _('Journal'), None, c_hdr_cell_style),
  151. ('partner', 1, 0, 'text', _('Partner'), None, c_hdr_cell_style),
  152. ('label', 1, 0, 'text', _('Label'), None, c_hdr_cell_style),
  153. ('rec', 1, 0, 'text', _('Rec.'), None, c_hdr_cell_style),
  154. ('debit', 1, 0, 'text', _('Debit'), None, c_hdr_cell_style_right),
  155. ('credit', 1, 0, 'text', _('Credit'), None, c_hdr_cell_style_right),
  156. ('cumul_bal', 1, 0, 'text', _('Cumul. Bal.'), None, c_hdr_cell_style_right),
  157. ]
  158. if _p.amount_currency(data):
  159. c_specs += [
  160. ('curr_bal', 1, 0, 'text', _('Curr. Bal.'), None, c_hdr_cell_style_right),
  161. ('curr_code', 1, 0, 'text', _('Curr.'), None, c_hdr_cell_style_center),
  162. ]
  163. c_hdr_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  164. # cell styles for ledger lines
  165. ll_cell_format = _xs['borders_all']
  166. ll_cell_style = xlwt.easyxf(ll_cell_format)
  167. ll_cell_style_right = xlwt.easyxf(ll_cell_format + _xs['right'])
  168. ll_cell_style_center = xlwt.easyxf(ll_cell_format + _xs['center'])
  169. ll_cell_style_date = xlwt.easyxf(ll_cell_format + _xs['left'], num_format_str = report_xls.date_format)
  170. ll_cell_style_decimal = xlwt.easyxf(ll_cell_format + _xs['right'], num_format_str = report_xls.decimal_format)
  171. cnt = 0
  172. for account in objects:
  173. if account.ledger_lines or account.init_balance:
  174. if not account.partners_order:
  175. continue
  176. cnt += 1
  177. account_total_debit = 0.0
  178. account_total_credit = 0.0
  179. account_balance_cumul = 0.0
  180. account_balance_cumul_curr = 0.0
  181. c_specs = [
  182. ('acc_title', nbr_columns, 0, 'text', ' - '.join([account.code, account.name]), None, account_cell_style),
  183. ]
  184. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  185. row_pos = self.xls_write_row(ws, row_pos, row_data, c_title_cell_style)
  186. row_pos += 1
  187. row_start_account = row_pos
  188. for partner_name, p_id, p_ref, p_name in account.partners_order:
  189. total_debit = 0.0
  190. total_credit = 0.0
  191. cumul_balance = 0.0
  192. cumul_balance_curr = 0.0
  193. part_cumul_balance = 0.0
  194. part_cumul_balance_curr = 0.0
  195. c_specs = [
  196. ('partner_title', nbr_columns, 0, 'text', partner_name or _('No Partner'), None, c_part_cell_style),
  197. ]
  198. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  199. row_pos = self.xls_write_row(ws, row_pos, row_data, c_title_cell_style)
  200. row_pos = self.xls_write_row(ws, row_pos, c_hdr_data)
  201. row_start_partner = row_pos
  202. total_debit = account.init_balance.get(p_id, {}).get('debit') or 0.0
  203. total_credit = account.init_balance.get(p_id, {}).get('credit') or 0.0
  204. init_line = False
  205. if _p.initial_balance_mode and (total_debit or total_credit):
  206. init_line = True
  207. part_cumul_balance = account.init_balance.get(p_id, {}).get('init_balance') or 0.0
  208. part_cumul_balance_curr = account.init_balance.get(p_id, {}).get('init_balance_currency') or 0.0
  209. balance_forward_currency = account.init_balance.get(p_id, {}).get('currency_name') or ''
  210. cumul_balance += part_cumul_balance
  211. cumul_balance_curr += part_cumul_balance_curr
  212. debit_cell = rowcol_to_cell(row_pos, 7)
  213. credit_cell = rowcol_to_cell(row_pos, 8)
  214. init_bal_formula = debit_cell + '-' + credit_cell
  215. ################## Print row 'Initial Balance' by partner #################
  216. c_specs = [('empty%s' %x, 1, 0, 'text', None) for x in range(5)]
  217. c_specs += [
  218. ('init_bal', 1, 0, 'text', _('Initial Balance')),
  219. ('rec', 1, 0, 'text', None),
  220. ('debit', 1, 0, 'number', total_debit, None, c_init_cell_style_decimal),
  221. ('credit', 1, 0, 'number', total_credit, None, c_init_cell_style_decimal),
  222. ('cumul_bal', 1, 0, 'number', None, init_bal_formula, c_init_cell_style_decimal),
  223. ]
  224. if _p.amount_currency(data):
  225. c_specs += [
  226. ('curr_bal', 1, 0, 'number', part_cumul_balance_curr, None, c_init_cell_style_decimal),
  227. ('curr_code', 1, 0, 'text', balance_forward_currency),
  228. ]
  229. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  230. row_pos = self.xls_write_row(ws, row_pos, row_data, c_init_cell_style)
  231. for line in account.ledger_lines.get(p_id, []):
  232. total_debit += line.get('debit') or 0.0
  233. total_credit += line.get('credit') or 0.0
  234. label_elements = [line.get('lname') or '']
  235. if line.get('invoice_number'):
  236. label_elements.append("(%s)" % (line['invoice_number'],))
  237. label = ' '.join(label_elements)
  238. cumul_balance += line.get('balance') or 0.0
  239. if init_line or row_pos > row_start_partner:
  240. cumbal_formula = rowcol_to_cell(row_pos-1, 9) + '+'
  241. else:
  242. cumbal_formula = ''
  243. debit_cell = rowcol_to_cell(row_pos, 7)
  244. credit_cell = rowcol_to_cell(row_pos, 8)
  245. cumbal_formula += debit_cell + '-' + credit_cell
  246. ################## Print row ledger line data #################
  247. if line.get('ldate'):
  248. c_specs = [
  249. ('ldate', 1, 0, 'date', datetime.strptime(line['ldate'],'%Y-%m-%d'), None, ll_cell_style_date),
  250. ]
  251. else:
  252. c_specs = [
  253. ('ldate', 1, 0, 'text', None),
  254. ]
  255. c_specs += [
  256. ('period', 1, 0, 'text', line.get('period_code') or ''),
  257. ('move', 1, 0, 'text', line.get('move_name') or ''),
  258. ('journal', 1, 0, 'text', line.get('jcode') or ''),
  259. ('partner', 1, 0, 'text', line.get('partner_name') or ''),
  260. ('label', 1, 0, 'text', label),
  261. ('rec_name', 1, 0, 'text', line.get('rec_name') or ''),
  262. ('debit', 1, 0, 'number', line.get('debit'), None, ll_cell_style_decimal),
  263. ('credit', 1, 0, 'number', line.get('credit'), None, ll_cell_style_decimal),
  264. ('cumul_bal', 1, 0, 'number', None, cumbal_formula, ll_cell_style_decimal),
  265. ]
  266. if _p.amount_currency(data):
  267. c_specs += [
  268. ('curr_bal', 1, 0, 'number', line.get('amount_currency') or 0.0, None, ll_cell_style_decimal),
  269. ('curr_code', 1, 0, 'text', line.get('currency_code') or '', None, ll_cell_style_center),
  270. ]
  271. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  272. row_pos = self.xls_write_row(ws, row_pos, row_data, ll_cell_style)
  273. #end for line
  274. ################## Print row Cumulated Balance by partner #################
  275. debit_partner_start = rowcol_to_cell(row_start_partner, 7)
  276. debit_partner_end = rowcol_to_cell(row_pos-1, 7)
  277. debit_partner_total = 'SUM(' + debit_partner_start + ':' + debit_partner_end + ')'
  278. credit_partner_start = rowcol_to_cell(row_start_partner, 8)
  279. credit_partner_end = rowcol_to_cell(row_pos-1, 8)
  280. credit_partner_total = 'SUM(' + credit_partner_start + ':' + credit_partner_end + ')'
  281. bal_partner_debit = rowcol_to_cell(row_pos, 7)
  282. bal_partner_credit = rowcol_to_cell(row_pos, 8)
  283. bal_partner_total = bal_partner_debit + '-' + bal_partner_credit
  284. c_specs = [('empty%s' %x, 1, 0, 'text', None) for x in range(5)]
  285. c_specs += [
  286. ('init_bal', 1, 0, 'text', _('Cumulated balance on Partner')),
  287. ('rec', 1, 0, 'text', None),
  288. ('debit', 1, 0, 'number', None, debit_partner_total, c_cumul_cell_style_decimal),
  289. ('credit', 1, 0, 'number', None, credit_partner_total, c_cumul_cell_style_decimal),
  290. ('cumul_bal', 1, 0, 'number', None, bal_partner_total, c_cumul_cell_style_decimal),
  291. ]
  292. if _p.amount_currency(data):
  293. if account.currency_id:
  294. c_specs += [('curr_bal', 1, 0, 'number', cumul_balance_curr or 0.0, None, c_cumul_cell_style_decimal)]
  295. else:
  296. c_specs += [('curr_bal', 1, 0, 'text', '-', None, c_cumul_cell_style_right)]
  297. c_specs += [('curr_code', 1, 0, 'text', account.currency_id.name if account.currency_id else u'', None, c_cumul_cell_style_center)]
  298. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  299. row_pos = self.xls_write_row(ws, row_pos, row_data, c_cumul_cell_style)
  300. row_pos += 1
  301. account_total_debit += total_debit
  302. account_total_credit += total_credit
  303. account_balance_cumul += cumul_balance
  304. account_balance_cumul_curr += cumul_balance_curr
  305. ################## Print row Cumulated Balance by account #################
  306. c_specs = [('acc_title', 5, 0, 'text', ' - '.join([account.code, account.name])), ]
  307. c_specs += [
  308. ('label', 1, 0, 'text', _('Cumulated balance on Account')),
  309. ('rec', 1, 0, 'text', None),
  310. ('debit', 1, 0, 'number', account_total_debit, None, account_cell_style_decimal),
  311. ('credit', 1, 0, 'number', account_total_credit, None, account_cell_style_decimal),
  312. ('cumul_bal', 1, 0, 'number', account_balance_cumul, None, account_cell_style_decimal),
  313. ]
  314. if _p.amount_currency(data):
  315. if account.currency_id:
  316. c_specs += [('curr_bal', 1, 0, 'number', account_balance_cumul_curr or 0.0, None, account_cell_style_decimal)]
  317. else:
  318. c_specs += [('curr_bal', 1, 0, 'text', '-', None, account_cell_style_right)]
  319. c_specs += [('curr_code', 1, 0, 'text', account.currency_id.name if account.currency_id else u'', None, account_cell_style)]
  320. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  321. row_pos = self.xls_write_row(ws, row_pos, row_data, account_cell_style)
  322. row_pos += 2
  323. partner_ledger_xls('report.account.account_report_partner_ledger_xls', 'account.account',
  324. parser=PartnersLedgerWebkit)
  325. # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: