Files
tryton/purchase.py
T

920 lines
35 KiB
Python

"Purchase"
from trytond.osv import fields, OSV
from decimal import Decimal
import datetime
from trytond.netsvc import LocalService
from trytond.report import CompanyReport
_STATES = {
'readonly': "state != 'draft'",
}
class Purchase(OSV):
'Purchase'
_name = 'purchase.purchase'
_description = __doc__
company = fields.Many2One('company.company', 'Company', required=True,
states=_STATES)
reference = fields.Char('Reference', size=None, readonly=True, select=1)
description = fields.Char('Description', size=None, states=_STATES)
state = fields.Selection([
('draft', 'Draft'),
('quotation', 'Quotation'),
('confirmed', 'Confirmed'),
('done', 'Done'),
('cancel', 'Cancel'),
], 'State', readonly=True, required=True)
purchase_date = fields.Date('Purchase Date', required=True, states=_STATES)
payment_term = fields.Many2One('account.invoice.payment_term',
'Payment Term', required=True, states=_STATES)
party = fields.Many2One('relationship.party', 'Party', change_default=True,
required=True, states=_STATES, on_change=['party', 'payment_term'])
contact_address = fields.Many2One('relationship.address', 'Contact Address',
domain="[('party', '=', party)]", states=_STATES)
invoice_address = fields.Many2One('relationship.address', 'Invoice Address',
domain="[('party', '=', party)]", states=_STATES)
warehouse = fields.Many2One('stock.location', 'Warehouse',
domain=[('type', '=', 'warehouse')], required=True, states=_STATES)
currency = fields.Many2One('currency.currency', 'Currency', required=True,
states=_STATES)
lines = fields.One2Many('purchase.line', 'purchase', 'Lines',
states=_STATES)
comment = fields.Text('Comment')
#TODO digits must depend of currency
untaxed_amount = fields.Function('get_untaxed_amount', type='numeric',
digits=(16, 2), string='Untaxed')
tax_amount = fields.Function('get_tax_amount', type='numeric',
digits=(16, 2), string='Tax')
total_amount = fields.Function('get_total_amount', type='numeric',
digits=(16, 2), string='Total')
invoice_method = fields.Selection([
('manual', 'Manual'),
('order', 'From Order'),
('packing', 'From Packing'),
], 'Invoice Method', required=True, states=_STATES)
invoice_state = fields.Selection([
('none', 'None'),
('waiting', 'Waiting'),
('paid', 'Paid'),
('exception', 'Exception'),
], 'Invoice State', readonly=True, required=True)
invoices = fields.Many2Many('account.invoice', 'purchase_invoices_rel',
'purchase', 'invoice', 'Invoices', readonly=True)
invoices_ignored = fields.Many2Many('account.invoice',
'purchase_invoice_ignored_rel', 'purchase', 'invoice',
'Invoices Ignored', readonly=True)
invoice_paid = fields.Function('get_invoice_paid', type='boolean',
string='Invoices Paid')
invoice_exception = fields.Function('get_invoice_exception', type='boolean',
string='Invoices Exception')
packing_state = fields.Selection([
('none', 'None'),
('waiting', 'Waiting'),
('received', 'Received'),
('exception', 'Exception'),
], 'Packing State', readonly=True, required=True)
packings = fields.Function('get_packings', type='many2many',
relation='stock.packing.in', string='Packings')
moves = fields.Function('get_moves', type='many2many',
relation='stock.move', string='Moves')
packing_done = fields.Function('get_packing_done', type='boolean',
string='Packing Done')
packing_exception = fields.Function('get_packing_exception', type='boolean',
string='Packings Exception')
def __init__(self):
super(Purchase, self).__init__()
self._rpc_allowed += [
'button_compute',
]
def default_company(self, cursor, user, context=None):
company_obj = self.pool.get('company.company')
if context is None:
context = {}
if context.get('company'):
return company_obj.name_get(cursor, user, context['company'],
context=context)[0]
return False
def default_state(self, cursor, user, context=None):
return 'draft'
def default_purchase_date(self, cursor, user, context=None):
return datetime.date.today()
def default_currency(self, cursor, user, context=None):
company_obj = self.pool.get('company.company')
currency_obj = self.pool.get('currency.currency')
if context is None:
context = {}
company = None
if context.get('company'):
company = company_obj.browse(cursor, user, context['company'],
context=context)
return currency_obj.name_get(cursor, user, company.currency.id,
context=context)[0]
return False
def default_invoice_method(self, cursor, user, context=None):
return 'order'
def default_invoice_state(self, cursor, user, context=None):
return 'none'
def default_packing_state(self, cursor, user, context=None):
return 'none'
def on_change_party(self, cursor, user, ids, vals, context=None):
party_obj = self.pool.get('relationship.party')
address_obj = self.pool.get('relationship.address')
payment_term_obj = self.pool.get('account.invoice.payment_term')
res = {
'invoice_address': False,
'contact_address': False,
'payment_term': False,
}
if vals.get('party'):
party = party_obj.browse(cursor, user, vals['party'],
context=context)
res['contact_address'] = party_obj.address_get(cursor, user,
party.id, type=None, context=context)
res['invoice_address'] = party_obj.address_get(cursor, user,
party.id, type='invoice', context=context)
if party.payment_term:
res['payment_term'] = party.payment_term.id
if res['contact_address']:
res['contact_address'] = address_obj.name_get(cursor, user,
res['contact_address'], context=context)[0]
if res['invoice_address']:
res['invoice_address'] = address_obj.name_get(cursor, user,
res['invoice_address'], context=context)[0]
if res['payment_term']:
res['payment_term'] = payment_term_obj.name_get(cursor, user,
res['payment_term'], context=context)[0]
return res
def get_untaxed_amount(self, cursor, user, ids, name, arg, context=None):
currency_obj = self.pool.get('currency.currency')
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
res.setdefault(purchase.id, Decimal('0.0'))
for line in purchase.lines:
if line.type != 'line':
continue
res[purchase.id] += line.amount
res[purchase.id] = currency_obj.round(cursor, user, purchase.currency,
res[purchase.id])
return res
def get_tax_context(self, cursor, user, purchase, context=None):
res = {}
if purchase.party.lang:
res['language'] = purchase.party.lang.code
return res
def get_tax_amount(self, cursor, user, ids, name, arg, context=None):
currency_obj = self.pool.get('currency.currency')
tax_obj = self.pool.get('account.tax')
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
ctx = context.copy()
ctx.update(self.get_tax_context(cursor, user,
purchase, context=context))
res.setdefault(purchase.id, Decimal('0.0'))
for line in purchase.lines:
for tax in tax_obj.compute(cursor, user, line.taxes,
line.unit_price, line.quantity, context=ctx):
res[purchase.id] += tax['amount']
res[purchase.id] = currency_obj.round(cursor, user, purchase.currency,
res[purchase.id])
res[purchase.id] = currency_obj.round(cursor, user, purchase.currency,
res[purchase.id])
return res
def get_total_amount(self, cursor, user, ids, name, arg, context=None):
currency_obj = self.pool.get('currency.currency')
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
res[purchase.id] = currency_obj.round(cursor, user, purchase.currency,
purchase.untaxed_amount + purchase.tax_amount)
return res
def get_invoice_paid(self, cursor, user, ids, name, args, context=None):
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
val = True
ignored_ids = [x.id for x in purchase.invoices_ignored]
for invoice in purchase.invoices:
if invoice.state != 'paid' \
and invoice.id not in ignored_ids:
val = False
break
res[purchase.id] = val
return res
def get_invoice_exception(self, cursor, user, ids, name, args, context=None):
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
val = False
ignored_ids = [x.id for x in purchase.invoices_ignored]
for invoice in purchase.invoices:
if invoice.state == 'cancel' \
and invoice.id not in ignored_ids:
val = True
break
res[purchase.id] = val
return res
def get_packings(self, cursor, user, ids, name, args, context=None):
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
res[purchase.id] = []
for line in purchase.lines:
for move in line.moves:
if move.packing_in:
if move.packing_in.id not in res[purchase.id]:
res[purchase.id].append(move.packing_in.id)
return res
def get_moves(self, cursor, user, ids, name, args, context=None):
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
res[purchase.id] = []
for line in purchase.lines:
res[purchase.id].extend([x.id for x in line.moves])
return res
def get_packing_done(self, cursor, user, ids, name, args, context=None):
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
val = True
for line in purchase.lines:
if not line.move_done:
val = False
break
res[purchase.id] = val
return res
def get_packing_exception(self, cursor, user, ids, name, args,
context=None):
res = {}
for purchase in self.browse(cursor, user, ids, context=context):
val = False
ignored_ids = []
for line in purchase.lines:
if line.move_exception:
val = True
break
res[purchase.id] = val
return res
def name_get(self, cursor, user, ids, context=None):
if not ids:
return []
if isinstance(ids, (int, long)):
ids = [ids]
res = []
for purchase in self.browse(cursor, user, ids, context=context):
res.append((purchase.id, purchase.reference or str(purchase.id) \
+ ' ' + purchase.party.name))
return res
def name_search(self, cursor, user, name='', args=None, operator='ilike',
context=None, limit=None):
if args is None:
args = []
if name:
ids = self.search(cursor, user, [('reference', operator, name)] + args,
limit=limit, context=context)
if not ids:
ids = self.search(cursor, user, [('party', operator, name)] + args,
limit=limit, context=context)
res = self.name_get(cursor, user, ids, context=context)
return res
def copy(self, cursor, user, purchase_id, default=None, context=None):
if default is None:
default = {}
default = default.copy()
default['state'] = 'draft'
default['reference'] = False
default['invoice_state'] = 'none'
default['invoices'] = False
default['invoices_ignored'] = False
default['packing_state'] = 'none'
return super(Purchase, self).copy(cursor, user, purchase_id,
default=default, context=context)
def button_compute(self, cursor, user, ids, context=None):
pass
def set_reference(self, cursor, user, purchase_id, context=None):
sequence_obj = self.pool.get('ir.sequence')
purchase = self.browse(cursor, user, purchase_id, context=context)
if purchase.reference:
return True
reference = sequence_obj.get(cursor, user, 'purchase.purchase')
self.write(cursor, user, purchase_id, {
'reference': reference,
}, context=context)
return True
def _get_invoice_line_purchase_line(self, cursor, user, purchase,
context=None):
'''
Return list of invoice line values for each purchase lines
'''
line_obj = self.pool.get('purchase.line')
res = {}
for line in purchase.lines:
val = line_obj.get_invoice_line(cursor, user, line,
context=context)
if val:
res[line.id] = val
return res
def create_invoice(self, cursor, user, purchase_id, context=None):
invoice_obj = self.pool.get('account.invoice')
journal_obj = self.pool.get('account.journal')
invoice_line_obj = self.pool.get('account.invoice.line')
purchase_line_obj = self.pool.get('purchase.line')
purchase = self.browse(cursor, user, purchase_id, context=context)
invoice_lines = self._get_invoice_line_purchase_line(cursor, user,
purchase, context=context)
if not invoice_lines:
return
journal_id = journal_obj.search(cursor, user, [
('type', '=', 'expense'),
], limit=1, context=context)
if journal_id:
journal_id = journal_id[0]
invoice_id = invoice_obj.create(cursor, user, {
'company': purchase.company.id,
'type': 'in_invoice',
'reference': purchase.reference,
'journal': journal_id,
'party': purchase.party.id,
'contact_address': purchase.contact_address.id,
'invoice_address': purchase.invoice_address.id,
'currency': purchase.currency.id,
'account': purchase.party.account_payable.id,
'payment_term': purchase.payment_term.id,
}, context=context)
for line_id in invoice_lines:
vals = invoice_lines[line_id]
vals['invoice'] = invoice_id
invoice_line_id = invoice_line_obj.create(cursor, user, vals,
context=context)
purchase_line_obj.write(cursor, user, line_id, {
'invoice_lines': [('add', invoice_line_id)],
}, context=context)
invoice_obj.button_compute(cursor, user, [invoice_id], context=context)
self.write(cursor, user, purchase_id, {
'invoices': [('add', invoice_id)],
}, context=context)
return invoice_id
def ignore_invoice_exception(self, cursor, user, purchase_id, context=None):
purchase = self.browse(cursor, user, purchase_id, context=context)
invoice_ids = []
for invoice in purchase.invoices:
if invoice.state == 'cancel':
invoice_ids.append(invoice.id)
if invoice_ids:
self.write(cursor, user, purchase_id, {
'invoices_ignored': [('add', x) for x in invoice_ids],
}, context=context)
def create_move(self, cursor, user, purchase_id, context=None):
'''
Create move for each purchase lines
'''
line_obj = self.pool.get('purchase.line')
purchase = self.browse(cursor, user, purchase_id, context=context)
for line in purchase.lines:
line_obj.create_move(cursor, user, line, context=context)
def ignore_packing_exception(self, cursor, user, purchase_id, context=None):
line_obj = self.pool.get('purchase.line')
purchase = self.browse(cursor, user, purchase_id, context=context)
for line in purchase.lines:
line_obj.ignore_move_exception(cursor, user, line, context=context)
Purchase()
class PurchaseLine(OSV):
'Purchase Line'
_name = 'purchase.line'
_rec_name = 'description'
_description = __doc__
purchase = fields.Many2One('purchase.purchase', 'Purchase', ondelete='CASCADE',
select=1)
sequence = fields.Integer('Sequence')
type = fields.Selection([
('line', 'Line'),
('subtotal', 'Subtotal'),
('title', 'Title'),
], 'Type', select=1, required=True)
quantity = fields.Float('Quantity',
states={
'invisible': "type != 'line'",
'required': "type == 'line'",
})
unit = fields.Many2One('product.uom', 'Unit',
states={
'required': "product",
'invisible': "type != 'line'",
}, domain="[('category', '=', (product, 'product'))]")
product = fields.Many2One('product.product', 'Product',
states={
'invisible': "type != 'line'",
}, on_change=['product', 'unit', 'quantity', 'description',
'parent.party', 'parent.currency'])
unit_price = fields.Numeric('Unit Price', digits=(16, 4),
states={
'invisible': "type != 'line'",
'required': "type == 'line'",
})
amount = fields.Function('get_amount', type='numeric', string='Amount',
states={
'invisible': "type not in ('line', 'subtotal')",
})
description = fields.Char('Description', size=None, required=True)
comment = fields.Text('Comment',
states={
'invisible': "type != 'line'",
})
taxes = fields.Many2Many('account.tax', 'purchase_line_account_tax',
'line', 'tax', 'Taxes', domain=[('parent', '=', False)],
states={
'invisible': "type != 'line'",
})
invoice_lines = fields.Many2Many('account.invoice.line',
'purchase_line_invoice_lines_rel', 'purchase_line', 'invoice_line',
'Invoice Lines', readonly=True)
moves = fields.One2Many('stock.move', 'purchase_line', 'Moves',
readonly=True)
moves_ignored = fields.Many2Many('stock.move', 'purchase_line_moves_ignored_rel',
'purchase_line', 'move', 'Moves Ignored', readonly=True)
move_done = fields.Function('get_move_done', type='boolean',
string='Moves Done')
move_exception = fields.Function('get_move_exception', type='boolean',
string='Moves Exception')
def __init__(self):
super(PurchaseLine, self).__init__()
self._order.insert(0, ('sequence', 'ASC'))
def default_type(self, cursor, user, context=None):
return 'line'
def default_quantity(self, cursor, user, context=None):
return 0.0
def default_unit_price(self, cursor, user, context=None):
return Decimal('0.0')
def get_move_done(self, cursor, user, ids, name, args, context=None):
uom_obj = self.pool.get('product.uom')
res = {}
for line in self.browse(cursor, user, ids, context=context):
val = True
if line.product.type == 'service':
res[line.id] = True
continue
ignored_ids = [x.id for x in line.moves_ignored]
quantity = line.quantity
for move in line.moves:
if move.state != 'done' \
and move.id not in ignored_ids:
val = False
break
quantity -= uom_obj.compute_qty(cursor, user, move.uom,
move.quantity, line.unit)
if val:
if quantity > 0.0:
val = False
res[line.id] = val
return res
def get_move_exception(self, cursor, user, ids, name, args, context=None):
res = {}
for line in self.browse(cursor, user, ids, context=context):
val = False
ignored_ids = [x.id for x in line.moves_ignored]
for move in line.moves:
if move.state == 'cancel' \
and move.id not in ignored_ids:
val = True
break
res[line.id] = val
return res
def on_change_product(self, cursor, user, ids, vals, context=None):
party_obj = self.pool.get('relationship.party')
product_obj = self.pool.get('product.product')
uom_obj = self.pool.get('product.uom')
if context is None:
context = {}
if not vals.get('product'):
return {}
res = {}
ctx = context.copy()
party = None
if vals.get('parent.party'):
party = party_obj.browse(cursor, user, vals['parent.party'],
context=context)
if party.lang:
ctx['language'] = party.lang.code
product = product_obj.browse(cursor, user, vals['product'],
context=context)
ctx2 = context.copy()
if vals.get('parent.currency'):
ctx2['currency'] = vals['parent.currency']
if vals.get('parent.party'):
ctx2['supplier'] = vals['parent.party']
if vals.get('unit'):
ctx2['uom'] = vals['unit']
res['unit_price'] = product_obj.get_purchase_price(cursor, user,
[product.id], vals.get('quantity', 0), context=ctx2)[product.id]
res['taxes'] = []
for tax in product.supplier_taxes:
if party:
if party.get(tax.group.code):
res['taxes'].append(party.get(tax.group.code).id)
continue
res['taxes'].append(tax.id)
if not vals.get('description'):
res['description'] = product_obj.name_get(cursor, user, product.id,
context=ctx)[0][1]
category = product.default_uom.category
if not vals.get('unit') \
or vals.get('unit') not in [x.id for x in category.uoms]:
res['unit'] = uom_obj.name_get(cursor, user, product.default_uom.id,
context=context)[0]
return res
def get_amount(self, cursor, user, ids, name, arg, context=None):
currency_obj = self.pool.get('currency.currency')
res = {}
for line in self.browse(cursor, user, ids, context=context):
if line.type == 'line':
res[line.id] = currency_obj.round(cursor, user,
line.purchase.currency,
Decimal(str(line.quantity)) * line.unit_price)
elif line.type == 'subtotal':
res[line.id] = Decimal('0.0')
for line2 in line.purchase.lines:
if line2.type == 'line':
res[line.id] += currency_obj.round(cursor, user,
line2.purchase.currency,
Decimal(str(line2.quantity)) * line2.unit_price)
elif line2.type == 'subtotal':
if line.id == line2.id:
break
res[line.id] = Decimal('0.0')
else:
res[line.id] = Decimal('0.0')
return res
def get_invoice_line(self, cursor, user, line, context=None):
'''
Return invoice line values for purchase line
'''
uom_obj = self.pool.get('product.uom')
res = {}
res['sequence'] = line.sequence
res['type'] = line.type
res['description'] = line.description
if line.type != 'line':
return res
if line.purchase.invoice_method == 'order':
res['quantity'] = line.quantity
else:
quantity = 0.0
for move in line.moves:
if move.state == 'done':
quantity += uom_obj.compute_qty(cursor, user, move.uom,
move.quantity, line.unit)
for invoice_line in line.invoice_lines:
quantity -= uom_obj.compute_qty(cursor, user,
invoice_line.unit, invoice_line.quantity, line.unit)
res['quantity'] = quantity
if res['quantity'] <= 0.0:
return None
res['unit'] = line.unit.id
res['product'] = line.product.id
res['unit_price'] = line.unit_price
res['taxes'] = [('set', [x.id for x in line.taxes])]
res['account'] = line.product.account_expense_used.id
return res
def copy(self, cursor, user, line_id, default=None, context=None):
if default is None:
default = {}
default = default.copy()
default['moves'] = False
default['moves_ignored'] = False
default['invoice_lines'] = False
return super(PurchaseLine, self).copy(cursor, user, line_id,
default=default, context=context)
def create_move(self, cursor, user, line, context=None):
'''
Create move line
'''
move_obj = self.pool.get('stock.move')
uom_obj = self.pool.get('product.uom')
vals = {}
if line.type != 'line':
return
if line.product.type == 'service':
return
quantity = line.quantity
for move in line.moves:
quantity -= uom_obj.compute_qty(cursor, user, move.uom,
move.quantity, line.unit)
if quantity <= 0.0:
return
vals['quantity'] = quantity
vals['uom'] = line.unit
vals['product'] = line.product.id
vals['from_location'] = line.purchase.party.supplier_location.id
vals['to_location'] = line.purchase.warehouse.input_location.id
vals['state'] = 'waiting'
vals['company'] = line.purchase.company.id
vals['unit_price'] = line.unit_price
vals['currency'] = line.purchase.currency.id
move_id = move_obj.create(cursor, user, vals, context=context)
self.write(cursor, user, line.id, {
'moves': [('add', move_id)],
}, context=context)
return move_id
def ignore_move_exception(self, cursor, user, line, context=None):
move_ids = []
for move in line.moves:
if move.state == 'cancel':
move_ids.append(move.id)
if move_ids:
self.write(cursor, user, line.id, {
'moves_ignored': [('add', x) for x in move_ids],
}, context=context)
PurchaseLine()
class PurchaseReport(CompanyReport):
_name = 'purchase.purchase'
PurchaseReport()
class Template(OSV):
_name = "product.template"
purchasable = fields.Boolean('Purchasable')
product_suppliers = fields.One2Many('purchase.product_supplier',
'product', 'Suppliers', states={
'invisible': "not purchasable",
})
def default_purchasable(self, cursor, user, context=None):
return True
Template()
class Product(OSV):
_name = 'product.product'
def get_purchase_price(self, cursor, user, ids, quantity=0, context=None):
'''
Return price for product ids.
context can have :
- uom
- supplier
- currency
'''
uom_obj = self.pool.get('product.uom')
user_obj = self.pool.get('res.user')
currency_obj = self.pool.get('currency.currency')
res = {}
for product in self.browse(cursor, user, ids, context=context):
res[product.id] = product.cost_price
if context.get('supplier') and product.product_suppliers:
supplier_id = context['supplier']
for product_supplier in product.product_suppliers:
if product_supplier.party.id == supplier_id:
for price in product_supplier.prices:
if price.quantity <= quantity:
res[product.id] = price.price
break
if context.get('uom'):
uom = uom_obj.browse(cursor, user, context['uom'],
context=context)
res[product.id] = uom_obj.compute_price(cursor,
user, product.default_uom, res[product.id],
uom)
if context.get('currency'):
currency = currency_obj.browse(cursor, user,
context['currency'], context=context)
user2 = user_obj.browse(cursor, user, user, context=context)
if user2.company.currency.id != currency.id:
res[product.id] = currency_obj.compute(cursor, user,
user2.company.currency, res[product.id],
currency, context=context)
return res
Product()
class ProductSupplier(OSV):
'Product Supplier'
_name = 'purchase.product_supplier'
_description = __doc__
product = fields.Many2One('product.template', 'Product', required=True,
ondelete='CASCADE', select=1)
party = fields.Many2One('relationship.party', 'Supplier', required=True,
ondelete='CASCADE', select=1)
name = fields.Char('Name', size=None, translate=True, select=1)
code = fields.Char('Code', size=None, select=1)
sequence = fields.Integer('Sequence')
prices = fields.One2Many('purchase.product_supplier.price',
'product_supplier', 'Prices')
company = fields.Many2One('company.company', 'Company', required=True,
ondelete='CASCADE', select=1)
def __init__(self):
super(ProductSupplier, self).__init__()
self._order.insert(0, ('sequence', 'ASC'))
def default_company(self, cursor, user, context=None):
company_obj = self.pool.get('company.company')
if context is None:
context = {}
if context.get('company'):
return company_obj.name_get(cursor, user, context['company'],
context=context)[0]
return False
ProductSupplier()
class ProductSupplierPrice(OSV):
'Product Supplier Price'
_name = 'purchase.product_supplier.price'
product_supplier = fields.Many2One('purchase.product_supplier',
'Supplier', required=True, ondelete='CASCADE')
quantity = fields.Float('Quantity', required=True, help='Minimal quantity')
price = fields.Numeric('Price', required=True, digits=(16, 4))
def __init__(self):
super(ProductSupplierPrice, self).__init__()
self._order.insert(0, ('quantity', 'ASC'))
def default_currency(self, cursor, user, context=None):
company_obj = self.pool.get('company.company')
currency_obj = self.pool.get('currency.currency')
if context is None:
context = {}
company = None
if context.get('company'):
company = company_obj.browse(cursor, user, context['company'],
context=context)
return currency_obj.name_get(cursor, user, company.currency.id,
context=context)[0]
return False
ProductSupplierPrice()
class PackingIn(OSV):
_name = 'stock.packing.in'
def write(self, cursor, user, ids, vals, context=None):
workflow_service = LocalService('workflow')
purchase_line_obj = self.pool.get('purchase.line')
res = super(PackingIn, self).write(cursor, user, ids, vals,
context=context)
if 'state' in vals and vals['state'] in ('received', 'cancel'):
purchase_ids = []
move_ids = []
if isinstance(ids, (int, long)):
ids = [ids]
for packing in self.browse(cursor, user, ids, context=context):
move_ids.extend([x.id for x in packing.incoming_moves])
purchase_line_ids = purchase_line_obj.search(cursor, user, [
('moves', 'in', move_ids),
], context=context)
if purchase_line_ids:
for purchase_line in purchase_line_obj.browse(cursor, user,
purchase_line_ids, context=context):
if purchase_line.purchase.id not in purchase_ids:
purchase_ids.append(purchase_line.purchase.id)
for purchase_id in purchase_ids:
workflow_service.trg_validate(user, 'purchase.purchase',
purchase_id, 'packing_update', cursor)
return res
PackingIn()
class Move(OSV):
_name = 'stock.move'
purchase_line = fields.Many2One('purchase.line', select=1,
states={
'readonly': "state != 'draft'",
})
purchase = fields.Function('get_purchase', type='many2one',
relation='purchase.purchase', string='Purchase',
fnct_search='search_purchase', select=1)
def get_purchase(self, cursor, user, ids, name, arg, context=None):
purchase_obj = self.pool.get('purchase.purchase')
res = {}
for move in self.browse(cursor, user, ids, context=context):
res[move.id] = False
if move.purchase_line:
res[move.id] = move.purchase_line.purchase.id
purchase_names = {}
for purchase_id, purchase_name in purchase_obj.name_get(cursor,
user, [x for x in res.values() if x], context=context):
purchase_names[purchase_id] = purchase_name
for i in res.keys():
if res[i] and res[i] in purchase_names:
res[i] = (res[i], purchase_names[res[i]])
else:
res[i] = False
return res
def search_purchase(self, cursor, user, name, args, context=None):
args2 = []
i = 0
while i < len(args):
field = args[i][0]
args2.append(('purchase_line.' + field, args[i][1], args[i][2]))
i += 1
return args2
def write(self, cursor, user, ids, vals, context=None):
workflow_service = LocalService('workflow')
purchase_line_obj = self.pool.get('purchase.line')
res = super(Move, self).write(cursor, user, ids, vals,
context=context)
if 'state' in vals and vals['state'] in ('cancel',):
purchase_ids = []
purchase_line_ids = purchase_line_obj.search(cursor, user, [
('moves', 'in', ids),
], context=context)
if purchase_line_ids:
for purchase_line in purchase_line_obj.browse(cursor, user,
purchase_line_ids, context=context):
if purchase_line.purchase.id not in purchase_ids:
purchase_ids.append(purchase_line.purchase.id)
for purchase_id in purchase_ids:
workflow_service.trg_validate(user, 'purchase.purchase',
purchase_id, 'packing_update', cursor)
return res
Move()