mirror of
https://github.com/OCA/rma.git
synced 2025-02-16 17:11:47 +02:00
Updated crm_claim_rma to Odoo v8
This commit is contained in:
@@ -85,7 +85,6 @@ Contributors:
|
||||
'crm_claim_rma_view.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'account_invoice_view.xml',
|
||||
'stock_view.xml',
|
||||
'res_partner_view.xml',
|
||||
'crm_claim_rma_data.xml',
|
||||
],
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
@@ -20,40 +21,39 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import fields, orm
|
||||
from tools.translate import _
|
||||
|
||||
from openerp.models import Model, api, _
|
||||
from openerp.fields import Many2one
|
||||
|
||||
|
||||
class account_invoice(orm.Model):
|
||||
|
||||
class AccountInvoice(Model):
|
||||
_inherit = "account.invoice"
|
||||
|
||||
_columns = {
|
||||
'claim_id': fields.many2one('crm.claim', 'Claim'),
|
||||
}
|
||||
claim_id = Many2one('crm.claim', string='Claim')
|
||||
|
||||
def _refund_cleanup_lines(self, cr, uid, lines, context=None):
|
||||
@api.model
|
||||
def _refund_cleanup_lines(self, lines):
|
||||
""" Override when from claim to update the quantity and link to the
|
||||
claim line."""
|
||||
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
new_lines = []
|
||||
inv_line_obj = self.pool.get('account.invoice.line')
|
||||
claim_line_obj = self.pool.get('claim.line')
|
||||
inv_line_obj = self.env['account.invoice.line']
|
||||
claim_line_obj = self.env['claim.line']
|
||||
|
||||
# check if is an invoice_line and we are from a claim
|
||||
if not (context.get('claim_line_ids') and lines and
|
||||
lines[0]._name == 'account.invoice.line'):
|
||||
return super(account_invoice, self)._refund_cleanup_lines(
|
||||
cr, uid, lines, context=None)
|
||||
return super(AccountInvoice, self)._refund_cleanup_lines(lines)
|
||||
|
||||
for __, claim_line_id, __ in context.get('claim_line_ids'):
|
||||
line = claim_line_obj.browse(cr, uid, claim_line_id,
|
||||
context=context)
|
||||
line = claim_line_obj.browse(claim_line_id)
|
||||
if not line.refund_line_id:
|
||||
# For each lines replace quantity and add claim_line_id
|
||||
inv_line = inv_line_obj.browse(cr, uid,
|
||||
line.invoice_line_id.id,
|
||||
context=context)
|
||||
inv_line = inv_line_obj.browse(line.invoice_line_id.id)
|
||||
clean_line = {}
|
||||
for field_name, field in inv_line._all_columns.iteritems():
|
||||
column_type = field.column._type
|
||||
@@ -72,38 +72,41 @@ class account_invoice(orm.Model):
|
||||
if not new_lines:
|
||||
# TODO use custom states to show button of this wizard or
|
||||
# not instead of raise an error
|
||||
raise orm.except_orm(
|
||||
_('Error !'),
|
||||
raise Warning(
|
||||
_('A refund has already been created for this claim !'))
|
||||
return [(0, 0, l) for l in new_lines]
|
||||
|
||||
def _prepare_refund(self, cr, uid, invoice, date=None, period_id=None,
|
||||
description=None, journal_id=None, context=None):
|
||||
@api.model
|
||||
def _prepare_refund(self, invoice, date=None, period_id=None,
|
||||
description=None, journal_id=None):
|
||||
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
result = super(account_invoice, self)._prepare_refund(
|
||||
cr, uid, invoice,
|
||||
date=date, period_id=period_id, description=description,
|
||||
journal_id=journal_id, context=context)
|
||||
|
||||
result = super(AccountInvoice, self)._prepare_refund(
|
||||
invoice, date=date, period_id=period_id, description=description,
|
||||
journal_id=journal_id)
|
||||
|
||||
if context.get('claim_id'):
|
||||
result['claim_id'] = context['claim_id']
|
||||
|
||||
return result
|
||||
|
||||
|
||||
class account_invoice_line(orm.Model):
|
||||
|
||||
class AccountInvoiceLine(Model):
|
||||
_inherit = "account.invoice.line"
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
claim_line_id = False
|
||||
if vals.get('claim_line_id'):
|
||||
claim_line_id = vals['claim_line_id']
|
||||
del vals['claim_line_id']
|
||||
line_id = super(account_invoice_line, self).create(
|
||||
cr, uid, vals, context=context)
|
||||
|
||||
line_id = super(AccountInvoiceLine, self).create(vals)
|
||||
if claim_line_id:
|
||||
claim_line_obj = self.pool.get('claim.line')
|
||||
claim_line_obj.write(cr, uid, claim_line_id,
|
||||
{'refund_line_id': line_id},
|
||||
context=context)
|
||||
claim_line = self.env['claim.line'].browse(claim_line_id)
|
||||
claim_line.write({'refund_line_id': line_id.id})
|
||||
|
||||
return line_id
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
@@ -24,11 +25,13 @@
|
||||
import calendar
|
||||
import math
|
||||
from openerp.osv import fields, orm, osv
|
||||
from openerp.models import Model, api, _, NewId
|
||||
from openerp.fields import (Char, Date, Float, One2many, Many2one, Selection,
|
||||
Text)
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from openerp.tools import (DEFAULT_SERVER_DATE_FORMAT,
|
||||
DEFAULT_SERVER_DATETIME_FORMAT)
|
||||
from openerp.tools.translate import _
|
||||
from openerp import SUPERUSER_ID
|
||||
|
||||
|
||||
@@ -42,19 +45,17 @@ class ProductNoSupplier(Exception):
|
||||
because the product has no supplier. """
|
||||
|
||||
|
||||
class substate_substate(orm.Model):
|
||||
class SubstateSubstate(Model):
|
||||
""" To precise a state (state=refused; substates= reason 1, 2,...) """
|
||||
_name = "substate.substate"
|
||||
_description = "substate that precise a given state"
|
||||
_columns = {
|
||||
'name': fields.char('Sub state', required=True),
|
||||
'substate_descr': fields.text(
|
||||
'Description',
|
||||
help="To give more information about the sub state"),
|
||||
}
|
||||
|
||||
name = Char(string='Sub state', required=True)
|
||||
substate_descr = Text(string='Description',
|
||||
help="To give more information about the sub state")
|
||||
|
||||
|
||||
class claim_line(orm.Model):
|
||||
class ClaimLine(Model):
|
||||
"""
|
||||
Class to handle a product return line (corresponding to one invoice line)
|
||||
"""
|
||||
@@ -68,143 +69,133 @@ class claim_line(orm.Model):
|
||||
'not_define': "Not Defined"}
|
||||
|
||||
# Method to calculate total amount of the line : qty*UP
|
||||
def _line_total_amount(self, cr, uid, ids, field_name, arg, context=None):
|
||||
@api.one
|
||||
def _line_total_amount(self):
|
||||
res = {}
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
res[line.id] = (line.unit_sale_price *
|
||||
line.product_returned_quantity)
|
||||
return res
|
||||
self.return_value = (self.unit_sale_price *
|
||||
self.product_returned_quantity)
|
||||
|
||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||
@api.model
|
||||
def copy_data(self, default=None):
|
||||
if default is None:
|
||||
default = {}
|
||||
|
||||
std_default = {
|
||||
'move_in_id': False,
|
||||
'move_out_id': False,
|
||||
'refund_line_id': False,
|
||||
}
|
||||
std_default.update(default)
|
||||
return super(claim_line, self).copy_data(
|
||||
cr, uid, id, default=std_default, context=context)
|
||||
return super(ClaimLine, self).copy_data(default=std_default)
|
||||
|
||||
def get_warranty_return_partner(self, cr, uid, context=None):
|
||||
seller = self.pool.get('product.supplierinfo')
|
||||
result = seller.get_warranty_return_partner(cr, uid, context=context)
|
||||
def get_warranty_return_partner(self):
|
||||
seller = self.env['product.supplierinfo']
|
||||
result = seller.get_warranty_return_partner()
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Description', required=True),
|
||||
'claim_origine': fields.selection(
|
||||
[('none', 'Not specified'),
|
||||
('legal', 'Legal retractation'),
|
||||
('cancellation', 'Order cancellation'),
|
||||
('damaged', 'Damaged delivered product'),
|
||||
('error', 'Shipping error'),
|
||||
('exchange', 'Exchange request'),
|
||||
('lost', 'Lost during transport'),
|
||||
('other', 'Other')
|
||||
],
|
||||
'Claim Subject',
|
||||
required=True,
|
||||
help="To describe the line product problem"),
|
||||
'claim_descr': fields.text(
|
||||
'Claim description',
|
||||
help="More precise description of the problem"),
|
||||
'product_id': fields.many2one(
|
||||
'product.product',
|
||||
string='Product',
|
||||
help="Returned product"),
|
||||
'product_returned_quantity': fields.float(
|
||||
'Quantity', digits=(12, 2),
|
||||
help="Quantity of product returned"),
|
||||
'unit_sale_price': fields.float(
|
||||
'Unit sale price', digits=(12, 2),
|
||||
help="Unit sale price of the product. Auto filled if retrun done "
|
||||
"by invoice selection. Be careful and check the automatic "
|
||||
"value as don't take into account previous refunds, invoice "
|
||||
"discount, can be for 0 if product for free,..."),
|
||||
'return_value': fields.function(
|
||||
_line_total_amount, string='Total return', type='float',
|
||||
help="Quantity returned * Unit sold price",),
|
||||
'prodlot_id': fields.many2one(
|
||||
'stock.production.lot',
|
||||
string='Serial/Lot n°',
|
||||
help="The serial/lot of the returned product"),
|
||||
'applicable_guarantee': fields.selection(
|
||||
[('us', 'Company'),
|
||||
('supplier', 'Supplier'),
|
||||
('brand', 'Brand manufacturer')],
|
||||
'Warranty type'),
|
||||
'guarantee_limit': fields.date(
|
||||
'Warranty limit',
|
||||
readonly=True,
|
||||
help="The warranty limit is computed as: invoice date + warranty "
|
||||
"defined on selected product."),
|
||||
'warning': fields.char(
|
||||
'Warranty',
|
||||
readonly=True,
|
||||
help="If warranty has expired"),
|
||||
'warranty_type': fields.selection(
|
||||
get_warranty_return_partner,
|
||||
'Warranty type',
|
||||
readonly=True,
|
||||
help="Who is in charge of the warranty return treatment towards "
|
||||
"the end customer. Company will use the current company "
|
||||
"delivery or default address and so on for supplier and brand"
|
||||
" manufacturer. Does not necessarily mean that the warranty "
|
||||
"to be applied is the one of the return partner (ie: can be "
|
||||
"returned to the company and be under the brand warranty"),
|
||||
'warranty_return_partner': fields.many2one(
|
||||
'res.partner',
|
||||
string='Warranty Address',
|
||||
help="Where the customer has to send back the product(s)"),
|
||||
'claim_id': fields.many2one(
|
||||
'crm.claim', string='Related claim',
|
||||
help="To link to the case.claim object"),
|
||||
'state': fields.selection(
|
||||
[('draft', 'Draft'),
|
||||
('refused', 'Refused'),
|
||||
('confirmed', 'Confirmed, waiting for product'),
|
||||
('in_to_control', 'Received, to control'),
|
||||
('in_to_treate', 'Controlled, to treate'),
|
||||
('treated', 'Treated')],
|
||||
string='State'),
|
||||
'substate_id': fields.many2one(
|
||||
'substate.substate',
|
||||
string='Sub state',
|
||||
help="Select a sub state to precise the standard state. Example 1:"
|
||||
" state = refused; substate could be warranty over, not in "
|
||||
"warranty, no problem,... . Example 2: state = to treate; "
|
||||
"substate could be to refund, to exchange, to repair,..."),
|
||||
'last_state_change': fields.date(
|
||||
string='Last change',
|
||||
help="To set the last state / substate change"),
|
||||
'invoice_line_id': fields.many2one(
|
||||
'account.invoice.line',
|
||||
string='Invoice Line',
|
||||
help='The invoice line related to the returned product'),
|
||||
'refund_line_id': fields.many2one(
|
||||
'account.invoice.line',
|
||||
string='Refund Line',
|
||||
help='The refund line related to the returned product'),
|
||||
'move_in_id': fields.many2one(
|
||||
'stock.move',
|
||||
string='Move Line from picking in',
|
||||
help='The move line related to the returned product'),
|
||||
'move_out_id': fields.many2one(
|
||||
'stock.move',
|
||||
string='Move Line from picking out',
|
||||
help='The move line related to the returned product'),
|
||||
'location_dest_id': fields.many2one(
|
||||
'stock.location',
|
||||
string='Return Stock Location',
|
||||
help='The return stock location of the returned product'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': 'draft',
|
||||
'name': 'none',
|
||||
}
|
||||
name = Char(string='Description', required=True, default=None)
|
||||
claim_origine = Selection(
|
||||
[('none', 'Not specified'),
|
||||
('legal', 'Legal retractation'),
|
||||
('cancellation', 'Order cancellation'),
|
||||
('damaged', 'Damaged delivered product'),
|
||||
('error', 'Shipping error'),
|
||||
('exchange', 'Exchange request'),
|
||||
('lost', 'Lost during transport'),
|
||||
('other', 'Other')
|
||||
],
|
||||
string='Claim Subject', required=True,
|
||||
help="To describe the line product problem")
|
||||
claim_descr = Text(
|
||||
string='Claim description',
|
||||
help="More precise description of the problem")
|
||||
product_id = Many2one(
|
||||
'product.product', string='Product', help="Returned product")
|
||||
product_returned_quantity = Float(
|
||||
string='Quantity', digits=(12, 2), help="Quantity of product returned")
|
||||
unit_sale_price = Float(
|
||||
string='Unit sale price', digits=(12, 2),
|
||||
help="Unit sale price of the product. Auto filled if retrun done "
|
||||
"by invoice selection. Be careful and check the automatic "
|
||||
"value as don't take into account previous refunds, invoice "
|
||||
"discount, can be for 0 if product for free,...")
|
||||
return_value = Float(
|
||||
string='Total return', compute='_line_total_amount',
|
||||
help="Quantity returned * Unit sold price",)
|
||||
prodlot_id = Many2one(
|
||||
'stock.production.lot',
|
||||
string='Serial/Lot n°', help="The serial/lot of the returned product")
|
||||
applicable_guarantee = Selection(
|
||||
[('us', 'Company'),
|
||||
('supplier', 'Supplier'),
|
||||
('brand', 'Brand manufacturer')],
|
||||
string='Warranty type')
|
||||
guarantee_limit = Date(
|
||||
string='Warranty limit',
|
||||
readonly=True,
|
||||
help="The warranty limit is computed as: invoice date + warranty "
|
||||
"defined on selected product.")
|
||||
warning = Char(
|
||||
string='Warranty',
|
||||
readonly=True,
|
||||
help="If warranty has expired")
|
||||
warranty_type = Selection(
|
||||
get_warranty_return_partner,
|
||||
string='Warranty type',
|
||||
readonly=True,
|
||||
help="Who is in charge of the warranty return treatment towards "
|
||||
"the end customer. Company will use the current company "
|
||||
"delivery or default address and so on for supplier and brand"
|
||||
" manufacturer. Does not necessarily mean that the warranty "
|
||||
"to be applied is the one of the return partner (ie: can be "
|
||||
"returned to the company and be under the brand warranty")
|
||||
warranty_return_partner = Many2one(
|
||||
'res.partner',
|
||||
string='Warranty Address',
|
||||
help="Where the customer has to send back the product(s)")
|
||||
claim_id = Many2one(
|
||||
'crm.claim',
|
||||
string='Related claim',
|
||||
help="To link to the case.claim object")
|
||||
state = Selection(
|
||||
[('draft', 'Draft'),
|
||||
('refused', 'Refused'),
|
||||
('confirmed', 'Confirmed, waiting for product'),
|
||||
('in_to_control', 'Received, to control'),
|
||||
('in_to_treate', 'Controlled, to treate'),
|
||||
('treated', 'Treated')],
|
||||
string='State',
|
||||
default="draft")
|
||||
substate_id = Many2one(
|
||||
'substate.substate',
|
||||
string='Sub state',
|
||||
help="Select a sub state to precise the standard state. Example 1:"
|
||||
" state = refused; substate could be warranty over, not in "
|
||||
"warranty, no problem,... . Example 2: state = to treate; "
|
||||
"substate could be to refund, to exchange, to repair,...")
|
||||
last_state_change = Date(
|
||||
string='Last change',
|
||||
help="To set the last state / substate change")
|
||||
invoice_line_id = Many2one(
|
||||
'account.invoice.line',
|
||||
string='Invoice Line',
|
||||
help='The invoice line related to the returned product')
|
||||
refund_line_id = Many2one(
|
||||
'account.invoice.line',
|
||||
string='Refund Line',
|
||||
help='The refund line related to the returned product')
|
||||
move_in_id = Many2one(
|
||||
'stock.move',
|
||||
string='Move Line from picking in',
|
||||
help='The move line related to the returned product')
|
||||
move_out_id = Many2one(
|
||||
'stock.move',
|
||||
string='Move Line from picking out',
|
||||
help='The move line related to the returned product')
|
||||
location_dest_id = Many2one(
|
||||
'stock.location',
|
||||
string='Return Stock Location',
|
||||
help='The return stock location of the returned product')
|
||||
|
||||
@staticmethod
|
||||
def warranty_limit(start, warranty_duration):
|
||||
@@ -227,14 +218,14 @@ class claim_line(orm.Model):
|
||||
days = int(days_month * decimal_part)
|
||||
return start + relativedelta(months=months, days=days)
|
||||
|
||||
def _warranty_limit_values(self, cr, uid, ids, invoice,
|
||||
claim_type, product, claim_date,
|
||||
context=None):
|
||||
def _warranty_limit_values(self, invoice, claim_type, product, claim_date):
|
||||
if not (invoice and claim_type and product and claim_date):
|
||||
return {'guarantee_limit': False, 'warning': False}
|
||||
|
||||
date_invoice = invoice.date_invoice
|
||||
if not date_invoice:
|
||||
raise InvoiceNoDate
|
||||
|
||||
warning = _(self.WARRANT_COMMENT['not_define'])
|
||||
date_invoice = datetime.strptime(date_invoice,
|
||||
DEFAULT_SERVER_DATE_FORMAT)
|
||||
@@ -246,6 +237,7 @@ class claim_line(orm.Model):
|
||||
warranty_duration = supplier.warranty_duration
|
||||
else:
|
||||
warranty_duration = product.warranty
|
||||
|
||||
limit = self.warranty_limit(date_invoice, warranty_duration)
|
||||
if warranty_duration > 0:
|
||||
claim_date = datetime.strptime(claim_date,
|
||||
@@ -254,99 +246,94 @@ class claim_line(orm.Model):
|
||||
warning = _(self.WARRANT_COMMENT['expired'])
|
||||
else:
|
||||
warning = _(self.WARRANT_COMMENT['valid'])
|
||||
|
||||
return {'guarantee_limit': limit.strftime(DEFAULT_SERVER_DATE_FORMAT),
|
||||
'warning': warning}
|
||||
|
||||
def set_warranty_limit(self, cr, uid, ids, claim_line, context=None):
|
||||
claim = claim_line.claim_id
|
||||
def set_warranty_limit(self):
|
||||
claim = self.claim_id
|
||||
invoice = claim.invoice_id
|
||||
claim_type = claim.claim_type
|
||||
claim_date = claim.date
|
||||
product = claim_line.product_id
|
||||
product = self.product_id
|
||||
try:
|
||||
values = self._warranty_limit_values(cr, uid, ids, invoice,
|
||||
claim_type, product,
|
||||
claim_date,
|
||||
context=context)
|
||||
values = self._warranty_limit_values(invoice, claim_type, product,
|
||||
claim_date)
|
||||
except InvoiceNoDate:
|
||||
raise orm.except_orm(
|
||||
_('Error'),
|
||||
_('Cannot find any date for invoice. '
|
||||
'Must be a validated invoice.'))
|
||||
raise osv.except_osv(
|
||||
_('Error'), _('Cannot find any date for invoice. '
|
||||
'Must be a validated invoice.'))
|
||||
except ProductNoSupplier:
|
||||
raise orm.except_orm(
|
||||
_('Error'),
|
||||
_('The product has no supplier configured.'))
|
||||
self.write(cr, uid, ids, values, context=context)
|
||||
raise osv.except_osv(
|
||||
_('Error'), _('The product has no supplier configured.'))
|
||||
|
||||
self.write(values)
|
||||
return True
|
||||
|
||||
def auto_set_warranty(self, cr, uid, ids, context):
|
||||
@api.multi
|
||||
def auto_set_warranty(self):
|
||||
""" Set warranty automatically
|
||||
if the user has not himself pressed on 'Calculate warranty state'
|
||||
button, it sets warranty for him"""
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
for line in self:
|
||||
if not line.warning:
|
||||
self.set_warranty(cr, uid, [line.id], context=context)
|
||||
line.set_warranty()
|
||||
return True
|
||||
|
||||
def get_destination_location(self, cr, uid, product_id,
|
||||
warehouse_id, context=None):
|
||||
def get_destination_location(self, product, warehouse):
|
||||
"""Compute and return the destination location ID to take
|
||||
for a return. Always take 'Supplier' one when return type different
|
||||
from company."""
|
||||
prod = False
|
||||
if product_id:
|
||||
prod_obj = self.pool.get('product.product')
|
||||
prod = prod_obj.browse(cr, uid, product_id, context=context)
|
||||
wh_obj = self.pool.get('stock.warehouse')
|
||||
wh = wh_obj.browse(cr, uid, warehouse_id, context=context)
|
||||
location_dest_id = wh.lot_stock_id.id
|
||||
if prod:
|
||||
seller = prod.seller_info_id
|
||||
if seller:
|
||||
location_dest_id = warehouse.lot_stock_id.id
|
||||
if product:
|
||||
sellers = product.seller_ids
|
||||
if sellers:
|
||||
seller = sellers[0]
|
||||
return_type = seller.warranty_return_partner
|
||||
if return_type != 'company':
|
||||
location_dest_id = seller.name.property_stock_supplier.id
|
||||
return location_dest_id
|
||||
|
||||
def onchange_product_id(self, cr, uid, ids, product_id, invoice_line_id,
|
||||
claim_id, company_id, warehouse_id,
|
||||
claim_type, claim_date, context=None):
|
||||
if not claim_id and not (company_id and warehouse_id and
|
||||
claim_type and claim_date):
|
||||
@api.onchange('product_id', 'invoice_line_id')
|
||||
def _onchange_product_invoice_line(self):
|
||||
product = self.product_id
|
||||
invoice_line = self.invoice_line_id
|
||||
context = self.env.context
|
||||
|
||||
claim = context.get('claim_id')
|
||||
company_id = context.get('company_id')
|
||||
warehouse_id = context.get('warehouse_id')
|
||||
claim_type = context.get('claim_type')
|
||||
claim_date = context.get('claim_date')
|
||||
|
||||
# claim_exists = not isinstance(claim.id, NewId)
|
||||
if not claim and not (company_id and warehouse_id and
|
||||
claim_type and claim_date):
|
||||
# if we have a claim_id, we get the info from there,
|
||||
# otherwise we get it from the args (on creation typically)
|
||||
return {}
|
||||
if not (product_id and invoice_line_id):
|
||||
return {}
|
||||
product_obj = self.pool['product.product']
|
||||
claim_obj = self.pool['crm.claim']
|
||||
invoice_line_obj = self.pool['account.invoice.line']
|
||||
claim_line_obj = self.pool.get('claim.line')
|
||||
product = product_obj.browse(cr, uid, product_id, context=context)
|
||||
invoice_line = invoice_line_obj.browse(cr, uid, invoice_line_id,
|
||||
context=context)
|
||||
invoice = invoice_line.invoice_id
|
||||
return False
|
||||
if not (product and invoice_line):
|
||||
return False
|
||||
|
||||
if claim_id:
|
||||
claim = claim_obj.browse(cr, uid, claim_id, context=context)
|
||||
invoice = invoice_line.invoice_id
|
||||
claim_line_obj = self.env['claim.line']
|
||||
|
||||
if claim:
|
||||
claim = self.env['crm.claim'].browse(claim)
|
||||
company = claim.company_id
|
||||
warehouse = claim.warehouse_id
|
||||
claim_type = claim.claim_type
|
||||
claim_date = claim.date
|
||||
else:
|
||||
warehouse_obj = self.pool['stock.warehouse']
|
||||
company_obj = self.pool['res.company']
|
||||
company = company_obj.browse(cr, uid, company_id, context=context)
|
||||
warehouse = warehouse_obj.browse(cr, uid, warehouse_id,
|
||||
context=context)
|
||||
warehouse_obj = self.env['stock.warehouse']
|
||||
company_obj = self.env['res.company']
|
||||
company = company_obj.browse(company_id)
|
||||
warehouse = warehouse_obj.browse(warehouse_id)
|
||||
|
||||
values = {}
|
||||
try:
|
||||
warranty = claim_line_obj._warranty_limit_values(
|
||||
cr, uid, [], invoice,
|
||||
claim_type, product,
|
||||
claim_date, context=context)
|
||||
invoice, claim_type, product, claim_date)
|
||||
except (InvoiceNoDate, ProductNoSupplier):
|
||||
# we don't mind at this point if the warranty can't be
|
||||
# computed and we don't want to block the user
|
||||
@@ -355,12 +342,12 @@ class claim_line(orm.Model):
|
||||
values.update(warranty)
|
||||
|
||||
warranty_address = claim_line_obj._warranty_return_address_values(
|
||||
cr, uid, [], product, company, warehouse, context=context)
|
||||
product, company, warehouse)
|
||||
values.update(warranty_address)
|
||||
return {'value': values}
|
||||
|
||||
def _warranty_return_address_values(self, cr, uid, ids, product, company,
|
||||
warehouse, context=None):
|
||||
self.update(values)
|
||||
|
||||
def _warranty_return_address_values(self, product, company, warehouse):
|
||||
"""Return the partner to be used as return destination and
|
||||
the destination stock location of the line in case of return.
|
||||
|
||||
@@ -375,8 +362,9 @@ class claim_line(orm.Model):
|
||||
'warranty_type': False,
|
||||
'location_dest_id': False}
|
||||
return_address = None
|
||||
seller = product.seller_info_id
|
||||
if seller:
|
||||
sellers = product.seller_ids
|
||||
if sellers:
|
||||
seller = sellers[0]
|
||||
return_address_id = seller.warranty_return_address.id
|
||||
return_type = seller.warranty_return_partner
|
||||
else:
|
||||
@@ -385,83 +373,77 @@ class claim_line(orm.Model):
|
||||
company.partner_id)
|
||||
return_address_id = return_address.id
|
||||
return_type = 'company'
|
||||
location_dest_id = self.get_destination_location(
|
||||
cr, uid, product.id, warehouse.id, context=context)
|
||||
location_dest_id = self.get_destination_location(product, warehouse)
|
||||
return {'warranty_return_partner': return_address_id,
|
||||
'warranty_type': return_type,
|
||||
'location_dest_id': location_dest_id}
|
||||
|
||||
def set_warranty_return_address(self, cr, uid, ids, claim_line,
|
||||
context=None):
|
||||
claim = claim_line.claim_id
|
||||
product = claim_line.product_id
|
||||
def set_warranty_return_address(self):
|
||||
claim = self.claim_id
|
||||
product = self.product_id
|
||||
company = claim.company_id
|
||||
warehouse = claim.warehouse_id
|
||||
values = self._warranty_return_address_values(
|
||||
cr, uid, ids, product, company, warehouse, context=context)
|
||||
self.write(cr, uid, ids, values, context=context)
|
||||
product, company, warehouse)
|
||||
self.write(values)
|
||||
return True
|
||||
|
||||
def set_warranty(self, cr, uid, ids, context=None):
|
||||
@api.multi
|
||||
def set_warranty(self):
|
||||
""" Calculate warranty limit and address """
|
||||
for claim_line in self.browse(cr, uid, ids, context=context):
|
||||
for claim_line in self:
|
||||
if not (claim_line.product_id and claim_line.invoice_line_id):
|
||||
raise orm.except_orm(
|
||||
_('Error !'),
|
||||
_('Please set product and invoice.'))
|
||||
self.set_warranty_limit(cr, uid, ids,
|
||||
claim_line, context=context)
|
||||
self.set_warranty_return_address(cr, uid, ids,
|
||||
claim_line, context=context)
|
||||
return True
|
||||
raise Warning(_('Please set product and invoice.'))
|
||||
claim_line.set_warranty_limit()
|
||||
claim_line.set_warranty_return_address()
|
||||
|
||||
|
||||
# TODO add the option to split the claim_line in order to manage the same
|
||||
# product separately
|
||||
class crm_claim(orm.Model):
|
||||
class CrmClaim(Model):
|
||||
_inherit = 'crm.claim'
|
||||
|
||||
def init(self, cr):
|
||||
|
||||
cr.execute("""
|
||||
UPDATE "crm_claim" SET "number"=id::varchar
|
||||
WHERE ("number" is NULL)
|
||||
OR ("number" = '/');
|
||||
""")
|
||||
|
||||
def _get_sequence_number(self, cr, uid, context=None):
|
||||
seq_obj = self.pool.get('ir.sequence')
|
||||
res = seq_obj.get(cr, uid, 'crm.claim.rma', context=context) or '/'
|
||||
@api.model
|
||||
def _get_sequence_number(self):
|
||||
seq_obj = self.env['ir.sequence']
|
||||
res = seq_obj.get('crm.claim.rma') or '/'
|
||||
return res
|
||||
|
||||
def _get_default_warehouse(self, cr, uid, context=None):
|
||||
user_obj = self.pool.get('res.users')
|
||||
user = user_obj.browse(cr, uid, uid, context=context)
|
||||
def _get_default_warehouse(self):
|
||||
user = self.env.user
|
||||
company_id = user.company_id.id
|
||||
wh_obj = self.pool.get('stock.warehouse')
|
||||
wh_ids = wh_obj.search(cr, uid,
|
||||
[('company_id', '=', company_id)],
|
||||
context=context)
|
||||
if not wh_ids:
|
||||
raise orm.except_orm(
|
||||
_('Error!'),
|
||||
wh_obj = self.env['stock.warehouse']
|
||||
wh = wh_obj.search([
|
||||
('company_id', '=', company_id)
|
||||
], limit=1)
|
||||
if not wh:
|
||||
raise Warning(
|
||||
_('There is no warehouse for the current user\'s company.'))
|
||||
return wh_ids[0]
|
||||
return wh
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
@api.multi
|
||||
def name_get(self):
|
||||
res = []
|
||||
if isinstance(ids, (int, long)):
|
||||
ids = [ids]
|
||||
for claim in self.browse(cr, uid, ids, context=context):
|
||||
for claim in self:
|
||||
number = claim.number and str(claim.number) or ''
|
||||
res.append((claim.id, '[' + number + '] ' + claim.name))
|
||||
return res
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if ('number' not in vals) or (vals.get('number') == '/'):
|
||||
vals['number'] = self._get_sequence_number(cr, uid,
|
||||
context=context)
|
||||
new_id = super(crm_claim, self).create(cr, uid, vals, context=context)
|
||||
return new_id
|
||||
vals['number'] = self._get_sequence_number()
|
||||
|
||||
claim = super(CrmClaim, self).create(vals)
|
||||
return claim
|
||||
|
||||
def copy_data(self, cr, uid, id, default=None, context=None):
|
||||
if default is None:
|
||||
@@ -469,125 +451,102 @@ class crm_claim(orm.Model):
|
||||
std_default = {
|
||||
'invoice_ids': False,
|
||||
'picking_ids': False,
|
||||
'number': self._get_sequence_number(cr, uid, context=context),
|
||||
'number': self._get_sequence_number(cr, uid, context),
|
||||
}
|
||||
std_default.update(default)
|
||||
return super(crm_claim, self).copy_data(
|
||||
cr, uid, id, default=std_default, context=context)
|
||||
return super(CrmClaim, self).copy_data(cr, uid, id, std_default,
|
||||
context=context)
|
||||
|
||||
_columns = {
|
||||
'number': fields.char(
|
||||
'Number', readonly=True,
|
||||
states={'draft': [('readonly', False)]},
|
||||
required=True,
|
||||
select=True,
|
||||
help="Company internal claim unique number"),
|
||||
'claim_type': fields.selection(
|
||||
[('customer', 'Customer'),
|
||||
('supplier', 'Supplier'),
|
||||
('other', 'Other')],
|
||||
string='Claim type',
|
||||
required=True,
|
||||
help="Customer: from customer to company.\n "
|
||||
"Supplier: from company to supplier."),
|
||||
'claim_line_ids': fields.one2many(
|
||||
'claim.line', 'claim_id',
|
||||
string='Return lines'),
|
||||
'planned_revenue': fields.float('Expected revenue'),
|
||||
'planned_cost': fields.float('Expected cost'),
|
||||
'real_revenue': fields.float('Real revenue'),
|
||||
'real_cost': fields.float('Real cost'),
|
||||
'invoice_ids': fields.one2many(
|
||||
'account.invoice', 'claim_id', 'Refunds'),
|
||||
'picking_ids': fields.one2many('stock.picking', 'claim_id', 'RMA'),
|
||||
'invoice_id': fields.many2one(
|
||||
'account.invoice', string='Invoice',
|
||||
help='Related original Cusotmer invoice'),
|
||||
'delivery_address_id': fields.many2one(
|
||||
'res.partner', string='Partner delivery address',
|
||||
help="This address will be used to deliver repaired or replacement"
|
||||
"products."),
|
||||
'warehouse_id': fields.many2one(
|
||||
'stock.warehouse', string='Warehouse',
|
||||
required=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'number': '/',
|
||||
'claim_type': 'customer',
|
||||
'warehouse_id': _get_default_warehouse,
|
||||
}
|
||||
number = Char(
|
||||
string='Number', readonly=True,
|
||||
required=True,
|
||||
select=True,
|
||||
default='/',
|
||||
help="Company internal claim unique number")
|
||||
claim_type = Selection(
|
||||
[('customer', 'Customer'),
|
||||
('supplier', 'Supplier'),
|
||||
('other', 'Other')],
|
||||
string='Claim type',
|
||||
required=True,
|
||||
default='customer',
|
||||
help="Customer: from customer to company.\n "
|
||||
"Supplier: from company to supplier.")
|
||||
claim_line_ids = One2many(
|
||||
'claim.line',
|
||||
'claim_id',
|
||||
string='Return lines')
|
||||
planned_revenue = Float(string='Expected revenue')
|
||||
planned_cost = Float(string='Expected cost')
|
||||
real_revenue = Float(string='Real revenue')
|
||||
real_cost = Float(string='Real cost')
|
||||
invoice_ids = One2many(
|
||||
'account.invoice',
|
||||
'claim_id',
|
||||
string='Refunds')
|
||||
picking_ids = One2many(
|
||||
'stock.picking',
|
||||
'claim_id',
|
||||
string='RMA')
|
||||
invoice_id = Many2one(
|
||||
'account.invoice',
|
||||
string='Invoice',
|
||||
help='Related original Customer invoice')
|
||||
delivery_address_id = Many2one(
|
||||
'res.partner',
|
||||
string='Partner delivery address',
|
||||
help="This address will be used to deliver repaired or replacement"
|
||||
"products.")
|
||||
warehouse_id = Many2one(
|
||||
'stock.warehouse',
|
||||
string='Warehouse',
|
||||
default=_get_default_warehouse,
|
||||
required=True)
|
||||
|
||||
_sql_constraints = [
|
||||
('number_uniq', 'unique(number, company_id)',
|
||||
'Number/Reference must be unique per Company!'),
|
||||
]
|
||||
|
||||
def onchange_partner_address_id(self, cr, uid, ids, add, email=False,
|
||||
context=None):
|
||||
res = super(crm_claim, self
|
||||
).onchange_partner_address_id(cr, uid, ids, add,
|
||||
email=email)
|
||||
if add:
|
||||
if (not res['value']['email_from']
|
||||
or not res['value']['partner_phone']):
|
||||
partner_obj = self.pool.get('res.partner')
|
||||
address = partner_obj.browse(cr, uid, add, context=context)
|
||||
for other_add in address.partner_id.address:
|
||||
if other_add.email and not res['value']['email_from']:
|
||||
res['value']['email_from'] = other_add.email
|
||||
if other_add.phone and not res['value']['partner_phone']:
|
||||
res['value']['partner_phone'] = other_add.phone
|
||||
return res
|
||||
|
||||
def onchange_invoice_id(self, cr, uid, ids, invoice_id, warehouse_id,
|
||||
claim_type, claim_date, company_id, lines,
|
||||
create_lines=False, context=None):
|
||||
invoice_line_obj = self.pool.get('account.invoice.line')
|
||||
invoice_obj = self.pool.get('account.invoice')
|
||||
product_obj = self.pool['product.product']
|
||||
claim_line_obj = self.pool.get('claim.line')
|
||||
company_obj = self.pool['res.company']
|
||||
warehouse_obj = self.pool['stock.warehouse']
|
||||
invoice_line_ids = invoice_line_obj.search(
|
||||
cr, uid,
|
||||
[('invoice_id', '=', invoice_id)],
|
||||
context=context)
|
||||
@api.onchange('invoice_id', 'warehouse_id', 'claim_type', 'date')
|
||||
def _onchange_invoice_warehouse_type_date(self):
|
||||
context = self.env.context
|
||||
invoice_obj = self.env['account.invoice']
|
||||
invoice_line_obj = self.env['account.invoice.line']
|
||||
product_obj = self.env['product.product']
|
||||
claim_line_obj = self.env['claim.line']
|
||||
invoice_lines = self.invoice_id.invoice_line
|
||||
claim_lines = []
|
||||
value = {}
|
||||
if not warehouse_id:
|
||||
warehouse_id = self._get_default_warehouse(cr, uid,
|
||||
context=context)
|
||||
invoice_lines = invoice_line_obj.browse(cr, uid, invoice_line_ids,
|
||||
context=context)
|
||||
if not self.warehouse_id:
|
||||
self.warehouse_id = self._get_default_warehouse()
|
||||
|
||||
claim_type = self.claim_type
|
||||
claim_date = self.date
|
||||
warehouse = self.warehouse_id
|
||||
company = self.company_id
|
||||
create_lines = context.get('create_lines')
|
||||
|
||||
def warranty_values(invoice, product):
|
||||
values = {}
|
||||
try:
|
||||
warranty = claim_line_obj._warranty_limit_values(
|
||||
cr, uid, [], invoice,
|
||||
claim_type, product,
|
||||
claim_date, context=context)
|
||||
invoice, claim_type, product, claim_date)
|
||||
except (InvoiceNoDate, ProductNoSupplier):
|
||||
# we don't mind at this point if the warranty can't be
|
||||
# computed and we don't want to block the user
|
||||
values.update({'guarantee_limit': False, 'warning': False})
|
||||
else:
|
||||
values.update(warranty)
|
||||
company = company_obj.browse(cr, uid, company_id, context=context)
|
||||
warehouse = warehouse_obj.browse(cr, uid, warehouse_id,
|
||||
context=context)
|
||||
|
||||
warranty_address = claim_line_obj._warranty_return_address_values(
|
||||
cr, uid, [], product, company,
|
||||
warehouse, context=context)
|
||||
product, company, warehouse)
|
||||
values.update(warranty_address)
|
||||
return values
|
||||
|
||||
if create_lines: # happens when the invoice is changed
|
||||
for invoice_line in invoice_lines:
|
||||
location_dest_id = claim_line_obj.get_destination_location(
|
||||
cr, uid, invoice_line.product_id.id,
|
||||
warehouse_id, context=context)
|
||||
invoice_line.product_id, warehouse)
|
||||
line = {
|
||||
'name': invoice_line.name,
|
||||
'claim_origine': "none",
|
||||
@@ -600,78 +559,40 @@ class crm_claim(orm.Model):
|
||||
}
|
||||
line.update(warranty_values(invoice_line.invoice_id,
|
||||
invoice_line.product_id))
|
||||
claim_lines.append(line)
|
||||
elif lines: # happens when the date, warehouse or claim type is
|
||||
# modified
|
||||
for command in lines:
|
||||
code = command[0]
|
||||
assert code != 6, "command 6 not supported in on_change"
|
||||
if code in (0, 1, 4):
|
||||
# 0: link a new record with values
|
||||
# 1: update an existing record with values
|
||||
# 4: link to existing record
|
||||
line_id = command[1]
|
||||
if code == 4:
|
||||
code = 1 # we want now to update values
|
||||
values = {}
|
||||
else:
|
||||
values = command[2]
|
||||
invoice_line_id = values.get('invoice_line_id')
|
||||
product_id = values.get('product_id')
|
||||
if code == 1: # get the existing line
|
||||
# if the fields have not changed, fallback
|
||||
# on the database values
|
||||
browse_line = claim_line_obj.read(cr, uid,
|
||||
line_id,
|
||||
['invoice_line_id',
|
||||
'product_id'],
|
||||
context=context)
|
||||
if not invoice_line_id:
|
||||
invoice_line_id = browse_line['invoice_line_id'][0]
|
||||
if not product_id:
|
||||
product_id = browse_line['product_id'][0]
|
||||
claim_lines.append([0, 0, line])
|
||||
|
||||
if invoice_line_id and product_id:
|
||||
invoice_line = invoice_line_obj.browse(cr, uid,
|
||||
invoice_line_id,
|
||||
context=context)
|
||||
product = product_obj.browse(cr, uid, product_id,
|
||||
context=context)
|
||||
values.update(warranty_values(invoice_line.invoice_id,
|
||||
product))
|
||||
claim_lines.append((code, line_id, values))
|
||||
elif code in (2, 3, 5):
|
||||
claim_lines.append(command)
|
||||
for line in claim_lines:
|
||||
value = self._convert_to_cache(
|
||||
{'claim_line_ids': line}, validate=False)
|
||||
self.update(value)
|
||||
|
||||
value = {'claim_line_ids': claim_lines}
|
||||
delivery_address_id = False
|
||||
if invoice_id:
|
||||
invoice = invoice_obj.browse(cr, uid, invoice_id, context=context)
|
||||
delivery_address_id = invoice.partner_id.id
|
||||
value['delivery_address_id'] = delivery_address_id
|
||||
if self.invoice_id:
|
||||
self.delivery_address_id = self.invoice_id.partner_id.id
|
||||
|
||||
return {'value': value}
|
||||
|
||||
def message_get_reply_to(self, cr, uid, ids, context=None):
|
||||
@api.model
|
||||
def message_get_reply_to(self):
|
||||
""" Override to get the reply_to of the parent project. """
|
||||
# return [claim.section_id.message_get_reply_to()[0]
|
||||
# if claim.section_id else False
|
||||
# for claim in self.browse(cr, SUPERUSER_ID, ids,
|
||||
# context=context)]
|
||||
return [claim.section_id.message_get_reply_to()[0]
|
||||
if claim.section_id else False
|
||||
for claim in self.browse(cr, SUPERUSER_ID, ids,
|
||||
context=context)]
|
||||
for claim in self]
|
||||
|
||||
def message_get_suggested_recipients(self, cr, uid, ids, context=None):
|
||||
recipients = super(crm_claim, self
|
||||
).message_get_suggested_recipients(cr, uid, ids,
|
||||
context=context)
|
||||
@api.model
|
||||
def message_get_suggested_recipients(self):
|
||||
recipients = super(CrmClaim, self
|
||||
).message_get_suggested_recipients()
|
||||
try:
|
||||
for claim in self.browse(cr, uid, ids, context=context):
|
||||
for claim in self:
|
||||
if claim.partner_id:
|
||||
self._message_add_suggested_recipient(
|
||||
cr, uid, recipients, claim,
|
||||
recipients, claim,
|
||||
partner=claim.partner_id, reason=_('Customer'))
|
||||
elif claim.email_from:
|
||||
self._message_add_suggested_recipient(
|
||||
cr, uid, recipients, claim,
|
||||
recipients, claim,
|
||||
email=claim.email_from, reason=_('Customer Email'))
|
||||
except (osv.except_osv, orm.except_orm):
|
||||
# no read access rights -> just ignore suggested recipients
|
||||
|
||||
@@ -92,16 +92,14 @@
|
||||
<group>
|
||||
<group string="Returned good">
|
||||
<field name="product_returned_quantity"/>
|
||||
<field name="product_id"
|
||||
on_change="onchange_product_id(product_id, invoice_line_id, claim_id, False, False, False, False, context)"/>
|
||||
<field name="product_id" />
|
||||
<field name="prodlot_id"/>
|
||||
<field name="unit_sale_price"/>
|
||||
<field name="return_value"/>
|
||||
</group>
|
||||
<group string="Linked Document">
|
||||
<field name="claim_id" />
|
||||
<field name="invoice_line_id"
|
||||
on_change="onchange_product_id(product_id, invoice_line_id, claim_id, False, False, False, False, context)"/>
|
||||
<field name="invoice_line_id" />
|
||||
<field name="refund_line_id"/>
|
||||
<field name="move_in_id"/>
|
||||
<field name="move_out_id"/>
|
||||
@@ -168,7 +166,7 @@
|
||||
<separator string="Product Return" colspan="4"/>
|
||||
<group>
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="invoice_id" on_change="onchange_invoice_id(invoice_id, warehouse_id, claim_type, date, company_id, claim_line_ids, True, context)" domain="['|',('commercial_partner_id','=',partner_id),('partner_id','=',partner_id)]" />
|
||||
<field name="invoice_id" domain="['|',('commercial_partner_id','=',partner_id),('partner_id','=',partner_id)]" context="{'create_lines': True}"/>
|
||||
<field name="delivery_address_id" context="{'tree_view_ref': 'crm_claim_rma.view_partner_contact_tree', 'search_default_parent_id': partner_id}"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -189,15 +187,13 @@
|
||||
<group>
|
||||
<group string="Returned good">
|
||||
<field name="product_returned_quantity"/>
|
||||
<field name="product_id"
|
||||
on_change="onchange_product_id(product_id, invoice_line_id, False, parent.company_id, parent.warehouse_id, parent.claim_type, parent.date, context)"/>
|
||||
<field name="product_id" context="{'claim_id': parent.id, 'company_id': parent.company_id, 'warehouse_id': parent.warehouse_id, 'claim_type': parent.claim_type, 'claim_date': parent.date}"/>
|
||||
<field name="prodlot_id"/>
|
||||
<field name="unit_sale_price"/>
|
||||
<field name="return_value"/>
|
||||
</group>
|
||||
<group string="Linked Document">
|
||||
<field name="invoice_line_id"
|
||||
on_change="onchange_product_id(product_id, invoice_line_id, False, parent.company_id, parent.warehouse_id, parent.claim_type, parent.date, context)"/>
|
||||
<field name="invoice_line_id" context="{'claim_id': parent.id, 'company_id': parent.company_id, 'warehouse_id': parent.warehouse_id, 'claim_type': parent.claim_type, 'claim_date': parent.date}"/>
|
||||
<field name="refund_line_id"/>
|
||||
<field name="move_in_id"/>
|
||||
<field name="move_out_id"/>
|
||||
@@ -225,23 +221,23 @@
|
||||
</form>
|
||||
</field>
|
||||
</group>
|
||||
<group col="4" colspan="4" attrs="{'invisible':[('state', '<>','open')]}">
|
||||
<group col="4" colspan="4" attrs="{'invisible': True}" >
|
||||
<separator string="Action" colspan="4" />
|
||||
<button name="%(action_claim_picking_in)d"
|
||||
string="New Products Return" states="open"
|
||||
string="New Products Return"
|
||||
type="action" target="new"
|
||||
context="{'warehouse_id': warehouse_id,
|
||||
'partner_id': partner_id}"/>
|
||||
|
||||
<button name="%(action_claim_picking_out)d"
|
||||
string="New Delivery" states="open"
|
||||
string="New Delivery"
|
||||
type="action" target="new"
|
||||
context="{'warehouse_id': warehouse_id,
|
||||
'partner_id': partner_id}"/>
|
||||
|
||||
<button name="%(account.action_account_invoice_refund)d"
|
||||
type='action' string='New Refund'
|
||||
states='open' icon="gtk-execute"
|
||||
icon="gtk-execute"
|
||||
context="{
|
||||
'invoice_ids': [invoice_id],
|
||||
'claim_line_ids': claim_line_ids,
|
||||
@@ -297,18 +293,18 @@
|
||||
src_model="crm.claim"/>
|
||||
<!-- Right side link to picking in -->
|
||||
<act_window
|
||||
domain="[('type', '=', 'in')]"
|
||||
id="act_crm_claim_rma_picking_in"
|
||||
name="Incoming Shipment and Returns"
|
||||
res_model="stock.picking.in"
|
||||
src_model="crm.claim"/>
|
||||
domain="[('picking_type_id.code', '=', 'incoming')]"
|
||||
id="act_crm_claim_rma_picking_in"
|
||||
name="Incoming Shipment and Returns"
|
||||
res_model="stock.picking"
|
||||
src_model="crm.claim"/>
|
||||
<!-- Right side link to picking out -->
|
||||
<act_window
|
||||
domain="[('type', '=', 'out')]"
|
||||
id="act_crm_claim_rma_picking_out"
|
||||
name="Deliveries"
|
||||
res_model="stock.picking.out"
|
||||
src_model="crm.claim"/>
|
||||
<act_window
|
||||
domain="[('picking_type_id.code', '=', 'outgoing')]"
|
||||
id="act_crm_claim_rma_picking_out"
|
||||
name="Deliveries"
|
||||
res_model="stock.picking"
|
||||
src_model="crm.claim"/>
|
||||
|
||||
<record model="ir.ui.view" id="crm_claim_rma_form_view2">
|
||||
<field name="name">CRM - Claim product return Form</field>
|
||||
@@ -316,8 +312,8 @@
|
||||
<field name="inherit_id" ref="crm_claim.crm_case_claims_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="date_deadline" position="after">
|
||||
<field name="claim_type" on_change="onchange_invoice_id(invoice_id, warehouse_id, claim_type, date, company_id, claim_line_ids, False, context)"/>
|
||||
<field name="warehouse_id" on_change="onchange_invoice_id(invoice_id, warehouse_id, claim_type, date, company_id, claim_line_ids, False, context)"/>
|
||||
<field name="claim_type" context="{'create_lines': False}" />
|
||||
<field name="warehouse_id" context="{'create_lines': False}"/>
|
||||
</field>
|
||||
<field name="name" position="replace">
|
||||
<div class="oe_title">
|
||||
@@ -329,7 +325,7 @@
|
||||
</field>
|
||||
<field name="user_id" position="before">
|
||||
<field name="name" />
|
||||
<field name="date" on_change="onchange_invoice_id(invoice_id, warehouse_id, claim_type, date, company_id, claim_line_ids, False, context)"/>
|
||||
<field name="date" context="{'create_lines': False}"/>
|
||||
</field>
|
||||
<xpath expr="//sheet[@string='Claims']/group[1]" position="inside">
|
||||
<div class="oe_right oe_button_box" name="buttons">
|
||||
@@ -404,15 +400,15 @@
|
||||
<field name="search_view_id" ref="view_crm_claim_lines_filter"/>
|
||||
</record>
|
||||
<!-- substates action -->
|
||||
<record id="act_crm_claim_substates" model="ir.actions.act_window">
|
||||
<field name="name">Claim line substates</field>
|
||||
<field name="res_model">substate.substate</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<!--<record id="act_crm_claim_substates" model="ir.actions.act_window">-->
|
||||
<!--<field name="name">Claim line substates</field>-->
|
||||
<!--<field name="res_model">substate.substate</field>-->
|
||||
<!--<field name="view_type">form</field>-->
|
||||
<!--</record>-->
|
||||
<!-- Menu -->
|
||||
<menuitem name="Return lines" id="menu_crm_case_claims_claim_lines"
|
||||
parent="base.menu_aftersale" action="act_crm_case_claim_lines" sequence="2"/>
|
||||
<menuitem name="Returned line substates" id="menu_crm_case_claims_claim_line_substates"
|
||||
parent="crm_claim.menu_config_claim" action="act_crm_claim_substates" sequence="2"/>
|
||||
<!--<menuitem name="Returned line substates" id="menu_crm_case_claims_claim_line_substates"-->
|
||||
<!--parent="crm_claim.menu_config_claim" action="act_crm_claim_substates" sequence="2"/>-->
|
||||
</data>
|
||||
</openerp>
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
<field name="email"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="is_company" invisible="1"/>
|
||||
<field name="country" invisible="1"/>
|
||||
<!--<field name="country" invisible="1"/>-->
|
||||
<field name="country_id"/>
|
||||
<field name="parent_id" invisible="1"/>
|
||||
</tree>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
@@ -20,65 +21,40 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import fields, orm
|
||||
|
||||
from openerp.models import Model, api
|
||||
from openerp.fields import Many2one
|
||||
|
||||
|
||||
class stock_picking(orm.Model):
|
||||
|
||||
class StockPicking(Model):
|
||||
_inherit = "stock.picking"
|
||||
|
||||
_columns = {
|
||||
'claim_id': fields.many2one('crm.claim', 'Claim'),
|
||||
}
|
||||
claim_id = Many2one('crm.claim', string='Claim')
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
if ('name' not in vals) or (vals.get('name') == '/'):
|
||||
sequence_obj = self.pool.get('ir.sequence')
|
||||
if vals['type'] == 'internal':
|
||||
seq_obj_name = self._name
|
||||
else:
|
||||
seq_obj_name = 'stock.picking.' + vals['type']
|
||||
vals['name'] = sequence_obj.get(cr, uid, seq_obj_name,
|
||||
context=context)
|
||||
new_id = super(stock_picking, self).create(cr, uid, vals,
|
||||
context=context)
|
||||
return new_id
|
||||
|
||||
|
||||
class stock_picking_out(orm.Model):
|
||||
|
||||
_inherit = "stock.picking.out"
|
||||
|
||||
_columns = {
|
||||
'claim_id': fields.many2one('crm.claim', 'Claim'),
|
||||
}
|
||||
|
||||
|
||||
class stock_picking_in(orm.Model):
|
||||
|
||||
_inherit = "stock.picking.in"
|
||||
|
||||
_columns = {
|
||||
'claim_id': fields.many2one('crm.claim', 'Claim'),
|
||||
}
|
||||
sequence_obj = self.env['ir.sequence']
|
||||
seq_obj_name = self._name
|
||||
vals['name'] = sequence_obj.get(seq_obj_name)
|
||||
|
||||
picking = super(StockPicking, self).create(vals)
|
||||
return picking
|
||||
|
||||
# This part concern the case of a wrong picking out. We need to create a new
|
||||
# stock_move in a picking already open.
|
||||
# In order to don't have to confirm the stock_move we override the create and
|
||||
# confirm it at the creation only for this case
|
||||
class stock_move(orm.Model):
|
||||
|
||||
class StockMove(Model):
|
||||
_inherit = "stock.move"
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
move_id = super(stock_move, self
|
||||
).create(cr, uid, vals, context=context)
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
move = super(StockMove, self).create(vals)
|
||||
if vals.get('picking_id'):
|
||||
picking_obj = self.pool.get('stock.picking')
|
||||
picking = picking_obj.browse(cr, uid, vals['picking_id'],
|
||||
context=context)
|
||||
if picking.claim_id and picking.type == u'in':
|
||||
self.write(cr, uid, move_id, {'state': 'confirmed'},
|
||||
context=context)
|
||||
return move_id
|
||||
picking_obj = self.env['stock.picking']
|
||||
picking = picking_obj.browse(vals['picking_id'])
|
||||
if picking.claim_id and picking.picking_type_id.code == 'incoming':
|
||||
move.write({'state': 'confirmed'})
|
||||
|
||||
return move
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<!-- INHERITED VIEW FOR THE OBJECT : stock_picking -->
|
||||
|
||||
<record id="picking_in_form" model="ir.ui.view">
|
||||
<field name="name">crm_claim_rma.picking_in_form</field>
|
||||
<field name="model">stock.picking.in</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_in_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='move_type']" position="after">
|
||||
<field name="claim_id" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="picking_out_form" model="ir.ui.view">
|
||||
<field name="name">crm_claim_rma.picking_out_form</field>
|
||||
<field name="model">stock.picking.out</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_out_form" />
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/sheet/notebook/page/group/group/field[@name='move_type']" position="after">
|
||||
<field name="claim_id" />
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_picking_in_search" model="ir.ui.view">
|
||||
<field name="name">crm_claim_rma.picking_in_search</field>
|
||||
<field name="model">stock.picking.in</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_in_search" />
|
||||
<field name="arch" type="xml">
|
||||
<filter string="To Invoice" name="to_invoice" icon="terp-dolar" domain="[('invoice_state', '=', '2binvoiced')]" position="after">
|
||||
<separator/>
|
||||
<filter string="RMA" icon="terp-accessories-archiver-minus" domain="[('claim_id', '!=', 'False')]" />
|
||||
<field name="claim_id" string="RMA" invisible="True"/>
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_picking_out_search" model="ir.ui.view">
|
||||
<field name="name">crm_claim_rma.picking_out_search</field>
|
||||
<field name="model">stock.picking.out</field>
|
||||
<field name="inherit_id" ref="stock.view_picking_out_search" />
|
||||
<field name="arch" type="xml">
|
||||
<filter icon="terp-dolar" name="to_invoice" string="To Invoice" domain="[('invoice_state','=','2binvoiced')]" help="Delivery orders to invoice" position="after">
|
||||
<separator/>
|
||||
<filter string="RMA" icon="terp-accessories-archiver-minus" domain="[('claim_id', '!=', 'False')]" />
|
||||
</filter>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
@@ -20,5 +21,6 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from . import claim_make_picking
|
||||
from . import account_invoice_refund
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
@@ -20,27 +21,32 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import orm
|
||||
|
||||
from openerp.models import api, TransientModel
|
||||
from openerp.fields import Char
|
||||
|
||||
class account_invoice_refund(orm.TransientModel):
|
||||
|
||||
class AccountInvoiceRefund(TransientModel):
|
||||
_inherit = "account.invoice.refund"
|
||||
|
||||
def compute_refund(self, cr, uid, ids, mode='refund', context=None):
|
||||
@api.one
|
||||
def _get_description(self):
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
description = context.get('description') or ''
|
||||
self.description = description
|
||||
|
||||
description = Char(default=_get_description)
|
||||
|
||||
@api.model
|
||||
def compute_refund(self, mode='refund'):
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
if context.get('invoice_ids'):
|
||||
context['active_ids'] = context.get('invoice_ids')
|
||||
return super(account_invoice_refund, self).compute_refund(
|
||||
cr, uid, ids, mode=mode, context=context)
|
||||
|
||||
def _get_description(self, cr, uid, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
description = context.get('description') or ''
|
||||
return description
|
||||
return super(AccountInvoiceRefund, self).compute_refund(mode=mode)
|
||||
|
||||
_defaults = {
|
||||
'description': _get_description,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# Copyright 2015 Eezee-It
|
||||
# Copyright 2013 Camptocamp
|
||||
# Copyright 2009-2013 Akretion,
|
||||
# Author: Emmanuel Samyn, Raphaël Valyi, Sébastien Beau,
|
||||
@@ -20,144 +21,151 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import fields, orm
|
||||
|
||||
from openerp.models import api, TransientModel, _
|
||||
from openerp.fields import Many2many, Many2one
|
||||
from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
|
||||
from openerp import netsvc
|
||||
from openerp.tools.translate import _
|
||||
import time
|
||||
|
||||
|
||||
class claim_make_picking(orm.TransientModel):
|
||||
|
||||
class ClaimMakePicking(TransientModel):
|
||||
_name = 'claim_make_picking.wizard'
|
||||
_description = 'Wizard to create pickings from claim lines'
|
||||
_columns = {
|
||||
'claim_line_source_location': fields.many2one(
|
||||
'stock.location',
|
||||
string='Source Location',
|
||||
help="Location where the returned products are from.",
|
||||
required=True),
|
||||
'claim_line_dest_location': fields.many2one(
|
||||
'stock.location',
|
||||
string='Dest. Location',
|
||||
help="Location where the system will stock the returned products.",
|
||||
required=True),
|
||||
'claim_line_ids': fields.many2many(
|
||||
'claim.line',
|
||||
'claim_line_picking',
|
||||
'claim_picking_id',
|
||||
'claim_line_id',
|
||||
string='Claim lines'),
|
||||
}
|
||||
|
||||
def _get_claim_lines(self, cr, uid, context):
|
||||
# TODO use custom states to show buttons of this wizard or not instead
|
||||
# of raise an error
|
||||
if context is None:
|
||||
context = {}
|
||||
line_obj = self.pool.get('claim.line')
|
||||
if context.get('picking_type') == 'out':
|
||||
move_field = 'move_out_id'
|
||||
else:
|
||||
move_field = 'move_in_id'
|
||||
good_lines = []
|
||||
line_ids = line_obj.search(
|
||||
cr, uid,
|
||||
[('claim_id', '=', context['active_id'])],
|
||||
context=context)
|
||||
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
||||
if not line[move_field] or line[move_field].state == 'cancel':
|
||||
good_lines.append(line.id)
|
||||
if not good_lines:
|
||||
raise orm.except_orm(
|
||||
_('Error'),
|
||||
_('A picking has already been created for this claim.'))
|
||||
return good_lines
|
||||
|
||||
# Get default source location
|
||||
def _get_source_loc(self, cr, uid, context):
|
||||
@api.one
|
||||
def _get_source_loc(self):
|
||||
loc_id = False
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
warehouse_obj = self.pool.get('stock.warehouse')
|
||||
|
||||
warehouse_obj = self.env['stock.warehouse']
|
||||
warehouse_id = context.get('warehouse_id')
|
||||
if context.get('picking_type') == 'out':
|
||||
loc_id = warehouse_obj.read(
|
||||
cr, uid, warehouse_id,
|
||||
['lot_stock_id'],
|
||||
context=context)['lot_stock_id'][0]
|
||||
warehouse_id, ['lot_stock_id'])['lot_stock_id'][0]
|
||||
elif context.get('partner_id'):
|
||||
loc_id = self.pool.get('res.partner').read(
|
||||
cr, uid, context['partner_id'],
|
||||
['property_stock_customer'],
|
||||
context=context)['property_stock_customer'][0]
|
||||
return loc_id
|
||||
loc_id = self.env['res.partner'].read(
|
||||
context['partner_id'], ['property_stock_customer']
|
||||
)['property_stock_customer'][0]
|
||||
|
||||
def _get_common_dest_location_from_line(self, cr, uid, line_ids, context):
|
||||
self.claim_line_source_location = loc_id
|
||||
|
||||
def _get_common_dest_location_from_line(self, line_ids):
|
||||
"""Return the ID of the common location between all lines. If no common
|
||||
destination was found, return False"""
|
||||
loc_id = False
|
||||
line_obj = self.pool.get('claim.line')
|
||||
line_obj = self.env['claim.line']
|
||||
line_location = []
|
||||
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
||||
|
||||
for line in line_obj.browse(line_ids):
|
||||
if line.location_dest_id.id not in line_location:
|
||||
line_location.append(line.location_dest_id.id)
|
||||
|
||||
if len(line_location) == 1:
|
||||
loc_id = line_location[0]
|
||||
|
||||
return loc_id
|
||||
|
||||
def _get_common_partner_from_line(self, cr, uid, line_ids, context):
|
||||
"""Return the ID of the common partner between all lines. If no common
|
||||
partner was found, return False"""
|
||||
partner_id = False
|
||||
line_obj = self.pool.get('claim.line')
|
||||
line_partner = []
|
||||
for line in line_obj.browse(cr, uid, line_ids, context=context):
|
||||
if (line.warranty_return_partner
|
||||
and line.warranty_return_partner.id
|
||||
not in line_partner):
|
||||
line_partner.append(line.warranty_return_partner.id)
|
||||
if len(line_partner) == 1:
|
||||
partner_id = line_partner[0]
|
||||
return partner_id
|
||||
|
||||
# Get default destination location
|
||||
def _get_dest_loc(self, cr, uid, context):
|
||||
@api.one
|
||||
def _get_dest_loc(self):
|
||||
"""Return the location_id to use as destination.
|
||||
If it's an outoing shippment: take the customer stock property
|
||||
If it's an incoming shippment take the location_dest_id common to all
|
||||
lines, or if different, return None."""
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
loc_id = False
|
||||
if context.get('picking_type') == 'out' and context.get('partner_id'):
|
||||
loc_id = self.pool.get('res.partner').read(
|
||||
cr, uid, context.get('partner_id'),
|
||||
['property_stock_customer'],
|
||||
context=context)['property_stock_customer'][0]
|
||||
loc_id = self.env['res.partner'].read(
|
||||
context.get('partner_id'), ['property_stock_customer']
|
||||
)['property_stock_customer'][0]
|
||||
elif context.get('picking_type') == 'in' and context.get('partner_id'):
|
||||
# Add the case of return to supplier !
|
||||
line_ids = self._get_claim_lines(cr, uid, context=context)
|
||||
loc_id = self._get_common_dest_location_from_line(cr, uid,
|
||||
line_ids,
|
||||
context=context)
|
||||
return loc_id
|
||||
line_ids = self._get_claim_lines()
|
||||
loc_id = self._get_common_dest_location_from_line(line_ids)
|
||||
|
||||
_defaults = {
|
||||
'claim_line_source_location': _get_source_loc,
|
||||
'claim_line_dest_location': _get_dest_loc,
|
||||
'claim_line_ids': _get_claim_lines,
|
||||
}
|
||||
self.claim_line_dest_location = loc_id
|
||||
|
||||
def action_cancel(self, cr, uid, ids, context=None):
|
||||
@api.one
|
||||
def _get_claim_lines(self):
|
||||
print "GET CLAIM LINES"
|
||||
# TODO use custom states to show buttons of this wizard or not instead
|
||||
# of raise an error
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
line_obj = self.env['claim.line']
|
||||
if context.get('picking_type') == 'out':
|
||||
move_field = 'move_out_id'
|
||||
else:
|
||||
move_field = 'move_in_id'
|
||||
|
||||
good_lines = []
|
||||
lines = line_obj.search(
|
||||
[('claim_id', '=', context['active_id'])])
|
||||
for line in lines:
|
||||
if not line[move_field] or line[move_field].state == 'cancel':
|
||||
good_lines.append(line.id)
|
||||
|
||||
if not good_lines:
|
||||
raise Warning(
|
||||
_('A picking has already been created for this claim.'))
|
||||
|
||||
print "LINES: ", good_lines
|
||||
self.claim_line_ids = good_lines
|
||||
|
||||
claim_line_source_location = Many2one(
|
||||
'stock.location', string='Source Location', required=True,
|
||||
default='_get_source_loc',
|
||||
help="Location where the returned products are from.")
|
||||
claim_line_dest_location = Many2one(
|
||||
'stock.location', string='Dest. Location', required=True,
|
||||
default='_get_dest_loc',
|
||||
help="Location where the system will stock the returned products.")
|
||||
claim_line_ids = Many2many(
|
||||
'claim.line',
|
||||
'claim_line_picking',
|
||||
'claim_picking_id',
|
||||
'claim_line_id',
|
||||
string='Claim lines', default=_get_claim_lines)
|
||||
|
||||
def _get_common_partner_from_line(self, line_ids):
|
||||
"""Return the ID of the common partner between all lines. If no common
|
||||
partner was found, return False"""
|
||||
partner_id = False
|
||||
line_obj = self.env['claim.line']
|
||||
line_partner = []
|
||||
for line in line_obj.browse(line_ids):
|
||||
if (line.warranty_return_partner
|
||||
and line.warranty_return_partner.id
|
||||
not in line_partner):
|
||||
line_partner.append(line.warranty_return_partner.id)
|
||||
|
||||
if len(line_partner) == 1:
|
||||
partner_id = line_partner[0]
|
||||
|
||||
return partner_id
|
||||
|
||||
@api.multi
|
||||
def action_cancel(self):
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
# If "Create" button pressed
|
||||
def action_create_picking(self, cr, uid, ids, context=None):
|
||||
picking_obj = self.pool.get('stock.picking')
|
||||
@api.model
|
||||
def action_create_picking(self):
|
||||
picking_obj = self.env['stock.picking']
|
||||
context = self.env.context
|
||||
if context is None:
|
||||
context = {}
|
||||
view_obj = self.pool.get('ir.ui.view')
|
||||
|
||||
view_obj = self.env['ir.ui.view']
|
||||
name = 'RMA picking out'
|
||||
if context.get('picking_type') == 'out':
|
||||
p_type = 'out'
|
||||
@@ -170,44 +178,43 @@ class claim_make_picking(orm.TransientModel):
|
||||
note = 'RMA picking ' + str(context.get('picking_type'))
|
||||
name = note
|
||||
model = 'stock.picking.' + p_type
|
||||
view_id = view_obj.search(cr, uid,
|
||||
[('model', '=', model),
|
||||
('type', '=', 'form'),
|
||||
],
|
||||
context=context)[0]
|
||||
wizard = self.browse(cr, uid, ids[0], context=context)
|
||||
claim = self.pool.get('crm.claim').browse(cr, uid,
|
||||
context['active_id'],
|
||||
context=context)
|
||||
view_id = view_obj.search([
|
||||
('model', '=', model),
|
||||
('type', '=', 'form')
|
||||
], limit=1).id
|
||||
|
||||
claim = self.env['crm.claim'].browse(context['active_id'])
|
||||
partner_id = claim.delivery_address_id.id
|
||||
line_ids = [x.id for x in wizard.claim_line_ids]
|
||||
wizard = self
|
||||
claim_lines = wizard.clame_line_ids
|
||||
# line_ids = [x.id for x in wizard.claim_line_ids]
|
||||
|
||||
# In case of product return, we don't allow one picking for various
|
||||
# product if location are different
|
||||
# or if partner address is different
|
||||
if context.get('product_return'):
|
||||
common_dest_loc_id = self._get_common_dest_location_from_line(
|
||||
cr, uid, line_ids, context=context)
|
||||
claim_lines.ids)
|
||||
if not common_dest_loc_id:
|
||||
raise orm.except_orm(
|
||||
_('Error !'),
|
||||
raise Warning(
|
||||
_('A product return cannot be created for various '
|
||||
'destination locations, please choose line with a '
|
||||
'same destination location.'))
|
||||
self.pool.get('claim.line').auto_set_warranty(cr, uid,
|
||||
line_ids,
|
||||
context=context)
|
||||
|
||||
claim_lines.auto_set_warranty()
|
||||
common_dest_partner_id = self._get_common_partner_from_line(
|
||||
cr, uid, line_ids, context=context)
|
||||
claim_lines.ids)
|
||||
|
||||
if not common_dest_partner_id:
|
||||
raise orm.except_orm(
|
||||
_('Error !'),
|
||||
raise Warning(
|
||||
_('A product return cannot be created for various '
|
||||
'destination addresses, please choose line with a '
|
||||
'same address.'))
|
||||
|
||||
partner_id = common_dest_partner_id
|
||||
|
||||
# create picking
|
||||
picking_id = picking_obj.create(
|
||||
cr, uid,
|
||||
picking = picking_obj.create(
|
||||
{'origin': claim.number,
|
||||
'type': p_type,
|
||||
'move_type': 'one', # direct
|
||||
@@ -220,14 +227,13 @@ class claim_make_picking(orm.TransientModel):
|
||||
'location_dest_id': wizard.claim_line_dest_location.id,
|
||||
'note': note,
|
||||
'claim_id': claim.id,
|
||||
},
|
||||
context=context)
|
||||
}).id
|
||||
|
||||
# Create picking lines
|
||||
fmt = DEFAULT_SERVER_DATETIME_FORMAT
|
||||
for wizard_claim_line in wizard.claim_line_ids:
|
||||
move_obj = self.pool.get('stock.move')
|
||||
move_obj = self.env['stock.move']
|
||||
move_id = move_obj.create(
|
||||
cr, uid,
|
||||
{'name': wizard_claim_line.product_id.name_template,
|
||||
'priority': '0',
|
||||
'date': time.strftime(fmt),
|
||||
@@ -237,23 +243,23 @@ class claim_make_picking(orm.TransientModel):
|
||||
'product_uom': wizard_claim_line.product_id.uom_id.id,
|
||||
'partner_id': partner_id,
|
||||
'prodlot_id': wizard_claim_line.prodlot_id.id,
|
||||
'picking_id': picking_id,
|
||||
'picking_id': picking.id,
|
||||
'state': 'draft',
|
||||
'price_unit': wizard_claim_line.unit_sale_price,
|
||||
'company_id': claim.company_id.id,
|
||||
'location_id': wizard.claim_line_source_location.id,
|
||||
'location_dest_id': wizard.claim_line_dest_location.id,
|
||||
'note': note,
|
||||
},
|
||||
context=context)
|
||||
self.pool.get('claim.line').write(
|
||||
cr, uid, wizard_claim_line.id,
|
||||
{write_field: move_id}, context=context)
|
||||
}).id
|
||||
|
||||
wizard_claim_line.write({write_field: move_id})
|
||||
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
if picking_id:
|
||||
if picking:
|
||||
cr, uid = self.env.cr, self.env.uid
|
||||
wf_service.trg_validate(uid, 'stock.picking',
|
||||
picking_id, 'button_confirm', cr)
|
||||
picking_obj.action_assign(cr, uid, [picking_id])
|
||||
picking.id, 'button_confirm', cr)
|
||||
picking.action_assign()
|
||||
domain = ("[('type', '=', '%s'), ('partner_id', '=', %s)]" %
|
||||
(p_type, partner_id))
|
||||
return {
|
||||
@@ -263,7 +269,7 @@ class claim_make_picking(orm.TransientModel):
|
||||
'view_id': view_id,
|
||||
'domain': domain,
|
||||
'res_model': model,
|
||||
'res_id': picking_id,
|
||||
'res_id': picking.id,
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
crm_claim_rma for OpenERP
|
||||
Copyright (c) 2015 Eezee-It (www.eezee-it.com)
|
||||
Copyright (C) 2011 Akretion Benoît GUILLOT <benoit.guillot@akretion.com>
|
||||
The licence is in the file __openerp__.py
|
||||
-->
|
||||
|
||||
Reference in New Issue
Block a user