1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # analytic_point_of_sale module for OpenERP, Analytic Point of sale
5 # Copyright (C) 2017 L'Heureux Cyclage (<http://www.heureux-cyclage.org>)
8 # This file is a part of analytic_point_of_sale
10 # analytic_point_of_sale is free software: you can redistribute it and/or
11 # modify it under the terms of the GNU General Public License as published
12 # by the Free Software Foundation, either version 3 of the License, or (at
13 # your option) any later version.
15 # analytic_point_of_sale is distributed in the hope that it will be useful,
16 # but WITHOUT ANY WARRANTY; without even the implied warranty of
17 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
18 # Public License for more details.
20 # You should have received a copy of the GNU General Public License along
21 # with this program. If not, see <http://www.gnu.org/licenses/>.
23 ##############################################################################
25 from openerp
.osv
import osv
26 from openerp
.osv
import orm
27 from openerp
.osv
import fields
28 from openerp
.tools
.translate
import _
31 class pos_order(orm
.Model
):
32 _inherit
= 'pos.order'
34 def _create_account_move_line(self
, cr
, uid
, ids
, session
=None, move_id
=None, context
=None):
35 # Tricky, via the workflow, we only have one id in the ids variable
36 """Create a account move line of order grouped by products or not."""
37 account_move_obj
= self
.pool
.get('account.move')
38 account_period_obj
= self
.pool
.get('account.period')
39 account_tax_obj
= self
.pool
.get('account.tax')
40 property_obj
= self
.pool
.get('ir.property')
41 cur_obj
= self
.pool
.get('res.currency')
42 shop_obj
= self
.pool
.get('sale.shop')
44 #session_ids = set(order.session_id for order in self.browse(cr, uid, ids, context=context))
46 if session
and not all(session
.id == order
.session_id
.id for order
in self
.browse(cr
, uid
, ids
, context
=context
)):
47 raise osv
.except_osv(_('Error!'), _('Selected orders do not have the same session!'))
50 have_to_group_by
= session
and session
.config_id
.group_by
or False
52 for order
in self
.browse(cr
, uid
, ids
, context
=context
):
53 if order
.account_move
:
55 if order
.state
!= 'paid':
58 current_company
= order
.sale_journal
.company_id
59 analytic_account_id
= order
.shop_id
.project_id
.id
60 print("#DEBUG: analytic_account_id = %s" % analytic_account_id
)
63 account_def
= property_obj
.get(cr
, uid
, 'property_account_receivable', 'res.partner', context
=context
)
65 order_account
= order
.partner_id
and \
66 order
.partner_id
.property_account_receivable
and \
67 order
.partner_id
.property_account_receivable
.id or \
68 account_def
and account_def
.id or current_company
.account_receivable
.id
71 # Create an entry for the sale
72 move_id
= account_move_obj
.create(cr
, uid
, {
74 'journal_id': order
.sale_journal
.id,
77 def insert_data(data_type
, values
):
78 # if have_to_group_by:
80 sale_journal_id
= order
.sale_journal
.id
81 period
= account_period_obj
.find(cr
, uid
, context
=dict(context
or {}, company_id
=current_company
.id, account_period_prefer_normal
=True))[0]
83 # 'quantity': line.qty,
84 # 'product_id': line.product_id.id,
86 'date': order
.date_order
[:10],
88 'journal_id' : sale_journal_id
,
91 'company_id': current_company
.id,
94 if data_type
== 'product':
95 key
= ('product', values
['partner_id'], values
['product_id'], values
['debit'] > 0)
96 elif data_type
== 'tax':
97 key
= ('tax', values
['partner_id'], values
['tax_code_id'], values
['debit'] > 0)
98 elif data_type
== 'counter_part':
99 key
= ('counter_part', values
['partner_id'], values
['account_id'], values
['debit'] > 0)
103 grouped_data
.setdefault(key
, [])
105 # if not have_to_group_by or (not grouped_data[key]):
106 # grouped_data[key].append(values)
111 if not grouped_data
[key
]:
112 grouped_data
[key
].append(values
)
114 current_value
= grouped_data
[key
][0]
115 current_value
['quantity'] = current_value
.get('quantity', 0.0) + values
.get('quantity', 0.0)
116 current_value
['credit'] = current_value
.get('credit', 0.0) + values
.get('credit', 0.0)
117 current_value
['debit'] = current_value
.get('debit', 0.0) + values
.get('debit', 0.0)
118 current_value
['tax_amount'] = current_value
.get('tax_amount', 0.0) + values
.get('tax_amount', 0.0)
120 grouped_data
[key
].append(values
)
122 #because of the weird way the pos order is written, we need to make sure there is at least one line,
123 #because just after the 'for' loop there are references to 'line' and 'income_account' variables (that
124 #are set inside the for loop)
125 #TOFIX: a deep refactoring of this method (and class!) is needed in order to get rid of this stupid hack
126 assert order
.lines
, _('The POS order must have lines when calling this method')
127 # Create an move for each order line
129 cur
= order
.pricelist_id
.currency_id
130 for line
in order
.lines
:
133 for t
in line
.product_id
.taxes_id
:
134 if t
.company_id
.id == current_company
.id:
136 computed_taxes
= account_tax_obj
.compute_all(cr
, uid
, taxes
, line
.price_unit
* (100.0-line
.discount
) / 100.0, line
.qty
)['taxes']
138 for tax
in computed_taxes
:
139 tax_amount
+= cur_obj
.round(cr
, uid
, cur
, tax
['amount'])
140 group_key
= (tax
['tax_code_id'], tax
['base_code_id'], tax
['account_collected_id'], tax
['id'])
142 group_tax
.setdefault(group_key
, 0)
143 group_tax
[group_key
] += cur_obj
.round(cr
, uid
, cur
, tax
['amount'])
145 amount
= line
.price_subtotal
147 # Search for the income account
148 if line
.product_id
.property_account_income
.id:
149 income_account
= line
.product_id
.property_account_income
.id
150 elif line
.product_id
.categ_id
.property_account_income_categ
.id:
151 income_account
= line
.product_id
.categ_id
.property_account_income_categ
.id
153 raise osv
.except_osv(_('Error!'), _('Please define income '\
154 'account for this product: "%s" (id:%d).') \
155 % (line
.product_id
.name
, line
.product_id
.id, ))
157 # Empty the tax list as long as there is no tax code:
160 while computed_taxes
:
161 tax
= computed_taxes
.pop(0)
162 tax_code_id
, tax_amount
= super(sale_order
, self
).compute_tax(amount
, tax
, line
)
164 # If there is one we stop
168 # Create a move for the line
169 insert_data('product', {
170 'name': line
.product_id
.name
,
171 'quantity': line
.qty
,
172 'product_id': line
.product_id
.id,
173 'account_id': income_account
,
174 'analytic_account_id': analytic_account_id
,
175 'credit': ((amount
>0) and amount
) or 0.0,
176 'debit': ((amount
<0) and -amount
) or 0.0,
177 'tax_code_id': tax_code_id
,
178 'tax_amount': tax_amount
,
179 'partner_id': order
.partner_id
and self
.pool
.get("res.partner")._find
_accounting
_partner
(order
.partner_id
).id or False
182 # For each remaining tax with a code, whe create a move line
183 for tax
in computed_taxes
:
184 tax_code_id
, tax_amount
= super(sale_order
, self
).compute_tax(amount
, tax
, line
)
190 'product_id':line
.product_id
.id,
191 'quantity': line
.qty
,
192 'account_id': income_account
,
195 'tax_code_id': tax_code_id
,
196 'tax_amount': tax_amount
,
197 'partner_id': order
.partner_id
and self
.pool
.get("res.partner")._find
_accounting
_partner
(order
.partner_id
).id or False
200 # Create a move for each tax group
201 (tax_code_pos
, base_code_pos
, account_pos
, tax_id
)= (0, 1, 2, 3)
203 for key
, tax_amount
in group_tax
.items():
204 tax
= self
.pool
.get('account.tax').browse(cr
, uid
, key
[tax_id
], context
=context
)
206 'name': _('Tax') + ' ' + tax
.name
,
207 'quantity': line
.qty
,
208 'product_id': line
.product_id
.id,
209 'account_id': key
[account_pos
] or income_account
,
210 'credit': ((tax_amount
>0) and tax_amount
) or 0.0,
211 'debit': ((tax_amount
<0) and -tax_amount
) or 0.0,
212 'tax_code_id': key
[tax_code_pos
],
213 'tax_amount': tax_amount
,
214 'partner_id': order
.partner_id
and self
.pool
.get("res.partner")._find
_accounting
_partner
(order
.partner_id
).id or False
218 insert_data('counter_part', {
219 'name': _("Trade Receivables"), #order.name,
220 'account_id': order_account
,
221 'credit': ((order
.amount_total
< 0) and -order
.amount_total
) or 0.0,
222 'debit': ((order
.amount_total
> 0) and order
.amount_total
) or 0.0,
223 'partner_id': order
.partner_id
and self
.pool
.get("res.partner")._find
_accounting
_partner
(order
.partner_id
).id or False
226 order
.write({'state':'done', 'account_move': move_id
})
229 for group_key
, group_data
in grouped_data
.iteritems():
230 print("#DEBUG: group_key = %s - group_data = %s" % (group_key
, group_data
))
231 for value
in group_data
:
232 all_lines
.append((0, 0, value
),)
233 if move_id
: #In case no order was changed
234 self
.pool
.get("account.move").write(cr
, uid
, [move_id
], {'line_id':all_lines
}, context
=context
)
238 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: