diff --git a/addons/account/invoice.py b/addons/account/invoice.py index fc5dbb69d9f..c3599ad86ea 100644 --- a/addons/account/invoice.py +++ b/addons/account/invoice.py @@ -148,7 +148,7 @@ class account_invoice(osv.osv): _order = "number" _columns = { 'name': fields.char('Description', size=64, select=True,readonly=True, states={'draft':[('readonly',False)]}), - 'origin': fields.char('Origin', size=64), + 'origin': fields.char('Origin', size=64, help="Reference of the document that produced this invoice."), 'type': fields.selection([ ('out_invoice','Customer Invoice'), ('in_invoice','Supplier Invoice'), @@ -156,8 +156,8 @@ class account_invoice(osv.osv): ('in_refund','Supplier Refund'), ],'Type', readonly=True, select=True), - 'number': fields.char('Invoice Number', size=32, readonly=True), - 'reference': fields.char('Invoice Reference', size=64), + 'number': fields.char('Invoice Number', size=32, readonly=True, help="Uniq number of the invoice, computed automatically when the invoice is created."), + 'reference': fields.char('Invoice Reference', size=64, help="The partner reference of this invoice."), 'reference_type': fields.selection(_get_reference_type, 'Reference Type', required=True), 'comment': fields.text('Additionnal Information'), @@ -181,11 +181,11 @@ class account_invoice(osv.osv): 'period_id': fields.many2one('account.period', 'Force Period', help="Keep empty to use the period of the validation date."), - 'account_id': fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}), + 'account_id': fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft':[('readonly',False)]}, help="The partner account used for this invoice."), 'invoice_line': fields.one2many('account.invoice.line', 'invoice_id', 'Invoice Lines', readonly=True, states={'draft':[('readonly',False)]}), 'tax_line': fields.one2many('account.invoice.tax', 'invoice_id', 'Tax Lines', readonly=True, states={'draft':[('readonly',False)]}), - 'move_id': fields.many2one('account.move', 'Invoice Movement', readonly=True), + 'move_id': fields.many2one('account.move', 'Invoice Movement', readonly=True, help="Link to the automatically generated account moves."), 'amount_untaxed': fields.function(_amount_untaxed, method=True, digits=(16,2),string='Untaxed', store=True), 'amount_tax': fields.function(_amount_tax, method=True, digits=(16,2), string='Tax', store=True), 'amount_total': fields.function(_amount_total, method=True, digits=(16,2), string='Total', store=True), @@ -193,11 +193,11 @@ class account_invoice(osv.osv): 'journal_id': fields.many2one('account.journal', 'Journal', required=True,readonly=True, states={'draft':[('readonly',False)]}), 'company_id': fields.many2one('res.company', 'Company', required=True), 'check_total': fields.float('Total', digits=(16,2), states={'open':[('readonly',True)],'close':[('readonly',True)]}), - 'reconciled': fields.function(_reconciled, method=True, string='Paid/Reconciled', type='boolean'), + 'reconciled': fields.function(_reconciled, method=True, string='Paid/Reconciled', type='boolean', help="The account moves of the invoice have been reconciled with account moves of the payment(s)."), 'partner_bank': fields.many2one('res.partner.bank', 'Bank Account', help='The bank account to pay to or to be paid from'), 'move_lines':fields.function(_get_lines , method=True,type='many2many' , relation='account.move.line',string='Move Lines'), - 'residual': fields.function(_amount_residual, method=True, digits=(16,2),string='Residual', store=True), + 'residual': fields.function(_amount_residual, method=True, digits=(16,2),string='Residual', store=True, help="Remaining amount due."), 'payment_ids': fields.function(_compute_lines, method=True, relation='account.move.line', type="many2many", string='Payments'), } _defaults = { @@ -815,9 +815,9 @@ class account_invoice_line(osv.osv): _columns = { 'name': fields.char('Description', size=256, required=True), 'invoice_id': fields.many2one('account.invoice', 'Invoice Ref', ondelete='cascade', select=True), - 'uos_id': fields.many2one('product.uom', 'Unit', ondelete='set null'), + 'uos_id': fields.many2one('product.uom', 'Unit of Measure', ondelete='set null'), 'product_id': fields.many2one('product.product', 'Product', ondelete='set null'), - 'account_id': fields.many2one('account.account', 'Account', required=True, domain=[('type','<>','view'), ('type', '<>', 'closed')]), + 'account_id': fields.many2one('account.account', 'Account', required=True, domain=[('type','<>','view'), ('type', '<>', 'closed')], help="The income or expense account related to the selected product."), 'price_unit': fields.float('Unit Price', required=True, digits=(16, int(config['price_accuracy']))), 'price_subtotal': fields.function(_amount_line, method=True, string='Subtotal',store=True), 'quantity': fields.float('Quantity', required=True), @@ -984,9 +984,9 @@ class account_invoice_tax(osv.osv): 'manual': fields.boolean('Manual'), 'sequence': fields.integer('Sequence'), - 'base_code_id': fields.many2one('account.tax.code', 'Base Code'), + 'base_code_id': fields.many2one('account.tax.code', 'Base Code', help="The case of the tax declaration."), 'base_amount': fields.float('Base Code Amount', digits=(16,2)), - 'tax_code_id': fields.many2one('account.tax.code', 'Tax Code'), + 'tax_code_id': fields.many2one('account.tax.code', 'Tax Code', help="The case of the tax declaration."), 'tax_amount': fields.float('Tax Code Amount', digits=(16,2)), } def base_change(self, cr, uid, ids, base): diff --git a/addons/account/partner.py b/addons/account/partner.py index ef68a12de48..c1eac82b99c 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -86,8 +86,8 @@ class res_partner(osv.osv): return [('id','in',map(lambda x:x[0], res))] _columns = { - 'credit': fields.function(_credit_debit_get, fnct_search=_credit_search, method=True, string='Total Receivable', multi='dc'), - 'debit': fields.function(_credit_debit_get, fnct_search=_debit_search, method=True, string='Total Payable', multi='dc'), + 'credit': fields.function(_credit_debit_get, fnct_search=_credit_search, method=True, string='Total Receivable', multi='dc', help="Total amount this customer owns you."), + 'debit': fields.function(_credit_debit_get, fnct_search=_debit_search, method=True, string='Total Payable', multi='dc', help="Total amount you have to pay to this supplier."), 'debit_limit': fields.float('Payable Limit'), 'property_account_payable': fields.property( 'account.account', diff --git a/addons/account_payment/__init__.py b/addons/account_payment/__init__.py index 3b652e0b3a3..7fc464279cd 100644 --- a/addons/account_payment/__init__.py +++ b/addons/account_payment/__init__.py @@ -36,6 +36,7 @@ import payment import wizard import account_move_line import account_invoice +import report # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account_payment/payment.py b/addons/account_payment/payment.py index 3f4665878b8..22ca132453c 100644 --- a/addons/account_payment/payment.py +++ b/addons/account_payment/payment.py @@ -39,8 +39,8 @@ class payment_type(osv.osv): _name= 'payment.type' _description= 'Payment type' _columns= { - 'name': fields.char('Name', size=64, required=True), - 'code': fields.char('Code', size=64, required=True), + 'name': fields.char('Name', size=64, required=True,help='Payment Type'), + 'code': fields.char('Code', size=64, required=True,help='Specify the Code for Payment Type'), 'suitable_bank_types': fields.many2many('res.partner.bank.type', 'bank_type_payment_type_rel', 'pay_type_id','bank_type_id', @@ -54,12 +54,12 @@ class payment_mode(osv.osv): _name= 'payment.mode' _description= 'Payment mode' _columns= { - 'name': fields.char('Name', size=64, required=True), + 'name': fields.char('Name', size=64, required=True,help='Mode of Payment'), 'bank_id': fields.many2one('res.partner.bank', "Bank account", - required=True), + required=True,help='Bank Account for the Payment Mode'), 'journal': fields.many2one('account.journal', 'Journal', required=True, - domain=[('type', '=', 'cash')]), - 'type': fields.many2one('payment.type','Payment type',required=True), + domain=[('type', '=', 'cash')],help='Cash Journal for the Payment Mode'), + 'type': fields.many2one('payment.type','Payment type',required=True,help='Select the Payment Type for the Payment Mode.'), } def suitable_bank_types(self,cr,uid,payment_code=None,context={}): @@ -102,9 +102,9 @@ class payment_order(osv.osv): return res _columns = { - 'date_planned': fields.date('Scheduled date if fixed'), + 'date_planned': fields.date('Scheduled date if fixed',help='Select a date if you have chosen Preferred Date to be fixed.'), 'reference': fields.char('Reference',size=128,required=1), - 'mode': fields.many2one('payment.mode','Payment mode', select=True, required=1), + 'mode': fields.many2one('payment.mode','Payment mode', select=True, required=1,help='Select the Payment Mode to be applied.'), 'state': fields.selection([ ('draft', 'Draft'), ('open','Confirmed'), @@ -118,7 +118,7 @@ class payment_order(osv.osv): ('now', 'Directly'), ('due', 'Due date'), ('fixed', 'Fixed date') - ], "Prefered date", change_default=True, required=True), + ], "Prefered date", change_default=True, required=True,help="Choose an option for the Payment Order:'Fixed' stands for a date specified by you.'Directly' stands for the direct execution.'Due date' stands for the scheduled date of execution."), 'date_created': fields.date('Creation date', readonly=True), 'date_done': fields.date('Execution date', readonly=True), } @@ -381,9 +381,9 @@ class payment_line(osv.osv): _columns = { 'name': fields.char('Your Reference', size=64, required=True), - 'communication': fields.char('Communication', size=64, required=True), - 'communication2': fields.char('Communication 2', size=64), - 'move_line_id': fields.many2one('account.move.line','Entry line', domain=[('reconcile_id','=', False), ('account_id.type', '=','payable')]), + 'communication': fields.char('Communication', size=64, required=True,help="Used as the message between ordering customer and current company.Depicts 'What do you want to say to the receipent about this oder?'"), + 'communication2': fields.char('Communication 2', size=64,help='The successor message of Communication.'), + 'move_line_id': fields.many2one('account.move.line','Entry line', domain=[('reconcile_id','=', False), ('account_id.type', '=','payable')],help='This Entry Line will be referred for the information of the ordering customer.'), 'amount_currency': fields.float('Amount in Partner Currency', digits=(16,2), required=True, help='Payment amount in the partner currency'), # 'to_pay_currency': fields.function(_to_pay_currency, string='To Pay', @@ -396,7 +396,7 @@ class payment_line(osv.osv): 'bank_id': fields.many2one('res.partner.bank', 'Destination Bank account'), 'order_id': fields.many2one('payment.order', 'Order', required=True, ondelete='cascade', select=True), - 'partner_id': fields.many2one('res.partner', string="Partner",required=True), + 'partner_id': fields.many2one('res.partner', string="Partner",required=True,help='The Ordering Customer'), 'amount': fields.function(_amount, string='Amount in Company Currency', method=True, type='float', help='Payment amount in the company currency'), @@ -410,8 +410,8 @@ class payment_line(osv.osv): # type='char'), 'ml_maturity_date': fields.function(_get_ml_maturity_date, method=True, type='char', string='Maturity Date'), 'ml_inv_ref': fields.function(_get_ml_inv_ref, method=True, type='many2one', relation='account.invoice', string='Invoice Ref'), - 'info_owner': fields.function(info_owner, string="Owner Account", method=True, type="text"), - 'info_partner': fields.function(info_partner, string="Destination Account", method=True, type="text"), + 'info_owner': fields.function(info_owner, string="Owner Account", method=True, type="text",help='Address of the Main Partner'), + 'info_partner': fields.function(info_partner, string="Destination Account", method=True, type="text",help='Address of the Ordering Customer.'), # 'partner_payable': fields.function(partner_payable, string="Partner payable", method=True, type='float'), # 'value_date': fields.function(_value_date, string='Value Date', # method=True, type='date'), diff --git a/addons/delivery/delivery_view.xml b/addons/delivery/delivery_view.xml index 307f9128ed0..7816896f771 100644 --- a/addons/delivery/delivery_view.xml +++ b/addons/delivery/delivery_view.xml @@ -3,7 +3,7 @@ - + delivery.carrier.tree delivery.carrier @@ -37,7 +37,7 @@ tree,form - + delivery.grid.tree @@ -51,7 +51,7 @@ - + delivery.grid.form delivery.grid @@ -85,7 +85,7 @@ tree,form - + delivery.grid.line.form delivery.grid.line @@ -118,7 +118,7 @@ - + delivery.sale.order_withcarrier.form.view form @@ -130,20 +130,7 @@ - - - delivery.stock.picking_withcarrier.form.view - form - stock.picking - - - - - - - - - + delivery.stock.picking_withcarrier.out.form.view form @@ -151,13 +138,12 @@ - - + delivery.stock.picking_withcarrier.delivery.form.view form @@ -165,13 +151,12 @@ - - + Packings to be invoiced stock.picking @@ -181,8 +166,7 @@ [('invoice_state','=','2binvoiced'),('state','=','done'),('type','=','out')] - - + Generate Draft Invoices On Receptions stock.picking @@ -192,7 +176,6 @@ [('invoice_state','=','2binvoiced'),('state','=','done'),('type','=','in')] - - + diff --git a/addons/mrp/mrp.py b/addons/mrp/mrp.py index bb6684ca04f..170cefd6fbc 100644 --- a/addons/mrp/mrp.py +++ b/addons/mrp/mrp.py @@ -49,26 +49,28 @@ class mrp_workcenter(osv.osv): _name = 'mrp.workcenter' _description = 'Workcenter' _columns = { - 'name': fields.char('Name', size=64, required=True), + 'name': fields.char('Workcenter Name', size=64, required=True), 'active': fields.boolean('Active'), 'type': fields.selection([('machine','Machine'),('hr','Human Resource'),('tool','Tool')], 'Type', required=True), - 'code': fields.char('Code', size=8), - 'timesheet_id': fields.many2one('hr.timesheet.group', 'Timesheet'), - 'note': fields.text('Description'), + 'code': fields.char('Code', size=16), + 'timesheet_id': fields.many2one('hr.timesheet.group', 'Working Time', help="The normal working time of the workcenter."), + 'note': fields.text('Description', help="Description of the workcenter. Explain here what's a cycle according to this workcenter."), - 'capacity_per_cycle': fields.float('Capacity per Cycle'), + 'capacity_per_cycle': fields.float('Capacity per Cycle', help="Number of operation this workcenter can do in parallel. If this workcenter represent a team of 5 workers, the capacity per cycle is 5."), - 'time_cycle': fields.float('Time for 1 cycle (hour)'), - 'time_start': fields.float('Time before prod.'), - 'time_stop': fields.float('Time after prod.'), - 'time_efficiency': fields.float('Time Efficiency'), + 'time_cycle': fields.float('Time for 1 cycle (hour)', help="Time in hours for doing one cycle."), + 'time_start': fields.float('Time before prod.', help="Time in hours for the setup."), + 'time_stop': fields.float('Time after prod.', help="Time in hours for the cleaning."), + 'time_efficiency': fields.float('Time Efficiency', help="Factor that multiplies all times expressed in the workcenter."), 'costs_hour': fields.float('Cost per hour'), - 'costs_hour_account_id': fields.many2one('account.analytic.account', 'Hour Account', domain=[('type','=','expense')]), + 'costs_hour_account_id': fields.many2one('account.analytic.account', 'Hour Account', domain=[('type','<>','view')], + help="Complete this only if you want automatic analytic accounting entries on production orders."), 'costs_cycle': fields.float('Cost per cycle'), - 'costs_cycle_account_id': fields.many2one('account.analytic.account', 'Cycle Account', domain=[('type','=','expense')]), + 'costs_cycle_account_id': fields.many2one('account.analytic.account', 'Cycle Account', domain=[('type','<>','view')], + help="Complete this only if you want automatic analytic accounting entries on production orders."), 'costs_journal_id': fields.many2one('account.analytic.journal', 'Analytic Journal'), - 'costs_general_account_id': fields.many2one('account.account', 'General Account'), + 'costs_general_account_id': fields.many2one('account.account', 'General Account', domain=[('type','<>','view')]), } _defaults = { 'active': lambda *a: 1, @@ -93,7 +95,7 @@ class mrp_property(osv.osv): _description = 'Property' _columns = { 'name': fields.char('Name', size=64, required=True), - 'composition': fields.selection([('min','min'),('max','max'),('plus','plus')], 'Properties composition', required=True), + 'composition': fields.selection([('min','min'),('max','max'),('plus','plus')], 'Properties composition', required=True, help="Not used in computations, for information purpose only."), 'group_id': fields.many2one('mrp.property.group', 'Property Group', required=True), 'description': fields.text('Description'), } @@ -113,7 +115,11 @@ class mrp_routing(osv.osv): 'note': fields.text('Description'), 'workcenter_lines': fields.one2many('mrp.routing.workcenter', 'routing_id', 'Workcenters'), - 'location_id': fields.many2one('stock.location', 'Production Location'), + 'location_id': fields.many2one('stock.location', 'Production Location', + help="Keep empty if you produce at the location where the finnished products are needed." \ + "Put a location if you produce at a fixed location. This can be a partner location " \ + "if you subcontract the manufacturing operations." + ), } _defaults = { 'active': lambda *a: 1, @@ -127,8 +133,8 @@ class mrp_routing_workcenter(osv.osv): 'workcenter_id': fields.many2one('mrp.workcenter', 'Workcenter', required=True), 'name': fields.char('Name', size=64, required=True), 'sequence': fields.integer('Sequence'), - 'cycle_nbr': fields.float('Number of cycle', required=True), - 'hour_nbr': fields.float('Number of hours', required=True), + 'cycle_nbr': fields.float('Number of Cycle', required=True), + 'hour_nbr': fields.float('Number of Hours', required=True), 'routing_id': fields.many2one('mrp.routing', 'Parent Routing', select=True), 'note': fields.text('Description') } @@ -145,11 +151,11 @@ class mrp_bom(osv.osv): 'name': fields.char('Name', size=64, required=True), 'code': fields.char('Code', size=16), 'active': fields.boolean('Active'), - 'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True, help="Use a phantom bill of material in lines that have a sub-bom and that have to be automatically computed in one line, without habing two production orders."), - 'date_start': fields.date('Valid from'), - 'date_stop': fields.date('Valid until'), + 'type': fields.selection([('normal','Normal BoM'),('phantom','Sets / Phantom')], 'BoM Type', required=True, help="Use a phantom bill of material in lines that have a sub-bom and that have to be automatically computed in one line, without having two production orders."), + 'date_start': fields.date('Valid From', help="Validity of this BoM or component. Keep empty if it's always valid."), + 'date_stop': fields.date('Valid Until', help="Validity of this BoM or component. Keep empty if it's always valid."), 'sequence': fields.integer('Sequence'), - 'position': fields.char('Internal Ref.', size=64), + 'position': fields.char('Internal Ref.', size=64, help="Reference to a position in an external plan."), 'product_id': fields.many2one('product.product', 'Product', required=True), 'product_uos_qty': fields.float('Product UOS Qty'), 'product_uos': fields.many2one('product.uom', 'Product UOS'), @@ -304,7 +310,7 @@ class mrp_production(osv.osv): _name = 'mrp.production' _description = 'Production' _date_name = 'date_planned' - + def _get_sale_order(self,cr,uid,ids,field_name=False): move_obj=self.pool.get('stock.move') def get_parent_move(move_id): @@ -324,13 +330,13 @@ class mrp_production(osv.osv): if field_name=='client_order_ref': res[production['id']]=move.sale_line_id and move.sale_line_id.order_id.client_order_ref or False return res - + def _sale_name_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict): return self._get_sale_order(cr,uid,ids,field_name='name') - + def _sale_ref_calc(self, cr, uid, ids, prop, unknow_none, unknow_dict): return self._get_sale_order(cr,uid,ids,field_name='client_order_ref') - + _columns = { 'name': fields.char('Reference', size=64, required=True), 'origin': fields.char('Origin', size=64), @@ -640,11 +646,9 @@ mrp_production() class stock_move(osv.osv): _name = 'stock.move' _inherit = 'stock.move' - _columns = { - 'production_id': fields.many2one('mrp.production', 'Production', select=True), - } - + 'production_id': fields.many2one('mrp.production', 'Production', select=True), + } stock_move() class mrp_production_workcenter_line(osv.osv): diff --git a/addons/process/process.py b/addons/process/process.py index f2d64499667..89c543f795d 100644 --- a/addons/process/process.py +++ b/addons/process/process.py @@ -64,6 +64,7 @@ class process_process(osv.osv): } def graph_get(self, cr, uid, id, res_model, res_id, scale, context): + pool = pooler.get_pool(cr.dbname) process = pool.get('process.process').browse(cr, uid, [id])[0] @@ -71,31 +72,73 @@ class process_process(osv.osv): current_user = pool.get('res.users').browse(cr, uid, [uid], context)[0] expr_context = Env(current_object, current_user) - + + def get_resource_info(node): + ret = False + + src_model = res_model + src_id = res_id + + if node.transition_in: + tr = node.transition_in[0] + src = nodes.get(tr.source_node_id.id) + if src['res']: + src_model = src['res']['model'] + src_id = src['res']['id'] + else: + return False + + fields = pool.get(src_model).fields_get(cr, uid, context=context) + + for name, field in fields.items(): + if node.model_id and field.get('relation', False) == node.model_id.model: + src_obj = pool.get(src_model).browse(cr, uid, [src_id], context)[0] + rel = src_obj[name] + if rel: + if isinstance(rel, (list, tuple)): + rel = rel[0] + ret = {} + ret['name'] = rel.name_get(context)[0][1] + ret['model'] = field['relation'] + ret['id'] = rel.id + + return ret + + notes = process.note nodes = {} start = [] transitions = {} + states = dict(pool.get(res_model).fields_get(cr, uid, context=context).get('state', {}).get('selection', {})) + title = "%s - Resource: %s, State: %s" % (process.name, current_object.name, states.get(getattr(current_object, 'state'), 'N/A')) + for node in process.node_ids: data = {} data['name'] = node.name data['model'] = (node.model_id or None) and node.model_id.model data['kind'] = node.kind + data['subflow'] = (node.subflow_id or False) and [node.subflow_id.id, node.subflow_id.name] data['notes'] = node.note - data['active'] = 0 - data['gray'] = 0 + data['active'] = False + data['gray'] = False + data['res'] = get_resource_info(node) if node.menu_id: data['menu'] = {'name': node.menu_id.complete_name, 'id': node.menu_id.id} - if node.kind == "state" and node.model_id and node.model_id.model == res_model: + if node.model_id and node.model_id.model == res_model: + + data['res'] = resource = {} + resource['name'] = current_object.name_get(context)[0][1] + resource['model'] = res_model + resource['id'] = res_id + try: - if eval(node.model_states, expr_context): - data['active'] = current_object.name_get(context)[0][1] + data['active'] = eval(node.model_states, expr_context) except Exception, e: # waring: invalid state expression pass - + if not data['active']: try: gray = True @@ -129,6 +172,10 @@ class process_process(osv.osv): role = {} role['name'] = r.role_id.name roles.append(role) + for r in tr.role_ids: + role = {} + role['name'] = r.name + roles.append(role) transitions[tr.id] = data g = tools.graph(nodes.keys(), map(lambda x: (x['source'], x['target']), transitions.values())) @@ -136,8 +183,8 @@ class process_process(osv.osv): #g.scale(100, 100, 180, 120) g.scale(*scale) graph = g.result_get() - miny = -1 + miny = -1 for k,v in nodes.items(): x = graph[k]['y'] y = graph[k]['x'] @@ -150,7 +197,8 @@ class process_process(osv.osv): for k, v in nodes.items(): y = v['y'] v['y'] = min(y - miny + 10, y) - return dict(nodes=nodes, transitions=transitions) + + return dict(title=title, notes=notes, nodes=nodes, transitions=transitions) process_process() @@ -165,6 +213,7 @@ class process_node(osv.osv): 'note': fields.text('Notes', translate=True), 'model_id': fields.many2one('ir.model', 'Object', ondelete='set null'), 'model_states': fields.char('States Expression', size=128), + 'subflow_id': fields.many2one('process.process', 'Subflow', ondelete='set null'), 'flow_start': fields.boolean('Starting Flow'), 'transition_in': fields.one2many('process.transition', 'target_node_id', 'Starting Transitions'), 'transition_out': fields.one2many('process.transition', 'source_node_id', 'Ending Transitions'), @@ -197,7 +246,12 @@ class process_transition(osv.osv): 'target_node_id': fields.many2one('process.node', 'Target Node', required=True, ondelete='cascade'), 'action_ids': fields.one2many('process.transition.action', 'transition_id', 'Buttons'), 'transition_ids': fields.many2many('workflow.transition', 'process_transition_ids', 'ptr_id', 'wtr_id', 'Workflow Transitions'), +<<<<<<< TREE 'note': fields.text('Description', translate=True), +======= + 'role_ids': fields.many2many('res.roles', 'process_transition_roles_rel', 'tid', 'rid', 'Roles'), + 'note': fields.text('Description', translate=True), +>>>>>>> MERGE-SOURCE } process_transition() diff --git a/addons/process/process_demo.xml b/addons/process/process_demo.xml index 0b1ae921c34..cc603d5b165 100644 --- a/addons/process/process_demo.xml +++ b/addons/process/process_demo.xml @@ -1,5 +1,6 @@ +<<<<<<< TREE @@ -155,4 +156,161 @@ +======= + + + + + + Sales Workflow + Sales flow for services companies. + + + + + + Quotation + Quotations are sale orders in draft mode + + + state + object.state == 'draft' + + + + + Sale Order + Manages the delivery in invoicing process + + + state + object.state == 'manual' + + + + + Invoice + In case you invoiced on Sale Order + + + state + + + + + + Tasks + In case you sale services on order + + + subflow + + + + + + Packing List + The workers pack the requested items + + + state + + + + + + Delivery Order + The transporter take the box and deliver it + + + state + + + + + + Invoice + In case you invoice based on deliveries + + + subflow + + + + + + + + Invoice on order + + object.order_policy != 'picking' + + + + + Invoice on delivery + + object.order_policy == 'picking' + + + + + + + Confirm Quotation + + + + + + Packing + + + + + + Invoice on order + + + + + + Create Tasks + + + + + + Deliver Goods + + + + + + Invoice or delivery + + + + + + + + Confirm + workflow + order_confirm + + + + + Cancel + workflow + cancel + + + + + + + +>>>>>>> MERGE-SOURCE diff --git a/addons/process/process_view.xml b/addons/process/process_view.xml index d9a4d93799f..c4deb35994c 100644 --- a/addons/process/process_view.xml +++ b/addons/process/process_view.xml @@ -31,6 +31,7 @@ + @@ -62,6 +63,9 @@ + + + @@ -124,6 +128,7 @@ action="action_process_form" parent="menu_process"/> +<<<<<<< TREE process.node.tree @@ -231,6 +236,119 @@ action="action_process_node_form" parent="menu_process"/> +======= + + + process.node.tree + process.node + tree + + + + + + + + + + + + + process.node.form + process.node + form + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + +
+ + + +
+ +
+
+ + + Process Nodes + process.node + form + tree,form + + + + +>>>>>>> MERGE-SOURCE @@ -274,9 +392,13 @@
- - - + + + + + + + diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index e5d52cbb632..3d597f45a8c 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -56,10 +56,10 @@ class price_type(osv.osv): _name = "product.price.type" _description = "Price type" _columns = { - "name" : fields.char("Price Name", size=32, required=True, translate=True) , + "name" : fields.char("Price Name", size=32, required=True, translate=True, help="Name of this kind of price."), "active" : fields.boolean("Active"), - "field" : fields.selection(_price_field_get, "Product Field", required=True), - "currency_id" : fields.many2one('res.currency', "Currency", required=True), + "field" : fields.selection(_price_field_get, "Product Field", required=True, help="Associated field in the product form."), + "currency_id" : fields.many2one('res.currency', "Currency", required=True, help="The currency the field is expressed in."), } _defaults = { "active": lambda *args: True, @@ -76,7 +76,7 @@ class product_pricelist_type(osv.osv): _description = "Pricelist Type" _columns = { 'name': fields.char('Name',size=64, required=True), - 'key': fields.char('Key', size=64, required=True), + 'key': fields.char('Key', size=64, required=True, help="Used in the code to select specific prices based on the context. Keep unchanged."), } product_pricelist_type() @@ -88,7 +88,7 @@ class product_pricelist(osv.osv): _name = "product.pricelist" _description = "Pricelist" _columns = { - 'name': fields.char('Name',size=64, required=True, translate=True), + 'name': fields.char('Pricelist Name',size=64, required=True, translate=True), 'active': fields.boolean('Active'), 'type': fields.selection(_pricelist_type_get, 'Pricelist Type', required=True), 'version_id': fields.one2many('product.pricelist.version', 'pricelist_id', 'Pricelist Versions'), @@ -247,8 +247,8 @@ class product_pricelist_version(osv.osv): 'active': fields.boolean('Active'), 'items_id': fields.one2many('product.pricelist.item', 'price_version_id', 'Price List Items', required=True), - 'date_start': fields.date('Start Date'), - 'date_end': fields.date('End Date'), + 'date_start': fields.date('Start Date', help="Starting date for validity of this pricelist version."), + 'date_end': fields.date('End Date', help="Ending date for validity of this pricelist version."), } _defaults = { 'active': lambda *a: 1, @@ -320,22 +320,26 @@ class product_pricelist_item(osv.osv): 'price_discount': lambda *a: 0, } _columns = { - 'name': fields.char('Name', size=64), + 'name': fields.char('Rule Name', size=64, help="Explicit rule name for this pricelist line."), 'price_version_id': fields.many2one('product.pricelist.version', 'Price List Version', required=True, select=True), - 'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade'), - 'product_id': fields.many2one('product.product', 'Product', ondelete='cascade'), - 'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade'), + 'product_tmpl_id': fields.many2one('product.template', 'Product Template', ondelete='cascade', help="Set a template if this rule only apply to a template of product. Keep empty for all products"), + 'product_id': fields.many2one('product.product', 'Product', ondelete='cascade', help="Set a product if this rule only apply to one product. Keep empty for all products"), + 'categ_id': fields.many2one('product.category', 'Product Category', ondelete='cascade', help="Set a category of product if this rule only apply to products of a category and his childs. Keep empty for all products"), - 'min_quantity': fields.integer('Min. Quantity', required=True), + 'min_quantity': fields.integer('Min. Quantity', required=True, help="The rule only apply if the partner buys/sells more than this quantity."), 'sequence': fields.integer('Sequence', required=True), - 'base': fields.selection(_price_field_get, 'Based on', required=True, size=-1), + 'base': fields.selection(_price_field_get, 'Based on', required=True, size=-1, help="The mode of computation of the price for this rule."), 'base_pricelist_id': fields.many2one('product.pricelist', 'If Other Pricelist'), 'price_surcharge': fields.float('Price Surcharge', digits=(16, int(config['price_accuracy']))), 'price_discount': fields.float('Price Discount', digits=(16,4)), 'price_round': fields.float('Price Rounding', - digits=(16, int(config['price_accuracy']))), + digits=(16, int(config['price_accuracy'])), + help="Sets the price so that it is a multiple of this value.\n" \ + "Rounding is applied after the discount and before the surcharge.\n" \ + "To have prices that ends by 9.99, set rounding 10, surcharge -0.01" \ + ), 'price_min_margin': fields.float('Price Min. Margin', digits=(16, int(config['price_accuracy']))), 'price_max_margin': fields.float('Price Max. Margin', diff --git a/addons/profile_manufacturing/__terp__.py b/addons/profile_manufacturing/__terp__.py index 40479ffc38f..92ea4224877 100644 --- a/addons/profile_manufacturing/__terp__.py +++ b/addons/profile_manufacturing/__terp__.py @@ -31,7 +31,7 @@ "version":"1.0", "author":"Tiny", "category":"Profile", - "depends":["mrp", "crm", "sale", "delivery","board_manufacturing"], + "depends":["mrp", "sale", "delivery","board_manufacturing"], "demo_xml":[], "update_xml":[ "security/ir.model.access.csv", diff --git a/addons/purchase/purchase.py b/addons/purchase/purchase.py index 13d48317139..26fdf26c953 100644 --- a/addons/purchase/purchase.py +++ b/addons/purchase/purchase.py @@ -154,14 +154,19 @@ class purchase_order(osv.osv): _columns = { 'name': fields.char('Order Reference', size=64, required=True, select=True), - 'origin': fields.char('Origin', size=64), + 'origin': fields.char('Origin', size=64, + help="Reference of the document that generated this purchase order request." + ), 'partner_ref': fields.char('Partner Ref.', size=64), 'date_order':fields.date('Date Ordered', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}), - 'date_approve':fields.date('Date Approved'), + 'date_approve':fields.date('Date Approved', readonly=1), 'partner_id':fields.many2one('res.partner', 'Supplier', required=True, states={'confirmed':[('readonly',True)], 'approved':[('readonly',True)]}, change_default=True), 'partner_address_id':fields.many2one('res.partner.address', 'Address', required=True, states={'posted':[('readonly',True)]}), - 'dest_address_id':fields.many2one('res.partner.address', 'Destination Address', states={'posted':[('readonly',True)]}), + 'dest_address_id':fields.many2one('res.partner.address', 'Destination Address', states={'posted':[('readonly',True)]}, + help="Put an address if you want to deliver directly from the supplier to the customer." \ + "In this case, it will remove the warehouse link and set the customer location." + ), 'warehouse_id': fields.many2one('stock.warehouse', 'Warehouse', states={'posted':[('readonly',True)]}), 'location_id': fields.many2one('stock.location', 'Destination', required=True), @@ -177,7 +182,12 @@ class purchase_order(osv.osv): 'shipped_rate': fields.function(_shipped_rate, method=True, string='Received', type='float'), 'invoiced':fields.boolean('Invoiced & Paid', readonly=True, select=True), 'invoiced_rate': fields.function(_invoiced_rate, method=True, string='Invoiced', type='float'), - 'invoice_method': fields.selection([('manual','Manual'),('order','From order'),('picking','From picking')], 'Invoicing Control', required=True), + 'invoice_method': fields.selection([('manual','Manual'),('order','From Order'),('picking','From Picking')], 'Invoicing Control', required=True, + help="From Order: a draft invoice will be pre-generated based on the purchase order. The accountant " \ + "will just have to validate this invoice for control.\n" \ + "From Picking: a draft invoice will be pre-genearted based on validated receptions.\n" \ + "Manual: no invoice will be pre-generated. The accountant will have to encode manually." + ), 'minimum_planned_date':fields.function(_minimum_planned_date, fnct_inv=_set_minimum_planned_date, method=True,store=True, string='Planned Date', type='datetime', help="This is computed as the minimum scheduled date of all purchase order lines' products."), 'amount_untaxed': fields.function(_amount_untaxed, method=True, string='Untaxed Amount'), 'amount_tax': fields.function(_amount_tax, method=True, string='Taxes'), diff --git a/addons/stock/product.py b/addons/stock/product.py index 5e0f4b5ee4a..f66e41acd4a 100644 --- a/addons/stock/product.py +++ b/addons/stock/product.py @@ -77,10 +77,13 @@ class product_product(osv.osv): _product_outgoing_qty = _get_product_available_func(('confirmed','waiting','assigned'), ('out',)) _product_incoming_qty = _get_product_available_func(('confirmed','waiting','assigned'), ('in',)) _columns = { - 'qty_available': fields.function(_product_qty_available, method=True, type='float', string='Real Stock'), - 'virtual_available': fields.function(_product_virtual_available, method=True, type='float', string='Virtual Stock'), - 'incoming_qty': fields.function(_product_incoming_qty, method=True, type='float', string='Incoming'), - 'outgoing_qty': fields.function(_product_outgoing_qty, method=True, type='float', string='Outgoing'), + 'qty_available': fields.function(_product_qty_available, method=True, type='float', string='Real Stock', help="Current quantities of products in selected locations or all internal if none have been selected."), + 'virtual_available': fields.function(_product_virtual_available, method=True, type='float', string='Virtual Stock', help="Futur stock for this product according to the selected location or all internal if none have been selected. Computed as: Real Stock - Outgoing + Incoming."), + 'incoming_qty': fields.function(_product_incoming_qty, method=True, type='float', string='Incoming', help="Quantities of products that are planned to arrive in selected locations or all internal if none have been selected."), + 'outgoing_qty': fields.function(_product_outgoing_qty, method=True, type='float', string='Outgoing', help="Quantities of products that are planned to leave in selected locations or all internal if none have been selected."), + 'track_production' : fields.boolean('Track Production Lots' , help="Force to use a Production Lot during production order"), + 'track_incoming' : fields.boolean('Track Incomming Lots', help="Force to use a Production Lot during receptions"), + 'track_outgoing' : fields.boolean('Track Outging Lots', help="Force to use a Production Lot during deliveries"), } product_product() diff --git a/addons/stock/product_view.xml b/addons/stock/product_view.xml index d4b1e9c7cf4..823f8da8d4a 100644 --- a/addons/stock/product_view.xml +++ b/addons/stock/product_view.xml @@ -68,6 +68,12 @@ + + + + + + diff --git a/addons/stock/stock.py b/addons/stock/stock.py index 4f65a49d89e..154ebd6aa3a 100644 --- a/addons/stock/stock.py +++ b/addons/stock/stock.py @@ -1225,10 +1225,6 @@ class stock_move(osv.osv): 'ref': ref, }) - - if (move.product_id.tracking and not move.prodlot_id): - raise osv.except_osv('Warning ! ','You should put a production lot for : '+move.product_id.name) - self.write(cr, uid, ids, {'state':'done'}) wf_service = netsvc.LocalService("workflow") @@ -1236,7 +1232,6 @@ class stock_move(osv.osv): wf_service.trg_trigger(uid, 'stock.move', id, cr) return True - def unlink(self, cr, uid, ids, context=None): for move in self.browse(cr, uid, ids, context=context): if move.state != 'draft': diff --git a/addons/warning/warning.py b/addons/warning/warning.py index c4b347e76c0..be2c3f74ca1 100644 --- a/addons/warning/warning.py +++ b/addons/warning/warning.py @@ -34,15 +34,15 @@ from osv import fields,osv class res_partner(osv.osv): _inherit = 'res.partner' _columns = { - 'sale_warn' : fields.boolean('Sale Order'), - 'sale_warn_msg' : fields.char('Message for Sale Order', size=64), - 'purchase_warn' : fields.boolean('Purchase Order'), - 'purchase_warn_msg' : fields.char('Message for Purchase Order', size=64), - 'picking_warn' : fields.boolean('Stock Picking'), - 'picking_warn_msg' : fields.char('Message for Stock Picking', size=64), - 'invoice_warn' : fields.boolean('Invoice'), - 'invoice_warn_msg' : fields.char('Message for Invoice', size=64), - } + 'sale_warn' : fields.boolean('Sale Order'), + 'sale_warn_msg' : fields.char('Message for Sale Order', size=64), + 'purchase_warn' : fields.boolean('Purchase Order'), + 'purchase_warn_msg' : fields.char('Message for Purchase Order', size=64), + 'picking_warn' : fields.boolean('Stock Picking'), + 'picking_warn_msg' : fields.char('Message for Stock Picking', size=64), + 'invoice_warn' : fields.boolean('Invoice'), + 'invoice_warn_msg' : fields.char('Message for Invoice', size=64), + } res_partner()