Example #1
0
 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'})
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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'))
Example #6
0
    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)
Example #8
0
    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
Example #9
0
    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)
Example #11
0
    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
Example #12
0
    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
Example #13
0
    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)
Example #15
0
 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)
Example #17
0
    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
Example #18
0
    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
Example #20
0
    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
Example #21
0
    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)
Example #22
0
    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,
        }
Example #26
0
    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
Example #27
0
    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'
                  ))
Example #29
0
    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'
                  ))
Example #30
0
    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)
Example #31
0
    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'))
Example #33
0
    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
Example #35
0
    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'))
Example #37
0
    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
Example #38
0
    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,
        }
Example #39
0
    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'
                  ))
Example #41
0
    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
Example #45
0
    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,
        }
Example #46
0
    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"