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.

457 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 account.ledger_lines or account.init_balance:
  196. if not account.partners_order:
  197. continue
  198. cnt += 1
  199. account_total_debit = 0.0
  200. account_total_credit = 0.0
  201. account_balance_cumul = 0.0
  202. account_balance_cumul_curr = 0.0
  203. c_specs = [
  204. ('acc_title', nbr_columns, 0, 'text',
  205. ' - '.join([account.code, account.name]), None,
  206. account_cell_style),
  207. ]
  208. row_data = self.xls_row_template(
  209. c_specs, [x[0] for x in c_specs])
  210. row_pos = self.xls_write_row(
  211. ws, row_pos, row_data, c_title_cell_style)
  212. row_pos += 1
  213. for partner_name, p_id, p_ref, p_name in \
  214. account.partners_order:
  215. total_debit = 0.0
  216. total_credit = 0.0
  217. cumul_balance = 0.0
  218. cumul_balance_curr = 0.0
  219. part_cumul_balance = 0.0
  220. part_cumul_balance_curr = 0.0
  221. c_specs = [
  222. ('partner_title', nbr_columns, 0, 'text',
  223. partner_name or _('No Partner'), None,
  224. c_part_cell_style),
  225. ]
  226. row_data = self.xls_row_template(
  227. c_specs, [x[0] for x in c_specs])
  228. row_pos = self.xls_write_row(
  229. ws, row_pos, row_data, c_title_cell_style)
  230. row_pos = self.xls_write_row(ws, row_pos, c_hdr_data)
  231. row_start_partner = row_pos
  232. total_debit = account.init_balance.get(
  233. p_id, {}).get('debit') or 0.0
  234. total_credit = account.init_balance.get(
  235. p_id, {}).get('credit') or 0.0
  236. init_line = False
  237. if _p.initial_balance_mode and \
  238. (total_debit or total_credit):
  239. init_line = True
  240. part_cumul_balance = account.init_balance.get(
  241. p_id, {}).get('init_balance') or 0.0
  242. part_cumul_balance_curr = account.init_balance.get(
  243. p_id, {}).get('init_balance_currency') or 0.0
  244. balance_forward_currency = account.init_balance.get(
  245. p_id, {}).get('currency_name') or ''
  246. cumul_balance += part_cumul_balance
  247. cumul_balance_curr += part_cumul_balance_curr
  248. debit_cell = rowcol_to_cell(row_pos, 7)
  249. credit_cell = rowcol_to_cell(row_pos, 8)
  250. init_bal_formula = debit_cell + '-' + credit_cell
  251. # Print row 'Initial Balance' by partn
  252. c_specs = [('empty%s' % x, 1, 0, 'text', None)
  253. for x in range(5)]
  254. c_specs += [
  255. ('init_bal', 1, 0, 'text', _('Initial Balance')),
  256. ('rec', 1, 0, 'text', None),
  257. ('debit', 1, 0, 'number', total_debit,
  258. None, c_init_cell_style_decimal),
  259. ('credit', 1, 0, 'number', total_credit,
  260. None, c_init_cell_style_decimal),
  261. ('cumul_bal', 1, 0, 'number', None,
  262. init_bal_formula, c_init_cell_style_decimal),
  263. ]
  264. if _p.amount_currency(data):
  265. c_specs += [
  266. ('curr_bal', 1, 0, 'number',
  267. part_cumul_balance_curr,
  268. None, c_init_cell_style_decimal),
  269. ('curr_code', 1, 0, 'text',
  270. balance_forward_currency),
  271. ]
  272. row_data = self.xls_row_template(
  273. c_specs, [x[0] for x in c_specs])
  274. row_pos = self.xls_write_row(
  275. ws, row_pos, row_data, c_init_cell_style)
  276. for line in account.ledger_lines.get(p_id, []):
  277. total_debit += line.get('debit') or 0.0
  278. total_credit += line.get('credit') or 0.0
  279. label_elements = [line.get('lname') or '']
  280. if line.get('invoice_number'):
  281. label_elements.append(
  282. "(%s)" % (line['invoice_number'],))
  283. label = ' '.join(label_elements)
  284. cumul_balance += line.get('balance') or 0.0
  285. if init_line or row_pos > row_start_partner:
  286. cumbal_formula = rowcol_to_cell(
  287. row_pos - 1, 9) + '+'
  288. else:
  289. cumbal_formula = ''
  290. debit_cell = rowcol_to_cell(row_pos, 7)
  291. credit_cell = rowcol_to_cell(row_pos, 8)
  292. cumbal_formula += debit_cell + '-' + credit_cell
  293. # Print row ledger line data #
  294. if line.get('ldate'):
  295. c_specs = [
  296. ('ldate', 1, 0, 'date', datetime.strptime(
  297. line['ldate'], '%Y-%m-%d'), None,
  298. ll_cell_style_date),
  299. ]
  300. else:
  301. c_specs = [
  302. ('ldate', 1, 0, 'text', None),
  303. ]
  304. c_specs += [
  305. ('period', 1, 0, 'text',
  306. line.get('period_code') or ''),
  307. ('move', 1, 0, 'text',
  308. line.get('move_name') or ''),
  309. ('journal', 1, 0, 'text', line.get('jcode') or ''),
  310. ('partner', 1, 0, 'text',
  311. line.get('partner_name') or ''),
  312. ('label', 1, 0, 'text', label),
  313. ('rec_name', 1, 0, 'text',
  314. line.get('rec_name') or ''),
  315. ('debit', 1, 0, 'number', line.get('debit'),
  316. None, ll_cell_style_decimal),
  317. ('credit', 1, 0, 'number', line.get('credit'),
  318. None, ll_cell_style_decimal),
  319. ('cumul_bal', 1, 0, 'number', None,
  320. cumbal_formula, ll_cell_style_decimal),
  321. ]
  322. if _p.amount_currency(data):
  323. c_specs += [
  324. ('curr_bal', 1, 0, 'number', line.get(
  325. 'amount_currency') or 0.0, None,
  326. ll_cell_style_decimal),
  327. ('curr_code', 1, 0, 'text', line.get(
  328. 'currency_code') or '', None,
  329. ll_cell_style_center),
  330. ]
  331. row_data = self.xls_row_template(
  332. c_specs, [x[0] for x in c_specs])
  333. row_pos = self.xls_write_row(
  334. ws, row_pos, row_data, ll_cell_style)
  335. # end for line
  336. # Print row Cumulated Balance by partner #
  337. debit_partner_start = rowcol_to_cell(row_start_partner, 7)
  338. debit_partner_end = rowcol_to_cell(row_pos - 1, 7)
  339. debit_partner_total = 'SUM(' + debit_partner_start + \
  340. ':' + debit_partner_end + ')'
  341. credit_partner_start = rowcol_to_cell(row_start_partner, 8)
  342. credit_partner_end = rowcol_to_cell(row_pos - 1, 8)
  343. credit_partner_total = 'SUM(' + credit_partner_start + \
  344. ':' + credit_partner_end + ')'
  345. bal_partner_debit = rowcol_to_cell(row_pos, 7)
  346. bal_partner_credit = rowcol_to_cell(row_pos, 8)
  347. bal_partner_total = bal_partner_debit + \
  348. '-' + bal_partner_credit
  349. c_specs = [('empty%s' % x, 1, 0, 'text', None)
  350. for x in range(5)]
  351. c_specs += [
  352. ('init_bal', 1, 0, 'text',
  353. _('Cumulated balance on Partner')),
  354. ('rec', 1, 0, 'text', None),
  355. ('debit', 1, 0, 'number', None,
  356. debit_partner_total, c_cumul_cell_style_decimal),
  357. ('credit', 1, 0, 'number', None,
  358. credit_partner_total, c_cumul_cell_style_decimal),
  359. ('cumul_bal', 1, 0, 'number', None,
  360. bal_partner_total, c_cumul_cell_style_decimal),
  361. ]
  362. if _p.amount_currency(data):
  363. if account.currency_id:
  364. c_specs += [('curr_bal', 1, 0, 'number',
  365. cumul_balance_curr or 0.0, None,
  366. c_cumul_cell_style_decimal)]
  367. else:
  368. c_specs += [('curr_bal', 1, 0, 'text',
  369. '-', None, c_cumul_cell_style_right)]
  370. c_specs += [('curr_code', 1, 0, 'text',
  371. account.currency_id.name if
  372. account.currency_id else u'', None,
  373. c_cumul_cell_style_center)]
  374. row_data = self.xls_row_template(
  375. c_specs, [x[0] for x in c_specs])
  376. row_pos = self.xls_write_row(
  377. ws, row_pos, row_data, c_cumul_cell_style)
  378. row_pos += 1
  379. account_total_debit += total_debit
  380. account_total_credit += total_credit
  381. account_balance_cumul += cumul_balance
  382. account_balance_cumul_curr += cumul_balance_curr
  383. # Print row Cumulated Balance by account #
  384. c_specs = [
  385. ('acc_title', 5, 0, 'text', ' - '.
  386. join([account.code, account.name])), ]
  387. c_specs += [
  388. ('label', 1, 0, 'text', _('Cumulated balance on Account')),
  389. ('rec', 1, 0, 'text', None),
  390. ('debit', 1, 0, 'number', account_total_debit,
  391. None, account_cell_style_decimal),
  392. ('credit', 1, 0, 'number', account_total_credit,
  393. None, account_cell_style_decimal),
  394. ('cumul_bal', 1, 0, 'number', account_balance_cumul,
  395. None, account_cell_style_decimal),
  396. ]
  397. if _p.amount_currency(data):
  398. if account.currency_id:
  399. c_specs += [('curr_bal', 1, 0, 'number',
  400. account_balance_cumul_curr or 0.0, None,
  401. account_cell_style_decimal)]
  402. else:
  403. c_specs += [('curr_bal', 1, 0, 'text',
  404. '-', None, account_cell_style_right)]
  405. c_specs += [('curr_code', 1, 0, 'text',
  406. account.currency_id.name if
  407. account.currency_id else u'', None,
  408. account_cell_style)]
  409. row_data = self.xls_row_template(
  410. c_specs, [x[0] for x in c_specs])
  411. row_pos = self.xls_write_row(
  412. ws, row_pos, row_data, account_cell_style)
  413. row_pos += 2
  414. partner_ledger_xls('report.account.account_report_partner_ledger_xls',
  415. 'account.account',
  416. parser=PartnersLedgerWebkit)