1 # -*- coding: utf-8 -*-
2 ##############################################################################
4 # OpenERP, Open Source Management Solution
5 # Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
7 # This program is free software: you can redistribute it and/or modify
8 # it under the terms of the GNU Affero General Public License as
9 # published by the Free Software Foundation, either version 3 of the
10 # License, or (at your option) any later version.
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU Affero General Public License for more details.
17 # You should have received a copy of the GNU Affero General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 ##############################################################################
23 from osv import osv,fields
24 from tools.translate import _
27 class pos_return(osv.osv_memory):
29 _description = 'Point of sale return'
31 def default_get(self, cr, uid, fields, context=None):
33 To get default values for the object.
35 @param self: The object pointer.
36 @param cr: A database cursor
37 @param uid: ID of the user currently logged in
38 @param fields: List of fields for which we want default values
39 @param context: A standard dictionary
41 @return: A dictionary which of fields with values.
45 res = super(pos_return, self).default_get(cr, uid, fields, context=context)
46 order_obj = self.pool.get('pos.order')
49 active_ids = context.get('active_ids')
50 for order in order_obj.browse(cr, uid, active_ids, context=context):
51 for line in order.lines:
52 if 'return%s'%(line.id) in fields:
53 res['return%s'%(line.id)] = line.qty
56 def view_init(self, cr, uid, fields_list, context=None):
58 Creates view dynamically and adding fields at runtime.
59 @param self: The object pointer.
60 @param cr: A database cursor
61 @param uid: ID of the user currently logged in
62 @param context: A standard dictionary
63 @return: New arch of view with new columns.
65 res = super(pos_return, self).view_init(cr, uid, fields_list, context=context)
66 order_obj=self.pool.get('pos.order')
70 active_ids=context.get('active_ids')
71 for order in order_obj.browse(cr, uid, active_ids, context=context):
72 for line in order.lines:
73 if 'return%s'%(line.id) not in self._columns:
74 self._columns['return%s'%(line.id)] = fields.float("Quantity")
78 def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False,submenu=False):
81 Changes the view dynamically
83 @param self: The object pointer.
84 @param cr: A database cursor
85 @param uid: ID of the user currently logged in
86 @param context: A standard dictionary
88 @return: New arch of view.
91 result = super(pos_return, self).fields_view_get(cr, uid, view_id, view_type, context, toolbar,submenu)
94 active_model = context.get('active_model')
95 if not active_model and active_model != 'pos.order':
97 order_obj = self.pool.get('pos.order')
98 active_id = context.get('active_id', False)
100 _moves_arch_lst="""<?xml version="1.0"?>
101 <form string="Return lines">
102 <label string="Quantities you enter, match to products that will return to the stock." colspan="4"/>"""
103 _line_fields = result['fields']
104 order=order_obj.browse(cr, uid, active_id, context=context)
105 for line in order.lines:
107 _line_fields.update({
108 'return%s'%(line.id) : {
109 'string': line.product_id.name,
115 _moves_arch_lst += """
116 <field name="return%s"/>
122 <separator colspan="4"/>
123 <button icon='gtk-cancel' special="cancel"
125 <button icon='gtk-ok' name= "create_returns"
126 string="Return with Exchange" type="object"/>
127 <button icon='gtk-ok' name="create_returns2"
128 string="Refund Without Exchange" type="object"/>
131 result['arch'] = _moves_arch_lst
132 result['fields'] = _line_fields
136 def create_returns(self, cr, uid, data, context=None):
138 @param self: The object pointer.
139 @param cr: A database cursor
140 @param uid: ID of the user currently logged in
141 @param context: A standard dictionary
143 @return: Return the add product form again for adding more product
148 current_rec = self.read(cr, uid, data[0], context=context)
149 order_obj =self.pool.get('pos.order')
150 line_obj = self.pool.get('pos.order.line')
151 pos_current = order_obj.browse(cr, uid, context.get('active_id'), context=context)
152 pos_line_ids = pos_current.lines
154 for pos_line in pos_line_ids:
155 line_field = "return"+str(pos_line.id)
156 pos_list = current_rec.keys()
158 if line_field in pos_list :
159 less_qty = current_rec.get(line_field)
160 pos_cur_line = line_obj.browse(cr, uid, pos_line.id, context=context)
161 qty = pos_cur_line.qty
163 newline_vals.update({'qty':qty})
164 line_obj.write(cr, uid, pos_line.id, newline_vals, context=context)
166 'name': _('Add Product'),
169 'res_model': 'pos.add.product',
174 'type': 'ir.actions.act_window',
176 def create_returns2(self, cr, uid, ids, context=None):
179 active_id = context.get('active_id', False)
180 order_obj =self.pool.get('pos.order')
181 line_obj = self.pool.get('pos.order.line')
182 picking_obj = self.pool.get('stock.picking')
183 stock_move_obj = self.pool.get('stock.move')
184 property_obj= self.pool.get("ir.property")
185 uom_obj =self. pool.get('product.uom')
186 statementl_obj = self.pool.get('account.bank.statement.line')
187 wf_service = netsvc.LocalService("workflow")
188 #Todo :Need to clean the code
190 data = self.read(cr, uid, ids)[0]
191 date_cur = time.strftime('%Y-%m-%d %H:%M:%S')
193 for order_id in order_obj.browse(cr, uid, [active_id], context=context):
194 prop_ids = property_obj.search(cr, uid,[('name', '=', 'property_stock_customer')])
195 val = property_obj.browse(cr, uid, prop_ids[0], context=context).value_reference
196 cr.execute("SELECT s.id FROM stock_location s, stock_warehouse w "
197 "WHERE w.lot_stock_id=s.id AND w.id=%s ",
198 (order_id.shop_id.warehouse_id.id,))
200 location_id = res and res[0] or None
201 stock_dest_id = val.id
202 new_picking = picking_obj.copy(cr, uid, order_id.picking_id.id, {'name':'%s (return)' % order_id.name,
206 'address_id': order_id.partner_id.id,
208 new_order = order_obj.copy(cr, uid, order_id.id, {'name': 'Refund %s'%order_id.name,
212 account_def = property_obj.get(cr, uid, 'property_account_payable', 'res.partner', context=context)
214 for line in order_id.lines:
217 qty = data['return%s' %line.id]
218 amount += qty * line.price_unit
221 stock_move_obj.create(cr, uid, {
223 'product_uos_qty': uom_obj._compute_qty(cr, uid, qty ,line.product_id.uom_id.id),
224 'picking_id': new_picking,
225 'product_uom': line.product_id.uom_id.id,
226 'location_id': location_id,
227 'product_id': line.product_id.id,
228 'location_dest_id': stock_dest_id,
229 'name': '%s (return)' %order_id.name,
233 line_obj.copy(cr, uid, line.id, {'qty': -qty, 'order_id': new_order})
234 statementl_obj.create(cr, uid, {
235 'name': 'Refund %s'%order_id.name,
236 'statement_id': order_id.statement_ids[0].statement_id.id,
237 'pos_statement_id': new_order,
238 'date': time.strftime('%Y-%m-%d'),
239 'account_id': order_id.partner_id and order_id.partner_id.property_account_payable \
240 and order_id.partner_id.property_account_payable.id or account_def.id,
243 order_obj.write(cr,uid, [active_id,new_order], {'state': 'done'})
244 wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
245 picking_obj.force_assign(cr, uid, [new_picking], context)
247 'domain': "[('id', 'in', ["+str(new_order)+"])]",
248 'name': 'Refunded Orders',
250 'view_mode': 'tree,form',
251 'res_model': 'pos.order',
256 'type': 'ir.actions.act_window'
262 class add_product(osv.osv_memory):
263 _inherit = 'pos.add.product'
264 def select_product(self, cr, uid, ids, context=None):
266 To get the product and quantity and add in order .
267 @param self: The object pointer.
268 @param cr: A database cursor
269 @param uid: ID of the user currently logged in
270 @param context: A standard dictionary
271 @return : Retrun the add product form again for adding more product
276 active_id=context.get('active_id', False)
277 data = self.read(cr, uid, ids)
278 data = data and data[0] or False
280 order_obj = self.pool.get('pos.order')
281 picking_obj = self.pool.get('stock.picking')
282 stock_move_obj = self.pool.get('stock.move')
283 property_obj= self.pool.get("ir.property")
284 date_cur=time.strftime('%Y-%m-%d')
285 uom_obj = self.pool.get('product.uom')
286 prod_obj=self.pool.get('product.product')
287 wf_service = netsvc.LocalService("workflow")
288 order_obj.add_product(cr, uid, active_id, data['product_id'], data['quantity'], context=context)
290 for order_id in order_obj.browse(cr, uid, [active_id], context=context):
291 prod=data['product_id']
293 prop_ids = property_obj.search(cr, uid, [('name', '=', 'property_stock_customer')])
294 val = property_obj.browse(cr, uid, prop_ids[0]).value_reference
295 cr.execute("SELECT s.id FROM stock_location s, stock_warehouse w "
296 "WHERE w.lot_stock_id=s.id AND w.id=%s ",
297 (order_id.shop_id.warehouse_id.id,))
299 location_id=res and res[0] or None
300 stock_dest_id = val.id
302 prod_id=prod_obj.browse(cr, uid, prod, context=context)
303 new_picking=picking_obj.create(cr, uid, {
304 'name':'%s (Added)' %order_id.name,
310 stock_move_obj.create(cr, uid, {
312 'product_uos_qty': uom_obj._compute_qty(cr, uid, prod_id.uom_id.id, qty, prod_id.uom_id.id),
313 'picking_id':new_picking,
314 'product_uom':prod_id.uom_id.id,
315 'location_id':location_id,
316 'product_id':prod_id.id,
317 'location_dest_id':stock_dest_id,
318 'name':'%s (return)' %order_id.name,
322 wf_service.trg_validate(uid, 'stock.picking', new_picking, 'button_confirm', cr)
323 picking_obj.force_assign(cr, uid, [new_picking], context)
324 order_obj.write(cr,uid,active_id,{'picking_id':new_picking})
327 'name': _('Add Product'),
330 'res_model': 'pos.add.product',
335 'type': 'ir.actions.act_window',
338 def close_action(self, cr, uid, ids, context=None):
339 if context is None: context = {}
340 active_ids=context.get('active_ids', False)
341 order_obj = self.pool.get('pos.order')
342 lines_obj = self.pool.get('pos.order.line')
343 picking_obj = self.pool.get('stock.picking')
344 stock_move_obj = self.pool.get('stock.move')
345 property_obj= self.pool.get("ir.property")
346 invoice_obj=self.pool.get('account.invoice')
347 date_cur=time.strftime('%Y-%m-%d %H:%M:%S')
348 uom_obj = self.pool.get('product.uom')
349 return_boj=self.pool.get('pos.return')
350 return_id = return_boj.search(cr,uid,[])
353 data = return_boj.read(cr,uid,return_id,[])[0]
355 wf_service = netsvc.LocalService("workflow")
356 self_data = self.browse(cr, uid, ids)[0]
357 order_obj.add_product(cr, uid, active_ids[0], self_data.product_id.id, self_data.quantity, context=context)
359 for order_id in order_obj.browse(cr, uid, active_ids, context=context):
360 prop_ids =property_obj.search(cr, uid, [('name', '=', 'property_stock_customer')])
361 val = property_obj.browse(cr, uid, prop_ids[0]).value_reference
362 cr.execute("SELECT s.id FROM stock_location s, stock_warehouse w "
363 " WHERE w.lot_stock_id=s.id AND w.id=%s ",
364 (order_id.shop_id.warehouse_id.id,))
366 location_id=res and res[0] or None
367 stock_dest_id = val.id
369 order_obj.write(cr,uid,[order_id.id],{'type_rec':'Exchange'})
370 if order_id.invoice_id:
371 invoice_obj.refund(cr, uid, [order_id.invoice_id.id], time.strftime('%Y-%m-%d'), False, order_id.name)
372 new_picking=picking_obj.create(cr, uid, {
373 'name':'%s (return)' %order_id.name,
374 'move_lines':[], 'state':'draft',
378 for line in order_id.lines:
379 key= 'return%s' % line.id
381 if data.has_key(key):
383 lines_obj.write(cr,uid,[line.id], {
384 'qty_rfd':(line.qty or 0.0) + data[key],
385 'qty':line.qty-(data[key] or 0.0)
389 stock_move_obj.create(cr, uid, {
391 'product_uos_qty': uom_obj._compute_qty(cr, uid, qty, line.product_id.uom_id.id),
392 'picking_id':new_picking,
393 'product_uom':line.product_id.uom_id.id,
394 'location_id':location_id,
395 'product_id':line.product_id.id,
396 'location_dest_id':stock_dest_id,
397 'name':'%s (return)' % order_id.name,
400 wf_service.trg_validate(uid, 'stock.picking',new_picking,'button_confirm', cr)
401 picking_obj.force_assign(cr, uid, [new_picking], context)
402 obj=order_obj.browse(cr,uid, active_ids[0])
403 context.update({'return':'return'})
405 if obj.amount_total != obj.amount_paid:
407 'name': _('Make Payment'),
411 'res_model': 'pos.make.payment',
415 'type': 'ir.actions.act_window',
420 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: