Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # This file is part of Tryton. The COPYRIGHT file at the top level of
- # this repository contains the full copyright notices and license terms.
- import datetime
- from decimal import Decimal
- from itertools import product, groupby
- from trytond.pool import Pool, PoolMeta
- from trytond.pyson import Eval, Bool, If
- from trytond.model import Workflow, ModelView, fields, ModelSQL, \
- sequence_ordered
- from trytond.wizard import Wizard, StateView, StateTransition, Button
- from trytond.transaction import Transaction
- from trytond.modules.product import price_digits
- __all__ = ['Configuration', 'Group', 'PurchaseRequestQuotation',
- 'CreatePurchaseRequestQuotationAskSuppliers', 'PurchaseRequest',
- 'CreatePurchaseRequestQuotation']
- STATES = [
- ('draft', 'Draft'),
- ('sent', 'Sent'),
- ('rejected', 'Rejected'),
- ('answered', 'Answered'),
- ('cancel', 'Canceled'),
- ]
- class Configuration:
- __metaclass__ = PoolMeta
- __name__ = 'purchase.configuration'
- purchase_request_quotation_group_sequence = fields.Property(
- fields.Many2One(
- 'ir.sequence', 'Purchase Request Quotation Group Sequence',
- domain=[
- ('company', 'in',
- [Eval('context', {}).get('company', -1), None]),
- ('code', '=', 'purchase.request.quotation.group'),
- ],
- required=True))
- class Group(Workflow, ModelSQL, ModelView):
- "Purchase Request For Quotation Group"
- __name__ = 'purchase.request.quotation.group'
- _rec_name = 'number'
- number = fields.Char('Number', required=True, readonly=True)
- company = fields.Many2One('company.company', 'Company', required=True,
- readonly=True, select=True, domain=[
- ('id', If(Eval('context', {}).contains('company'), '=', '!='),
- Eval('context', {}).get('company', -1)),
- ])
- supplier = fields.Many2One('party.party', 'Supplier', required=True,
- readonly=True, select=True)
- request_quotations = fields.One2Many('purchase.request.quotation', 'group',
- 'Purchase Request For Quotation', readonly=True)
- state = fields.Selection(STATES, 'State', readonly=True, required=True)
- @classmethod
- def __setup__(cls):
- super(Group, cls).__setup__()
- cls._transitions |= set((
- ('draft', 'cancel'),
- ('cancel', 'draft'),
- ('draft', 'sent'),
- ('sent', 'rejected'),
- ('sent', 'answered'),
- ('answered', 'rejected'),
- ('rejected', 'answered'),
- ))
- cls._buttons.update({
- 'cancel': {
- 'invisible': Eval('state') != 'draft',
- },
- 'send': {
- 'invisible': Eval('state') != 'draft',
- },
- 'answer': {
- 'invisible': ~Eval('state').in_(
- ['sent', 'rejected']),
- },
- 'reject': {
- 'invisible': ~Eval('state').in_(
- ['sent', 'answered']),
- },
- })
- @staticmethod
- def default_company():
- return Transaction().context.get('company')
- @staticmethod
- def default_state():
- return 'draft'
- @classmethod
- def create(cls, vlist):
- pool = Pool()
- Sequence = pool.get('ir.sequence')
- Config = pool.get('purchase.configuration')
- config = Config(1)
- vlist = [v.copy() for v in vlist]
- for values in vlist:
- if values.get('number') is None:
- values['number'] = Sequence.get_id(
- config.purchase_request_quotation_group_sequence.id)
- return super(Group, cls).create(vlist)
- @classmethod
- def copy(cls, groups, default=None):
- if default is None:
- default = {}
- else:
- default = default.copy()
- default.setdefault('request_quotations', None)
- return super(Group, cls).copy(groups, default=default)
- @classmethod
- @ModelView.button
- @Workflow.transition('cancel')
- def cancel(cls, quotations):
- pass
- @classmethod
- @Workflow.transition('draft')
- def draft(cls, quotations):
- pass
- @classmethod
- @ModelView.button
- @Workflow.transition('send')
- def send(cls, quotations):
- pass
- @classmethod
- @ModelView.button
- @Workflow.transition('answer')
- def answer(cls, quotations):
- pass
- @classmethod
- @ModelView.button
- @Workflow.transition('reject')
- def reject(cls, quotations):
- pass
- class PurchaseRequestQuotation(
- sequence_ordered(), ModelSQL, ModelView):
- "Purchase Request For Quotation"
- __name__ = 'purchase.request.quotation'
- company = fields.Many2One('company.company', 'Company', required=True,
- readonly=True,
- domain=[
- ('id', If(Eval('context', {}).contains('company'), '=', '!='),
- Eval('context', {}).get('company', -1)),
- ], select=True)
- supplier = fields.Many2One('party.party', 'Supplier', required=True,
- readonly=True, select=True)
- supply_date = fields.Date('Expected Supply Date')
- product = fields.Function(fields.Many2One('product.product', 'Product'),
- 'get_product', searcher='search_product')
- description = fields.Text('Description',
- states={
- 'required': ~Eval('product')
- },
- depends=['product'])
- quantity = fields.Float(
- 'Quantity', digits=(16, Eval('unit_digits', 2)), required=True,
- depends=['unit_digits'])
- unit = fields.Many2One(
- 'product.uom', 'Unit', ondelete='RESTRICT',
- states={
- 'required': Bool(Eval('product')),
- },
- domain=[
- If(Bool(Eval('product_uom_category')),
- ('category', '=', Eval('product_uom_category')),
- ('category', '!=', -1)),
- ],
- depends=['product', 'product_uom_category'])
- unit_digits = fields.Function(
- fields.Integer('Unit Digits'), 'on_change_with_unit_digits')
- product_uom_category = fields.Function(
- fields.Many2One('product.uom.category', 'Product Uom Category'),
- 'on_change_with_product_uom_category')
- unit_price = fields.Numeric('Unit Price', digits=price_digits)
- currency = fields.Many2One('currency.currency', 'Currency')
- currency_digits = fields.Function(
- fields.Integer('Currency Digits'), 'on_change_with_currency_digits')
- amount = fields.Function(
- fields.Numeric('Amount',
- digits=(16, Eval('currency_digits', 2)),
- depends=['currency_digits']), 'on_change_with_amount')
- request = fields.Many2One('purchase.request', 'Request',
- ondelete='CASCADE', select=True, required=True)
- group = fields.Many2One('purchase.request.quotation.group', 'Group',
- readonly=True,
- ondelete='RESTRICT',
- domain=[
- ('company', '=', Eval('company', -1)),
- ],
- depends=['company'])
- group_state = fields.Function(
- fields.Selection(STATES, 'Request for Quotation Group State'),
- 'on_change_with_group_state')
- @fields.depends('group', '_parent_group.state')
- def on_change_with_group_state(self, name=None):
- if self.group:
- return self.group.state
- @fields.depends('quantity', 'unit_price', 'unit', 'currency')
- def on_change_with_amount(self, name=None):
- if (self.unit_price is None) or (self.quantity is None):
- return None
- amount = Decimal(str(self.quantity)) * self.unit_price
- if self.currency:
- amount = self.currency.round(amount)
- return amount
- @fields.depends('product')
- def on_change_with_product_uom_category(self, name=None):
- if self.product:
- return self.product.default_uom_category.id
- @fields.depends('unit')
- def on_change_with_unit_digits(self, name=None):
- if self.unit:
- return self.unit.digits
- return 2
- @fields.depends('currency')
- def on_change_with_currency_digits(self, name=None):
- if self.currency:
- return self.currency.digits
- return 2
- def get_product(self, name):
- if self.request and self.request.product:
- return self.request.product.id
- @classmethod
- def search_product(cls, name, clause):
- return [('request.product',) + tuple(clause[1:])]
- class CreatePurchaseRequestQuotationAskSuppliers(ModelView):
- 'Create Purchase Request Quotation Ask Suppliers'
- __name__ = 'purchase.request.create_quotation.ask_suppliers'
- requests = fields.Many2Many('purchase.request', None, None, 'Requests',
- required=True, readonly=True)
- suppliers = fields.Many2Many('party.party', None, None, 'Suppliers',
- required=True)
- class CreatePurchaseRequestQuotation(Wizard):
- 'Create Purchase Request Quotation'
- __name__ = 'purchase.request.create_quotation'
- start_state = 'ask_suppliers'
- ask_suppliers = StateView(
- 'purchase.request.create_quotation.ask_suppliers',
- 'purchase_request_quotation.' +
- 'purchase_request_create_quotation_ask_suppliers', [
- Button('Cancel', 'end', 'tryton-cancel'),
- Button('Continue', 'start', 'tryton-go-next', default=True),
- ])
- start = StateTransition()
- @classmethod
- def __setup__(cls):
- super(CreatePurchaseRequestQuotation, cls).__setup__()
- cls._error_messages.update({
- 'previous_quotation': ('You already made a quotation with '
- 'one of the selected requests: "%(requests)s".'),
- })
- def default_ask_suppliers(self, fields):
- pool = Pool()
- suppliers = []
- request_quotation_state = []
- Request = pool.get('purchase.request')
- request_ids = Transaction().context['active_ids']
- requests = Request.search([
- ('id', 'in', request_ids),
- ('state', 'in', ['draft', 'quotation']),
- ])
- for request in requests:
- if request.state == 'quotation':
- request_quotation_state.append(request)
- if request.party:
- suppliers.append(request.party.id)
- if request_quotation_state:
- self.raise_user_warning('warning', 'previous_quotation', {
- 'requests': ', '.join(r.rec_name
- for r in request_quotation_state),
- })
- return {
- 'requests': [r.id for r in requests],
- 'suppliers': suppliers,
- }
- def transition_start(self):
- pool = Pool()
- Request = pool.get('purchase.request')
- Quotation = pool.get('purchase.request.quotation')
- new_quotations = []
- request_ids = Transaction().context['active_ids']
- requests = Request.search([
- ('id', 'in', request_ids),
- ('state', 'in', ['draft', 'quotation']),
- ])
- for request in requests:
- new_quotations.append({
- 'company': request.company,
- 'request': request,
- 'description': request.description,
- 'quantity': request.quantity,
- 'unit': request.uom,
- 'currency': request.currency,
- 'supply_date': (
- request.supply_date or datetime.date.max),
- })
- suppliers = []
- for supplier in getattr(self.ask_suppliers, 'suppliers', []):
- suppliers.append({
- 'supplier': supplier,
- })
- if suppliers:
- quotation_lines = []
- '''
- Cartesian product between purchase_requests and suppliers
- '''
- for (nq, s) in product(new_quotations, suppliers):
- merged_dict = {}
- merged_dict.update(nq)
- merged_dict.update(s)
- quotation = Quotation()
- for f, v in merged_dict.iteritems():
- setattr(quotation, f, v)
- quotation_lines.append(quotation)
- Quotation.save(quotation_lines)
- quotations = sorted(quotation_lines,
- key=self._group_purchase_request_quotation_key)
- for key, grouped_quotations in groupby(quotations,
- key=self._group_purchase_request_quotation_key):
- group = self._new_group(dict(key))
- grouped_quotations = list(grouped_quotations)
- group.save()
- Quotation.write(grouped_quotations, {'group': group.id})
- return 'end'
- def _group_purchase_request_quotation_key(self, quotation):
- return (
- ('company', quotation.company),
- ('supplier', quotation.supplier),
- )
- def _new_group(self, values):
- pool = Pool()
- Group = pool.get('purchase.request.quotation.group')
- return Group(**values)
- class PurchaseRequest:
- __metaclass__ = PoolMeta
- __name__ = 'purchase.request'
- quotations = fields.One2Many('purchase.request.quotation',
- 'request', 'Quotations', readonly=True)
- @classmethod
- def __setup__(cls):
- super(PurchaseRequest, cls).__setup__()
- selection = ('quotation', 'Quotation')
- if selection not in cls.state.selection:
- cls.state.selection.append(selection)
- def get_state(self, name):
- state = super(PurchaseRequest, self).get_state(name)
- if state == 'draft' and self.quotations:
- state = 'quotation'
- return state
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement