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.

375 lines
16 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.general_ledger \
  27. import GeneralLedgerWebkit
  28. from openerp.tools.translate import _
  29. # import logging
  30. # _logger = logging.getLogger(__name__)
  31. class GeneralLedgerWebkitSupplier(GeneralLedgerWebkit):
  32. """ Extends General Ledger Parser to add the supplier invoice
  33. number in the move lines """
  34. def _get_move_line_select(self):
  35. res = super(GeneralLedgerWebkitSupplier, self)._get_move_line_select()
  36. return res + """
  37. , i.supplier_invoice_number AS supplier_invoice_number
  38. """
  39. _column_sizes = [
  40. ('date', 12),
  41. ('period', 12),
  42. ('move', 20),
  43. ('supp_inv_no', 22),
  44. ('journal', 12),
  45. ('account_code', 12),
  46. ('partner', 30),
  47. ('label', 45),
  48. ('counterpart', 30),
  49. ('debit', 15),
  50. ('credit', 15),
  51. ('cumul_bal', 15),
  52. ('curr_bal', 15),
  53. ('curr_code', 7),
  54. ]
  55. # Header column spans
  56. COLS_COA = 3
  57. COLS_FY = 1
  58. COLS_DF = 3
  59. COLS_AF = 1
  60. COLS_TM = 2
  61. COLS_IB = 2
  62. # Full column span
  63. COLS_TOT = sum((COLS_COA, COLS_FY, COLS_DF, COLS_AF, COLS_TM, COLS_IB))
  64. class general_ledger_xls(report_xls):
  65. column_sizes = [x[1] for x in _column_sizes]
  66. def generate_xls_report(self, _p, _xs, data, objects, wb):
  67. ws = wb.add_sheet(_p.report_name[:31])
  68. ws.panes_frozen = True
  69. ws.remove_splits = True
  70. ws.portrait = 0 # Landscape
  71. ws.fit_width_to_pages = 1
  72. row_pos = 0
  73. # set print header/footer
  74. ws.header_str = self.xls_headers['standard']
  75. ws.footer_str = self.xls_footers['standard']
  76. # cf. account_report_general_ledger.mako
  77. initial_balance_text = {'initial_balance': _('Computed'),
  78. 'opening_balance': _('Opening Entries'),
  79. False: _('No')}
  80. # Title
  81. cell_style = xlwt.easyxf(_xs['xls_title'])
  82. report_name = ' - '.join([_p.report_name.upper(),
  83. _p.company.partner_id.name,
  84. _p.company.currency_id.name])
  85. c_specs = [
  86. ('report_name', COLS_TOT, 0, 'text', report_name),
  87. ]
  88. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  89. row_pos = self.xls_write_row(
  90. ws, row_pos, row_data, row_style=cell_style)
  91. # write empty row to define column sizes
  92. c_sizes = self.column_sizes
  93. c_specs = [('empty%s' % i, 1, c_sizes[i], 'text', None)
  94. for i in range(0, len(c_sizes))]
  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, set_column_size=True)
  98. # Header Table
  99. cell_format = _xs['bold'] + _xs['fill_blue'] + _xs['borders_all']
  100. cell_style = xlwt.easyxf(cell_format)
  101. cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  102. c_specs = [
  103. ('coa', COLS_COA, 0, 'text', _('Chart of Account')),
  104. ('fy', COLS_FY, 0, 'text', _('Fiscal Year')),
  105. ('df', COLS_DF, 0, 'text', _p.filter_form(data) ==
  106. 'filter_date' and _('Dates Filter') or _('Periods Filter')),
  107. ('af', COLS_AF, 0, 'text', _('Accounts Filter')),
  108. ('tm', COLS_TM, 0, 'text', _('Target Moves')),
  109. ('ib', COLS_IB, 0, 'text', _('Initial Balance')),
  110. ]
  111. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  112. row_pos = self.xls_write_row(
  113. ws, row_pos, row_data, row_style=cell_style_center)
  114. cell_format = _xs['borders_all']
  115. cell_style = xlwt.easyxf(cell_format)
  116. cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  117. c_specs = [
  118. ('coa', COLS_COA, 0, 'text', _p.chart_account.name),
  119. ('fy', COLS_FY, 0, 'text',
  120. _p.fiscalyear.name if _p.fiscalyear else '-'),
  121. ]
  122. df = _('From') + ': '
  123. if _p.filter_form(data) == 'filter_date':
  124. df += _p.start_date if _p.start_date else u''
  125. else:
  126. df += _p.start_period.name if _p.start_period else u''
  127. df += ' ' + _('To') + ': '
  128. if _p.filter_form(data) == 'filter_date':
  129. df += _p.stop_date if _p.stop_date else u''
  130. else:
  131. df += _p.stop_period.name if _p.stop_period else u''
  132. c_specs += [
  133. ('df', COLS_DF, 0, 'text', df),
  134. ('af', COLS_AF, 0, 'text', _p.accounts(data) and ', '.join(
  135. [account.code for account in _p.accounts(data)]) or _('All')),
  136. ('tm', COLS_TM, 0, 'text', _p.display_target_move(data)),
  137. ('ib', COLS_IB, 0, 'text', initial_balance_text[
  138. _p.initial_balance_mode]),
  139. ]
  140. row_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  141. row_pos = self.xls_write_row(
  142. ws, row_pos, row_data, row_style=cell_style_center)
  143. ws.set_horz_split_pos(row_pos)
  144. row_pos += 1
  145. # Column Title Row
  146. cell_format = _xs['bold']
  147. c_title_cell_style = xlwt.easyxf(cell_format)
  148. # Column Header Row
  149. cell_format = _xs['bold'] + _xs['fill'] + _xs['borders_all']
  150. c_hdr_cell_style = xlwt.easyxf(cell_format)
  151. c_hdr_cell_style_right = xlwt.easyxf(cell_format + _xs['right'])
  152. c_hdr_cell_style_center = xlwt.easyxf(cell_format + _xs['center'])
  153. c_hdr_cell_style_decimal = xlwt.easyxf(
  154. cell_format + _xs['right'],
  155. num_format_str=report_xls.decimal_format)
  156. # Column Initial Balance Row
  157. cell_format = _xs['italic'] + _xs['borders_all']
  158. c_init_cell_style = xlwt.easyxf(cell_format)
  159. c_init_cell_style_decimal = xlwt.easyxf(
  160. cell_format + _xs['right'],
  161. num_format_str=report_xls.decimal_format)
  162. c_specs = [
  163. ('date', 1, 0, 'text', _('Date'), None, c_hdr_cell_style),
  164. ('period', 1, 0, 'text', _('Period'), None, c_hdr_cell_style),
  165. ('move', 1, 0, 'text', _('Entry'), None, c_hdr_cell_style),
  166. ('supp_inv_no', 1, 0, 'text', _('Supplier Invoice Number'),
  167. None, c_hdr_cell_style),
  168. ('journal', 1, 0, 'text', _('Journal'), None, c_hdr_cell_style),
  169. ('account_code', 1, 0, 'text',
  170. _('Account'), None, c_hdr_cell_style),
  171. ('partner', 1, 0, 'text', _('Partner'), None, c_hdr_cell_style),
  172. ('label', 1, 0, 'text', _('Label'), None, c_hdr_cell_style),
  173. ('counterpart', 1, 0, 'text',
  174. _('Counterpart'), None, c_hdr_cell_style),
  175. ('debit', 1, 0, 'text', _('Debit'), None, c_hdr_cell_style_right),
  176. ('credit', 1, 0, 'text', _('Credit'),
  177. None, c_hdr_cell_style_right),
  178. ('cumul_bal', 1, 0, 'text', _('Cumul. Bal.'),
  179. None, c_hdr_cell_style_right),
  180. ]
  181. if _p.amount_currency(data):
  182. c_specs += [
  183. ('curr_bal', 1, 0, 'text', _('Curr. Bal.'),
  184. None, c_hdr_cell_style_right),
  185. ('curr_code', 1, 0, 'text', _('Curr.'),
  186. None, c_hdr_cell_style_center),
  187. ]
  188. c_hdr_data = self.xls_row_template(c_specs, [x[0] for x in c_specs])
  189. # cell styles for ledger lines
  190. ll_cell_format = _xs['borders_all']
  191. ll_cell_style = xlwt.easyxf(ll_cell_format)
  192. ll_cell_style_center = xlwt.easyxf(ll_cell_format + _xs['center'])
  193. ll_cell_style_date = xlwt.easyxf(
  194. ll_cell_format + _xs['left'],
  195. num_format_str=report_xls.date_format)
  196. ll_cell_style_decimal = xlwt.easyxf(
  197. ll_cell_format + _xs['right'],
  198. num_format_str=report_xls.decimal_format)
  199. cnt = 0
  200. for account in objects:
  201. display_initial_balance = account.init_balance and \
  202. (account.init_balance.get(
  203. 'debit', 0.0) != 0.0 or account.
  204. init_balance.get('credit', 0.0) != 0.0)
  205. display_ledger_lines = account.ledger_lines
  206. if _p.display_account_raw(data) == 'all' or \
  207. (display_ledger_lines or display_initial_balance):
  208. # TO DO : replace cumul amounts by xls formulas
  209. cnt += 1
  210. cumul_debit = 0.0
  211. cumul_credit = 0.0
  212. cumul_balance = 0.0
  213. cumul_balance_curr = 0.0
  214. c_specs = [
  215. ('acc_title', COLS_TOT, 0, 'text',
  216. ' - '.join([account.code, account.name])),
  217. ]
  218. row_data = self.xls_row_template(
  219. c_specs, [x[0] for x in c_specs])
  220. row_pos = self.xls_write_row(
  221. ws, row_pos, row_data, c_title_cell_style)
  222. row_pos = self.xls_write_row(ws, row_pos, c_hdr_data)
  223. row_start = row_pos
  224. if display_initial_balance:
  225. cumul_debit = account.init_balance.get('debit') or 0.0
  226. cumul_credit = account.init_balance.get('credit') or 0.0
  227. cumul_balance = account.init_balance.get(
  228. 'init_balance') or 0.0
  229. cumul_balance_curr = account.init_balance.get(
  230. 'init_balance_currency') or 0.0
  231. c_specs = [('empty%s' % x, 1, 0, 'text', None)
  232. for x in range(7)]
  233. c_specs += [
  234. ('init_bal', 1, 0, 'text', _('Initial Balance')),
  235. ('counterpart', 1, 0, 'text', None),
  236. ('debit', 1, 0, 'number', cumul_debit,
  237. None, c_init_cell_style_decimal),
  238. ('credit', 1, 0, 'number', cumul_credit,
  239. None, c_init_cell_style_decimal),
  240. ('cumul_bal', 1, 0, 'number', cumul_balance,
  241. None, c_init_cell_style_decimal),
  242. ]
  243. if _p.amount_currency(data):
  244. c_specs += [
  245. ('curr_bal', 1, 0, 'number', cumul_balance_curr,
  246. None, c_init_cell_style_decimal),
  247. ('curr_code', 1, 0, 'text', None),
  248. ]
  249. row_data = self.xls_row_template(
  250. c_specs, [x[0] for x in c_specs])
  251. row_pos = self.xls_write_row(
  252. ws, row_pos, row_data, c_init_cell_style)
  253. for line in account.ledger_lines:
  254. cumul_debit += line.get('debit') or 0.0
  255. cumul_credit += line.get('credit') or 0.0
  256. cumul_balance_curr += line.get('amount_currency') or 0.0
  257. cumul_balance += line.get('balance') or 0.0
  258. label_elements = [line.get('lname') or '']
  259. if line.get('invoice_number'):
  260. label_elements.append(
  261. "(%s)" % (line['invoice_number'],))
  262. label = ' '.join(label_elements)
  263. if line.get('ldate'):
  264. c_specs = [
  265. ('ldate', 1, 0, 'date', datetime.strptime(
  266. line['ldate'], '%Y-%m-%d'), None,
  267. ll_cell_style_date),
  268. ]
  269. else:
  270. c_specs = [
  271. ('ldate', 1, 0, 'text', None),
  272. ]
  273. c_specs += [
  274. ('period', 1, 0, 'text',
  275. line.get('period_code') or ''),
  276. ('move', 1, 0, 'text', line.get('move_name') or ''),
  277. ('supp_inv_no', 1, 0, 'text',
  278. line.get('supplier_invoice_number') or ''),
  279. ('journal', 1, 0, 'text', line.get('jcode') or ''),
  280. ('account_code', 1, 0, 'text', account.code),
  281. ('partner', 1, 0, 'text',
  282. line.get('partner_name') or ''),
  283. ('label', 1, 0, 'text', label),
  284. ('counterpart', 1, 0, 'text',
  285. line.get('counterparts') or ''),
  286. ('debit', 1, 0, 'number', line.get('debit', 0.0),
  287. None, ll_cell_style_decimal),
  288. ('credit', 1, 0, 'number', line.get('credit', 0.0),
  289. None, ll_cell_style_decimal),
  290. ('cumul_bal', 1, 0, 'number', cumul_balance,
  291. None, ll_cell_style_decimal),
  292. ]
  293. if _p.amount_currency(data):
  294. c_specs += [
  295. ('curr_bal', 1, 0, 'number', line.get(
  296. 'amount_currency') or 0.0, None,
  297. ll_cell_style_decimal),
  298. ('curr_code', 1, 0, 'text', line.get(
  299. 'currency_code') or '', None,
  300. ll_cell_style_center),
  301. ]
  302. row_data = self.xls_row_template(
  303. c_specs, [x[0] for x in c_specs])
  304. row_pos = self.xls_write_row(
  305. ws, row_pos, row_data, ll_cell_style)
  306. debit_start = rowcol_to_cell(row_start, 9)
  307. debit_end = rowcol_to_cell(row_pos - 1, 9)
  308. debit_formula = 'SUM(' + debit_start + ':' + debit_end + ')'
  309. credit_start = rowcol_to_cell(row_start, 10)
  310. credit_end = rowcol_to_cell(row_pos - 1, 10)
  311. credit_formula = 'SUM(' + credit_start + ':' + credit_end + ')'
  312. balance_debit = rowcol_to_cell(row_pos, 9)
  313. balance_credit = rowcol_to_cell(row_pos, 10)
  314. balance_formula = balance_debit + '-' + balance_credit
  315. c_specs = [
  316. ('acc_title', COLS_TOT - 4, 0, 'text',
  317. ' - '.join([account.code, account.name])),
  318. ('cum_bal', 1, 0, 'text',
  319. _('Cumulated Balance on Account'),
  320. None, c_hdr_cell_style_right),
  321. ('debit', 1, 0, 'number', None,
  322. debit_formula, c_hdr_cell_style_decimal),
  323. ('credit', 1, 0, 'number', None,
  324. credit_formula, c_hdr_cell_style_decimal),
  325. ('balance', 1, 0, 'number', None,
  326. balance_formula, c_hdr_cell_style_decimal),
  327. ]
  328. if _p.amount_currency(data):
  329. if account.currency_id:
  330. c_specs += [('curr_bal', 1, 0, 'number',
  331. cumul_balance_curr, None,
  332. c_hdr_cell_style_decimal)]
  333. else:
  334. c_specs += [('curr_bal', 1, 0, 'text', None)]
  335. c_specs += [('curr_code', 1, 0, 'text', None)]
  336. row_data = self.xls_row_template(
  337. c_specs, [x[0] for x in c_specs])
  338. row_pos = self.xls_write_row(
  339. ws, row_pos, row_data, c_hdr_cell_style)
  340. row_pos += 1
  341. general_ledger_xls('report.account.account_report_general_ledger_xls',
  342. 'account.account',
  343. parser=GeneralLedgerWebkitSupplier)