Initial commit of purchase module
This commit is contained in:
+27
@@ -0,0 +1,27 @@
|
||||
# Copyright (c) 2004-2006 Tiny SPRL. (http://tiny.be)
|
||||
# Copyright (c) 2007-2008 Cedric Krier.
|
||||
#
|
||||
# WARNING: This program as such is intended to be used by professional
|
||||
# programmers who take the whole responsability of assessing all potential
|
||||
# consequences resulting from its eventual inadequacies and bugs
|
||||
# End users who are looking for a ready-to-use solution with commercial
|
||||
# garantees and support are strongly adviced to contact a Free Software
|
||||
# Service Company
|
||||
#
|
||||
# This program is Free Software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
from purchase import *
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
'name': 'Purchase',
|
||||
'version': '0.1',
|
||||
'author': 'B2CK',
|
||||
'email': 'info@b2ck.com',
|
||||
'website': 'http://www.tryton.org/',
|
||||
'category': 'Generic Modules',
|
||||
'description': 'Purchase Management',
|
||||
'depends': [
|
||||
'company',
|
||||
'partner',
|
||||
'stock',
|
||||
'account',
|
||||
'product',
|
||||
'account_invoice',
|
||||
'workflow',
|
||||
'res',
|
||||
'ir',
|
||||
],
|
||||
'xml': [
|
||||
'purchase.xml',
|
||||
],
|
||||
}
|
||||
+866
@@ -0,0 +1,866 @@
|
||||
"Purchase"
|
||||
|
||||
from trytond.osv import fields, OSV
|
||||
from decimal import Decimal
|
||||
import datetime
|
||||
from trytond.netsvc import LocalService
|
||||
|
||||
_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)
|
||||
partner = fields.Many2One('partner.partner', 'Partner', change_default=True,
|
||||
required=True, states=_STATES, on_change=['partner', 'payment_term'])
|
||||
contact_address = fields.Many2One('partner.address', 'Contact Address',
|
||||
domain="[('partner', '=', partner)]", states=_STATES)
|
||||
invoice_address = fields.Many2One('partner.address', 'Invoice Address',
|
||||
domain="[('partner', '=', partner)]", states=_STATES)
|
||||
warehouse = fields.Many2One('stock.location', 'Warehouse',
|
||||
domain=[('type', '=', 'warehouse')], required=True, states=_STATES)
|
||||
currency = fields.Many2One('account.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('account.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_partner(self, cursor, user, ids, vals, context=None):
|
||||
partner_obj = self.pool.get('partner.partner')
|
||||
address_obj = self.pool.get('partner.address')
|
||||
payment_term_obj = self.pool.get('account.invoice.payment_term')
|
||||
res = {
|
||||
'invoice_address': False,
|
||||
'contact_address': False,
|
||||
'payment_term': False,
|
||||
}
|
||||
if vals.get('partner'):
|
||||
partner = partner_obj.browse(cursor, user, vals['partner'],
|
||||
context=context)
|
||||
res['contact_address'] = partner_obj.address_get(cursor, user,
|
||||
partner.id, type=None, context=context)
|
||||
res['invoice_address'] = partner_obj.address_get(cursor, user,
|
||||
partner.id, type='invoice', context=context)
|
||||
if partner.payment_term:
|
||||
res['payment_term'] = partner.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('account.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.partner.lang:
|
||||
res['language'] = purchase.partner.lang.code
|
||||
return res
|
||||
|
||||
def get_tax_amount(self, cursor, user, ids, name, arg, context=None):
|
||||
currency_obj = self.pool.get('account.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('account.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.incoming_packing_in:
|
||||
if move.incoming_packing_in.id not in res[purchase.id]:
|
||||
res[purchase.id].append(move.incoming_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 '/' + ' ' \
|
||||
+ purchase.partner.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, [('partner', 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,
|
||||
'partner': purchase.partner.id,
|
||||
'contact_address': purchase.contact_address.id,
|
||||
'invoice_address': purchase.invoice_address.id,
|
||||
'currency': purchase.currency.id,
|
||||
'account': purchase.partner.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.partner', '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.Many2Many('stock.move', 'purchase_line_moves_rel',
|
||||
'purchase_line', 'move', '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
|
||||
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):
|
||||
partner_obj = self.pool.get('partner.partner')
|
||||
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()
|
||||
partner = None
|
||||
if vals.get('parent.partner'):
|
||||
partner = partner_obj.browse(cursor, user, vals['parent.partner'],
|
||||
context=context)
|
||||
if partner.lang:
|
||||
ctx['language'] = partner.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.partner'):
|
||||
ctx2['supplier'] = vals['parent.partner']
|
||||
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 partner:
|
||||
if partner.get(tax.group.code):
|
||||
res['taxes'].append(partner.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('account.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
|
||||
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.partner.supplier_location.id
|
||||
vals['to_location'] = line.purchase.warehouse.input_location.id
|
||||
vals['state'] = 'waiting'
|
||||
|
||||
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 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('account.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.partner.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)
|
||||
partner = fields.Many2One('partner.partner', 'Partner', 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('account.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'
|
||||
|
||||
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()
|
||||
+647
@@ -0,0 +1,647 @@
|
||||
<?xml version="1.0"?>
|
||||
<tryton>
|
||||
<data>
|
||||
<menuitem name="Purchase" id="menu_purchase" sequence="4"/>
|
||||
<record model="res.group" id="group_purchase">
|
||||
<field name="name">Purchase</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="purchase_view_form">
|
||||
<field name="model">purchase.purchase</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Purchase" col="6">
|
||||
<label name="partner"/>
|
||||
<field name="partner"/>
|
||||
<label name="contact_address"/>
|
||||
<field name="contact_address"/>
|
||||
<label name="invoice_address"/>
|
||||
<field name="invoice_address"/>
|
||||
<label name="description"/>
|
||||
<field name="description" colspan="3"/>
|
||||
<label name="reference"/>
|
||||
<field name="reference"/>
|
||||
<notebook colspan="6">
|
||||
<page string="Purchase">
|
||||
<label name="purchase_date"/>
|
||||
<field name="purchase_date"/>
|
||||
<label name="payment_term"/>
|
||||
<field name="payment_term"/>
|
||||
<label name="warehouse"/>
|
||||
<field name="warehouse"/>
|
||||
<label name="currency"/>
|
||||
<field name="currency"/>
|
||||
<field name="lines" colspan="4">
|
||||
<tree string="Lines" sequence="sequence">
|
||||
<field name="type"/>
|
||||
<field name="product"/>
|
||||
<field name="description"/>
|
||||
<field name="quantity"/>
|
||||
<field name="unit"/>
|
||||
<field name="unit_price"/>
|
||||
<field name="taxes"/>
|
||||
<field name="amount"/>
|
||||
<field name="sequence" tree_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
<group col="2" colspan="2">
|
||||
<label name="invoice_state"/>
|
||||
<field name="invoice_state"/>
|
||||
<label name="packing_state"/>
|
||||
<field name="packing_state"/>
|
||||
</group>
|
||||
<group col="4" colspan="2">
|
||||
<label colspan="2"/>
|
||||
<label name="untaxed_amount"/>
|
||||
<field name="untaxed_amount"/>
|
||||
<label colspan="2"/>
|
||||
<label name="tax_amount"/>
|
||||
<field name="tax_amount"/>
|
||||
<button name="button_compute" string="Compute"
|
||||
type="object" colspan="2"
|
||||
states="{'readonly': '''state != 'draft' '''}"/>
|
||||
<label name="total_amount"/>
|
||||
<field name="total_amount"/>
|
||||
<label colspan="2"/>
|
||||
<label name="state"/>
|
||||
<field name="state"/>
|
||||
<group col="6" colspan="4">
|
||||
<button name="quotation" string="Quotation"
|
||||
states="{'invisible': '''state != 'draft' '''}"/>
|
||||
<button name="draft" string="Draft"
|
||||
states="{'invisible': '''state != 'quotation' '''}"/>
|
||||
<button name="confirm" string="Confirm"
|
||||
states="{'invisible': '''state != 'quotation' '''}"/>
|
||||
<button name="cancel" string="Cancel"
|
||||
states="{'invisible': '''not ((state in ('draft', 'quotation')) or (invoice_state != 'exception') or (packing_state != 'exception')) '''}"/>
|
||||
<button name="invoice_ok" string="Ignore Invoice Exception"
|
||||
states="{'invisible': '''invoice_state != 'exception' or state == 'cancel' '''}"/>
|
||||
<button name="packing_ok" string="Ignore Packing Exception"
|
||||
states="{'invisible': '''packing_state != 'exception' or state == 'cancel' '''}"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Other Info">
|
||||
<label name="company"/>
|
||||
<field name="company"/>
|
||||
<label name="invoice_method"/>
|
||||
<field name="invoice_method"/>
|
||||
<separator name="comment" colspan="4"/>
|
||||
<field name="comment" colspan="4"/>
|
||||
</page>
|
||||
<page string="Invoices">
|
||||
<field name="invoices" colspan="4"/>
|
||||
</page>
|
||||
<page string="Packings">
|
||||
<field name="moves" colspan="4"/>
|
||||
<field name="packings" colspan="4"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="purchase_view_tree">
|
||||
<field name="model">purchase.purchase</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Purchases">
|
||||
<field name="reference" select="1"/>
|
||||
<field name="purchase_date" select="1"/>
|
||||
<field name="partner" select="1"/>
|
||||
<field name="warehouse"/>
|
||||
<field name="currency" select="2"/>
|
||||
<field name="untaxed_amount" select="2"/>
|
||||
<field name="total_amount" select="2"/>
|
||||
<field name="state" select="1"/>
|
||||
<field name="invoice_state" select="2"/>
|
||||
<field name="packing_state" select="2"/>
|
||||
<field name="description" select="2"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.action.act_window" id="act_purchase_form">
|
||||
<field name="name">Purchases</field>
|
||||
<field name="res_model">purchase.purchase</field>
|
||||
<field name="view_type">form</field>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_purchase_form_view1">
|
||||
<field name="sequence" eval="10"/>
|
||||
<field name="view" ref="purchase_view_tree"/>
|
||||
<field name="act_window" ref="act_purchase_form"/>
|
||||
</record>
|
||||
<record model="ir.action.act_window.view" id="act_purchase_form_view2">
|
||||
<field name="sequence" eval="20"/>
|
||||
<field name="view" ref="purchase_view_form"/>
|
||||
<field name="act_window" ref="act_purchase_form"/>
|
||||
</record>
|
||||
<menuitem parent="menu_purchase" action="act_purchase_form"
|
||||
id="menu_purchase_form"/>
|
||||
|
||||
<record model="ir.model.access" id="access_purchase">
|
||||
<field name="model" search="[('model', '=', 'purchase.purchase')]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_purchase_purchase">
|
||||
<field name="model" search="[('model', '=', 'purchase.purchase')]"/>
|
||||
<field name="group" ref="group_purchase"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.sequence.type" id="sequence_type_purchase">
|
||||
<field name="name">Purchase</field>
|
||||
<field name="code">purchase.purchase</field>
|
||||
</record>
|
||||
<record model="ir.sequence" id="sequence_purchase">
|
||||
<field name="name">Purchase</field>
|
||||
<field name="code">purchase.purchase</field>
|
||||
</record>
|
||||
<record model="workflow" id="purchase_workflow">
|
||||
<field name="name">Purchase workflow</field>
|
||||
<field name="osv">purchase.purchase</field>
|
||||
<field name="on_create" eval="True"/>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_draft">
|
||||
<field name="name">Draft</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'state': 'draft'})</field>
|
||||
<field name="flow_start" eval="True"/>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_quotation">
|
||||
<field name="name">Quotation</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">set_reference() write({'state': 'quotation'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_confirmed">
|
||||
<field name="name">Confirmed</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="split_mode">AND</field>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'state': 'confirmed'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_method">
|
||||
<field name="name">Invoice Method</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="split_mode">OR</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_purchase">
|
||||
<field name="name">Invoice</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">create_invoice()</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_waiting_invoice_purchase">
|
||||
<field name="name">Waiting Invoice</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'invoice_state': 'waiting'}) ignore_invoice_exception()</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_purchase_exception">
|
||||
<field name="name">Invoice Exception</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'invoice_state': 'exception'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_done">
|
||||
<field name="name">Invoice Done</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'invoice_state': 'paid'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_method_done">
|
||||
<field name="name">Invoice Method Done</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_packing">
|
||||
<field name="name">Packing</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">create_move()</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_waiting_packing">
|
||||
<field name="name">Waiting Packing</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'packing_state': 'waiting'}) ignore_packing_exception() create_move()</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_packing_exception">
|
||||
<field name="name">Packing Exception</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'packing_state': 'exception'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_packing_method">
|
||||
<field name="name">Invoice Packing Method</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="split_mode">OR</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_packing">
|
||||
<field name="name">Invoice Packing</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">create_invoice() write({'invoice_state': 'waiting'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_waiting_invoice_packing">
|
||||
<field name="name">Waiting Invoice Packing</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'invoice_state': 'waiting', 'packing_state': 'received'}) ignore_invoice_exception()</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_packing_exception">
|
||||
<field name="name">Invoice Packing Exception</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="action">write({'invoice_state': 'exception'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_packing_done">
|
||||
<field name="name">Invoice Packing Done</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'invoice_state': 'paid'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_invoice_packing_method_done">
|
||||
<field name="name">Invoice Packing Method Done</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'packing_state': 'received'})</field>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_done">
|
||||
<field name="name">Done</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="join_mode">AND</field>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'state': 'done'})</field>
|
||||
<field name="flow_stop" eval="True"/>
|
||||
</record>
|
||||
<record model="workflow.activity" id="purchase_activity_cancel">
|
||||
<field name="name">Cancel</field>
|
||||
<field name="workflow" ref="purchase_workflow"/>
|
||||
<field name="kind">function</field>
|
||||
<field name="action">write({'state': 'cancel'})</field>
|
||||
<field name="flow_stop" eval="True"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_draft_quotation">
|
||||
<field name="act_from" ref="purchase_activity_draft"/>
|
||||
<field name="act_to" ref="purchase_activity_quotation"/>
|
||||
<field name="signal">quotation</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_draft_cancel">
|
||||
<field name="act_from" ref="purchase_activity_draft"/>
|
||||
<field name="act_to" ref="purchase_activity_cancel"/>
|
||||
<field name="signal">cancel</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_quotation_draft">
|
||||
<field name="act_from" ref="purchase_activity_quotation"/>
|
||||
<field name="act_to" ref="purchase_activity_draft"/>
|
||||
<field name="signal">draft</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_quotation_confirmed">
|
||||
<field name="act_from" ref="purchase_activity_quotation"/>
|
||||
<field name="act_to" ref="purchase_activity_confirmed"/>
|
||||
<field name="signal">confirm</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_quotation_cancel">
|
||||
<field name="act_from" ref="purchase_activity_quotation"/>
|
||||
<field name="act_to" ref="purchase_activity_cancel"/>
|
||||
<field name="signal">cancel</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_confirmed_invoice_method">
|
||||
<field name="act_from" ref="purchase_activity_confirmed"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_method"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_method_invoice_purchase">
|
||||
<field name="act_from" ref="purchase_activity_invoice_method"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_purchase"/>
|
||||
<field name="condition">invoice_method == 'order'</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_method_invoice_done">
|
||||
<field name="act_from" ref="purchase_activity_invoice_method"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_method_done"/>
|
||||
<field name="condition">invoice_method != 'order'</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_purchase_waiting_invoice_purchase">
|
||||
<field name="act_from" ref="purchase_activity_invoice_purchase"/>
|
||||
<field name="act_to" ref="purchase_activity_waiting_invoice_purchase"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_waiting_invoice_purchase_invoice_purchase_exception">
|
||||
<field name="act_from" ref="purchase_activity_waiting_invoice_purchase"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_purchase_exception"/>
|
||||
<field name="trigger_model">account.invoice</field>
|
||||
<field name="trigger_expr_id">invoices</field>
|
||||
<field name="condition">invoice_exception</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_purchase_exception_invoice_purchase">
|
||||
<field name="act_from" ref="purchase_activity_invoice_purchase_exception"/>
|
||||
<field name="act_to" ref="purchase_activity_waiting_invoice_purchase"/>
|
||||
<field name="signal">invoice_ok</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_purchase_exception_cancel">
|
||||
<field name="act_from" ref="purchase_activity_invoice_purchase_exception"/>
|
||||
<field name="act_to" ref="purchase_activity_cancel"/>
|
||||
<field name="signal">cancel</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_waiting_invoice_purchase_invoice_done">
|
||||
<field name="act_from" ref="purchase_activity_waiting_invoice_purchase"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_done"/>
|
||||
<field name="trigger_model">account.invoice</field>
|
||||
<field name="trigger_expr_id">invoices</field>
|
||||
<field name="condition">invoice_paid</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_done_invoice_method_done">
|
||||
<field name="act_from" ref="purchase_activity_invoice_done"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_method_done"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_method_done_done">
|
||||
<field name="act_from" ref="purchase_activity_invoice_method_done"/>
|
||||
<field name="act_to" ref="purchase_activity_done"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_confirmed_packing">
|
||||
<field name="act_from" ref="purchase_activity_confirmed"/>
|
||||
<field name="act_to" ref="purchase_activity_packing"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_packing_waiting_packing">
|
||||
<field name="act_from" ref="purchase_activity_packing"/>
|
||||
<field name="act_to" ref="purchase_activity_waiting_packing"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_waiting_packing_packing_exception">
|
||||
<field name="act_from" ref="purchase_activity_waiting_packing"/>
|
||||
<field name="act_to" ref="purchase_activity_packing_exception"/>
|
||||
<field name="signal">packing_update</field>
|
||||
<field name="condition">packing_exception</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_packing_exception_cancel">
|
||||
<field name="act_from" ref="purchase_activity_packing_exception"/>
|
||||
<field name="act_to" ref="purchase_activity_cancel"/>
|
||||
<field name="signal">cancel</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_packing_exception_waiting_packing">
|
||||
<field name="act_from" ref="purchase_activity_packing_exception"/>
|
||||
<field name="act_to" ref="purchase_activity_waiting_packing"/>
|
||||
<field name="signal">packing_ok</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_waiting_packing_invoice_packing_method">
|
||||
<field name="act_from" ref="purchase_activity_waiting_packing"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_packing_method"/>
|
||||
<field name="signal">packing_update</field>
|
||||
<field name="condition">not packing_exception</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_waiting_packing_invoice_packing_method2">
|
||||
<field name="act_from" ref="purchase_activity_waiting_packing"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_packing_method"/>
|
||||
<field name="condition">packing_done</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_method_invoice_packing">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing_method"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_packing"/>
|
||||
<field name="condition">invoice_method == 'packing'</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_method_invoice_packing_method_done">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing_method"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_packing_method_done"/>
|
||||
<field name="condition">invoice_method != 'packing' and packing_done</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_method_waiting_packing">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing_method"/>
|
||||
<field name="act_to" ref="purchase_activity_waiting_packing"/>
|
||||
<field name="condition">invoice_method != 'packing' and not packing_done</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_waitin_packing">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing"/>
|
||||
<field name="act_to" ref="purchase_activity_waiting_packing"/>
|
||||
<field name="condition">not packing_done</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_waiting_invoice_packing">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing"/>
|
||||
<field name="act_to" ref="purchase_activity_waiting_invoice_packing"/>
|
||||
<field name="condition">packing_done</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_waiting_invoice_packing_invoice_packing_exception">
|
||||
<field name="act_from" ref="purchase_activity_waiting_invoice_packing"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_packing_exception"/>
|
||||
<field name="trigger_model">account.invoice</field>
|
||||
<field name="trigger_expr_id">invoices</field>
|
||||
<field name="condition">invoice_exception</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_exception_cancel">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing_exception"/>
|
||||
<field name="act_to" ref="purchase_activity_cancel"/>
|
||||
<field name="signal">cancel</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_exception_waiting_invoice_packing">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing_exception"/>
|
||||
<field name="act_to" ref="purchase_activity_waiting_invoice_packing"/>
|
||||
<field name="signal">invoice_ok</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_waiting_invoice_packing_done">
|
||||
<field name="act_from" ref="purchase_activity_waiting_invoice_packing"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_packing_done"/>
|
||||
<field name="trigger_model">account.invoice</field>
|
||||
<field name="trigger_expr_id">invoices</field>
|
||||
<field name="condition">invoice_paid</field>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_done_invoice_packing_method_done">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing_done"/>
|
||||
<field name="act_to" ref="purchase_activity_invoice_packing_method_done"/>
|
||||
</record>
|
||||
<record model="workflow.transition" id="purchase_transition_invoice_packing_done_done">
|
||||
<field name="act_from" ref="purchase_activity_invoice_packing_method_done"/>
|
||||
<field name="act_to" ref="purchase_activity_done"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="purchase_line_view_form">
|
||||
<field name="model">purchase.line</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Purchase Line">
|
||||
<label name="purchase"/>
|
||||
<field name="purchase" colspan="3"/>
|
||||
<label name="type"/>
|
||||
<field name="type"/>
|
||||
<label name="sequence"/>
|
||||
<field name="sequence"/>
|
||||
<label name="quantity"/>
|
||||
<field name="quantity"/>
|
||||
<label name="unit"/>
|
||||
<field name="unit"/>
|
||||
<label name="product"/>
|
||||
<field name="product"/>
|
||||
<newline/>
|
||||
<label name="description"/>
|
||||
<field name="description" colspan="3"/>
|
||||
<label name="amount"/>
|
||||
<field name="amount"/>
|
||||
<label name="unit_price"/>
|
||||
<field name="unit_price"/>
|
||||
<separator name="comment" colspan="4"/>
|
||||
<field name="comment" colspan="4"/>
|
||||
<separator name="taxes" colspan="4"/>
|
||||
<field name="taxes" colspan="4"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="purchase_line_view_tree">
|
||||
<field name="model">purchase.line</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Purchase Lines">
|
||||
<field name="purchase" select="1"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="product" select="1"/>
|
||||
<field name="description" select="1"/>
|
||||
<field name="quantity" select="1"/>
|
||||
<field name="unit" select="2"/>
|
||||
<field name="unit_price" select="2"/>
|
||||
<field name="taxes"/>
|
||||
<field name="amount"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_purchase_line">
|
||||
<field name="model" search="[('model', '=', 'purchase.line')]"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
<record model="ir.model.access" id="access_purchase_line_purchase">
|
||||
<field name="model" search="[('model', '=', 'purchase.line')]"/>
|
||||
<field name="group" ref="group_purchase"/>
|
||||
<field name="perm_read" eval="True"/>
|
||||
<field name="perm_write" eval="True"/>
|
||||
<field name="perm_create" eval="True"/>
|
||||
<field name="perm_unlink" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_supplier_view_form">
|
||||
<field name="model">purchase.product_supplier</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Product Supplier">
|
||||
<label name="product"/>
|
||||
<field name="product" colspan="4"/>
|
||||
<label name="partner"/>
|
||||
<field name="partner"/>
|
||||
<label name="sequence"/>
|
||||
<field name="sequence"/>
|
||||
<label name="name"/>
|
||||
<field name="name"/>
|
||||
<label name="code"/>
|
||||
<field name="code"/>
|
||||
<field name="prices" colspan="4"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="product_supplier_view_tree">
|
||||
<field name="model">purchase.product_supplier</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Product Suppliers">
|
||||
<field name="product" select="1"/>
|
||||
<field name="partner" select="1"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="sequence" select="2"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.rule.group" id="rule_group_product_supplier">
|
||||
<field name="model" search="[('model', '=', 'purchase.product_supplier')]"/>
|
||||
<field name="global_p" eval="True"/>
|
||||
</record>
|
||||
<record model="ir.rule" id="rule_product_supplier">
|
||||
<field name="field" search="[('name', '=', 'company'), ('model.model', '=', 'purchase.product_supplier')]"/>
|
||||
<field name="operator">=</field>
|
||||
<field name="operand">User/Current Company</field>
|
||||
<field name="rule_group" ref="rule_group_product_supplier"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_supplier_price_view_form">
|
||||
<field name="model">purchase.product_supplier.price</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<form string="Product Supplier Price" col="6">
|
||||
<label name="product_supplier"/>
|
||||
<field name="product_supplier" colspan="5"/>
|
||||
<label name="quantity"/>
|
||||
<field name="quantity"/>
|
||||
<label name="price"/>
|
||||
<field name="price"/>
|
||||
</form>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="product_supplier_price_view_tree">
|
||||
<field name="model">purchase.product_supplier.price</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<tree string="Product Supplier Prices">
|
||||
<field name="product_supplier"/>
|
||||
<field name="quantity"/>
|
||||
<field name="price"/>
|
||||
</tree>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="product_view_form">
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit" ref="product.product_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<data>
|
||||
<xpath expr="/form/notebook/page[@string="Properties"]"
|
||||
position="after">
|
||||
<page string="Suppliers">
|
||||
<label name="purchasable"/>
|
||||
<field name="purchasable"/>
|
||||
<field name="product_suppliers" colspan="4">
|
||||
<tree string="Product Suppliers" sequence="sequence">
|
||||
<field name="partner"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="sequence" tree_invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</xpath>
|
||||
</data>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="product_view_tree">
|
||||
<field name="model">product.product</field>
|
||||
<field name="inherit" ref="product.product_view_tree"/>
|
||||
<field name="arch" type="xml">
|
||||
<![CDATA[
|
||||
<data>
|
||||
<xpath expr="/tree/field[@name="default_uom"]"
|
||||
position="after">
|
||||
<field name="purchasable" select="2"/>
|
||||
</xpath>
|
||||
</data>
|
||||
]]>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</tryton>
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
from distutils.core import setup
|
||||
from distutils.command import sdist
|
||||
|
||||
|
||||
class mysdist(sdist.sdist):
|
||||
|
||||
def add_defaults(self):
|
||||
sdist.sdist.add_defaults(self)
|
||||
if self.distribution.has_pure_modules():
|
||||
build_py = self.get_finalized_command('build_py')
|
||||
data = []
|
||||
for package in build_py.packages:
|
||||
src_dir = build_py.get_package_dir(package)
|
||||
data.extend(build_py.find_data_files(package, src_dir))
|
||||
self.filelist.extend(data)
|
||||
|
||||
info = eval(file('__tryton__.py').read())
|
||||
|
||||
requires = ['trytond'] + ['trytond-' + x for x in info.get('depends', [])]
|
||||
|
||||
setup(name='trytond-' + info['name'].lower(),
|
||||
version=info.get('version', '0'),
|
||||
description=info.get('description', ''),
|
||||
author=info.get('author', ''),
|
||||
author_email=info.get('email', ''),
|
||||
url=info.get('website', ''),
|
||||
package_dir={'trytond.modules.' + info['name'].lower(): '.'},
|
||||
packages=[
|
||||
'trytond.modules.' + info['name'].lower(),
|
||||
],
|
||||
package_data={
|
||||
'trytond.modules.' + info['name'].lower(): info.get('xml', []),
|
||||
},
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: Plugins',
|
||||
'Intended Audience :: Developers',
|
||||
'Intended Audience :: Financial and Insurance Industry',
|
||||
'Intended Audience :: Legal Industry',
|
||||
'Natural Language :: English',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
'Topic :: Office/Business',
|
||||
'Topic :: Office/Business :: Financial :: Accounting',
|
||||
],
|
||||
license=info.get('license', 'GPL-2'),
|
||||
#requires=requires,
|
||||
cmdclass={
|
||||
'sdist': mysdist,
|
||||
},
|
||||
)
|
||||
Reference in New Issue
Block a user