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.

461 lines
21 KiB

11 years ago
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. from datetime import datetime
  24. from openerp.addons.report_xls.report_xls import report_xls
  25. from openerp.addons.report_xls.utils import rowcol_to_cell
  26. from openerp.addons.account_financial_report_webkit.report.partners_ledger \
  27. import PartnersLedgerWebkit
  28. from openerp.tools.translate import _
  29. # import logging
  30. # _logger = logging.getLogger(__name__)
  31. _column_sizes = [
  32. ('date', 12),
  33. ('period', 12),
  34. ('move', 20),
  35. ('journal', 12),
  36. ('partner', 30),
  37. ('label', 58),
  38. ('rec', 12),
  39. ('debit', 15),
  40. ('credit', 15),
  41. ('cumul_bal', 15),
  42. ('curr_bal', 15),
  43. ('curr_code', 7),
  44. ]
  45. class partner_ledger_xls(report_xls):
  46. column_sizes = [x[1] for x in _column_sizes]
  47. def generate_xls_report(self, _p, _xs, data, objects, wb):
  48. ws = wb.add_sheet(_p.report_name[:31])
  49. ws.panes_frozen = True
  50. ws.remove_splits = True
  51. ws.portrait = 0 # Landscape
  52. ws.fit_width_to_pages = 1
  53. row_pos = 0
  54. # set print header/footer
  55. ws.header_str = self.xls_headers['standard']
  56. ws.footer_str = self.xls_footers['standard']
  57. # cf. account_report_partner_ledger.mako
  58. initial_balance_text = {'initial_balance': _('Computed'),
  59. 'opening_balance': _('Opening Entries'),
  60. False: _('No')}
  61. # Title
  62. cell_style = xlwt.easyxf(_xs['xls_title'])
  63. report_name = ' - '.join([_p.report_name.upper(),
  64. _p.company.partner_id.name,
  65. _p.company.currency_id.name])
  66. c_specs = [
  67. ('report_name', 1, 0, 'text', report_name),
  68. ]
  69. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  70. row_pos = self.xls_write_row(
  71. ws, row_pos, row_data, row_style=cell_style)
  72. # write empty row to define column sizes
  73. c_sizes = self.column_sizes
  74. c_specs = [('empty%s' % i, 1, c_sizes[i], 'text', None)
  75. for i in range(0, len(c_sizes))]
  76. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  77. row_pos = self.xls_write_row(
  78. ws, row_pos, row_data, set_column_size=True)
  79. # Header Table
  80. nbr_columns = 10
  81. if _p.amount_currency(data):
  82. nbr_columns = 12
  83. cell_format = _xs['bold'] + _xs['fill_blue'] + _xs['borders_all']
  84. cell_style = xlwt.easyxf(cell_format)
  85. cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  86. c_specs = [
  87. ('coa', 2, 0, 'text', _('Chart of Account')),
  88. ('fy', 1, 0, 'text', _('Fiscal Year')),
  89. ('df', 2, 0, 'text', _p.filter_form(data) ==
  90. 'filter_date' and _('Dates Filter') or _('Periods Filter')),
  91. ('af', 1, 0, 'text', _('Accounts Filter')),
  92. ('tm', 2, 0, 'text', _('Target Moves')),
  93. ('ib', nbr_columns - 8, 0, 'text', _('Initial Balance')),
  94. ]
  95. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  96. row_pos = self.xls_write_row(
  97. ws, row_pos, row_data, row_style=cell_style_center)
  98. cell_format = _xs['borders_all']
  99. cell_style = xlwt.easyxf(cell_format)
  100. cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  101. c_specs = [
  102. ('coa', 2, 0, 'text', _p.chart_account.name),
  103. ('fy', 1, 0, 'text', _p.fiscalyear.name if _p.fiscalyear else '-'),
  104. ]
  105. df = _('From') + ': '
  106. if _p.filter_form(data) == 'filter_date':
  107. df += _p.start_date if _p.start_date else u''
  108. else:
  109. df += _p.start_period.name if _p.start_period else u''
  110. df += ' ' + _('To') + ': '
  111. if _p.filter_form(data) == 'filter_date':
  112. df += _p.stop_date if _p.stop_date else u''
  113. else:
  114. df += _p.stop_period.name if _p.stop_period else u''
  115. c_specs += [
  116. ('df', 2, 0, 'text', df),
  117. ('af', 1, 0, 'text', _('Custom Filter')
  118. if _p.partner_ids else _p.display_partner_account(data)),
  119. ('tm', 2, 0, 'text', _p.display_target_move(data)),
  120. ('ib', nbr_columns - 8, 0, 'text',
  121. initial_balance_text[_p.initial_balance_mode]),
  122. ]
  123. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  124. row_pos = self.xls_write_row(
  125. ws, row_pos, row_data, row_style=cell_style_center)
  126. ws.set_horz_split_pos(row_pos)
  127. row_pos += 1
  128. # Account Title Row
  129. cell_format = _xs['xls_title'] + _xs['bold'] + \
  130. _xs['fill'] + _xs['borders_all']
  131. account_cell_style = xlwt.easyxf(cell_format)
  132. account_cell_style_right = xlwt.easyxf(cell_format + _xs['right'])
  133. account_cell_style_decimal = xlwt.easyxf(
  134. cell_format + _xs['right'],
  135. num_format_str=report_xls.decimal_format)
  136. # Column Title Row
  137. cell_format = _xs['bold']
  138. c_title_cell_style = xlwt.easyxf(cell_format)
  139. # Column Header Row
  140. cell_format = _xs['bold'] + _xs['fill'] + _xs['borders_all']
  141. c_hdr_cell_style = xlwt.easyxf(cell_format)
  142. c_hdr_cell_style_right = xlwt.easyxf(cell_format + _xs['right'])
  143. c_hdr_cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  144. # Column Initial Balance Row
  145. cell_format = _xs['italic'] + _xs['borders_all']
  146. c_init_cell_style = xlwt.easyxf(cell_format)
  147. c_init_cell_style_decimal = xlwt.easyxf(
  148. cell_format + _xs['right'],
  149. num_format_str=report_xls.decimal_format)
  150. # Column Cumulated balance Row
  151. cell_format = _xs['bold'] + _xs['fill'] + _xs['borders_all']
  152. c_cumul_cell_style = xlwt.easyxf(cell_format)
  153. c_cumul_cell_style_right = xlwt.easyxf(cell_format + _xs['right'])
  154. c_cumul_cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  155. c_cumul_cell_style_decimal = xlwt.easyxf(
  156. cell_format + _xs['right'],
  157. num_format_str=report_xls.decimal_format)
  158. # Column Partner Row
  159. cell_format = _xs['bold']
  160. c_part_cell_style = xlwt.easyxf(cell_format)
  161. c_specs = [
  162. ('date', 1, 0, 'text', _('Date'), None, c_hdr_cell_style),
  163. ('period', 1, 0, 'text', _('Period'), None, c_hdr_cell_style),
  164. ('move', 1, 0, 'text', _('Entry'), None, c_hdr_cell_style),
  165. ('journal', 1, 0, 'text', _('Journal'), None, c_hdr_cell_style),
  166. ('partner', 1, 0, 'text', _('Partner'), None, c_hdr_cell_style),
  167. ('label', 1, 0, 'text', _('Label'), None, c_hdr_cell_style),
  168. ('rec', 1, 0, 'text', _('Rec.'), None, c_hdr_cell_style),
  169. ('debit', 1, 0, 'text', _('Debit'), None, c_hdr_cell_style_right),
  170. ('credit', 1, 0, 'text', _('Credit'),
  171. None, c_hdr_cell_style_right),
  172. ('cumul_bal', 1, 0, 'text', _('Cumul. Bal.'),
  173. None, c_hdr_cell_style_right),
  174. ]
  175. if _p.amount_currency(data):
  176. c_specs += [
  177. ('curr_bal', 1, 0, 'text', _('Curr. Bal.'),
  178. None, c_hdr_cell_style_right),
  179. ('curr_code', 1, 0, 'text', _('Curr.'),
  180. None, c_hdr_cell_style_center),
  181. ]
  182. c_hdr_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  183. # cell styles for ledger lines
  184. ll_cell_format = _xs['borders_all']
  185. ll_cell_style = xlwt.easyxf(ll_cell_format)
  186. ll_cell_style_center = xlwt.easyxf(ll_cell_format + _xs['center'])
  187. ll_cell_style_date = xlwt.easyxf(
  188. ll_cell_format + _xs['left'],
  189. num_format_str=report_xls.date_format)
  190. ll_cell_style_decimal = xlwt.easyxf(
  191. ll_cell_format + _xs['right'],
  192. num_format_str=report_xls.decimal_format)
  193. cnt = 0
  194. for account in objects:
  195. if _p['ledger_lines'].get(account.id, False) or \
  196. _p['init_balance'].get(account.id, False):
  197. if not _p['partners_order'].get(account.id, False):
  198. continue
  199. cnt += 1
  200. account_total_debit = 0.0
  201. account_total_credit = 0.0
  202. account_balance_cumul = 0.0
  203. account_balance_cumul_curr = 0.0
  204. c_specs = [
  205. ('acc_title', nbr_columns, 0, 'text',
  206. ' - '.join([account.code, account.name]), None,
  207. account_cell_style),
  208. ]
  209. row_data = self.xls_row_template(
  210. c_specs, [x[0] for x in c_specs])
  211. row_pos = self.xls_write_row(
  212. ws, row_pos, row_data, c_title_cell_style)
  213. row_pos += 1
  214. for partner_name, p_id, p_ref, p_name in \
  215. _p['partners_order'][account.id]:
  216. total_debit = 0.0
  217. total_credit = 0.0
  218. cumul_balance = 0.0
  219. cumul_balance_curr = 0.0
  220. part_cumul_balance = 0.0
  221. part_cumul_balance_curr = 0.0
  222. c_specs = [
  223. ('partner_title', nbr_columns, 0, 'text',
  224. partner_name or _('No Partner'), None,
  225. c_part_cell_style),
  226. ]
  227. row_data = self.xls_row_template(
  228. c_specs, [x[0] for x in c_specs])
  229. row_pos = self.xls_write_row(
  230. ws, row_pos, row_data, c_title_cell_style)
  231. row_pos = self.xls_write_row(ws, row_pos, c_hdr_data)
  232. row_start_partner = row_pos
  233. total_debit = _p['init_balance'][account.id].get(
  234. p_id, {}).get('debit') or 0.0
  235. total_credit = _p['init_balance'][account.id].get(
  236. p_id, {}).get('credit') or 0.0
  237. init_line = False
  238. if _p.initial_balance_mode and \
  239. (total_debit or total_credit):
  240. init_line = True
  241. part_cumul_balance = \
  242. _p['init_balance'][account.id].get(
  243. p_id, {}).get('init_balance') or 0.0
  244. part_cumul_balance_curr = \
  245. _p['init_balance'][account.id].get(
  246. p_id, {}).get('init_balance_currency') or 0.0
  247. balance_forward_currency = \
  248. _p['init_balance'][account.id].get(
  249. p_id, {}).get('currency_name') or ''
  250. cumul_balance += part_cumul_balance
  251. cumul_balance_curr += part_cumul_balance_curr
  252. debit_cell = rowcol_to_cell(row_pos, 7)
  253. credit_cell = rowcol_to_cell(row_pos, 8)
  254. init_bal_formula = debit_cell + '-' + credit_cell
  255. # Print row 'Initial Balance' by partn
  256. c_specs = [('empty%s' % x, 1, 0, 'text', None)
  257. for x in range(5)]
  258. c_specs += [
  259. ('init_bal', 1, 0, 'text', _('Initial Balance')),
  260. ('rec', 1, 0, 'text', None),
  261. ('debit', 1, 0, 'number', total_debit,
  262. None, c_init_cell_style_decimal),
  263. ('credit', 1, 0, 'number', total_credit,
  264. None, c_init_cell_style_decimal),
  265. ('cumul_bal', 1, 0, 'number', None,
  266. init_bal_formula, c_init_cell_style_decimal),
  267. ]
  268. if _p.amount_currency(data):
  269. c_specs += [
  270. ('curr_bal', 1, 0, 'number',
  271. part_cumul_balance_curr,
  272. None, c_init_cell_style_decimal),
  273. ('curr_code', 1, 0, 'text',
  274. balance_forward_currency),
  275. ]
  276. row_data = self.xls_row_template(
  277. c_specs, [x[0] for x in c_specs])
  278. row_pos = self.xls_write_row(
  279. ws, row_pos, row_data, c_init_cell_style)
  280. for line in _p['ledger_lines'][account.id].get(p_id, []):
  281. total_debit += line.get('debit') or 0.0
  282. total_credit += line.get('credit') or 0.0
  283. label_elements = [line.get('lname') or '']
  284. if line.get('invoice_number'):
  285. label_elements.append(
  286. "(%s)" % (line['invoice_number'],))
  287. label = ' '.join(label_elements)
  288. cumul_balance += line.get('balance') or 0.0
  289. if init_line or row_pos > row_start_partner:
  290. cumbal_formula = rowcol_to_cell(
  291. row_pos - 1, 9) + '+'
  292. else:
  293. cumbal_formula = ''
  294. debit_cell = rowcol_to_cell(row_pos, 7)
  295. credit_cell = rowcol_to_cell(row_pos, 8)
  296. cumbal_formula += debit_cell + '-' + credit_cell
  297. # Print row ledger line data #
  298. if line.get('ldate'):
  299. c_specs = [
  300. ('ldate', 1, 0, 'date', datetime.strptime(
  301. line['ldate'], '%Y-%m-%d'), None,
  302. ll_cell_style_date),
  303. ]
  304. else:
  305. c_specs = [
  306. ('ldate', 1, 0, 'text', None),
  307. ]
  308. c_specs += [
  309. ('period', 1, 0, 'text',
  310. line.get('period_code') or ''),
  311. ('move', 1, 0, 'text',
  312. line.get('move_name') or ''),
  313. ('journal', 1, 0, 'text', line.get('jcode') or ''),
  314. ('partner', 1, 0, 'text',
  315. line.get('partner_name') or ''),
  316. ('label', 1, 0, 'text', label),
  317. ('rec_name', 1, 0, 'text',
  318. line.get('rec_name') or ''),
  319. ('debit', 1, 0, 'number', line.get('debit'),
  320. None, ll_cell_style_decimal),
  321. ('credit', 1, 0, 'number', line.get('credit'),
  322. None, ll_cell_style_decimal),
  323. ('cumul_bal', 1, 0, 'number', None,
  324. cumbal_formula, ll_cell_style_decimal),
  325. ]
  326. if _p.amount_currency(data):
  327. c_specs += [
  328. ('curr_bal', 1, 0, 'number', line.get(
  329. 'amount_currency') or 0.0, None,
  330. ll_cell_style_decimal),
  331. ('curr_code', 1, 0, 'text', line.get(
  332. 'currency_code') or '', None,
  333. ll_cell_style_center),
  334. ]
  335. row_data = self.xls_row_template(
  336. c_specs, [x[0] for x in c_specs])
  337. row_pos = self.xls_write_row(
  338. ws, row_pos, row_data, ll_cell_style)
  339. # end for line
  340. # Print row Cumulated Balance by partner #
  341. debit_partner_start = rowcol_to_cell(row_start_partner, 7)
  342. debit_partner_end = rowcol_to_cell(row_pos - 1, 7)
  343. debit_partner_total = 'SUM(' + debit_partner_start + \
  344. ':' + debit_partner_end + ')'
  345. credit_partner_start = rowcol_to_cell(row_start_partner, 8)
  346. credit_partner_end = rowcol_to_cell(row_pos - 1, 8)
  347. credit_partner_total = 'SUM(' + credit_partner_start + \
  348. ':' + credit_partner_end + ')'
  349. bal_partner_debit = rowcol_to_cell(row_pos, 7)
  350. bal_partner_credit = rowcol_to_cell(row_pos, 8)
  351. bal_partner_total = bal_partner_debit + \
  352. '-' + bal_partner_credit
  353. c_specs = [('empty%s' % x, 1, 0, 'text', None)
  354. for x in range(5)]
  355. c_specs += [
  356. ('init_bal', 1, 0, 'text',
  357. _('Cumulated balance on Partner')),
  358. ('rec', 1, 0, 'text', None),
  359. ('debit', 1, 0, 'number', None,
  360. debit_partner_total, c_cumul_cell_style_decimal),
  361. ('credit', 1, 0, 'number', None,
  362. credit_partner_total, c_cumul_cell_style_decimal),
  363. ('cumul_bal', 1, 0, 'number', None,
  364. bal_partner_total, c_cumul_cell_style_decimal),
  365. ]
  366. if _p.amount_currency(data):
  367. if account.currency_id:
  368. c_specs += [('curr_bal', 1, 0, 'number',
  369. cumul_balance_curr or 0.0, None,
  370. c_cumul_cell_style_decimal)]
  371. else:
  372. c_specs += [('curr_bal', 1, 0, 'text',
  373. '-', None, c_cumul_cell_style_right)]
  374. c_specs += [('curr_code', 1, 0, 'text',
  375. account.currency_id.name if
  376. account.currency_id else u'', None,
  377. c_cumul_cell_style_center)]
  378. row_data = self.xls_row_template(
  379. c_specs, [x[0] for x in c_specs])
  380. row_pos = self.xls_write_row(
  381. ws, row_pos, row_data, c_cumul_cell_style)
  382. row_pos += 1
  383. account_total_debit += total_debit
  384. account_total_credit += total_credit
  385. account_balance_cumul += cumul_balance
  386. account_balance_cumul_curr += cumul_balance_curr
  387. # Print row Cumulated Balance by account #
  388. c_specs = [
  389. ('acc_title', 5, 0, 'text', ' - '.
  390. join([account.code, account.name])), ]
  391. c_specs += [
  392. ('label', 1, 0, 'text', _('Cumulated balance on Account')),
  393. ('rec', 1, 0, 'text', None),
  394. ('debit', 1, 0, 'number', account_total_debit,
  395. None, account_cell_style_decimal),
  396. ('credit', 1, 0, 'number', account_total_credit,
  397. None, account_cell_style_decimal),
  398. ('cumul_bal', 1, 0, 'number', account_balance_cumul,
  399. None, account_cell_style_decimal),
  400. ]
  401. if _p.amount_currency(data):
  402. if account.currency_id:
  403. c_specs += [('curr_bal', 1, 0, 'number',
  404. account_balance_cumul_curr or 0.0, None,
  405. account_cell_style_decimal)]
  406. else:
  407. c_specs += [('curr_bal', 1, 0, 'text',
  408. '-', None, account_cell_style_right)]
  409. c_specs += [('curr_code', 1, 0, 'text',
  410. account.currency_id.name if
  411. account.currency_id else u'', None,
  412. account_cell_style)]
  413. row_data = self.xls_row_template(
  414. c_specs, [x[0] for x in c_specs])
  415. row_pos = self.xls_write_row(
  416. ws, row_pos, row_data, account_cell_style)
  417. row_pos += 2
  418. partner_ledger_xls('report.account.account_report_partner_ledger_xls',
  419. 'account.account',
  420. parser=PartnersLedgerWebkit)