def cancel_request(self): for req in self: if self.state == 'done': raise osv.except_osv( _('Warning!'), _('Cannot cancel the request that is already processed.')) self.write({'state': 'cancel'})
def extract(self, product): """ Takes a product browse_record and extracts the appropriate data into self.data @param browse_record(product.product) product: the stock product browse record object """ if not product.x_new_ref: raise osv.except_osv( _("Product Missing Reference IP"), _("You have to enter a Reference IP for the product '%s' before you can continue" % product.name)) product_node = { 'CODE_ART': product.x_new_ref, 'LIB_LONG': product.name, 'TYPE_ART': product.type or '', 'CAT_ART': 'PRO', 'ART_PHYSIQUE': (product.type != 'service'), 'EAN': product.ean13 or '', 'DELAIVENTE': product.sale_delay or 0, 'LONGUEUR': product.x_depth or 0, 'LARGEUR': product.x_width or 0, 'HAUTEUR': product.x_height or 0, 'POIDS': int(product.weight_net * 1000) or 0, 'URL': product.x_url or '', } self.insert_data('PRODUCT', product_node)
def create_activity(self, cr, uid, vals_activity=None, vals_data=None, context=None): """ When creating a new activity of this type, an exception will be raised if the :class:`spell<base.nh_clinical_spell>` already has an open GCS. :returns: :class:`activity<activity.nh_activity>` id. :rtype: int """ if not vals_activity: vals_activity = {} if not vals_data: vals_data = {} assert vals_data.get('patient_id'), "patient_id is a required field!" activity_pool = self.pool['nh.activity'] domain = [['patient_id', '=', vals_data['patient_id']], ['data_model', '=', self._name], ['state', 'in', ['new', 'started', 'scheduled']]] ids = activity_pool.search(cr, SUPERUSER_ID, domain) if len(ids): raise osv.except_osv( "GCS Create Error!", "Having more than one activity of type '%s' " "is restricted. Terminate activities with " "ids=%s first" % (self._name, str(ids))) return super(nh_clinical_patient_observation_gcs, self).create_activity(cr, uid, vals_activity, vals_data, context)
def do_entry_timesheet(self): timesheet_id = False if self.analytic_account_id.id: timesheet_obj = self.pool.get('hr.analytic.timesheet') cr = self.env.cr uid = self.env.uid emp_obj = self.env['hr.employee'] hour = 0.0 res = timesheet_obj.default_get(cr, uid, ['product_id','product_uom_id']) if not res['product_uom_id']: raise osv.except_osv(_('User Error!'), _('Please define cost unit for this employee.')) up = timesheet_obj.on_change_unit_amount(cr, uid, False, res['product_id'], hour,False, res['product_uom_id'])['value'] res['name'] = "From Time Tracker" res['account_id'] = self.analytic_account_id.id res['unit_amount'] = hour res['service_desc_id'] = self.service_desc_id.id res['emp_comment'] = self.emp_comment emp_journal = emp_obj.search([('user_id', '=', self.env.uid)]).journal_id res['journal_id'] = emp_journal and emp_journal.id or False res.update(up) up = timesheet_obj.on_change_account_id(cr, uid, [], res['account_id']).get('value', {}) res.update(up) timesheet_id = timesheet_obj.create(cr, uid, res) return timesheet_id
def _email_alias_email(self): if self.email_alias_email: ir_model = self.env['ir.model'] mail_alias_model = self.env['mail.alias'] partner_model_ids = ir_model.search([ ('model', '=', 'res.partner') ]) if self.email_alias_email: alias_name = self.email_alias_email + "-crm" else: alias_name = "{0}-crm2".format(uuid4().hex) mail_alias_ids = mail_alias_model.search([ ('alias_name', '=', alias_name) ]) if not mail_alias_ids: alias = mail_alias_model.create({ 'alias_name': alias_name, 'alias_model_id': partner_model_ids[0].id }) self.email_alias = alias.id self.email_alias_email = None alias.alias_force_thread_id = self.id else: raise osv.except_osv(_('UserError'), _('El Alias ya existe'))
def create_activity(self, cr, uid, vals_activity=None, vals_data=None, context=None): """ When creating a new activity of this type, an exception will be raised if the :class:`spell<base.nh_clinical_spell>` already has an open GCS. :returns: :class:`activity<activity.nh_activity>` id. :rtype: int """ if not vals_activity: vals_activity = {} if not vals_data: vals_data = {} assert vals_data.get('patient_id'), "patient_id is a required field!" activity_pool = self.pool['nh.activity'] domain = [['patient_id', '=', vals_data['patient_id']], ['data_model', '=', self._name], ['state', 'in', ['new', 'started', 'scheduled']]] ids = activity_pool.search(cr, SUPERUSER_ID, domain) if len(ids): raise osv.except_osv("GCS Create Error!", "Having more than one activity of type '%s' " "is restricted. Terminate activities with " "ids=%s first" % (self._name, str(ids))) return super( nh_clinical_patient_observation_gcs, self).create_activity( cr, uid, vals_activity, vals_data, context)
def extract(self, product): """ Takes a product browse_record and extracts the appropriate data into self.data @param browse_record(product.product) product: the stock product browse record object """ if not product.x_new_ref: raise osv.except_osv(_("Product Missing Reference IP"), _("You have to enter a Reference IP for the product '%s' before you can continue" % product.name)) product_node = { 'CODE_ART': product.x_new_ref, 'LIB_LONG': product.name, 'TYPE_ART': product.type or '', 'CAT_ART': 'PRO', 'ART_PHYSIQUE': (product.type != 'service'), 'EAN': product.ean13 or '', 'DELAIVENTE': product.sale_delay or 0, 'LONGUEUR': product.x_depth or 0, 'LARGEUR': product.x_width or 0, 'HAUTEUR': product.x_height or 0, 'POIDS': product.weight_net or 0, 'URL': product.x_url or '', } self.insert_data('PRODUCT', product_node)
def action_number(self): obj_sequence = self.env['ir.sequence'] # We write document_number field with next invoice number by # document type for obj_inv in self: invtype = obj_inv.type # if we have a journal_document_class_id is beacuse we are in a # company that use this function # also if it has a reference number we use it (for example when # cancelling for modification) if obj_inv.journal_document_class_id and not obj_inv.sii_document_number: if invtype in ('out_invoice', 'out_refund'): if not obj_inv.journal_document_class_id.sequence_id: raise osv.except_osv(_('Error!'), _( 'Please define sequence on the journal related documents to this invoice.')) sii_document_number = obj_sequence.next_by_id( obj_inv.journal_document_class_id.sequence_id.id) elif invtype in ('in_invoice', 'in_refund'): sii_document_number = obj_inv.supplier_invoice_number obj_inv.write({'sii_document_number': sii_document_number}) document_class_id = obj_inv.journal_document_class_id.sii_document_class_id.id obj_inv.move_id.write( {'document_class_id': document_class_id, 'sii_document_number': self.sii_document_number}) res = super(account_invoice, self).action_number() return res
def action_number(self): obj_sequence = self.env['ir.sequence'] # We write document_number field with next invoice number by # document type for obj_inv in self: invtype = obj_inv.type # if we have a journal_document_class_id is beacuse we are in a # company that use this function # also if it has a reference number we use it (for example when # cancelling for modification) if obj_inv.journal_document_class_id and not obj_inv.afip_document_number: if invtype in ('out_invoice', 'out_refund'): if not obj_inv.journal_document_class_id.sequence_id: raise osv.except_osv(_('Error!'), _( 'Please define sequence on the journal related documents to this invoice.')) afip_document_number = obj_sequence.next_by_id( obj_inv.journal_document_class_id.sequence_id.id) elif invtype in ('in_invoice', 'in_refund'): afip_document_number = obj_inv.supplier_invoice_number obj_inv.write({'afip_document_number': afip_document_number}) document_class_id = obj_inv.journal_document_class_id.afip_document_class_id.id obj_inv.move_id.write( {'document_class_id': document_class_id, 'afip_document_number': self.afip_document_number}) res = super(account_invoice, self).action_number() return res
def quants_reserve(self, quants, move, link=False): """Overridden here to remove recompute_pack_op modification""" toreserve = self.env['stock.quant'] reserved_availability = move.reserved_availability # split quants if needed for quant, qty in quants: if qty <= 0.0 or (quant and quant.qty <= 0.0): raise osv.except_osv( _('Error!'), _('You can not reserve a negative quantity or a negative quant.' )) if not quant: continue self._quant_split(quant, qty) toreserve |= quant reserved_availability += quant.qty # reserve quants toreserve.sudo().write({'reservation_id': move.id}) # check if move'state needs to be set as 'assigned' rounding = move.product_id.uom_id.rounding dict_move = {} if float_compare(reserved_availability, move.product_qty, precision_rounding=rounding) == 0 and \ move.state in ('confirmed', 'waiting'): dict_move['state'] = 'assigned' elif float_compare( reserved_availability, 0, precision_rounding=rounding ) > 0 and not move.partially_available: dict_move['partially_available'] = True if dict_move: move.write(dict_move)
def price_validation(self, cr, uid, ids,product_id, context=None): user = order_id.env.context.get('uid', False) if not user: return res logged_in = self.pool.get('res.users').browse(order_id.env.cr, order_id.env.uid, order_id.env.context['uid'], order_id.env.context) option = -1 sp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_selling_price') msp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_minimum_selling_price') csp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_coordinator_selling_price') if msp: option = 1 elif sp: option = 0 elif csp: option = 2 product = product_id selling_price = product.lst_price if option == 1: selling_price = product.min_selling_price elif option == 0: selling_price = product.selling_price elif option == 2: selling_price = product.coordinator_selling_price if line.price_unit < selling_price: raise osv.except_osv("Error", "You can not give any discount greater than %f for %s \n You can request for for Executive/Manager approval" % ( selling_price, line.name)) return True
def _prac_amt(self, cr, uid, ids, context=None): res = {} _acc_ids = {} if context is None: context = {} account_obj = self.pool.get('account.account') for line in self.browse(cr, uid, ids, context=context): result = 0.0 acc_ids = [x.id for x in line.general_budget_id.account_ids] if not acc_ids: raise osv.except_osv( _('Error!'), _("The Budget '%s' has no accounts!") % ustr(line.general_budget_id.name)) if not str(acc_ids) in _acc_ids: acc_ids_all = account_obj._get_children_and_consol( cr, uid, acc_ids, context=context) _acc_ids[str(acc_ids)] = acc_ids_all else: acc_ids_all = _acc_ids[str(acc_ids)] date_to = line.date_to date_from = line.date_from segment_id = line.segment_id # get lower segments (one level) #segment_tmpl_ids = [segment_id.id] #segment_tmpl_ids += segment_id.segment_tmpl_id.get_direct_childs_ids() #segment_ids = self.pool.get('analytic_segment.segment').search(cr, uid, [('segment_tmpl_id', 'in', segment_tmpl_ids)]) segment_ids = [segment_id.id] if line.analytic_account_id.id: SQL = """ SELECT a.id, a.name, a.amount FROM account_analytic_line as a INNER JOIN account_move_line as l ON l.id = a.move_id INNER JOIN account_move as m ON m.id = l.move_id WHERE a.account_id = %s AND (a.date between to_date(%s, 'yyyy-mm-dd') AND to_date(%s, 'yyyy-mm-dd')) AND a.general_account_id = ANY(%s) AND m.segment_id = ANY(%s) """ #print SQL, line.analytic_account_id.id, date_from, date_to, acc_ids, segment_ids # TODO: add more lower leves (childs of childs) #analytic_ids = self.pool.get('account.analytic.account').search(cr, uid, [('parent_id', '=', line.analytic_account_id.id)]) #analytic_ids += [line.analytic_account_id.id] cr.execute(SQL, (line.analytic_account_id.id, date_from, date_to, acc_ids_all, segment_ids)) _result = cr.fetchall() #for i in _result: # print i result = sum([i[2] for i in _result]) if result is None: result = 0.0 res[line.id] = result #print res return res
def _analytic_line_ids(self, context=None): res = {} _acc_ids = {} if context is None: context = {} for obj in self: account_obj = self.pool.get('account.account') result = 0.0 acc_ids = [x.id for x in obj.general_budget_id.account_ids] if not acc_ids: raise osv.except_osv( _('Error!'), _("The Budget '%s' has no accounts!") % str(obj.general_budget_id.name)) if not str(acc_ids) in _acc_ids: acc_ids_all = account_obj._get_children_and_consol( self._cr, self._uid, acc_ids) _acc_ids[str(acc_ids)] = acc_ids_all else: acc_ids_all = _acc_ids[str(acc_ids)] date_to = obj.date_to date_from = obj.date_from segment_id = obj.segment_id segment_ids = [segment_id.id] if obj.analytic_account_id.id: SQL = """ SELECT a.id, a.name, a.amount FROM account_analytic_line as a INNER JOIN account_move_line as l ON l.id = a.move_id INNER JOIN account_move as m ON m.id = l.move_id WHERE a.account_id = %s AND (a.date between to_date(%s, 'yyyy-mm-dd') AND to_date(%s, 'yyyy-mm-dd')) AND a.general_account_id = ANY(%s) AND m.segment_id = ANY(%s) """ #print SQL, line.analytic_account_id.id, date_from, date_to, acc_ids, segment_ids # TODO: add more lower leves (childs of childs) #analytic_ids = self.pool.get('account.analytic.account').search(cr, uid, [('parent_id', '=', line.analytic_account_id.id)]) #analytic_ids += [line.analytic_account_id.id] self.env.cr.execute(SQL, (obj.analytic_account_id.id, date_from, date_to, acc_ids_all, segment_ids)) _result = self.env.cr.fetchall() #for i in _result: # print i if _result: self.analytic_line_ids = self.env[ 'account.analytic.line'].browse( [i[0] for i in _result])
def action_apply(self, cr, uid, ids, context=None): """ This is just copy paste from the tko_crm_pdf addon but removed the part where the origin of the opportunity is changed. """ from openerp import osv import time if context is None: context = {} lead_obj = self.pool['crm.lead'] lead_product_pool = self.pool.get('lead.product.rel') w = self.browse(cr, uid, ids, context=context)[0] if w.name == 'merge': opp_type = False for opp in w.opportunity_ids: if opp.type == 'opportunity': if not opp_type: opp_type = opp.opportunity_type elif opp.opportunity_type != opp_type: raise osv.except_osv(_('Error'), _("You can't join opportunities with different opportunity types!")) lead_id = lead_obj.merge_opportunity(cr, uid, [o.id for o in w.opportunity_ids], context=context) lead_ids = [lead_id] lead = lead_obj.read(cr, uid, lead_id, ['type', 'user_id'], context=context) if lead['type'] == "lead": context.update({'active_ids': lead_ids}) self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids, 'user_ids': [w.user_id.id], 'section_id': w.section_id.id}, context=context) elif not context.get('no_force_assignation') or not lead['user_id']: lead_obj.write(cr, uid, [lead_id], {'user_id': w.user_id.id, 'section_id': w.section_id.id, 'fundraising_date': w.fundraising_date}, context=context) else: lead_ids = context.get('active_ids', []) self._convert_opportunity(cr, uid, ids, {'lead_ids': lead_ids, 'user_ids': [w.user_id.id], 'section_id': w.section_id.id}, context=context) current_date = time.strftime("%Y-%m-%d") for lead_id in lead_ids: ref = self.pool.get('ir.sequence').get(cr, uid, w.opportunity_type + '.opportunity.sequence') product = lead_obj.browse(cr,uid,lead_id).product_id if w.action == 'exist': partner_id = w.partner_id.id if w.partner_id else False else: lead = lead_obj.browse(cr,uid,lead_id) partner_id = lead.partner_id.id if lead.partner_id else False lead_product_pool.create(cr,uid,{ 'lead_id': lead_id, 'product_id': product.id if product else False, }) vals = {'partner_id': partner_id,'opportunity_type': w.opportunity_type, 'opportunity_ref': ref, 'fundraising_date': w.fundraising_date, 'opportunity_date': current_date} lead_obj.write(cr, uid, [lead_id], vals, context=context) return self.pool.get('crm.lead').redirect_opportunity_view(cr, uid, lead_ids[0], context=context)
def print_quotation(self, cr, uid, ids, context=None): order_id = self.browse(cr, uid, ids, context) user = order_id.env.context.get('uid', False) if order_id.state == 'draft' or order_id.state == 'waiting_exec_approval' or order_id.state == 'waiting_mgr_approval': if not user: return res logged_in = self.pool.get('res.users').browse( order_id.env.cr, order_id.env.uid, order_id.env.context['uid'], order_id.env.context) cr = order_id.env.cr uid = logged_in.id option = -1 sp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_selling_price') msp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_minimum_selling_price') csp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_coordinator_selling_price') if msp: option = 1 elif sp: option = 0 elif csp: option = 2 for order in self.browse(cr, uid, ids, context): for line in order.order_line: product = line.product_id selling_price = product.lst_price if option == 1: selling_price = product.min_selling_price elif option == 0: selling_price = product.selling_price elif option == 2: selling_price = product.coordinator_selling_price if line.price_unit < selling_price: raise osv.except_osv( "Error", "You can not give any discount greater than %f for %s \n You can request for for Executive/Manager approval" % (selling_price, line.name)) ''' This function prints the sales order and mark it as sent, so that we can see more easily the next step of the workflow ''' assert len( ids ) == 1, 'This option should only be used for a single id at a time' self.signal_workflow(cr, uid, ids, 'quotation_sent') return self.pool['report'].get_action(cr, uid, ids, 'sale.report_saleorder', context=context)
def get_included_opening_period(self, period): if (self.name == 'account.account_report_trial_balance_webkit' and isinstance(period, unicode)): if '01-01' not in period: return [] period_obj = self.pool.get('account.period') initial_date = period period = period_obj.find(self.cr, self.uid, period) if not period: raise osv.except_osv(_( 'No period found for %s') % initial_date, '') period = period_obj.browse(self.cr, self.uid, period[0]) return super(TrialBalanceDateWebkit, self).get_included_opening_period( period)
def action_quote_approve(self, cr, uid, ids, context=None): order_id = self.browse(cr, uid, ids, context) print order_id price_list = order_id.partner_id.property_product_pricelist.id if price_list != 1: return res user = order_id.env.context.get('uid', False) if not user: return res logged_in = self.pool.get('res.users').browse( order_id.env.cr, order_id.env.uid, order_id.env.context['uid'], order_id.env.context) cr = order_id.env.cr uid = logged_in.id option = -1 sp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_selling_price') msp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_minimum_selling_price') csp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_coordinator_selling_price') if msp: option = 1 elif sp: option = 0 elif csp: option = 2 for order in self.browse(cr, uid, ids, context): for line in order.order_line: product = line.product_id selling_price = product.lst_price if option == 1: selling_price = product.min_selling_price elif option == 0: selling_price = product.selling_price elif option == 2: selling_price = product.coordinator_selling_price if line.price_unit < selling_price: raise osv.except_osv( "Error", "You can not give any discount greater than %f for %s \n You can request for manager approval" % (selling_price, line.name)) res = self.write(cr, uid, ids, {'state': 'quote_approved'}, context=context) return res
def batch_confirm(self, cr, uid, ids, context=None): if context is None: context = {} order_obj = self.pool.get('sale.order') for sale_order in order_obj.browse(cr, uid, context.get(('active_ids'), []), context=context): if sale_order.state != 'draft': raise osv.except_osv(_('Warning!'), _("订单 %s 不是草稿状态!") % (sale_order.name)) result = order_obj.action_button_confirm(cr, uid, [sale_order.id], context=context) return result
def make_purchase_order(self, partner_id): """ Create New RFQ for Supplier """ context = dict(self._context or {}) assert partner_id, 'Supplier should be specified' purchase_order = self.env['purchase.order'] purchase_order_line = self.env['purchase.order.line'] res_partner = self.env['res.partner'] supplier = res_partner.browse(partner_id) res = {} for requisition in self: if not requisition.multiple_rfq_per_supplier and supplier.id in filter(lambda x: x, [rfq.state != 'cancel' and rfq.partner_id.id or None for rfq in requisition.purchase_ids]): raise osv.except_osv(_('Warning!'), _('You have already one %s purchase order for this partner, you must cancel this purchase order to create a new quotation.') % rfq.state) context.update({'mail_create_nolog': True}) purchase_id = purchase_order.create(self._prepare_purchase_order(requisition, supplier)) res[requisition.id] = purchase_id for line in requisition.line_ids: if partner_id in line.suppliers.ids: purchase_order_line.create(self._prepare_purchase_order_line(requisition, line, purchase_id.id, supplier)) return res
def start(self, activity_id): super_return = super(NhClinicalObsStop, self).start(activity_id) activity_model = self.env['nh.activity'] activity = activity_model.browse(activity_id) cancel_reason_pme = \ self.env['ir.model.data'].get_object( 'nh_eobs', 'cancel_reason_patient_monitoring_exception' ) cancel_open_ews = self.cancel_open_ews(activity.parent_id.id, cancel_reason_pme.id) # self._cancel_open_food_and_fluid_review_tasks() if not cancel_open_ews: raise osv.except_osv( 'Error', 'There was an issue cancelling ' 'all open NEWS activities') self.set_obs_stop_flag(True) self.set_refusing_obs_flag(False) return super_return
def print_quotation(self, cr, uid, ids, context=None): order_id = self.browse(cr,uid,ids,context) user = order_id.env.context.get('uid', False) if order_id.state == 'draft' or order_id.state == 'waiting_exec_approval' or order_id.state == 'waiting_mgr_approval': if not user: return res logged_in = self.pool.get('res.users').browse(order_id.env.cr, order_id.env.uid, order_id.env.context['uid'], order_id.env.context) cr = order_id.env.cr uid = logged_in.id option = -1 sp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_selling_price') msp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_minimum_selling_price') csp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_coordinator_selling_price') if msp: option = 1 elif sp: option = 0 elif csp: option = 2 for order in self.browse(cr,uid,ids,context): for line in order.order_line: product = line.product_id selling_price = product.lst_price if option == 1: selling_price = product.min_selling_price elif option == 0: selling_price = product.selling_price elif option == 2: selling_price = product.coordinator_selling_price if line.price_unit < selling_price: raise osv.except_osv("Error", "You can not give any discount greater than %f for %s \n You can request for for Executive/Manager approval" % ( selling_price, line.name)) ''' This function prints the sales order and mark it as sent, so that we can see more easily the next step of the workflow ''' assert len(ids) == 1, 'This option should only be used for a single id at a time' self.signal_workflow(cr, uid, ids, 'quotation_sent') return self.pool['report'].get_action(cr, uid, ids, 'sale.report_saleorder', context=context)
def action_quote_approve(self,cr,uid,ids,context=None): order_id = self.browse(cr,uid,ids,context) print order_id price_list = order_id.partner_id.property_product_pricelist.id if price_list != 1: return res user = order_id.env.context.get('uid', False) if not user: return res logged_in = self.pool.get('res.users').browse(order_id.env.cr, order_id.env.uid, order_id.env.context['uid'], order_id.env.context) cr = order_id.env.cr uid = logged_in.id option = -1 sp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_selling_price') msp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_minimum_selling_price') csp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_coordinator_selling_price') if msp: option = 1 elif sp: option = 0 elif csp: option = 2 for order in self.browse(cr,uid,ids,context): for line in order.order_line: product = line.product_id selling_price = product.lst_price if option == 1: selling_price = product.min_selling_price elif option == 0: selling_price = product.selling_price elif option == 2: selling_price = product.coordinator_selling_price if line.price_unit < selling_price: raise osv.except_osv("Error", "You can not give any discount greater than %f for %s \n You can request for manager approval" % ( selling_price, line.name)) res = self.write(cr,uid,ids,{'state':'quote_approved'}, context=context) return res
def start(self, activity_id): super_return = super(NhClinicalObsStop, self).start(activity_id) activity_model = self.env['nh.activity'] activity = activity_model.browse(activity_id) cancel_reason_pme = \ self.env['ir.model.data'].get_object( 'nh_eobs', 'cancel_reason_patient_monitoring_exception' ) cancel_open_ews = self.cancel_open_ews(activity.parent_id.id, cancel_reason_pme.id) # self._cancel_open_food_and_fluid_review_tasks() if not cancel_open_ews: raise osv.except_osv( 'Error', 'There was an issue cancelling ' 'all open NEWS activities' ) self.set_obs_stop_flag(True) self.set_refusing_obs_flag(False) return super_return
def button_print_report(self, cr, uid, ids, data, context=None): datas = {} output_format = "" if context is None: context = {} datas["form"] = self.read(cr, uid, ids)[0] if datas["form"]["output_format"] == "xls": output_format = "report_income_statement_xls" elif datas["form"]["output_format"] == "ods": output_format = "report_income_statement_ods" else: err = "Output Format cannot be empty" raise osv.except_osv(_("Warning"), _(err)) return { "type": "ir.actions.report.xml", "report_name": output_format, "datas": datas, }
def button_print_report(self, cr, uid, ids, data, context=None): datas = {} output_format = '' if context is None: context = {} datas['form'] = self.read(cr, uid, ids)[0] if datas['form']['output_format'] == 'xls': output_format = 'report_income_statement_xls' elif datas['form']['output_format'] == 'ods': output_format = 'report_income_statement_ods' else: err = 'Output Format cannot be empty' raise osv.except_osv(_('Warning'), _(err)) return { 'type': 'ir.actions.report.xml', 'report_name': output_format, 'datas': datas, }
def price_validation(self, cr, uid, ids, product_id, context=None): user = order_id.env.context.get('uid', False) if not user: return res logged_in = self.pool.get('res.users').browse( order_id.env.cr, order_id.env.uid, order_id.env.context['uid'], order_id.env.context) option = -1 sp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_selling_price') msp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_minimum_selling_price') csp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_coordinator_selling_price') if msp: option = 1 elif sp: option = 0 elif csp: option = 2 product = product_id selling_price = product.lst_price if option == 1: selling_price = product.min_selling_price elif option == 0: selling_price = product.selling_price elif option == 2: selling_price = product.coordinator_selling_price if line.price_unit < selling_price: raise osv.except_osv( "Error", "You can not give any discount greater than %f for %s \n You can request for for Executive/Manager approval" % (selling_price, line.name)) return True
def _prepare_name_get(self, cr, uid, bank_dicts, context=None): """ Format the name of a res.partner.bank. This function is designed to be inherited to add replacement fields. :param bank_dicts: a list of res.partner.bank dicts, as returned by the method read() :return: [(id, name), ...], as returned by the method name_get() """ # prepare a mapping {code: format_layout} for all bank types bank_type_obj = self.pool.get('res.partner.bank.type') bank_types = bank_type_obj.browse(cr, uid, bank_type_obj.search(cr, uid, []), context=context) bank_code_format = dict((bt.code, bt.format_layout) for bt in bank_types) res = [] for data in bank_dicts: name = data['acc_number'] if data['state'] and bank_code_format.get(data['state']): try: if not data.get('bank_name'): data['bank_name'] = _('BANK') name = bank_code_format[data['state']] % data except Exception: raise osv.except_osv(_("Formating Error"), _("Invalid Bank Account Type Name format.")) res.append((data.get('id', False), name)) return res
def create_invoice(self, cr, uid, ids, context={}): invoice_obj = self.pool.get('account.invoice') appointment_obj = self.pool.get('medical.appointment') apps = context.get('active_ids') pats = [] for app_id in apps: pats.append( appointment_obj.browse(cr, uid, app_id).patient.name.id) if pats.count(pats[0]) == len(pats): invoice_data = {} for app_id in apps: appointment = appointment_obj.browse(cr, uid, app_id) # Check if the appointment is invoice exempt, and stop the invoicing process if appointment.no_invoice: raise osv.except_osv( _('UserError'), _('The appointment is invoice exempt')) if appointment.validity_status == 'invoiced': if len(apps) > 1: raise osv.except_osv( _('UserError'), _('At least one of the selected appointments is already invoiced' )) else: raise osv.except_osv(_('UserError'), _('Appointment already invoiced')) if appointment.validity_status == 'no': if len(apps) > 1: raise osv.except_osv( _('UserError'), _('At least one of the selected appointments can not be invoiced' )) else: raise osv.except_osv( _('UserError'), _('You can not invoice this appointment')) if appointment.patient.name.id: invoice_data['partner_id'] = appointment.patient.name.id res = self.pool.get('res.partner').address_get( cr, uid, [appointment.patient.name.id], ['contact', 'invoice']) invoice_data['address_contact_id'] = res['contact'] invoice_data['address_invoice_id'] = res['invoice'] invoice_data[ 'account_id'] = appointment.patient.name.property_account_receivable.id invoice_data[ 'fiscal_position'] = appointment.patient.name.property_account_position and appointment.patient.name.property_account_position.id or False invoice_data[ 'payment_term'] = appointment.patient.name.property_payment_term and appointment.patient.name.property_payment_term.id or False prods_data = {} for app_id in apps: appointment = appointment_obj.browse(cr, uid, app_id) logging.debug( 'appointment = %s; appointment.consultations = %s', appointment, appointment.consultations) if appointment.consultations: logging.debug( 'appointment.consultations = %s; appointment.consultations.id = %s', appointment.consultations, appointment.consultations.id) if prods_data.has_key(appointment.consultations.id): prods_data[ appointment.consultations.id]['quantity'] += 1 else: a = appointment.consultations.product_tmpl_id.property_account_income.id if not a: a = appointment.consultations.categ_id.property_account_income_categ.id prods_data[appointment.consultations.id] = { 'product_id': appointment.consultations.id, 'name': appointment.consultations.name, 'quantity': 1, 'account_id': a, 'price_unit': appointment.consultations.lst_price } else: raise osv.except_osv( _('UserError'), _('No consultation service is connected with the selected appointments' )) product_lines = [] for prod_id, prod_data in prods_data.items(): product_lines.append((0, 0, { 'product_id': prod_data['product_id'], 'name': prod_data['name'], 'quantity': prod_data['quantity'], 'account_id': prod_data['account_id'], 'price_unit': prod_data['price_unit'] })) invoice_data['invoice_line'] = product_lines invoice_id = invoice_obj.create(cr, uid, invoice_data) appointment_obj.write(cr, uid, apps, {'validity_status': 'invoiced'}) return { 'domain': "[('id','=', " + str(invoice_id) + ")]", 'name': 'Create invoice', 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'account.invoice', 'type': 'ir.actions.act_window' } else: raise osv.except_osv( _('UserError'), _('When multiple appointments are selected, patient must be the same' ))
def create_prescription_invoice(self, cr, uid, ids, context={}): invoice_obj = self.pool.get('account.invoice') pres_request_obj = self.pool.get('medical.prescription.order') # prescriptions = ids # Don't use this. It will be 1 (and it would go to the invoice status of the first prescription ) # To get the IDs of the prescriptions, use the context value array for active_ids prescriptions = context.get('active_ids') pats = [] for pres_id in prescriptions: pres = pres_request_obj.browse(cr, uid, pres_id) pats.append(pres.name) logging.debug('pres = %s; pats = %s', repr(pres), repr(pats)) if pats.count(pats[0]) == len(pats): invoice_data = {} for pres_id in prescriptions: pres = pres_request_obj.browse(cr, uid, pres_id) # Check if the prescription is invoice exempt, and stop the invoicing process if pres.no_invoice: raise osv.except_osv( _('UserError'), _('The prescription is invoice exempt')) if pres.invoice_status == 'invoiced': logging.debug('pres.invoice_status = %s', repr(pres.invoice_status)) if len(prescriptions) > 1: raise osv.except_osv( _('UserError'), _('At least one of the selected prescriptions is already invoiced' )) else: raise osv.except_osv( _('UserError'), _('Prescription already invoiced')) if pres.invoice_status == 'no': if len(prescriptions) > 1: raise osv.except_osv( _('UserError'), _('At least one of the selected prescriptions can not be invoiced' )) else: raise osv.except_osv( _('UserError'), _('You can not invoice this prescription')) logging.debug('pres.name = %s', repr(pres.name)) if pres.name.name.id: invoice_data['partner_id'] = pres.name.name.id res = self.pool.get('res.partner').address_get( cr, uid, [pres.name.name.id], ['contact', 'invoice']) invoice_data['address_contact_id'] = res['contact'] invoice_data['address_invoice_id'] = res['invoice'] invoice_data[ 'account_id'] = pres.name.name.property_account_receivable.id invoice_data[ 'fiscal_position'] = pres.name.name.property_account_position and pres.name.name.property_account_position.id or False invoice_data[ 'payment_term'] = pres.name.name.property_payment_term and pres.name.name.property_payment_term.id or False prods_data = {} for pres_id in prescriptions: pres = pres_request_obj.browse(cr, uid, pres_id) logging.debug('pres.name = %s; pres.prescription_line = %s', pres.name, pres.prescription_line) # Check for empty prescription lines if not pres.prescription_line: raise osv.except_osv( _('UserError'), _('You need to have at least one prescription item in your invoice' )) for pres_line in pres.prescription_line: logging.debug( 'pres_line = %s; pres_line.medicament.name = %s; pres_line.quantity = %s', pres_line, pres_line.medicament.name, pres_line.quantity) if prods_data.has_key(pres_line.medicament.name): prods_data[pres_line.medicament. name]['quantity'] += pres_line.quantity else: a = pres_line.medicament.name.product_tmpl_id.property_account_income.id if not a: a = pres_line.medicament.name.categ_id.property_account_income_categ.id prods_data[pres_line.medicament.name] = { 'product_id': pres_line.medicament.name.id, 'name': pres_line.medicament.name.name, 'quantity': pres_line.quantity, 'account_id': a, 'price_unit': pres_line.medicament.name.lst_price } product_lines = [] for prod_id, prod_data in prods_data.items(): logging.debug('product_id = %s', repr(prod_data['product_id'])) product_lines.append((0, 0, { 'product_id': prod_data['product_id'], 'name': prod_data['name'], 'quantity': prod_data['quantity'], 'account_id': prod_data['account_id'], 'price_unit': prod_data['price_unit'] })) invoice_data['invoice_line'] = product_lines invoice_id = invoice_obj.create(cr, uid, invoice_data) pres_request_obj.write(cr, uid, prescriptions, {'invoice_status': 'invoiced'}) return { 'domain': "[('id','=', " + str(invoice_id) + ")]", 'name': 'Create Prescription Invoice', 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'account.invoice', 'type': 'ir.actions.act_window' } else: raise osv.except_osv( _('UserError'), _('When multiple prescriptions are selected, patient must be the same' ))
def process_bank_reconciliation(self, cr, uid, id, mv_line_dicts, context=None): """ Creates a move line for each item of mv_line_dicts and for the statement line. Reconcile a new move line with its counterpart_move_line_id if specified. Finally, mark the statement line as reconciled by putting the newly created move id in the column journal_entry_id. :param int id: id of the bank statement line :param list of dicts mv_line_dicts: move lines to create. If counterpart_move_line_id is specified, reconcile with it """ if context is None: context = {} st_line = self.browse(cr, uid, id, context=context) company_currency = st_line.journal_id.company_id.currency_id statement_currency = st_line.journal_id.currency or company_currency bs_obj = self.pool.get('account.bank.statement') am_obj = self.pool.get('account.move') aml_obj = self.pool.get('account.move.line') currency_obj = self.pool.get('res.currency') # Checks if st_line.bank_reconcile_id.id: raise osv.except_osv( _('Error!'), _('The bank statement line was already reconciled.')) for mv_line_dict in mv_line_dicts: for field in ['debit', 'credit', 'amount_currency']: if field not in mv_line_dict: mv_line_dict[field] = 0.0 if mv_line_dict.get('counterpart_move_line_id'): mv_line = aml_obj.browse( cr, uid, mv_line_dict.get('counterpart_move_line_id'), context=context) if mv_line.bank_reconcile_id: raise osv.except_osv( _('Error!'), _('A selected move line was already reconciled.')) bank_reconcile_obj = self.pool.get('account.bank.statement.reconcile') bank_reconcile_name = (st_line.statement_id.name or st_line.name) + "/" + str(st_line.sequence) bank_reconcile_id = bank_reconcile_obj.create( cr, uid, {'name': bank_reconcile_name}) st_line.write({'bank_reconcile_id': bank_reconcile_id}) move_created = False for mv_line_dict in mv_line_dicts: for field in ['debit', 'credit', 'amount_currency']: if field not in mv_line_dict: mv_line_dict[field] = 0.0 if mv_line_dict.get('counterpart_move_line_id'): mv_line = aml_obj.browse( cr, uid, mv_line_dict.get('counterpart_move_line_id'), context=context) mv_line.write({'bank_reconcile_id': bank_reconcile_id}) move_created = True if not move_created: # Create the move move_name = (st_line.statement_id.name or st_line.name) + "/" + str(st_line.sequence) move_vals = bs_obj._prepare_move(cr, uid, st_line, move_name, context=context) move_id = am_obj.create(cr, uid, move_vals, context=context) # Create the move line for the statement line if st_line.statement_id.currency.id != company_currency.id: if st_line.currency_id == company_currency: amount = st_line.amount_currency else: ctx = context.copy() ctx['date'] = st_line.date amount = currency_obj.compute( cr, uid, st_line.statement_id.currency.id, company_currency.id, st_line.amount, context=ctx) else: amount = st_line.amount bank_st_move_vals = bs_obj._prepare_bank_move_line( cr, uid, st_line, move_id, amount, company_currency.id, context=context) aml_obj.create(cr, uid, bank_st_move_vals, context=context) # Complete the dicts st_line_currency = st_line.currency_id or statement_currency st_line_currency_rate = st_line.currency_id and ( st_line.amount_currency / st_line.amount) or False to_create = [] for mv_line_dict in mv_line_dicts: if mv_line_dict.get('is_tax_line'): continue mv_line_dict['bank_reconcile_id'] = bank_reconcile_id mv_line_dict['ref'] = move_name mv_line_dict['move_id'] = move_id mv_line_dict['period_id'] = st_line.statement_id.period_id.id mv_line_dict['journal_id'] = st_line.journal_id.id mv_line_dict['company_id'] = st_line.company_id.id mv_line_dict['statement_id'] = st_line.statement_id.id if mv_line_dict.get('counterpart_move_line_id'): mv_line = aml_obj.browse( cr, uid, mv_line_dict['counterpart_move_line_id'], context=context) mv_line_dict[ 'partner_id'] = mv_line.partner_id.id or st_line.partner_id.id mv_line_dict['account_id'] = mv_line.account_id.id if st_line_currency.id != company_currency.id: ctx = context.copy() ctx['date'] = st_line.date mv_line_dict['amount_currency'] = mv_line_dict[ 'debit'] - mv_line_dict['credit'] mv_line_dict['currency_id'] = st_line_currency.id if st_line.currency_id and statement_currency.id == company_currency.id and st_line_currency_rate: debit_at_current_rate = self.pool.get( 'res.currency').round( cr, uid, company_currency, mv_line_dict['debit'] / st_line_currency_rate) credit_at_current_rate = self.pool.get( 'res.currency').round( cr, uid, company_currency, mv_line_dict['credit'] / st_line_currency_rate) elif st_line.currency_id and st_line_currency_rate: debit_at_current_rate = currency_obj.compute( cr, uid, statement_currency.id, company_currency.id, mv_line_dict['debit'] / st_line_currency_rate, context=ctx) credit_at_current_rate = currency_obj.compute( cr, uid, statement_currency.id, company_currency.id, mv_line_dict['credit'] / st_line_currency_rate, context=ctx) else: debit_at_current_rate = currency_obj.compute( cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'], context=ctx) credit_at_current_rate = currency_obj.compute( cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'], context=ctx) if mv_line_dict.get('counterpart_move_line_id'): # post an account line that use the same currency rate than the counterpart (to balance the account) and post the difference in another line ctx['date'] = mv_line.date if mv_line.currency_id.id == mv_line_dict['currency_id'] \ and float_is_zero(abs(mv_line.amount_currency) - abs(mv_line_dict['amount_currency']), precision_rounding=mv_line.currency_id.rounding): debit_at_old_rate = mv_line.credit credit_at_old_rate = mv_line.debit else: debit_at_old_rate = currency_obj.compute( cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['debit'], context=ctx) credit_at_old_rate = currency_obj.compute( cr, uid, st_line_currency.id, company_currency.id, mv_line_dict['credit'], context=ctx) mv_line_dict['credit'] = credit_at_old_rate mv_line_dict['debit'] = debit_at_old_rate if debit_at_old_rate - debit_at_current_rate: currency_diff = debit_at_current_rate - debit_at_old_rate to_create.append( self.get_currency_rate_line(cr, uid, st_line, -currency_diff, move_id, context=context)) if credit_at_old_rate - credit_at_current_rate: currency_diff = credit_at_current_rate - credit_at_old_rate to_create.append( self.get_currency_rate_line(cr, uid, st_line, currency_diff, move_id, context=context)) if mv_line.currency_id and mv_line_dict[ 'currency_id'] == mv_line.currency_id.id: amount_unreconciled = mv_line.amount_residual_currency else: amount_unreconciled = currency_obj.compute( cr, uid, company_currency.id, mv_line_dict['currency_id'], mv_line.amount_residual, context=ctx) if float_is_zero(mv_line_dict['amount_currency'] + amount_unreconciled, precision_rounding=mv_line. currency_id.rounding): amount = mv_line_dict['debit'] or mv_line_dict[ 'credit'] sign = -1 if mv_line_dict['debit'] else 1 currency_rate_difference = sign * ( mv_line.amount_residual - amount) if not company_currency.is_zero( currency_rate_difference): exchange_lines = self._get_exchange_lines( cr, uid, st_line, mv_line, currency_rate_difference, mv_line_dict['currency_id'], move_id, context=context) for exchange_line in exchange_lines: to_create.append(exchange_line) else: mv_line_dict['debit'] = debit_at_current_rate mv_line_dict['credit'] = credit_at_current_rate elif statement_currency.id != company_currency.id: # statement is in foreign currency but the transaction is in company currency prorata_factor = ( mv_line_dict['debit'] - mv_line_dict['credit']) / st_line.amount_currency mv_line_dict[ 'amount_currency'] = prorata_factor * st_line.amount to_create.append(mv_line_dict) # If the reconciliation is performed in another currency than the company currency, the amounts are converted to get the right debit/credit. # If there is more than 1 debit and 1 credit, this can induce a rounding error, which we put in the foreign exchane gain/loss account. if st_line_currency.id != company_currency.id: diff_amount = bank_st_move_vals['debit'] - bank_st_move_vals['credit'] \ + sum(aml['debit'] for aml in to_create) - sum(aml['credit'] for aml in to_create) if not company_currency.is_zero(diff_amount): diff_aml = self.get_currency_rate_line(cr, uid, st_line, diff_amount, move_id, context=context) diff_aml['name'] = _( 'Rounding error from currency conversion') to_create.append(diff_aml) # Create move lines move_line_pairs_to_reconcile = [] for mv_line_dict in to_create: counterpart_move_line_id = None # NB : this attribute is irrelevant for aml_obj.create() and needs to be removed from the dict if mv_line_dict.get('counterpart_move_line_id'): counterpart_move_line_id = mv_line_dict[ 'counterpart_move_line_id'] del mv_line_dict['counterpart_move_line_id'] new_aml_id = aml_obj.create(cr, uid, mv_line_dict, context=context) if counterpart_move_line_id != None: move_line_pairs_to_reconcile.append( [new_aml_id, counterpart_move_line_id]) # Reconcile #for pair in move_line_pairs_to_reconcile: # aml_obj.reconcile_partial(cr, uid, pair, context=context) # Mark the statement line as reconciled self.write(cr, uid, id, {'journal_entry_id': move_id}, context=context)
def _run_wkhtmltopdf(self, cr, uid, headers, footers, bodies, landscape, paperformat, spec_paperformat_args=None, save_in_attachment=None): """Execute wkhtmltopdf as a subprocess in order to convert html given in input into a pdf document. Additiona :param header: list of string containing the headers :param footer: list of string containing the footers :param bodies: list of string containing the reports :param landscape: boolean to force the pdf to be rendered under a landscape format :param paperformat: ir.actions.report.paperformat to generate the wkhtmltopf arguments :param specific_paperformat_args: dict of prioritized paperformat arguments :param save_in_attachment: dict of reports to save/load in/from the db :returns: Content of the pdf as a string """ command_args = [] # Passing the cookie to wkhtmltopdf in order to resolve internal links. try: if request: command_args.extend(['--cookie', 'session_id', request.session.sid]) except AttributeError: pass # Wkhtmltopdf arguments command_args.extend(['--quiet']) # Less verbose error messages if paperformat: # Convert the paperformat record into arguments command_args.extend(self._build_wkhtmltopdf_args(paperformat, spec_paperformat_args)) # Force the landscape orientation if necessary if landscape and '--orientation' in command_args: command_args_copy = list(command_args) for index, elem in enumerate(command_args_copy): if elem == '--orientation': del command_args[index] del command_args[index] command_args.extend(['--orientation', 'landscape']) elif landscape and not '--orientation' in command_args: command_args.extend(['--orientation', 'landscape']) # Execute WKhtmltopdf pdfdocuments = [] temporary_files = [] for index, reporthtml in enumerate(bodies): local_command_args = [] pdfreport_fd, pdfreport_path = tempfile.mkstemp(suffix='.pdf', prefix='report.tmp.') temporary_files.append(pdfreport_path) # Directly load the document if we already have it if save_in_attachment and save_in_attachment['loaded_documents'].get(reporthtml[0]): with closing(os.fdopen(pdfreport_fd, 'w')) as pdfreport: pdfreport.write(save_in_attachment['loaded_documents'][reporthtml[0]]) pdfdocuments.append(pdfreport_path) continue else: os.close(pdfreport_fd) # Wkhtmltopdf handles header/footer as separate pages. Create them if necessary. if headers: head_file_fd, head_file_path = tempfile.mkstemp(suffix='.html', prefix='report.header.tmp.') temporary_files.append(head_file_path) with closing(os.fdopen(head_file_fd, 'w')) as head_file: head_file.write(headers[index]) local_command_args.extend(['--header-html', head_file_path]) if footers: foot_file_fd, foot_file_path = tempfile.mkstemp(suffix='.html', prefix='report.footer.tmp.') temporary_files.append(foot_file_path) with closing(os.fdopen(foot_file_fd, 'w')) as foot_file: foot_file.write(footers[index]) local_command_args.extend(['--footer-html', foot_file_path]) # Body stuff content_file_fd, content_file_path = tempfile.mkstemp(suffix='.html', prefix='report.body.tmp.') temporary_files.append(content_file_path) with closing(os.fdopen(content_file_fd, 'w')) as content_file: content_file.write(reporthtml[1]) try: wkhtmltopdf = [_get_wkhtmltopdf_bin()] + command_args + local_command_args wkhtmltopdf += [content_file_path] + [pdfreport_path] process = subprocess.Popen(wkhtmltopdf, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() if process.returncode not in [0, 1]: raise osv.except_osv(_('Report (PDF)'), _('Wkhtmltopdf failed (error code: %s). ' 'Message: %s') % (str(process.returncode), err)) # Save the pdf in attachment if marked if reporthtml[0] is not False and save_in_attachment.get(reporthtml[0]): with open(pdfreport_path, 'rb') as pdfreport: attachment = { 'name': save_in_attachment.get(reporthtml[0]), 'datas': base64.encodestring(pdfreport.read()), 'datas_fname': save_in_attachment.get(reporthtml[0]), 'res_model': save_in_attachment.get('model'), 'res_id': reporthtml[0], } try: self.pool['ir.attachment'].create(cr, uid, attachment) except AccessError: _logger.warning("Cannot save PDF report %r as attachment", attachment['name']) else: _logger.info('The PDF document %s is now saved in the database', attachment['name']) pdfdocuments.append(pdfreport_path) except: raise # Return the entire document if len(pdfdocuments) == 1: entire_report_path = pdfdocuments[0] else: entire_report_path = self._merge_pdf(pdfdocuments) temporary_files.append(entire_report_path) with open(entire_report_path, 'rb') as pdfdocument: content = pdfdocument.read() # Manual cleanup of the temporary files for temporary_file in temporary_files: try: os.unlink(temporary_file) except (OSError, IOError): _logger.error('Error when trying to remove file %s' % temporary_file) return content
def create_lab_invoice(self, cr, uid, ids, context={}): invoice_obj = self.pool.get('account.invoice') test_request_obj = self.pool.get('medical.patient.lab.test') tests = context.get ('active_ids') logging.debug('tests = %s', repr(tests)) pats = [] for test_id in tests: #pats.append(test_request_obj.browse(cr, uid, test_id).patient_id) cur_test = test_request_obj.browse(cr, uid, test_id) logging.debug('cur_test = %s; pats = %s', repr(cur_test), repr(pats)) pats.append(cur_test.patient_id) logging.debug('pats = %s', repr(pats)) if pats.count(pats[0]) == len(pats): invoice_data = {} for test_id in tests: #test = self.browse(cr, uid, test_id) test = test_request_obj.browse(cr, uid, test_id) logging.debug('test = %s', repr(test)) if test.invoice_status == 'invoiced': if len(tests) > 1: raise osv.except_osv(_('UserError'), _('At least one of the selected lab tests is already invoiced')) else: raise osv.except_osv(_('UserError'), _('Lab test already invoiced')) if test.invoice_status == 'no': if len(tests) > 1: raise osv.except_osv(_('UserError'), _('At least one of the selected lab tests can not be invoiced')) else: raise osv.except_osv(_('UserError'), _('You can not invoice this lab test')) logging.debug('test.patient_id = %s; test.patient_id.id = %s', test.patient_id, test.patient_id.id) if test.patient_id.name.id: invoice_data['partner_id'] = test.patient_id.name.id res = self.pool.get('res.partner').address_get(cr, uid, [test.patient_id.name.id], ['contact', 'invoice']) invoice_data['address_contact_id'] = res['contact'] invoice_data['address_invoice_id'] = res['invoice'] invoice_data['account_id'] = test.patient_id.name.property_account_receivable.id invoice_data['fiscal_position'] = test.patient_id.name.property_account_position and test.patient_id.name.property_account_position.id or False invoice_data['payment_term'] = test.patient_id.name.property_payment_term and test.patient_id.name.property_payment_term.id or False prods_data = {} tests = context.get ('active_ids') logging.debug('tests = %s', repr(tests)) for test_id in tests: test = test_request_obj.browse(cr, uid, test_id) logging.debug('test.name = %s; test.name.product_id = %s; test.name.product_id.id = %s', test.name, test.name.product_id, test.name.product_id.id) if prods_data.has_key(test.name.product_id.id): logging.debug('prods_data = %s; test.name.product_id.id = %s', prods_data, test.name.product_id.id) prods_data[test.name.product_id.id]['quantity'] += 1 else: logging.debug('test.name.product_id.id = %s', test.name.product_id.id) a = test.name.product_id.product_tmpl_id.property_account_income.id if not a: a = test.name.product_id.categ_id.property_account_income_categ.id prods_data[test.name.product_id.id] = {'product_id':test.name.product_id.id, 'name':test.name.product_id.name, 'quantity':1, 'account_id':a, 'price_unit':test.name.product_id.lst_price} logging.debug('prods_data[test.name.product_id.id] = %s', prods_data[test.name.product_id.id]) product_lines = [] for prod_id, prod_data in prods_data.items(): product_lines.append((0, 0, {'product_id':prod_data['product_id'], 'name':prod_data['name'], 'quantity':prod_data['quantity'], 'account_id':prod_data['account_id'], 'price_unit':prod_data['price_unit']})) invoice_data['invoice_line'] = product_lines invoice_id = invoice_obj.create(cr, uid, invoice_data) test_request_obj.write(cr, uid, tests, {'invoice_status':'invoiced'}) return { 'domain': "[('id','=', " + str(invoice_id) + ")]", 'name': 'Create Lab Invoice', 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'account.invoice', 'type': 'ir.actions.act_window' } else: raise osv.except_osv(_('UserError'), _('When multiple lab tests are selected, patient must be the same'))
def _run_wkhtmltopdf(self, cr, uid, headers, footers, bodies, landscape, paperformat, spec_paperformat_args=None, save_in_attachment=None): """Execute wkhtmltopdf as a subprocess in order to convert html given in input into a pdf document. Additiona :param header: list of string containing the headers :param footer: list of string containing the footers :param bodies: list of string containing the reports :param landscape: boolean to force the pdf to be rendered under a landscape format :param paperformat: ir.actions.report.paperformat to generate the wkhtmltopf arguments :param specific_paperformat_args: dict of prioritized paperformat arguments :param save_in_attachment: dict of reports to save/load in/from the db :returns: Content of the pdf as a string """ command_args = [] # Passing the cookie to wkhtmltopdf in order to resolve internal links. try: if request: command_args.extend( ['--cookie', 'session_id', request.session.sid]) except AttributeError: pass # Wkhtmltopdf arguments command_args.extend(['--quiet']) # Less verbose error messages if paperformat: # Convert the paperformat record into arguments command_args.extend( self._build_wkhtmltopdf_args(paperformat, spec_paperformat_args)) # Force the landscape orientation if necessary if landscape and '--orientation' in command_args: command_args_copy = list(command_args) for index, elem in enumerate(command_args_copy): if elem == '--orientation': del command_args[index] del command_args[index] command_args.extend(['--orientation', 'landscape']) elif landscape and not '--orientation' in command_args: command_args.extend(['--orientation', 'landscape']) # Execute WKhtmltopdf pdfdocuments = [] temporary_files = [] for index, reporthtml in enumerate(bodies): local_command_args = [] pdfreport_fd, pdfreport_path = tempfile.mkstemp( suffix='.pdf', prefix='report.tmp.') temporary_files.append(pdfreport_path) # Directly load the document if we already have it if save_in_attachment and save_in_attachment[ 'loaded_documents'].get(reporthtml[0]): with closing(os.fdopen(pdfreport_fd, 'w')) as pdfreport: pdfreport.write( save_in_attachment['loaded_documents'][reporthtml[0]]) pdfdocuments.append(pdfreport_path) continue else: os.close(pdfreport_fd) # Wkhtmltopdf handles header/footer as separate pages. Create them if necessary. if headers: head_file_fd, head_file_path = tempfile.mkstemp( suffix='.html', prefix='report.header.tmp.') temporary_files.append(head_file_path) with closing(os.fdopen(head_file_fd, 'w')) as head_file: head_file.write(headers[index]) local_command_args.extend(['--header-html', head_file_path]) if footers: foot_file_fd, foot_file_path = tempfile.mkstemp( suffix='.html', prefix='report.footer.tmp.') temporary_files.append(foot_file_path) with closing(os.fdopen(foot_file_fd, 'w')) as foot_file: foot_file.write(footers[index]) local_command_args.extend(['--footer-html', foot_file_path]) # Body stuff content_file_fd, content_file_path = tempfile.mkstemp( suffix='.html', prefix='report.body.tmp.') temporary_files.append(content_file_path) with closing(os.fdopen(content_file_fd, 'w')) as content_file: content_file.write(reporthtml[1]) try: wkhtmltopdf = [_get_wkhtmltopdf_bin() ] + command_args + local_command_args wkhtmltopdf += [content_file_path] + [pdfreport_path] process = subprocess.Popen(wkhtmltopdf, stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = process.communicate() if process.returncode not in [0, 1]: raise osv.except_osv( _('Report (PDF)'), _('Wkhtmltopdf failed (error code: %s). ' 'Message: %s') % (str(process.returncode), err)) # Save the pdf in attachment if marked if reporthtml[0] is not False and save_in_attachment.get( reporthtml[0]): with open(pdfreport_path, 'rb') as pdfreport: attachment = { 'name': save_in_attachment.get(reporthtml[0]), 'datas': base64.encodestring(pdfreport.read()), 'datas_fname': save_in_attachment.get(reporthtml[0]), 'res_model': save_in_attachment.get('model'), 'res_id': reporthtml[0], } try: self.pool['ir.attachment'].create( cr, uid, attachment) except AccessError: _logger.warning( "Cannot save PDF report %r as attachment", attachment['name']) else: _logger.info( 'The PDF document %s is now saved in the database', attachment['name']) pdfdocuments.append(pdfreport_path) except: raise # Return the entire document if len(pdfdocuments) == 1: entire_report_path = pdfdocuments[0] else: entire_report_path = self._merge_pdf(pdfdocuments) temporary_files.append(entire_report_path) with open(entire_report_path, 'rb') as pdfdocument: content = pdfdocument.read() # Manual cleanup of the temporary files for temporary_file in temporary_files: try: os.unlink(temporary_file) except (OSError, IOError): _logger.error('Error when trying to remove file %s' % temporary_file) return content
def _get_serialized_challenge_lines(self, cr, uid, challenge, user_id=False, restrict_goal_ids=False, restrict_top=False, context=None): """Return a serialised version of the goals information if the user has not completed every goal :challenge: browse record of challenge to compute :user_id: res.users id of the user retrieving progress (False if no distinction, only for ranking challenges) :restrict_goal_ids: <list(int)> compute only the results for this subset if gamification.goal ids, if False retrieve every goal of current running challenge :restrict_top: <int> for challenge lines where visibility_mode == 'ranking', retrieve only these bests results and itself, if False retrieve all restrict_goal_ids has priority over restrict_top format list # if visibility_mode == 'ranking' { 'name': <gamification.goal.description name>, 'description': <gamification.goal.description description>, 'condition': <reach condition {lower,higher}>, 'computation_mode': <target computation {manually,count,sum,python}>, 'monetary': <{True,False}>, 'suffix': <value suffix>, 'action': <{True,False}>, 'display_mode': <{progress,boolean}>, 'target': <challenge line target>, 'own_goal_id': <gamification.goal id where user_id == uid>, 'goals': [ { 'id': <gamification.goal id>, 'rank': <user ranking>, 'user_id': <res.users id>, 'name': <res.users name>, 'state': <gamification.goal state {draft,inprogress,reached,failed,canceled}>, 'completeness': <percentage>, 'current': <current value>, } ] }, # if visibility_mode == 'personal' { 'id': <gamification.goal id>, 'name': <gamification.goal.description name>, 'description': <gamification.goal.description description>, 'condition': <reach condition {lower,higher}>, 'computation_mode': <target computation {manually,count,sum,python}>, 'monetary': <{True,False}>, 'suffix': <value suffix>, 'action': <{True,False}>, 'display_mode': <{progress,boolean}>, 'target': <challenge line target>, 'state': <gamification.goal state {draft,inprogress,reached,failed,canceled}>, 'completeness': <percentage>, 'current': <current value>, } """ goal_obj = self.pool.get('gamification.goal') (start_date, end_date) = start_end_date_for_period(challenge.period) res_lines = [] all_reached = True for line in challenge.line_ids: line_data = { 'name': line.definition_id.name, 'description': line.definition_id.description, 'condition': line.definition_id.condition, 'computation_mode': line.definition_id.computation_mode, 'monetary': line.definition_id.monetary, 'suffix': line.definition_id.suffix, 'action': True if line.definition_id.action_id else False, 'display_mode': line.definition_id.display_mode, 'target': line.target_goal, } domain = [ ('line_id', '=', line.id), ('state', '!=', 'draft'), ] if restrict_goal_ids: domain.append(('ids', 'in', restrict_goal_ids)) else: # if no subset goals, use the dates for restriction if start_date: domain.append(('start_date', '=', start_date)) if end_date: domain.append(('end_date', '=', end_date)) if challenge.visibility_mode == 'personal': if not user_id: raise osv.except_osv( _('Error!'), _("Retrieving progress for personal challenge without user information" )) domain.append(('user_id', '=', user_id)) sorting = goal_obj._order limit = 1 else: line_data.update({ 'own_goal_id': False, 'goals': [], }) sorting = "completeness desc, current desc" limit = False goal_ids = goal_obj.search(cr, uid, domain, order=sorting, limit=limit, context=context) ranking = 0 for goal in goal_obj.browse(cr, uid, goal_ids, context=context): definition_id = goal.definition_id # new stuff evaled_domain = safe_eval(definition_id.domain, {'user': goal.user_id}) evaled_domain = str(evaled_domain) if challenge.visibility_mode == 'personal': # limit=1 so only one result line_data.update({ 'id': goal.id, 'current': goal.current, 'completeness': goal.completeness, 'state': goal.state, 'domain': evaled_domain, 'model': definition_id.model_id.model, }) if goal.state != 'reached': all_reached = False else: ranking += 1 if user_id and goal.user_id.id == user_id: line_data['own_goal_id'] = goal.id elif restrict_top and ranking > restrict_top: # not own goal and too low to be in top continue line_data['goals'].append({ 'id': goal.id, 'user_id': goal.user_id.id, 'name': goal.user_id.name, 'rank': ranking, 'current': goal.current, 'completeness': goal.completeness, 'state': goal.state, 'domain': evaled_domain, 'model': definition_id.model_id.model, }) if goal.state != 'reached': all_reached = False if goal_ids: res_lines.append(line_data) if all_reached and not challenge.show_reached: # new stuff return [] if challenge.precision: for line in res_lines: current = line.get('current') if current: current = round( current / challenge.precision) * challenge.precision line['current'] = current return res_lines
def process_data(self, date_from, date_to): # prepare groups _acc_ids = {} groups = {} X = [] XX = [] last_day = monthrange(date_to.year, date_to.month)[1] self.date_from = datetime(date_from.year, date_from.month, 1).strftime('%Y-%m-%d') self.date_to = datetime(date_to.year, date_to.month, last_day).strftime('%Y-%m-%d') # get data from budget lines for line in self.budget_id.crossovered_budget_line: # check dates if line.date_from >= self.date_from and line.date_to <= self.date_to: group = G[line.analytic_account_id.group] first_parent = line.analytic_account_id.first_parent().name account_name = line.analytic_account_id.name # Matrix # append parents at X if first_parent not in X: X.append(first_parent.upper().strip()) # Data if not groups.has_key(group): groups[group] = {} if not groups[group].has_key(account_name): groups[group][account_name] = {} if not groups[group][account_name].has_key(first_parent): groups[group][account_name][first_parent] = [] groups[group][account_name][first_parent].append((1, line)) # get data from analytic to prepare virtual groups _search = [('date', '>=', self.date_from), ('date', '<=', self.date_to)] segment_ids = [self.budget_id.segment_id.id] # check special case - campaigns # no with_children option with campaigns if self.budget_id.segment_id.campaign_id: segment_ids += [ i.id for i in self.budget_id.segment_id.campaign_id.segment_ids ] else: _search += [('company_id', '=', self.budget_id.company_id.id)] # first segment #segment_ids = [self.budget_id.segment_id.id] if self.budget_id.with_children: segment_ids += self.budget_id.segment_id.segment_tmpl_id.get_childs_ids( ) _search.append(('segment_id', 'in', segment_ids)) # all lines from the simpler search _analytic_lines = self.env['account.analytic.line'].sudo().search( _search) analytic_lines = [] analytic_lines_obj = [] for line in _analytic_lines: code0 = line.general_account_id.code[0] code1 = line.general_account_id.code[:2] if (code0 in ['6', '7'] and code1 != '68') or code1 in ['20', '21']: analytic_lines.append(line.id) analytic_lines_obj.append(line) account_obj = self.pool.get('account.account') print 'lines:', len(self.budget_id.crossovered_budget_line) for line in self.budget_id.crossovered_budget_line: acc_ids = [x.id for x in line.general_budget_id.account_ids] if not acc_ids: raise osv.except_osv( _('Error!'), _("The Budget '%s' has no accounts!") % str(line.general_budget_id.name)) #print 'acc_ids/1', len(acc_ids) if not str(acc_ids) in _acc_ids: acc_ids_all = account_obj._get_children_and_consol( self._cr, self._uid, acc_ids) _acc_ids[str(acc_ids)] = acc_ids_all else: acc_ids_all = _acc_ids[str(acc_ids)] date_to = line.date_to date_from = line.date_from segment_id = line.segment_id # get lower segments (one level) #segment_tmpl_ids = [segment_id.id] #segment_tmpl_ids += segment_id.segment_tmpl_id.get_direct_childs_ids() #segment_ids = [i.id for i in self.env['analytic_segment.segment'].search([('segment_tmpl_id', 'in', segment_tmpl_ids)])] segment_ids = [segment_id.id] if line.analytic_account_id.id: SQL = """ SELECT a.id, a.amount FROM account_analytic_line as a INNER JOIN account_move_line as l ON l.id = a.move_id INNER JOIN account_move as m ON m.id = l.move_id WHERE a.account_id = %s AND (a.date between to_date(%s, 'yyyy-mm-dd') AND to_date(%s, 'yyyy-mm-dd')) AND a.general_account_id = ANY(%s) AND m.segment_id = ANY(%s) """ #_z = line.analytic_account_id.id, date_from, date_to, list(acc_ids), list(segment_ids) #print 'params:', line.analytic_account_id.id, date_from, date_to, acc_ids, segment_ids self.env.cr.execute(SQL, (line.analytic_account_id.id, date_from, date_to, acc_ids_all, segment_ids)) result = self.env.cr.fetchall() for res in result: #print res if res[0] in analytic_lines: #print 'removed!!!' analytic_lines.remove(res[0]) # classify data # print len(anaylitic_lines) lines = self.env['account.analytic.line'].sudo().browse(analytic_lines) for l in lines: level = l.account_id.level if level <= 2: group = G[l.account_id.group] account_name = l.account_id.name elif level == 3: group = G[l.account_id.parent_id.group] account_name = l.account_id.parent_id.name elif level == 4: group = G[l.account_id.parent_id.parent_id.group] account_name = l.account_id.parent_id.parent_id.name first_parent = l.account_id.first_parent().name # Matrix # append parents at X if first_parent not in X: X.append(first_parent.upper().strip()) # Data if not groups.has_key(group): groups[group] = {} if not groups[group].has_key(account_name): groups[group][account_name] = {} if not groups[group][account_name].has_key(first_parent): groups[group][account_name][first_parent] = [] #print group, account_name, first_parent groups[group][account_name][first_parent].append((2, l)) # reordered X if not self.budget_id.segment_id.campaign_id: refs = [ 'SALARIOS', 'MATERIALES', 'SERVICIOS EXTERNOS', 'DESPLAZAMIENTOS', 'SUSCRIPCIONES - LICENCIAS', 'OTROS' ] else: refs = ['GASTOS', 'MUNICIPALES'] for item in refs: if item in X: XX.append(item) return X, XX, groups, analytic_lines, analytic_lines_obj
def create_invoice(self, cr, uid, ids, context={}): invoice_obj = self.pool.get('account.invoice') appointment_obj = self.pool.get('medical.appointment') apps = context.get ('active_ids') pats = [] for app_id in apps: pats.append(appointment_obj.browse( cr, uid, app_id).patient.name.id) if pats.count(pats[0]) == len(pats): invoice_data={} for app_id in apps: appointment = appointment_obj.browse( cr, uid, app_id) # Check if the appointment is invoice exempt, and stop the invoicing process if appointment.no_invoice : raise osv.except_osv(_('UserError'), _('The appointment is invoice exempt')) if appointment.validity_status=='invoiced': if len(apps) > 1: raise osv.except_osv(_('UserError'),_('At least one of the selected appointments is already invoiced')) else: raise osv.except_osv(_('UserError'),_('Appointment already invoiced')) if appointment.validity_status=='no': if len(apps) > 1: raise osv.except_osv(_('UserError'),_('At least one of the selected appointments can not be invoiced')) else: raise osv.except_osv(_('UserError'),_('You can not invoice this appointment')) if appointment.patient.name.id: invoice_data['partner_id'] = appointment.patient.name.id res = self.pool.get('res.partner').address_get(cr, uid, [appointment.patient.name.id], ['contact', 'invoice']) invoice_data['address_contact_id'] = res['contact'] invoice_data['address_invoice_id'] = res['invoice'] invoice_data['account_id'] = appointment.patient.name.property_account_receivable.id invoice_data['fiscal_position'] = appointment.patient.name.property_account_position and appointment.patient.name.property_account_position.id or False invoice_data['payment_term'] = appointment.patient.name.property_payment_term and appointment.patient.name.property_payment_term.id or False prods_data = {} for app_id in apps: appointment = appointment_obj.browse( cr, uid, app_id) logging.debug('appointment = %s; appointment.consultations = %s', appointment, appointment.consultations) if appointment.consultations: logging.debug('appointment.consultations = %s; appointment.consultations.id = %s', appointment.consultations, appointment.consultations.id) if prods_data.has_key(appointment.consultations.id): prods_data[appointment.consultations.id]['quantity'] += 1 else: a = appointment.consultations.product_tmpl_id.property_account_income.id if not a: a = appointment.consultations.categ_id.property_account_income_categ.id prods_data[appointment.consultations.id] = {'product_id':appointment.consultations.id, 'name':appointment.consultations.name, 'quantity':1, 'account_id':a, 'price_unit':appointment.consultations.lst_price} else: raise osv.except_osv(_('UserError'),_('No consultation service is connected with the selected appointments')) product_lines = [] for prod_id, prod_data in prods_data.items(): product_lines.append((0,0,{'product_id':prod_data['product_id'], 'name':prod_data['name'], 'quantity':prod_data['quantity'], 'account_id':prod_data['account_id'], 'price_unit':prod_data['price_unit']})) invoice_data['invoice_line'] = product_lines invoice_id = invoice_obj.create(cr, uid, invoice_data) appointment_obj.write(cr, uid, apps, {'validity_status':'invoiced'}) return { 'domain': "[('id','=', "+str(invoice_id)+")]", 'name': 'Create invoice', 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'account.invoice', 'type': 'ir.actions.act_window' } else: raise osv.except_osv(_('UserError'),_('When multiple appointments are selected, patient must be the same'))
def action_done(self, cr, uid, ids, context=None): """ Overwrite complete the method to introduce exception on the test. """ context = context or {} picking_obj = self.pool.get("stock.picking") quant_obj = self.pool.get("stock.quant") todo = [ move.id for move in self.browse(cr, uid, ids, context=context) if move.state == "draft" ] if todo: ids = self.action_confirm(cr, uid, todo, context=context) pickings = set() procurement_ids = set() # Search operations that are linked to the moves operations = set() move_qty = {} for move in self.browse(cr, uid, ids, context=context): move_qty[move.id] = move.product_qty for link in move.linked_move_operation_ids: operations.add(link.operation_id) # Sort operations according to entire packages first, then package + # lot, package only, lot only operations = list(operations) operations.sort( key=lambda x: ((x.package_id and not x.product_id) and -4 or 0) + (x.package_id and -2 or 0) + (x.lot_id and -1 or 0)) for ops in operations: if ops.picking_id: pickings.add(ops.picking_id.id) main_domain = [('qty', '>', 0)] for record in ops.linked_move_operation_ids: move = record.move_id self.check_tracking(cr, uid, move, not ops.product_id and ops.package_id.id or ops.lot_id.id, context=context) prefered_domain = [('reservation_id', '=', move.id)] fallback_domain = [('reservation_id', '=', False)] fallback_domain2 = [ '&', ('reservation_id', '!=', move.id), ('reservation_id', '!=', False) ] prefered_domain_list = \ [prefered_domain] + [fallback_domain] + [fallback_domain2] dom = main_domain + self.pool.get( 'stock.move.operation.link').get_specific_domain( cr, uid, record, context=context) quants = quant_obj.quants_get_prefered_domain( cr, uid, ops.location_id, move.product_id, record.qty, domain=dom, prefered_domain_list=prefered_domain_list, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) if ops.product_id: # If a product is given, the result is always put # immediately in the result package (if it is False, they # are without package) quant_dest_package_id = ops.result_package_id.id ctx = context else: # When a pack is moved entirely, the quants should not be # written anything for the destination package quant_dest_package_id = False ctx = context.copy() ctx['entire_pack'] = True quant_obj.quants_move(cr, uid, quants, move, ops.location_dest_id, location_from=ops.location_id, lot_id=ops.lot_id.id, owner_id=ops.owner_id.id, src_package_id=ops.package_id.id, dest_package_id=quant_dest_package_id, context=ctx) # Handle pack in pack if (not ops.product_id and ops.package_id and ops.result_package_id.id != ops.package_id.parent_id.id): self.pool.get('stock.quant.package').write( cr, SUPERUSER_ID, [ops.package_id.id], {'parent_id': ops.result_package_id.id}, context=context) if not move_qty.get(move.id): raise osv.except_osv( _("Error"), _("The roundings of your Unit of Measures %s on the" " move vs. %s on the product don't allow to do" " these operations or you are not transferring the" " picking at once. ") % (move.product_uom.name, move.product_id.uom_id.name)) move_qty[move.id] -= record.qty # Check for remaining qtys and unreserve/check move_dest_id in move_dest_ids = set() for move in self.browse(cr, uid, ids, context=context): move_qty_cmp = float_compare( move_qty[move.id], 0, precision_rounding=move.product_id.uom_id.rounding) if move_qty_cmp > 0: # (=In case no pack operations in picking) main_domain = [('qty', '>', 0)] prefered_domain = [('reservation_id', '=', move.id)] fallback_domain = [('reservation_id', '=', False)] fallback_domain2 = [ '&', ('reservation_id', '!=', move.id), ('reservation_id', '!=', False) ] prefered_domain_list = \ [prefered_domain] + [fallback_domain] + [fallback_domain2] self.check_tracking(cr, uid, move, move.restrict_lot_id.id, context=context) qty = move_qty[move.id] quants = quant_obj.quants_get_prefered_domain( cr, uid, move.location_id, move.product_id, qty, domain=main_domain, prefered_domain_list=prefered_domain_list, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) quant_obj.quants_move(cr, uid, quants, move, move.location_dest_id, lot_id=move.restrict_lot_id.id, owner_id=move.restrict_partner_id.id, context=context) # If the move has a destination, add it to the list to reserve if (move.move_dest_id and move.move_dest_id.state in ('waiting', 'confirmed')): move_dest_ids.add(move.move_dest_id.id) if move.procurement_id: procurement_ids.add(move.procurement_id.id) # unreserve the quants and make them available for other # operations/moves quant_obj.quants_unreserve(cr, uid, move, context=context) # Check the packages have been placed in the correct locations self._check_package_from_moves(cr, uid, ids, context=context) # set the move as done # NOTE VX: This section was overwritten. for move in self.browse(cr, uid, ids, context=context): if move.has_validate_picking_after_move_date(): move_date = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) else: move_date = move.date self.write(cr, uid, [move.id], { 'state': 'done', 'date': move_date }, context=context) self.pool.get('procurement.order').check(cr, uid, list(procurement_ids), context=context) # assign destination moves if move_dest_ids: self.action_assign(cr, uid, list(move_dest_ids), context=context) # check picking state to set the date_done is needed done_picking = [] for picking in picking_obj.browse(cr, uid, list(pickings), context=context): if picking.state == 'done' and not picking.date_done: done_picking.append(picking.id) if done_picking: picking_obj.write( cr, uid, done_picking, {'date_done': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context) return True
def action_quotation_send(self, cr, uid, ids, context=None): order_id = self.browse(cr,uid,ids,context) user = order_id.env.context.get('uid', False) if order_id.state == 'draft' or order_id.state == 'waiting_exec_approval' or order_id.state == 'waiting_mgr_approval': if not user: return res logged_in = self.pool.get('res.users').browse(order_id.env.cr, order_id.env.uid, order_id.env.context['uid'], order_id.env.context) cr = order_id.env.cr uid = logged_in.id option = -1 sp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_selling_price') msp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_minimum_selling_price') csp = self.pool.get('res.users').has_group(cr, uid, 'miipl_msp.group_sell_on_coordinator_selling_price') if msp: option = 1 elif sp: option = 0 elif csp: option = 2 for order in self.browse(cr,uid,ids,context): for line in order.order_line: product = line.product_id selling_price = product.lst_price if option == 1: selling_price = product.min_selling_price elif option == 0: selling_price = product.selling_price elif option == 2: selling_price = product.coordinator_selling_price if line.price_unit < selling_price: raise osv.except_osv("Error", "You can not give any discount greater than %f for %s \n You can request for for Executive/Manager approval" % ( selling_price, line.name)) ''' This function opens a window to compose an email, with the edi sale template message loaded by default ''' assert len(ids) == 1, 'This option should only be used for a single id at a time.' ir_model_data = self.pool.get('ir.model.data') try: template_id = ir_model_data.get_object_reference(cr, uid, 'sale', 'email_template_edi_sale')[1] except ValueError: template_id = False try: compose_form_id = ir_model_data.get_object_reference(cr, uid, 'mail', 'email_compose_message_wizard_form')[1] except ValueError: compose_form_id = False ctx = dict() ctx.update({ 'default_model': 'sale.order', 'default_res_id': ids[0], 'default_use_template': bool(template_id), 'default_template_id': template_id, 'default_composition_mode': 'comment', 'mark_so_as_sent': True }) return { 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'mail.compose.message', 'views': [(compose_form_id, 'form')], 'view_id': compose_form_id, 'target': 'new', 'context': ctx, }
def voucher_move_line_create(self, cr, uid, voucher_id, line_total, move_id, company_currency, current_currency, context=None): ''' Create one account move line, on the given account move, per voucher line where amount is not 0.0. It returns Tuple with tot_line what is total of difference between debit and credit and a list of lists with ids to be reconciled with this format (total_deb_cred,list_of_lists). :param voucher_id: Voucher id what we are working with :param line_total: Amount of the first line, which correspond to the amount we should totally split among all voucher lines. :param move_id: Account move wher those lines will be joined. :param company_currency: id of currency of the company to which the voucher belong :param current_currency: id of currency of the voucher :return: Tuple build as (remaining amount not allocated on voucher lines, list of account_move_line created in this method) :rtype: tuple(float, list of int) ''' if voucher_id and self.browse(cr, uid, voucher_id).opi: if context is None: context = {} move_line_obj = self.pool.get('account.move.line') currency_obj = self.pool.get('res.currency') tax_obj = self.pool.get('account.tax') tot_line = line_total rec_lst_ids = [] date = self.read(cr, uid, voucher_id, ['date'], context=context)['date'] ctx = context.copy() ctx.update({'date': date}) voucher = self.pool.get('account.voucher').browse(cr, uid, voucher_id, context=ctx) voucher_currency = voucher.journal_id.currency or voucher.company_id.currency_id ctx.update({ 'voucher_special_currency_rate': voucher_currency.rate * voucher.payment_rate, 'voucher_special_currency': voucher.payment_rate_currency_id and voucher.payment_rate_currency_id.id or False, }) prec = self.pool.get('decimal.precision').precision_get( cr, uid, 'Account') for line in voucher.line_ids: context_line = context.copy() context_line.update({'line_amount': line.amount}) # create one move line per voucher line where amount is not 0.0 # AND (second part of the clause) only if the original move line was not having debit = credit = 0 (which is a legal value) if not line.amount and not ( line.move_line_id and not float_compare(line.move_line_id.debit, line.move_line_id.credit, precision_digits=prec) and not float_compare(line.move_line_id.debit, 0.0, precision_digits=prec)): continue # convert the amount set on the voucher line into the currency of the voucher's company # this calls res_curreny.compute() with the right context, so that it will take either the rate on the voucher if it is relevant or will use the default behaviour amount = self._convert_amount(cr, uid, line.untax_amount or line.amount, voucher.id, context=ctx) # if the amount encoded in voucher is equal to the amount unreconciled, we need to compute the # currency rate difference if line.amount == line.amount_unreconciled: if not line.move_line_id: raise osv.except_osv( _('Wrong voucher line'), _("The invoice you are willing to pay is not valid anymore." )) sign = voucher.type in ('payment', 'purchase') and -1 or 1 currency_rate_difference = sign * ( line.move_line_id.amount_residual - amount) else: currency_rate_difference = 0.0 move_line = { 'journal_id': voucher.journal_id.id, 'period_id': voucher.period_id.id, 'name': line.name or '/', 'account_id': line.account_id.id, 'move_id': move_id, 'partner_id': voucher.partner_id.id, 'currency_id': line.move_line_id and (company_currency <> line.move_line_id.currency_id.id and line.move_line_id.currency_id.id) or False, 'analytic_account_id': line.account_analytic_id and line.account_analytic_id.id or False, 'quantity': 1, 'credit': 0.0, 'debit': 0.0, 'date': voucher.date, } if amount < 0: amount = -amount if line.type == 'dr': line.type = 'cr' else: line.type = 'dr' if (line.type == 'dr'): tot_line += amount move_line['debit'] = amount else: tot_line -= amount move_line['credit'] = amount if voucher.tax_id and voucher.type in ('sale', 'purchase'): move_line.update({ 'account_tax_id': voucher.tax_id.id, }) if move_line.get('account_tax_id', False): tax_data = tax_obj.browse(cr, uid, [move_line['account_tax_id']], context=context)[0] if not (tax_data.base_code_id and tax_data.tax_code_id): raise osv.except_osv( _('No Account Base Code and Account Tax Code!'), _("You have to configure account base code and account tax code on the '%s' tax!" ) % (tax_data.name)) # compute the amount in foreign currency foreign_currency_diff = 0.0 amount_currency = False corregido = False ajuste_negativo = False if line.move_line_id: # We want to set it on the account move line as soon as the original line had a foreign currency if line.move_line_id.currency_id and line.move_line_id.currency_id.id != company_currency: # we compute the amount in that foreign currency. if line.move_line_id.currency_id.id == current_currency: # if the voucher and the voucher line share the same currency, there is no computation to do # PCARBALLO modificacion del signo del monto. # si tiene monto en debito o en credito, entonces es el caso comun, # y no se modifica el calculo del signo con respecto al estandar. # de lo contrario, chequea si el voucher tiene lineas de credito # o lineas de debito, para modificar el signo en base a ese criterio. # Se declara ademas una variable booleana "corregido", que sirve # para verificar si el codigo ingreso o no a estos casos particulares. # Se utiliza mas adelante para el calculo de la diferencia de cambio. # ECHAVIANO 26/10 ACA ESTA EL PROBLEMA EN EL PAGO DEL AJUSTE > 0 if move_line['debit'] or move_line['credit']: sign = (move_line['debit'] - move_line['credit']) < 0 and -1 or 1 amount_currency = sign * (line.amount) elif voucher.line_dr_ids or voucher.line_cr_ids and line.amount != 0: if voucher.invoice_id and line.amount != 0: if voucher.invoice_id.type in ( 'in_invoice', 'out_refund' ): # fact de proveedor o rectificativa de cliente sign = 1 elif voucher.invoice_id.type in ( 'in_refund'): # rect de proveedor corregido = True sign = (line.amount > 0) and -1 or 1 ajuste_negativo = voucher.invoice_id.amount_total < 0 and True or False # if voucher.invoice_id.residual < 0: # sign = (line.amount > 0) and -1 or 1 # else: # sign = (line.amount > 0) and 1 or -1 elif voucher.invoice_id.type in ( 'out_invoice' ): # de cliente, dividido en un else por si es un caso diferente, puede agregarse en la condicion de arriba sign = (line.amount > 0) and -1 or 1 amount_currency = sign * (line.amount) else: # if the rate is specified on the voucher, it will be used thanks to the special keys in the context # otherwise we use the rates of the system amount_currency = currency_obj.compute( cr, uid, company_currency, line.move_line_id.currency_id.id, move_line['debit'] - move_line['credit'], context=ctx) if line.amount == line.amount_unreconciled: sign = voucher.type in ('payment', 'purchase') and -1 or 1 # PCARBALLO uso de la variable corregido. # Si estamos en los casos particulares anteriormente descritos, # entonces el signo cambia, para evitar que foreign_currency_diff de un valor no nulo. if corregido: sign = sign * -1 foreign_currency_diff = sign * line.move_line_id.amount_residual_currency + amount_currency else: foreign_currency_diff = ( line.move_line_id.amount_residual_currency - abs(amount_currency)) # ECHAVIANO cambio # PCARBALLO eliminar creacion lineas con cero rec_ids = [] if amount_currency != 0 or amount != 0: if corregido and ajuste_negativo: amount_currency = amount_currency * -1 move_line['amount_currency'] = amount_currency voucher_line = move_line_obj.create(cr, uid, move_line, context=context_line) rec_ids = [voucher_line, line.move_line_id.id] if len(rec_ids) == 0: rec_ids = [line.move_line_id.id] # PCARBALLO fin eliminar creacion lineas con cero if not currency_obj.is_zero(cr, uid, voucher.company_id.currency_id, currency_rate_difference): # Change difference entry in company currency exch_lines = self._get_exchange_lines( cr, uid, line, move_id, currency_rate_difference, company_currency, current_currency, context=context) #009-Agregando flag exch_lines[0].update({'exchange_line': True}) exch_lines[1].update({'exchange_line': True}) new_id = move_line_obj.create(cr, uid, exch_lines[0], context_line) move_line_obj.create(cr, uid, exch_lines[1], context_line) rec_ids.append(new_id) if line.move_line_id and line.move_line_id.currency_id and \ not currency_obj.is_zero(cr, uid, line.move_line_id.currency_id, foreign_currency_diff): # Change difference entry in voucher currency move_line_foreign_currency = { 'journal_id': line.voucher_id.journal_id.id, 'period_id': line.voucher_id.period_id.id, 'name': _('change') + ': ' + (line.name or '/'), 'account_id': line.account_id.id, 'move_id': move_id, 'partner_id': line.voucher_id.partner_id.id, 'currency_id': line.move_line_id.currency_id.id, 'amount_currency': -1 * foreign_currency_diff, 'quantity': 1, 'credit': 0.0, 'debit': 0.0, 'date': line.voucher_id.date, #009- pasando campo en true cuando se genera tipo de cambio 'exchange_line': True, } new_id = move_line_obj.create(cr, uid, move_line_foreign_currency, context=context_line) rec_ids.append(new_id) if line.move_line_id.id: rec_lst_ids.append(rec_ids) return (tot_line, rec_lst_ids) else: return super(GrpInternalPayOrder, self).voucher_move_line_create(cr, uid, voucher_id, line_total, move_id, company_currency, current_currency, context=context)
def create_lab_invoice(self, cr, uid, ids, context={}): invoice_obj = self.pool.get('account.invoice') test_request_obj = self.pool.get('medical.patient.lab.test') tests = context.get('active_ids') logging.debug('tests = %s', repr(tests)) pats = [] for test_id in tests: #pats.append(test_request_obj.browse(cr, uid, test_id).patient_id) cur_test = test_request_obj.browse(cr, uid, test_id) logging.debug('cur_test = %s; pats = %s', repr(cur_test), repr(pats)) pats.append(cur_test.patient_id) logging.debug('pats = %s', repr(pats)) if pats.count(pats[0]) == len(pats): invoice_data = {} for test_id in tests: #test = self.browse(cr, uid, test_id) test = test_request_obj.browse(cr, uid, test_id) logging.debug('test = %s', repr(test)) if test.invoice_status == 'invoiced': if len(tests) > 1: raise osv.except_osv( _('UserError'), _('At least one of the selected lab tests is already invoiced' )) else: raise osv.except_osv(_('UserError'), _('Lab test already invoiced')) if test.invoice_status == 'no': if len(tests) > 1: raise osv.except_osv( _('UserError'), _('At least one of the selected lab tests can not be invoiced' )) else: raise osv.except_osv( _('UserError'), _('You can not invoice this lab test')) logging.debug('test.patient_id = %s; test.patient_id.id = %s', test.patient_id, test.patient_id.id) if test.patient_id.name.id: invoice_data['partner_id'] = test.patient_id.name.id res = self.pool.get('res.partner').address_get( cr, uid, [test.patient_id.name.id], ['contact', 'invoice']) invoice_data['address_contact_id'] = res['contact'] invoice_data['address_invoice_id'] = res['invoice'] invoice_data[ 'account_id'] = test.patient_id.name.property_account_receivable.id invoice_data[ 'fiscal_position'] = test.patient_id.name.property_account_position and test.patient_id.name.property_account_position.id or False invoice_data[ 'payment_term'] = test.patient_id.name.property_payment_term and test.patient_id.name.property_payment_term.id or False prods_data = {} tests = context.get('active_ids') logging.debug('tests = %s', repr(tests)) for test_id in tests: test = test_request_obj.browse(cr, uid, test_id) logging.debug( 'test.name = %s; test.name.product_id = %s; test.name.product_id.id = %s', test.name, test.name.product_id, test.name.product_id.id) if prods_data.has_key(test.name.product_id.id): logging.debug( 'prods_data = %s; test.name.product_id.id = %s', prods_data, test.name.product_id.id) prods_data[test.name.product_id.id]['quantity'] += 1 else: logging.debug('test.name.product_id.id = %s', test.name.product_id.id) a = test.name.product_id.product_tmpl_id.property_account_income.id if not a: a = test.name.product_id.categ_id.property_account_income_categ.id prods_data[test.name.product_id.id] = { 'product_id': test.name.product_id.id, 'name': test.name.product_id.name, 'quantity': 1, 'account_id': a, 'price_unit': test.name.product_id.lst_price } logging.debug('prods_data[test.name.product_id.id] = %s', prods_data[test.name.product_id.id]) product_lines = [] for prod_id, prod_data in prods_data.items(): product_lines.append((0, 0, { 'product_id': prod_data['product_id'], 'name': prod_data['name'], 'quantity': prod_data['quantity'], 'account_id': prod_data['account_id'], 'price_unit': prod_data['price_unit'] })) invoice_data['invoice_line'] = product_lines invoice_id = invoice_obj.create(cr, uid, invoice_data) test_request_obj.write(cr, uid, tests, {'invoice_status': 'invoiced'}) return { 'domain': "[('id','=', " + str(invoice_id) + ")]", 'name': 'Create Lab Invoice', 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'account.invoice', 'type': 'ir.actions.act_window' } else: raise osv.except_osv( _('UserError'), _('When multiple lab tests are selected, patient must be the same' ))
def compute_refund(self, cr, uid, ids, mode='refund', is_operation=False, code_list=False, filter_column=False, context=None): print """ @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @param ids: the account invoice refund’s ID or list of IDs """ inv_obj = self.pool.get('account.invoice') reconcile_obj = self.pool.get('account.move.reconcile') account_m_line_obj = self.pool.get('account.move.line') mod_obj = self.pool.get('ir.model.data') act_obj = self.pool.get('ir.actions.act_window') inv_tax_obj = self.pool.get('account.invoice.tax') inv_line_obj = self.pool.get('account.invoice.line') res_users_obj = self.pool.get('res.users') if context is None: context = {} for form in self.browse(cr, uid, ids, context=context): created_inv = [] date = False period = False description = False company = res_users_obj.browse(cr, uid, uid, context=context).company_id journal_id = form.journal_id.id for inv in inv_obj.browse(cr, uid, context.get('active_ids'), context=context): if inv.state in ['draft', 'proforma2', 'cancel']: raise osv.except_osv( _('Error!'), _('Cannot %s draft/proforma/cancel invoice.') % (mode)) if inv.reconciled and mode in ('cancel', 'modify'): raise osv.except_osv( _('Error!'), _('Cannot %s invoice which is already reconciled, invoice should be unreconciled first. You can only refund this invoice.' ) % (mode)) if form.period.id: period = form.period.id else: period = inv.period_id and inv.period_id.id or False if not journal_id: journal_id = inv.journal_id.id if form.date: date = form.date if not form.period.id: cr.execute("select name from ir_model_fields \ where model = 'account.period' \ and name = 'company_id'") result_query = cr.fetchone() if result_query: cr.execute( """select p.id from account_fiscalyear y, account_period p where y.id=p.fiscalyear_id \ and date(%s) between p.date_start AND p.date_stop and y.company_id = %s limit 1""", ( date, company.id, )) else: cr.execute( """SELECT id from account_period where date(%s) between date_start AND date_stop \ limit 1 """, (date, )) res = cr.fetchone() if res: period = res[0] else: date = inv.date_invoice if form.description: description = form.description else: description = inv.name if not period: raise osv.except_osv(_('Insufficient Data!'), \ _('No period found on the invoice.')) refund_id = inv_obj.refund(cr, uid, [inv.id], date, period, description, journal_id, context=context) refund = inv_obj.browse(cr, uid, refund_id[0], context=context) inv_obj.write(cr, uid, [refund.id], { 'date_due': date, 'check_total': inv.check_total }) #Changement de la quantité à 1 si le prix est forfaitaire if is_operation: update_qty_on_refund = False op_ids = self.pool.get('operation.type').search( cr, uid, [('partner_categ_id', '=', inv.partner_id.categ_id.id), ('product_id', '=', inv.invoice_line[0].product_id.id) ]) if not op_ids: raise except_orm( _("Merci de configurer un type d'opération pour la catégorie %s " ), _("%s" % inv.partner_id.categ_id.name)) operations = self.pool.get('operation.type').browse( cr, uid, op_ids) for op in operations: if not op.product_id.property_account_income: raise except_orm( _("Merci de configurer le compte de revenus du produit %s " ), _("%s" % op.product_id.name)) for line in refund.invoice_line: if operations[0].fixed_price: line.write({'quantity': 1}) update_qty_on_refund = True #Changement de la quantité à 1 si le prix est forfaitaire inv_obj.button_compute(cr, uid, refund_id) created_inv.append(refund_id[0]) if mode in ('cancel', 'modify'): movelines = inv.move_id.line_id to_reconcile_ids = {} for line in movelines: if line.account_id.id == inv.account_id.id: to_reconcile_ids.setdefault( line.account_id.id, []).append(line.id) if line.reconcile_id: line.reconcile_id.unlink() refund.signal_workflow('invoice_open') refund = inv_obj.browse(cr, uid, refund_id[0], context=context) refund.invoice_print_auto() #MAJ de la quantité si le prix est forfaitaire if is_operation: if update_qty_on_refund: for line in refund.invoice_line: line.write( {'quantity': inv.invoice_line[0].quantity}) line.write({ 'price_subtotal': inv.invoice_line[0].price_unit }) line.invoice_id.write({ 'amount_untaxed': inv.invoice_line[0].price_unit, 'amount_total': inv.invoice_line[0].price_unit + inv.invoice_line[0].invoice_id.amount_tax }) #MAJ de la quantité si le prix est forfaitaire for tmpline in refund.move_id.line_id: if tmpline.account_id.id == inv.account_id.id: to_reconcile_ids[tmpline.account_id.id].append( tmpline.id) for account in to_reconcile_ids: account_m_line_obj.reconcile( cr, uid, to_reconcile_ids[account], writeoff_period_id=period, writeoff_journal_id=inv.journal_id.id, writeoff_acc_id=inv.account_id.id) if mode == 'modify': print "----------modify mode : avoir des opérations facturées---------------------------" invoice = inv_obj.read( cr, uid, [inv.id], [ 'name', 'type', 'number', 'reference', 'comment', 'date_due', 'partner_id', 'partner_insite', 'partner_contact', 'partner_ref', 'payment_term', 'account_id', 'currency_id', 'invoice_line', 'tax_line', 'journal_id', 'period_id', 'date_invoice' ], context=context) invoice = invoice[0] del invoice['id'] invoice_lines = inv_line_obj.browse( cr, uid, invoice['invoice_line'], context=context) invoice_lines = inv_obj._refund_cleanup_lines( cr, uid, invoice_lines, context=context) tax_lines = inv_tax_obj.browse(cr, uid, invoice['tax_line'], context=context) tax_lines = inv_obj._refund_cleanup_lines( cr, uid, tax_lines, context=context) invoice.update({ 'origin': inv.origin, 'op_id': inv.op_id.id, 'type': inv.type, 'date_invoice': date, 'state': 'draft', 'number': False, 'invoice_line': invoice_lines, 'tax_line': tax_lines, 'period_id': invoice['period_id'][0], 'name': description, }) for field in ('partner_id', 'account_id', 'currency_id', 'payment_term', 'journal_id'): invoice[ field] = invoice[field] and invoice[field][0] inv_id = inv_obj.create(cr, uid, invoice, {}) print "inv_id =", inv_id if is_operation: #self.update_invoice_line_store(cr,uid,code_list,refund,inv) database_id = self.pool.get( 'op.store.db.settings').search( cr, uid, [('is_db_store', '=', True)]) for db in self.pool.get( 'op.store.db.settings').browse( cr, uid, database_id): dbcr = self.pool.get('op.store.db.settings' ).get_cursor_database( cr, uid, ids, db.server, db.port, db.dbname, db.user, db.password) result_ids = [] for code in code_list: code_tuple = self.get_tuple([code]) code_to_refund="select id from invoice_line_store where state='done' and " \ "%s in %s and invoice_id='%s'"%(filter_column,code_tuple,str(inv.id)) dbcr.execute(code_to_refund) result = map(lambda x: x[0], dbcr.fetchall()) if not result: raise except_orm( _("Attention"), _("Le code '" + str(code) + "' est incorrect ou déjà utilisé pour un autre avoir" )) else: result_ids.append(result[0]) # list=self.get_tuple(code_list) # select_to_refund="select id from invoice_line_store where state='done' and " \ # "%s in %s and invoice_id='%s'"%(filter_column,list,str(inv.id)) # dbcr.execute(select_to_refund) # result_ids = map(lambda x: x[0], dbcr.fetchall()) # if not result_ids : # raise except_orm (_("Attention"),_("Les codes sont incorrectes ou déjà utilisés pour d'autres avoirs")) list2 = self.get_tuple(result_ids) req_to_refund = "update invoice_line_store set state='refund', refund_id='%s' where id in %s" % ( refund.id, list2) dbcr.execute(req_to_refund) codes = inv.line_store_ids.replace("(", "") codes = codes.replace(")", "") codes = codes.replace(" ", "") codes = codes.split(",") list3 = [] for code in codes: list3.append(int(code)) new_store_ids = set(list3) - set(result_ids) inv_obj.write( cr, uid, inv_id, {'line_store_ids': tuple(new_store_ids)}) #update invoice in in op line store to link it the new generated invoice from refund if len(new_store_ids) > 1: update_op_new_invoice = "update invoice_line_store set invoice_id=" + str( inv_id) + " where id in " + str( tuple(new_store_ids)) else: a = str(tuple(new_store_ids)) update_op_new_invoice = "update invoice_line_store set invoice_id=" + str( inv_id) + " where id = " + a[1:2] #update invoice in in op line store to link it the new generated invoice from refund dbcr.execute(update_op_new_invoice) invoice = inv_obj.read(cr, uid, [inv_id], ['invoice_line'], context=context) invoice_lines = inv_line_obj.browse( cr, uid, invoice[0]['invoice_line'], context=context) #Changement de la quantité à 1 si le prix est forfaitaire update_qty_on_new_invoice = False op_ids = self.pool.get( 'operation.type').search( cr, uid, [('partner_categ_id', '=', invoice_lines[0].invoice_id. partner_id.categ_id.id), ('product_id', '=', invoice_lines[0].product_id.id)]) if not op_ids: raise except_orm( _("Merci de configurer un type d'opération pour la catégrorie " ), _("%s" % invoice_lines[0].invoice_id. partner_id.categ_id.name)) operations = self.pool.get( 'operation.type').browse(cr, uid, op_ids) for op in operations: if not op.product_id.property_account_income: raise except_orm( _("Merci de configurer le compte de revenus du produit %s " ), _("%s" % op.product_id.name)) for line in invoice_lines: if operations[0].fixed_price: line.write({'quantity': 1}) update_qty_on_new_invoice = True else: line.write( {'quantity': len(new_store_ids)}) #Changement de la quantité à 1 si le prix est forfaitaire invoice = inv_obj.browse(cr, uid, inv_id) invoice.button_reset_taxes() workflow.trg_validate(uid, 'account.invoice', inv_id, 'invoice_open', cr) #MAJ de la quantité si le prix est forfaitaire if update_qty_on_new_invoice: for line in invoice_lines: line.write( {'quantity': len(new_store_ids)}) line.write({ 'price_subtotal': line.price_unit }) line.invoice_id.write({ 'amount_untaxed': line.price_unit, 'amount_total': line.price_unit + line.invoice_id.amount_tax }) #MAJ de la quantité si le prix est forfaitaire inv_obj.browse( cr, uid, inv_id).invoice_print_auto(operation=True) inv_obj.browse(cr, uid, inv_id).action_send_mail_auto() dbcr.execute("COMMIT") if inv.payment_term.id: data = inv_obj.onchange_payment_term_date_invoice( cr, uid, [inv_id], inv.payment_term.id, date) if 'value' in data and data['value']: inv_obj.write(cr, uid, [inv_id], data['value']) created_inv.append(inv_id) xml_id = (inv.type == 'out_refund') and 'action_invoice_tree1' or \ (inv.type == 'in_refund') and 'action_invoice_tree2' or \ (inv.type == 'out_invoice') and 'action_invoice_tree3' or \ (inv.type == 'in_invoice') and 'action_invoice_tree4' result = mod_obj.get_object_reference(cr, uid, 'account', xml_id) id = result and result[1] or False result = act_obj.read(cr, uid, [id], context=context)[0] invoice_domain = eval(result['domain']) invoice_domain.append(('id', 'in', created_inv)) result['domain'] = invoice_domain return result
def create_prescription_invoice(self, cr, uid, ids, context={}): invoice_obj = self.pool.get('account.invoice') pres_request_obj = self.pool.get('medical.prescription.order') # prescriptions = ids # Don't use this. It will be 1 (and it would go to the invoice status of the first prescription ) # To get the IDs of the prescriptions, use the context value array for active_ids prescriptions = context.get ('active_ids') pats = [] for pres_id in prescriptions: pres=pres_request_obj.browse(cr, uid, pres_id) pats.append(pres.name) logging.debug('pres = %s; pats = %s', repr(pres), repr(pats)) if pats.count(pats[0]) == len(pats): invoice_data = {} for pres_id in prescriptions: pres = pres_request_obj.browse(cr, uid, pres_id) # Check if the prescription is invoice exempt, and stop the invoicing process if pres.no_invoice : raise osv.except_osv(_('UserError'), _('The prescription is invoice exempt')) if pres.invoice_status == 'invoiced': logging.debug('pres.invoice_status = %s', repr(pres.invoice_status)) if len(prescriptions) > 1: raise osv.except_osv(_('UserError'), _('At least one of the selected prescriptions is already invoiced')) else: raise osv.except_osv(_('UserError'), _('Prescription already invoiced')) if pres.invoice_status == 'no': if len(prescriptions) > 1: raise osv.except_osv(_('UserError'), _('At least one of the selected prescriptions can not be invoiced')) else: raise osv.except_osv(_('UserError'), _('You can not invoice this prescription')) logging.debug('pres.name = %s', repr(pres.name)) if pres.name.name.id: invoice_data['partner_id'] = pres.name.name.id res = self.pool.get('res.partner').address_get(cr, uid, [pres.name.name.id], ['contact', 'invoice']) invoice_data['address_contact_id'] = res['contact'] invoice_data['address_invoice_id'] = res['invoice'] invoice_data['account_id'] = pres.name.name.property_account_receivable.id invoice_data['fiscal_position'] = pres.name.name.property_account_position and pres.name.name.property_account_position.id or False invoice_data['payment_term'] = pres.name.name.property_payment_term and pres.name.name.property_payment_term.id or False prods_data = {} for pres_id in prescriptions: pres = pres_request_obj.browse(cr, uid, pres_id) logging.debug('pres.name = %s; pres.prescription_line = %s', pres.name, pres.prescription_line) # Check for empty prescription lines if not pres.prescription_line: raise osv.except_osv(_('UserError'), _('You need to have at least one prescription item in your invoice')) for pres_line in pres.prescription_line: logging.debug('pres_line = %s; pres_line.medicament.name = %s; pres_line.quantity = %s', pres_line, pres_line.medicament.name, pres_line.quantity) if prods_data.has_key(pres_line.medicament.name): prods_data[pres_line.medicament.name]['quantity'] += pres_line.quantity else: a = pres_line.medicament.name.product_tmpl_id.property_account_income.id if not a: a = pres_line.medicament.name.categ_id.property_account_income_categ.id prods_data[pres_line.medicament.name] = {'product_id':pres_line.medicament.name.id, 'name':pres_line.medicament.name.name, 'quantity':pres_line.quantity, 'account_id':a, 'price_unit':pres_line.medicament.name.lst_price} product_lines = [] for prod_id, prod_data in prods_data.items(): logging.debug('product_id = %s', repr(prod_data['product_id'])) product_lines.append((0, 0, {'product_id':prod_data['product_id'], 'name':prod_data['name'], 'quantity':prod_data['quantity'], 'account_id':prod_data['account_id'], 'price_unit':prod_data['price_unit']})) invoice_data['invoice_line'] = product_lines invoice_id = invoice_obj.create(cr, uid, invoice_data) pres_request_obj.write(cr, uid, prescriptions, {'invoice_status':'invoiced'}) return { 'domain': "[('id','=', " + str(invoice_id) + ")]", 'name': 'Create Prescription Invoice', 'view_type': 'form', 'view_mode': 'tree,form', 'res_model': 'account.invoice', 'type': 'ir.actions.act_window' } else: raise osv.except_osv(_('UserError'), _('When multiple prescriptions are selected, patient must be the same'))
def _get_serialized_challenge_lines(self, cr, uid, challenge, user_id=False, restrict_goal_ids=False, restrict_top=False, context=None): """Return a serialised version of the goals information if the user has not completed every goal :challenge: browse record of challenge to compute :user_id: res.users id of the user retrieving progress (False if no distinction, only for ranking challenges) :restrict_goal_ids: <list(int)> compute only the results for this subset if gamification.goal ids, if False retrieve every goal of current running challenge :restrict_top: <int> for challenge lines where visibility_mode == 'ranking', retrieve only these bests results and itself, if False retrieve all restrict_goal_ids has priority over restrict_top format list # if visibility_mode == 'ranking' { 'name': <gamification.goal.description name>, 'description': <gamification.goal.description description>, 'condition': <reach condition {lower,higher}>, 'computation_mode': <target computation {manually,count,sum,python}>, 'monetary': <{True,False}>, 'suffix': <value suffix>, 'action': <{True,False}>, 'display_mode': <{progress,boolean}>, 'target': <challenge line target>, 'own_goal_id': <gamification.goal id where user_id == uid>, 'goals': [ { 'id': <gamification.goal id>, 'rank': <user ranking>, 'user_id': <res.users id>, 'name': <res.users name>, 'state': <gamification.goal state {draft,inprogress,reached,failed,canceled}>, 'completeness': <percentage>, 'current': <current value>, } ] }, # if visibility_mode == 'personal' { 'id': <gamification.goal id>, 'name': <gamification.goal.description name>, 'description': <gamification.goal.description description>, 'condition': <reach condition {lower,higher}>, 'computation_mode': <target computation {manually,count,sum,python}>, 'monetary': <{True,False}>, 'suffix': <value suffix>, 'action': <{True,False}>, 'display_mode': <{progress,boolean}>, 'target': <challenge line target>, 'state': <gamification.goal state {draft,inprogress,reached,failed,canceled}>, 'completeness': <percentage>, 'current': <current value>, } """ goal_obj = self.pool.get('gamification.goal') (start_date, end_date) = start_end_date_for_period(challenge.period) res_lines = [] all_reached = True for line in challenge.line_ids: line_data = { 'name': line.definition_id.name, 'description': line.definition_id.description, 'condition': line.definition_id.condition, 'computation_mode': line.definition_id.computation_mode, 'monetary': line.definition_id.monetary, 'suffix': line.definition_id.suffix, 'action': True if line.definition_id.action_id else False, 'display_mode': line.definition_id.display_mode, 'target': line.target_goal, } domain = [ ('line_id', '=', line.id), ('state', '!=', 'draft'), ] if restrict_goal_ids: domain.append(('ids', 'in', restrict_goal_ids)) else: # if no subset goals, use the dates for restriction if start_date: domain.append(('start_date', '=', start_date)) if end_date: domain.append(('end_date', '=', end_date)) if challenge.visibility_mode == 'personal': if not user_id: raise osv.except_osv(_('Error!'), _("Retrieving progress for personal challenge without user information")) domain.append(('user_id', '=', user_id)) sorting = goal_obj._order limit = 1 else: line_data.update({ 'own_goal_id': False, 'goals': [], }) sorting = "completeness desc, current desc" limit = False goal_ids = goal_obj.search(cr, uid, domain, order=sorting, limit=limit, context=context) ranking = 0 for goal in goal_obj.browse(cr, uid, goal_ids, context=context): definition_id = goal.definition_id # new stuff evaled_domain = safe_eval(definition_id.domain, {'user': goal.user_id}) evaled_domain = str(evaled_domain) if challenge.visibility_mode == 'personal': # limit=1 so only one result line_data.update({ 'id': goal.id, 'current': goal.current, 'completeness': goal.completeness, 'state': goal.state, 'domain': evaled_domain, 'model': definition_id.model_id.model, }) if goal.state != 'reached': all_reached = False else: ranking += 1 if user_id and goal.user_id.id == user_id: line_data['own_goal_id'] = goal.id elif restrict_top and ranking > restrict_top: # not own goal and too low to be in top continue line_data['goals'].append({ 'id': goal.id, 'user_id': goal.user_id.id, 'name': goal.user_id.name, 'rank': ranking, 'current': goal.current, 'completeness': goal.completeness, 'state': goal.state, 'domain': evaled_domain, 'model': definition_id.model_id.model, }) if goal.state != 'reached': all_reached = False if goal_ids: res_lines.append(line_data) if all_reached and not challenge.show_reached: # new stuff return [] if challenge.precision: for line in res_lines: current = line.get('current') if current: current = round(current / challenge.precision) * challenge.precision line['current'] = current return res_lines
def action_done_allow_past_date(self, cr, uid, ids, context=None): """NOTE: This method is a copy of the original one in odoo named action_done but we add a new sectiond of conde to introduce exception on the test. Look for "# NOTE VX: This section was overwritten." to find the added code. """ context = context or {} picking_obj = self.pool.get("stock.picking") quant_obj = self.pool.get("stock.quant") todo = [move.id for move in self.browse( cr, uid, ids, context=context) if move.state == "draft"] if todo: ids = self.action_confirm(cr, uid, todo, context=context) pickings = set() procurement_ids = set() # Search operations that are linked to the moves operations = set() move_qty = {} for move in self.browse(cr, uid, ids, context=context): move_qty[move.id] = move.product_qty for link in move.linked_move_operation_ids: operations.add(link.operation_id) # Sort operations according to entire packages first, then package + # lot, package only, lot only operations = list(operations) operations.sort(key=lambda x: ( (x.package_id and not x.product_id) and -4 or 0) + ( x.package_id and -2 or 0) + (x.lot_id and -1 or 0)) for ops in operations: if ops.picking_id: pickings.add(ops.picking_id.id) main_domain = [('qty', '>', 0)] for record in ops.linked_move_operation_ids: move = record.move_id self.check_tracking( cr, uid, move, not ops.product_id and ops.package_id.id or ops.lot_id.id, context=context) prefered_domain = [('reservation_id', '=', move.id)] fallback_domain = [('reservation_id', '=', False)] fallback_domain2 = ['&', ('reservation_id', '!=', move.id), ('reservation_id', '!=', False)] prefered_domain_list = \ [prefered_domain] + [fallback_domain] + [fallback_domain2] dom = main_domain + self.pool.get( 'stock.move.operation.link').get_specific_domain( cr, uid, record, context=context) quants = quant_obj.quants_get_prefered_domain( cr, uid, ops.location_id, move.product_id, record.qty, domain=dom, prefered_domain_list=prefered_domain_list, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) if ops.product_id: # If a product is given, the result is always put # immediately in the result package (if it is False, they # are without package) quant_dest_package_id = ops.result_package_id.id ctx = context else: # When a pack is moved entirely, the quants should not be # written anything for the destination package quant_dest_package_id = False ctx = context.copy() ctx['entire_pack'] = True quant_obj.quants_move( cr, uid, quants, move, ops.location_dest_id, location_from=ops.location_id, lot_id=ops.lot_id.id, owner_id=ops.owner_id.id, src_package_id=ops.package_id.id, dest_package_id=quant_dest_package_id, context=ctx) # Handle pack in pack if (not ops.product_id and ops.package_id and ops.result_package_id.id != ops.package_id.parent_id.id): self.pool.get('stock.quant.package').write( cr, SUPERUSER_ID, [ops.package_id.id], { 'parent_id': ops.result_package_id.id}, context=context) if not move_qty.get(move.id): raise osv.except_osv( _("Error"), _("The roundings of your Unit of Measures %s on the" " move vs. %s on the product don't allow to do" " these operations or you are not transferring the" " picking at once. ") % ( move.product_uom.name, move.product_id.uom_id.name)) move_qty[move.id] -= record.qty # Check for remaining qtys and unreserve/check move_dest_id in move_dest_ids = set() for move in self.browse(cr, uid, ids, context=context): move_qty_cmp = float_compare( move_qty[move.id], 0, precision_rounding=move.product_id.uom_id.rounding) if move_qty_cmp > 0: # (=In case no pack operations in picking) main_domain = [('qty', '>', 0)] prefered_domain = [('reservation_id', '=', move.id)] fallback_domain = [('reservation_id', '=', False)] fallback_domain2 = ['&', ('reservation_id', '!=', move.id), ('reservation_id', '!=', False)] prefered_domain_list = \ [prefered_domain] + [fallback_domain] + [fallback_domain2] self.check_tracking(cr, uid, move, move.restrict_lot_id.id, context=context) qty = move_qty[move.id] quants = quant_obj.quants_get_prefered_domain( cr, uid, move.location_id, move.product_id, qty, domain=main_domain, prefered_domain_list=prefered_domain_list, restrict_lot_id=move.restrict_lot_id.id, restrict_partner_id=move.restrict_partner_id.id, context=context) quant_obj.quants_move( cr, uid, quants, move, move.location_dest_id, lot_id=move.restrict_lot_id.id, owner_id=move.restrict_partner_id.id, context=context) # If the move has a destination, add it to the list to reserve if (move.move_dest_id and move.move_dest_id.state in ('waiting', 'confirmed')): move_dest_ids.add(move.move_dest_id.id) if move.procurement_id: procurement_ids.add(move.procurement_id.id) # unreserve the quants and make them available for other # operations/moves quant_obj.quants_unreserve(cr, uid, move, context=context) # Check the packages have been placed in the correct locations self._check_package_from_moves(cr, uid, ids, context=context) # set the move as done # NOTE VX: This section was overwritten. for move in self.browse(cr, uid, ids, context=context): if move.has_validate_picking_after_move_date(): move_date = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) else: move_date = move.date self.write( cr, uid, [move.id], {'state': 'done', 'date': move_date}, context=context) self.pool.get('procurement.order').check( cr, uid, list(procurement_ids), context=context) # assign destination moves if move_dest_ids: self.action_assign(cr, uid, list(move_dest_ids), context=context) # check picking state to set the date_done is needed done_picking = [] for picking in picking_obj.browse( cr, uid, list(pickings), context=context): if picking.state == 'done' and not picking.date_done: done_picking.append(picking.id) if done_picking: picking_obj.write( cr, uid, done_picking, {'date_done': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}, context=context) return True
def action_quotation_send(self, cr, uid, ids, context=None): order_id = self.browse(cr, uid, ids, context) user = order_id.env.context.get('uid', False) if order_id.state == 'draft' or order_id.state == 'waiting_exec_approval' or order_id.state == 'waiting_mgr_approval': if not user: return res logged_in = self.pool.get('res.users').browse( order_id.env.cr, order_id.env.uid, order_id.env.context['uid'], order_id.env.context) cr = order_id.env.cr uid = logged_in.id option = -1 sp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_selling_price') msp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_minimum_selling_price') csp = self.pool.get('res.users').has_group( cr, uid, 'miipl_msp.group_sell_on_coordinator_selling_price') if msp: option = 1 elif sp: option = 0 elif csp: option = 2 for order in self.browse(cr, uid, ids, context): for line in order.order_line: product = line.product_id selling_price = product.lst_price if option == 1: selling_price = product.min_selling_price elif option == 0: selling_price = product.selling_price elif option == 2: selling_price = product.coordinator_selling_price if line.price_unit < selling_price: raise osv.except_osv( "Error", "You can not give any discount greater than %f for %s \n You can request for for Executive/Manager approval" % (selling_price, line.name)) ''' This function opens a window to compose an email, with the edi sale template message loaded by default ''' assert len( ids ) == 1, 'This option should only be used for a single id at a time.' ir_model_data = self.pool.get('ir.model.data') try: template_id = ir_model_data.get_object_reference( cr, uid, 'sale', 'email_template_edi_sale')[1] except ValueError: template_id = False try: compose_form_id = ir_model_data.get_object_reference( cr, uid, 'mail', 'email_compose_message_wizard_form')[1] except ValueError: compose_form_id = False ctx = dict() ctx.update({ 'default_model': 'sale.order', 'default_res_id': ids[0], 'default_use_template': bool(template_id), 'default_template_id': template_id, 'default_composition_mode': 'comment', 'mark_so_as_sent': True }) return { 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'mail.compose.message', 'views': [(compose_form_id, 'form')], 'view_id': compose_form_id, 'target': 'new', 'context': ctx, }
def autoline_purchase_run(self): if self.state not in ('draft','sent','bid'): raise osv.except_osv('Quote / PO not in Draft State!'),('The Quote or PO must be in draft to run Auto Lines!') return # Get the input values to run the Auto Lines procedure supplier_id = self.partner_id.id # final customer id customer_id = self.customer_id.id line_prod_id = 0 product_ctg_id = 0 weight = 0 del_tot = 0 # traverse the order lines, but we want the first line that is the PCB in question # Should in a later version use a filter to be sure we get correct item by using product category. # supports only one product per Quote. q = None for line in self.order_line: if not line.product_id.product_tmpl_id.ntty_id: continue line_prod_id = line.product_id.id # Get the product and supplier id and product category product_ctg = self.env['product.template'].search([('id', '=', line_prod_id)]) del_tot = self.env['product.template'].search([('id', '=', line_prod_id)]).sale_delay product_ctg_id = product_ctg.categ_id.id # product_sup = self.env['product.supplierinfo'].search([('product_tmpl_id', '=', line_prod_id)]) # supplier_id = product_sup.name.id q = line.product_qty weight = product_ctg.weight * q # the weight field is not the correct one, problem extending the Sale Order model with a new autoline_weight field. self.autoline_weight = weight break # get the Auto Lines used by these objects. customer_autolines_obj = self.env['autoline.autoline'].search([('customer_id', '=', customer_id), ('active', '=', True), ('sales_purchase', '=', False)]) if len(customer_autolines_obj) > 0: self._check_rule(customer_autolines_obj, customer_id, supplier_id, line_prod_id, product_ctg_id, q, weight) product_ctg_autolines_obj = self.env['autoline.autoline'].search([('product_ctg_id', '=', product_ctg_id), ('active', '=', True), ('sales_purchase', '=', False)]) if len(product_ctg_autolines_obj) > 0: self._check_rule(product_ctg_autolines_obj, customer_id, supplier_id, line_prod_id, product_ctg_id, q, weight) product_autolines_obj = self.env['autoline.autoline'].search([('product_id', '=', line_prod_id), ('sales_purchase', '=', False)]) if len(product_autolines_obj) > 0: self._check_rule(product_autolines_obj, customer_id, supplier_id, line_prod_id, product_ctg_id, q, weight) company_wide_autolines_obj = self.env['autoline.autoline'].search([('active', '=', True), ('company_wide', '=', True), ('sales_purchase', '=', False)]) if len(company_wide_autolines_obj) > 0: self._check_rule(company_wide_autolines_obj, customer_id, supplier_id, line_prod_id, product_ctg_id, q, weight) # this one is a special one... supplier_autolines_obj = self.env['autoline.autoline'].search([('supplier_id', '=', supplier_id), ('active', '=', True), ('sales_purchase', '=', False)]) for autolines_obj in supplier_autolines_obj: res = False for rule in autolines_obj.rule_ids: if not rule.active is True: continue operator = rule.operator value_to_check = rule.chk_value field = rule.model_field.name model = rule.model_id if rule.model_subset is False: rule.model_subset == 'customer' partner_subset = rule.model_subset if model.model == 'res.partner' and partner_subset == 'customer': obj = self.env[model.model].search([(field, operator, value_to_check), ('id', '=', customer_id)]) elif model.model == 'res.partner' and partner_subset == 'supplier': obj = self.env[model.model].search([(field, operator, value_to_check), ('id', '=', supplier_id)]) elif model.model == 'product.template': obj = self.env[model.model].search([(field, operator, value_to_check), ('id', '=', line_prod_id)]) elif model.model == 'product.category': obj = self.env[model.model].search([(field, operator, value_to_check), ('id', '=', product_ctg_id)]) elif model.model == 'purchase.order': obj = self.env[model.model].search([(field, operator, value_to_check), ('id', '=', self.id)]) else: obj = None print "OBJ?", obj, len(obj) > 0 if len(obj) > 0: # Rule was True res = True else: # if more than rule is applied for the same Autoline the rules are AND'ed together. # This means that if one rule fails, the result is False res = False break if res: # do not add lines that are already added sku_id = autolines_obj.sku_id.id sku = self.env['product.template'].search([('id', '=', sku_id)]) sku_del = sku.sale_delay line_exists = self.order_line.search([('product_id', '=', sku_id), ('order_id', '=', self.id)]) print "Sku already added", line_exists, len(line_exists) == 0 if len(line_exists) == 0: # computation on SKU if autolines_obj.sku_option == 'multiply': self.order_line.create({'name': sku.name, 'order_id': self.id, 'product_id': sku_id, 'is_autoline': True, 'date_planned': datetime.today(), 'product_uom_qty': q, 'price_unit': sku.price, 'delay': sku_del,'is_autoline': True}) elif autolines_obj.sku_option == 'special': i_s = autolines_obj.supplier_id.name weight = math.ceil(weight) if weight > 50: basis = 49 rest = weight - 50 else: basis = weight - 1 rest = 0 if i_s == 'KBC': kg1 = 6.5 kg2to50 = 0.65 kg_plus = 0.52 elif i_s == 'WMD': kg1 = 2.3 kg2to50 = 0.77 kg_plus = 0.77 else: print "Unknown supplier", i_s, weight quit() comp_price = kg1 + (basis * kg2to50) + (rest * kg_plus) print "For ", weight, " kilos, freight to be charged: ", comp_price self.order_line.create({'name': sku.name, 'order_id': self.id, 'product_id': sku_id, 'is_autoline': True, 'date_planned': datetime.today(), 'product_uom_qty': 1, 'price_unit': comp_price, 'is_autoline': True}) else: self.order_line.create({'name': sku.name, 'order_id': self.id, 'product_id': sku_id, 'is_autoline': True, 'date_planned': datetime.today(), 'product_uom_qty': 1, 'price_unit': sku.price, 'delay': sku_del, 'is_autoline': True}) for line in self.order_line: if not line.product_id.product_tmpl_id.ntty_id or line.product_id.product_tmpl_id.ntty_id == '': # Product is not a PCB vals = { 'leadtime': 0, } line.write(vals) print "Supplier - Done"