Beispiel #1
0
class account_analytic_account(orm.Model):
    def _invoiced_calc(self, cr, uid, ids, name, arg, context=None):
        obj_invoice = self.pool.get('account.invoice')
        res = {}

        cr.execute('SELECT account_id as account_id, l.invoice_id '
                'FROM hr_analytic_timesheet h LEFT JOIN account_analytic_line l '
                    'ON (h.line_id=l.id) '
                    'WHERE l.account_id = ANY(%s)', (ids,))
        account_to_invoice_map = {}
        for rec in cr.dictfetchall():
            account_to_invoice_map.setdefault(rec['account_id'], []).append(rec['invoice_id'])

        for account in self.browse(cr, uid, ids, context=context):
            invoice_ids = filter(None, list(set(account_to_invoice_map.get(account.id, []))))
            for invoice in obj_invoice.browse(cr, uid, invoice_ids, context=context):
                res.setdefault(account.id, 0.0)
                res[account.id] += invoice.amount_untaxed
        for id in ids:
            res[id] = round(res.get(id, 0.0),2)

        return res

    _inherit = "account.analytic.account"
    _columns = {
        'pricelist_id': fields.many2one('product.pricelist', 'Pricelist',
            help="The product to invoice is defined on the employee form, the price will be deducted by this pricelist on the product."),
        'amount_max': fields.float('Max. Invoice Price',
            help="Keep empty if this contract is not limited to a total fixed price."),
        'amount_invoiced': fields.function(_invoiced_calc, string='Invoiced Amount',
            help="Total invoiced"),
        'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Timesheet Invoicing Ratio',
            help="You usually invoice 100% of the timesheets. But if you mix fixed price and timesheet invoicing, you may use another ratio. For instance, if you do a 20% advance invoice (fixed price, based on a sales order), you should invoice the rest on timesheet with a 80% ratio."),
    }

    def on_change_partner_id(self, cr, uid, ids, partner_id, name, context=None):
        res = super(account_analytic_account, self).on_change_partner_id(cr, uid, ids, partner_id, name, context=context)
        if partner_id:
            part = self.pool.get('res.partner').browse(cr, uid, partner_id, context=context)
            pricelist = part.property_product_pricelist and part.property_product_pricelist.id or False
            if pricelist:
                res['value']['pricelist_id'] = pricelist
        return res

    def set_close(self, cr, uid, ids, context=None):
        return self.write(cr, uid, ids, {'state': 'close'}, context=context)

    def set_cancel(self, cr, uid, ids, context=None):
        return self.write(cr, uid, ids, {'state': 'cancelled'}, context=context)

    def set_open(self, cr, uid, ids, context=None):
        return self.write(cr, uid, ids, {'state': 'open'}, context=context)

    def set_pending(self, cr, uid, ids, context=None):
        return self.write(cr, uid, ids, {'state': 'pending'}, context=context)
class magento_website(orm.Model):
    _inherit = 'magento.website'

    _columns = {
        'pricelist_id': fields.many2one('product.pricelist',
                                        'Pricelist',
                                        domain="[('type', '=', 'sale')]",
                                        help='The pricelist used to define '
                                             'the prices of the products in '
                                             'Magento for this website.\n'
                                             'Choose a pricelist only if the '
                                             'prices are different for this '
                                             'website.\n'
                                             'When empty, the default price '
                                             'will be used.'),
    }

    def update_all_prices(self, cr, uid, ids, context=None):
        """ Update the prices of all the products linked to the
        website. """
        if not hasattr(ids, '__iter__'):
            ids = [ids]
        for website in self.browse(cr, uid, ids, context=context):
            session = ConnectorSession(cr, uid, context=context)
            if website.magento_id == '0':
                # 'Admin' website -> default values
                # Update the default prices on all the products.
                binding_ids = website.backend_id.product_binding_ids
            else:
                binding_ids = website.product_binding_ids
            for binding in binding_ids:
                export_product_price.delay(session,
                                           'magento.product.product',
                                           binding.id,
                                           website_id=website.id)
        return True

    def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, context=None):
        if not ids:  # new record
            return {}
        warning = {
            'title': _('Warning'),
            'message': _('If you change the pricelist of the website, '
                         'the price of all the products linked with this '
                         'website will be updated in Magento.')
        }
        return {'warning': warning}

    def write(self, cr, uid, ids, vals, context=None):
        if 'pricelist_id' in vals:
            self.update_all_prices(cr, uid, ids, context=context)
        return super(magento_website, self).write(cr, uid, ids,
                                                  vals, context=context)
class magento_backend(orm.Model):
    _inherit = 'magento.backend'

    def _get_pricelist_id(self, cr, uid, context=None):
        data_obj = self.pool.get('ir.model.data')
        ref = data_obj.get_object_reference(cr, uid, 'product', 'list0')
        if ref:
            return ref[1]
        return False

    _columns = {
        'pricelist_id': fields.many2one('product.pricelist',
                                        'Pricelist',
                                        required=True,
                                        domain="[('type', '=', 'sale')]",
                                        help='The price list used to define '
                                             'the prices of the products in '
                                             'Magento.'),
    }

    _defaults = {
        'pricelist_id': _get_pricelist_id,
    }

    def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, context=None):
        if not ids:  # new record
            return {}
        warning = {
            'title': _('Warning'),
            'message': _('If you change the pricelist of the backend, '
                         'the price of all the products will be updated '
                         'in Magento.')
        }
        return {'warning': warning}

    def _update_default_prices(self, cr, uid, ids, context=None):
        """ Update the default prices of the products linked with
        this backend.

        The default prices are linked with the 'Admin' website (id: 0).
        """
        website_obj = self.pool.get('magento.website')
        website_ids = website_obj.search(cr, uid,
                                         [('backend_id', 'in', ids),
                                          ('magento_id', '=', '0')],
                                         context=context)
        website_obj.update_all_prices(cr, uid, website_ids, context=context)

    def write(self, cr, uid, ids, vals, context=None):
        if 'pricelist_id' in vals:
            self._update_default_prices(cr, uid, ids, context=context)
        return super(magento_backend, self).write(cr, uid, ids,
                                                  vals, context=context)
Beispiel #4
0
class product_link(Model):
    _inherit = "product.link"
    
    _columns = {
        'quantity': fields.float('Quantity'),
        'uom_id': fields.many2one('product.uom', 'Unit of Measure', help="Unit of Measure for selling or buying this goodies"),
        'start_date': fields.date('Start Date'),
        'end_date': fields.date('End Date'),
        'supplier_goodies': fields.boolean('Supplier Goodies', help=("If it's a supplier goodies "
                                "the product will be automatically added to the purchase order")),
        'cost_price': fields.float('Cost Price'),
    }

    def _get_uom_id(self, cr, uid, *args):
        cr.execute('select id from product_uom order by id limit 1')
        res = cr.fetchone()
        return res and res[0] or False

    _defaults = {
            'uom_id': _get_uom_id,
    }

    def get_link_type_selection(self, cr, uid, context=None):
        res = super(product_link, self).get_link_type_selection(cr, uid, context=context)
        res.append(('goodies', 'Goodies'))
        return res


    def get_quantity(self, cr, uid, ids, qty, context=None):
        link = self.browse(cr, uid, ids[0], context=context)
        return link.quantity * qty

    def run_active_unactive(self, cr, uid, context=None):
        
        to_unactive_ids = self.search(cr, uid, [
                        ['is_active', '=', True],
                        '|',
                            ['end_date', '<', datetime.today().strftime("%Y-%m-%d")],
                            ['start_date', '>', datetime.today().strftime("%Y-%m-%d")]
                        ], context=context)
        self.write(cr, uid, to_unactive_ids, {'is_active': False}, context=context)
        
        to_active_ids = self.search(cr, uid, [
                        ['is_active', '=', True],
                        '|',
                            ['end_date', '>=', datetime.today().strftime("%Y-%m-%d")],
                            ['start_date', '<=', datetime.today().strftime("%Y-%m-%d")]
                        ], context=context)
        self.write(cr, uid, to_active_ids, {'is_active': True}, context=context)
Beispiel #5
0
class utec_adelanto_viaticos(osv.osv):
    _inherit = 'account.voucher'

    _columns = {
        'solicitud_viatico_id': fields.many2one('grp.solicitud.viaticos', string=u'Solicitud de viajes',
                                                domain=[('lleva_adelanto', '=', True), ('state', '=', 'autorizado')],
                                                readonly=True, states={'draft': [('readonly', False)]},
                                                ondelete='restrict', required=False),  # TODO: SPRING 11 GAP 28 L
        'moneda_solicitud': fields.related('solicitud_viatico_id', 'currency_id', type='many2one', relation='res.currency',
                                      string='Moneda de solicitud', readonly=True),
        'adelanto_solicitud': fields.related('solicitud_viatico_id', 'total_adelanto', type='float',
                                           string='Total adelanto', readonly=True),
    }

    def onchange_solicitud_viatico_id(self, cr, uid, ids, solicitud_viatico_id, context=None):
        value = {}
        if solicitud_viatico_id:
            solicitud = self.pool.get('grp.solicitud.viaticos').browse(cr, uid, solicitud_viatico_id, context=context)
            value.update({'moneda_solicitud': solicitud.currency_id.id, 'adelanto_solicitud': solicitud.total_adelanto})
        else:
            value.update({'moneda_solicitud': False, 'adelanto_solicitud': False})
        return {'value': value}

    def _check_montos(self, cr, uid, ids, context=None):
        for adelanto in self.browse(cr, uid, ids, context=context):
            # Si el voucher es un adelanto de viatico
            if adelanto.solicitud_viatico_id.id and adelanto.type == 'payment':  # TODO: SPRING 11 GAP 28 L
                #calculo la moneda del metodo de pago
                if adelanto.journal_id.currency.id:
                    moneda_diario = adelanto.journal_id.currency.id
                else:
                    moneda_diario = adelanto.journal_id.company_id.currency_id.id
                # Si la moneda de la solicitud es la misma que la del metodo de pago
                if adelanto.solicitud_viatico_id.currency_id.id == moneda_diario:
                    # Si los montos no coinciden
                    if round(adelanto.solicitud_viatico_id.total_adelanto,2) != adelanto.amount:
                        return False
        return True

    _constraints = [
        (_check_montos, 'Si la moneda de la solicitud es la misma que la del adelanto, los montos deben coincidir', ['amount','adelanto_solicitud'])
    ]
Beispiel #6
0
class purchase_order_line(Model):
    _inherit = "purchase.order.line"

    _columns = {
        'goodie_for_line_id':
        fields.many2one('purchase.order.line',
                        'Goodies for',
                        help='The product linked to this goodie lines'),
        'goodies_line_ids':
        fields.one2many('purchase.order.line',
                        'goodie_for_line_id',
                        'Goodies linked',
                        help=''),
    }

    def write(self, cr, uid, ids, vals, context=None):
        if context is None: context = {}
        #TODO I should apply this only for automatic po need a read only mode
        if context.get("updated_from_op"):
            if not context.get('goodies_create_update'):
                ctx = context.copy()
                ctx['goodies_create_update'] = True
                for line in self.browse(cr, uid, ids, context=None):
                    if line.product_id.is_purchase_goodies(context=ctx):
                        vals[
                            'product_qty'] = self._get_new_qty_for_none_goodies_line(
                                cr,
                                uid,
                                vals['product_qty'],
                                line.product_id.id,
                                line.order_id.id,
                                context=ctx)
                    super(purchase_order_line, self).write(cr,
                                                           uid,
                                                           line.id,
                                                           vals,
                                                           context=ctx)

                    qty_added = vals['product_qty'] - line.product_qty
                    for goodie in line.product_id.supplier_goodies_ids:
                        qty = goodie.get_quantity(qty_added, context=ctx)
                        po_line_for_goodie = False
                        for goodies_line in line.goodies_line_ids:
                            if goodies_line.product_id.id == goodie.linked_product_id.id:
                                po_line_for_goodie = goodies_line
                                break
                        #TODO manage correctly uom
                        print 'po_line_for_goodie', po_line_for_goodie
                        if po_line_for_goodie:
                            po_line_for_goodie.write(
                                {
                                    'product_qty':
                                    po_line_for_goodie.product_qty + qty
                                },
                                context=ctx)
                        else:
                            self.create(cr,
                                        uid,
                                        self._prepare_goodies_line(
                                            cr,
                                            uid,
                                            line.id,
                                            goodie,
                                            qty,
                                            line.order_id,
                                            line.date_planned,
                                            context=ctx),
                                        context=ctx)
                        self.update_none_goodies_line(
                            cr,
                            uid,
                            qty,
                            goodie.linked_product_id.id,
                            line.order_id.id,
                            context=ctx)
                return True
        return super(purchase_order_line, self).write(cr,
                                                      uid,
                                                      ids,
                                                      vals,
                                                      context=context)

    def create(self, cr, uid, vals, context=None):
        if context is None: context = {}
        if not context.get('goodies_create_update'):
            ctx = context.copy()
            ctx['goodies_create_update'] = True
            product_obj = self.pool.get('product.product')
            product = product_obj.browse(cr,
                                         uid,
                                         vals['product_id'],
                                         context=ctx)

            if product.is_purchase_goodies(context=ctx):
                vals['product_qty'] = self._get_new_qty_for_none_goodies_line(
                    cr,
                    uid,
                    vals['product_qty'],
                    vals['product_id'],
                    vals['order_id'],
                    context=ctx)

            line_id = super(purchase_order_line, self).create(cr,
                                                              uid,
                                                              vals,
                                                              context=context)

            order = self.pool.get('purchase.order').browse(cr,
                                                           uid,
                                                           vals['order_id'],
                                                           context=context)
            for goodie in product.supplier_goodies_ids:
                qty = goodie.get_quantity(vals['product_qty'], context=ctx)
                self.create(cr,
                            uid,
                            self._prepare_goodies_line(
                                cr,
                                uid,
                                line_id,
                                goodie,
                                qty,
                                order,
                                vals.get('date_planned'),
                                context=ctx),
                            context=ctx)
                self.update_none_goodies_line(cr,
                                              uid,
                                              qty,
                                              goodie.linked_product_id.id,
                                              order.id,
                                              context=ctx)
            return line_id
        else:
            return super(purchase_order_line, self).create(cr,
                                                           uid,
                                                           vals,
                                                           context=context)

    def _get_new_qty_for_none_goodies_line(self,
                                           cr,
                                           uid,
                                           qty,
                                           product_id,
                                           order_id,
                                           context=None):
        """If we want to buy X more product B we have to check if there is not already goodies
        line that containt this product. If yes we have to reduce the qty to buy by the the total
        of goodies lines
        :params qty float: quantity of product to buy
        :params product_id int: product id
        :params order_id: order id
        :return: the quantity for the none goodies line reduced by the quantity of goodies line
        :rtype: float
        """
        goodies_line_ids = self.search(
            cr,
            uid, [['order_id', '=', order_id], ['product_id', '=', product_id],
                  ['goodie_for_line_id', '!=', False]],
            context=context)
        for goodie_line in self.browse(cr,
                                       uid,
                                       goodies_line_ids,
                                       context=context):
            qty -= goodie_line.product_qty
        if qty < 0:
            qty = 0
        return qty

    def update_none_goodies_line(self,
                                 cr,
                                 uid,
                                 goodies_qty,
                                 product_id,
                                 order_id,
                                 context=None):
        """Update the none line goodies, by this I mean :
        If you sold a product A with a goodies B
        If the scheduler have run a minimal rule for B before running the A rule.
        We have a line for the B product and we should remove the qty added by the goodies
        :params goodies_qty float: quantity of goodies product
        :params product_id int: product id
        :params order_id: order id
        :return: True
        :rtype: Boolean
        """
        product_line_id = self.search(
            cr,
            uid, [['order_id', '=', order_id], ['product_id', '=', product_id],
                  ['goodie_for_line_id', '=', False]],
            context=context)
        if product_line_id:
            product_line = self.browse(cr,
                                       uid,
                                       product_line_id[0],
                                       context=context)
            new_qty = product_line.product_qty - goodies_qty
            if new_qty < 0: new_qty = 0
            product_line.write({'product_qty': new_qty}, context=context)
        return True

    def _prepare_goodies_line(self,
                              cr,
                              uid,
                              line_id,
                              goodie,
                              qty,
                              order,
                              date_planned,
                              context=None):
        """Prepare the purchase order line for goodies
        :params goodies browse_record: browse_record of product_links
        :params qty float: quantity of goodies to buy
        :params order browse_record: purchase order that contain this line
        :params schedule_date str: planned to for receiving the product
        :return: dictionnary of value for creating the purchase order line
        :rtype: dict
        """
        #TODO manage correctly uom
        acc_pos_obj = self.pool.get('account.fiscal.position')
        taxes_ids = goodie.product_id.supplier_taxes_id
        taxes = acc_pos_obj.map_tax(cr, uid,
                                    order.partner_id.property_account_position,
                                    taxes_ids)
        ctx = context.copy()
        #set the partner id in the context in order to have the good name for product
        ctx['partner_id'] = order.partner_id.id
        product = self.pool.get('product.product').browse(
            cr, uid, goodie.linked_product_id.id, context=ctx)
        return {
            'name': ">>>%s" % product.partner_ref,
            'product_qty': qty,
            'product_id': product.id,
            'product_uom': product.uom_po_id.id,
            'price_unit': goodie.cost_price or 0.0,
            'date_planned': date_planned,
            'notes': product.description_purchase,
            'taxes_id': [(6, 0, taxes)],
            'order_id': order.id,
            'goodie_for_line_id': line_id
        }
Beispiel #7
0
class partner(osv.osv):

    """"""

    _inherit = 'res.partner'

    def _retrieve_user(self, cr, uid, ids, arg, karg, context=None):
        """ retrieve the (possibly inactive) user corresponding to wizard_user.partner_id
            @param wizard_user: browse record of model portal.wizard.user
            @return: browse record of model res.users
        """
        context = dict(context or {}, active_test=False)
        res_users = self.pool.get('res.users')
        res = {}
        for i in ids:
            domain = [('partner_id', '=', i)]
            user_ids = res_users.search(cr, uid, domain, context=context)
            user_id = False
            if user_ids:
                user_id = user_ids[0]
            res[i] = user_id
        return res

    _columns = {
        'login': fields.related('related_user_id', 'login', string='Login', type='char', size=64, readonly=True,
                                help="Used to log into the system"),
        'password': fields.related('related_user_id', 'password', string='Password', type='char', size=64, readonly=True,
                                   help="Keep empty if you don't want the user to be able to connect on the system."),
        'related_user_id': fields.function(_retrieve_user, relation='res.users', string='User', type='many2one', ),
        'template_user_id': fields.many2one('res.users', string="Template User", domain=[('active', '=', False)],),
    }

    def open_related_user(self, cr, uid, ids, context=None):
        user_id = self.browse(
            cr, uid, ids[0], context=context).related_user_id.id
        if not user_id:
            return False
        view_ref = self.pool.get('ir.model.data').get_object_reference(
            cr, uid, 'base', 'view_users_form')
        view_id = view_ref and view_ref[1] or False,
        return {
            'type': 'ir.actions.act_window',
            'view_id': view_id,
            'res_model': 'res.users',
            'view_mode': 'form',
            'res_id': user_id,
            'target': 'current',
            # 'flags': {'form': {'action_buttons': True, 'options': {'mode': 'edit'}}}
        }

    def delete_user(self, cr, uid, ids, context=None):
        user_id = self.browse(
            cr, uid, ids[0], context=context).related_user_id.id
        if not user_id:
            return False
        return self.pool.get('res.users').unlink(cr, uid, [user_id], context=context)

    def retrieve_user(self, cr, uid, partner, context=None):
        """ retrieve the (possibly inactive) user corresponding to partner
            @param partner: browse record of model portal.wizard.user
            @return: browse record of model res.users
        """

        context = dict(context or {}, active_test=False)
        res_users = self.pool.get('res.users')
        domain = [('partner_id', '=', partner.id)]
        user_ids = res_users.search(cr, uid, domain, context=context)
        return user_ids

    def quickly_create_user(self, cr, uid, ids, context=None):
        res_users = self.pool.get('res.users')
        # Make this an option
        context = dict(context or {}, no_reset_password=True)
        # TODO Pasar argumentos para activar o desactivar
        create_user = True

        for partner in self.browse(cr, SUPERUSER_ID, ids, context):
            group_ids = []
            if not partner.template_user_id:
                raise osv.except_osv(_('Non template user selected!'),
                                     _('Please define a template user for this partner: "%s" (id:%d).') % (partner.name, partner.id))
            group_ids = [x.id for x in partner.template_user_id.groups_id]
            user_ids = self.retrieve_user(cr, SUPERUSER_ID, partner, context)
            if create_user:
                # create a user if necessary, and make sure it is in the portal
                # group
                if not user_ids:
                    user_ids = [
                        self._create_user(cr, SUPERUSER_ID, partner, context)]
                res_users.write(
                    cr, SUPERUSER_ID, user_ids, {'active': True, 'groups_id': [(6, 0, group_ids)]})
                # prepare for the signup process
                # TODO make an option of this
                # partner.signup_prepare()
                # TODO option to send or not email
                # self._send_email(cr, uid, partner, context)
            elif user_ids:
                # deactivate user
                res_users.write(cr, SUPERUSER_ID, user_ids, {'active': False})

    def _create_user(self, cr, uid, partner, context=None):
        """ create a new user for partner.partner_id
            @param partner: browse record of model partner.user
            @return: browse record of model res.users
        """
        res_users = self.pool.get('res.users')
        # to prevent shortcut creation
        create_context = dict(
            context or {}, noshortcut=True, no_reset_password=True)
        if partner.email:
            login = extract_email(partner.email)
        else:
            login = self._clean_and_make_unique(
                cr, uid, partner.name, context=context)
        values = {
            # 'email': extract_email(partner.email),
            'login': login,
            # 'login': extract_email(partner.email),
            'partner_id': partner.id,
            'company_id': partner.company_id.id,
            'company_ids': [(4, partner.company_id.id)],
            'password': ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(6)),
            'groups_id': [(6, 0, [])],
        }
        return res_users.create(cr, uid, values, context=create_context)

    def _clean_and_make_unique(self, cr, uid, name, context=None):
        # when an alias name appears to already be an email, we keep the local
        # part only
        name = remove_accents(name).lower().split('@')[0]
        name = re.sub(r'[^\w+.]+', '.', name)
        return self._find_unique(cr, uid, name, context=context)

    def _find_unique(self, cr, uid, name, context=None):
        """Find a unique alias name similar to ``name``. If ``name`` is
           already taken, make a variant by adding an integer suffix until
           an unused alias is found.
        """
        sequence = None
        while True:
            new_name = "%s%s" % (
                name, sequence) if sequence is not None else name
            if not self.pool.get('res.users').search(cr, uid, [('login', '=', new_name)]):
                break
            sequence = (sequence + 1) if sequence else 2
        return new_name
Beispiel #8
0
class account_analytic_line(orm.Model):
    _inherit = 'account.analytic.line'
    _columns = {
        'invoice_id': fields.many2one('account.invoice', 'Invoice', ondelete="set null", copy=False),
        'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Invoiceable', help="It allows to set the discount while making invoice, keep empty if the activities should not be invoiced."),
    }

    def _default_journal(self, cr, uid, context=None):
        proxy = self.pool.get('hr.employee')
        record_ids = proxy.search(cr, uid, [('user_id', '=', uid)], context=context)
        if record_ids:
            employee = proxy.browse(cr, uid, record_ids[0], context=context)
            return employee.journal_id and employee.journal_id.id or False
        return False

    def _default_general_account(self, cr, uid, context=None):
        proxy = self.pool.get('hr.employee')
        record_ids = proxy.search(cr, uid, [('user_id', '=', uid)], context=context)
        if record_ids:
            employee = proxy.browse(cr, uid, record_ids[0], context=context)
            if employee.product_id and employee.product_id.property_account_income:
                return employee.product_id.property_account_income.id
        return False

    _defaults = {
        'journal_id' : _default_journal,
        'general_account_id' : _default_general_account,
    }

    def write(self, cr, uid, ids, vals, context=None):
        self._check_inv(cr, uid, ids, vals)
        return super(account_analytic_line,self).write(cr, uid, ids, vals,
                context=context)

    def _check_inv(self, cr, uid, ids, vals):
        select = ids
        if isinstance(select, (int, long)):
            select = [ids]
        if ( not vals.has_key('invoice_id')) or vals['invoice_id' ] == False:
            for line in self.browse(cr, uid, select):
                if line.invoice_id:
                    raise osv.except_osv(_('Error!'),
                        _('You cannot modify an invoiced analytic line!'))
        return True

    def _get_invoice_price(self, cr, uid, account, product_id, user_id, qty, context = {}):
        pro_price_obj = self.pool.get('product.pricelist')
        if account.pricelist_id:
            pl = account.pricelist_id.id
            price = pro_price_obj.price_get(cr,uid,[pl], product_id, qty or 1.0, account.partner_id.id, context=context)[pl]
        else:
            price = 0.0
        return price

    def invoice_cost_create(self, cr, uid, ids, data=None, context=None):
        analytic_account_obj = self.pool.get('account.analytic.account')
        account_payment_term_obj = self.pool.get('account.payment.term')
        invoice_obj = self.pool.get('account.invoice')
        product_obj = self.pool.get('product.product')
        invoice_factor_obj = self.pool.get('hr_timesheet_invoice.factor')
        fiscal_pos_obj = self.pool.get('account.fiscal.position')
        product_uom_obj = self.pool.get('product.uom')
        invoice_line_obj = self.pool.get('account.invoice.line')
        invoices = []
        if context is None:
            context = {}
        if data is None:
            data = {}

        journal_types = {}

        # prepare for iteration on journal and accounts
        for line in self.pool.get('account.analytic.line').browse(cr, uid, ids, context=context):
            if line.journal_id.type not in journal_types:
                journal_types[line.journal_id.type] = set()
            journal_types[line.journal_id.type].add(line.account_id.id)
        for journal_type, account_ids in journal_types.items():
            for account in analytic_account_obj.browse(cr, uid, list(account_ids), context=context):
                partner = account.partner_id
                if (not partner) or not (account.pricelist_id):
                    raise osv.except_osv(_('Analytic Account Incomplete!'),
                            _('Contract incomplete. Please fill in the Customer and Pricelist fields.'))

                date_due = False
                if partner.property_payment_term:
                    pterm_list= account_payment_term_obj.compute(cr, uid,
                            partner.property_payment_term.id, value=1,
                            date_ref=time.strftime('%Y-%m-%d'))
                    if pterm_list:
                        pterm_list = [line[0] for line in pterm_list]
                        pterm_list.sort()
                        date_due = pterm_list[-1]

                curr_invoice = {
                    'name': time.strftime('%d/%m/%Y') + ' - '+account.name,
                    'partner_id': account.partner_id.id,
                    'company_id': account.company_id.id,
                    'payment_term': partner.property_payment_term.id or False,
                    'account_id': partner.property_account_receivable.id,
                    'currency_id': account.pricelist_id.currency_id.id,
                    'date_due': date_due,
                    'fiscal_position': account.partner_id.property_account_position.id
                }
                context2 = context.copy()
                context2['lang'] = partner.lang
                # set company_id in context, so the correct default journal will be selected
                context2['force_company'] = curr_invoice['company_id']
                # set force_company in context so the correct product properties are selected (eg. income account)
                context2['company_id'] = curr_invoice['company_id']

                last_invoice = invoice_obj.create(cr, uid, curr_invoice, context=context2)
                invoices.append(last_invoice)

                cr.execute("""SELECT product_id, user_id, to_invoice, sum(amount), sum(unit_amount), product_uom_id
                        FROM account_analytic_line as line LEFT JOIN account_analytic_journal journal ON (line.journal_id = journal.id)
                        WHERE account_id = %s
                            AND line.id IN %s AND journal.type = %s AND to_invoice IS NOT NULL
                        GROUP BY product_id, user_id, to_invoice, product_uom_id""", (account.id, tuple(ids), journal_type))

                for product_id, user_id, factor_id, total_price, qty, uom in cr.fetchall():
                    context2.update({'uom': uom})

                    if data.get('product'):
                        # force product, use its public price
                        product_id = data['product'][0]
                        unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, context2)
                    elif journal_type == 'general' and product_id:
                        # timesheets, use sale price
                        unit_price = self._get_invoice_price(cr, uid, account, product_id, user_id, qty, context2)
                    else:
                        # expenses, using price from amount field
                        unit_price = total_price*-1.0 / qty

                    factor = invoice_factor_obj.browse(cr, uid, factor_id, context=context2)
                    # factor_name = factor.customer_name and line_name + ' - ' + factor.customer_name or line_name
                    factor_name = factor.customer_name
                    curr_line = {
                        'price_unit': unit_price,
                        'quantity': qty,
                        'product_id': product_id or False,
                        'discount': factor.factor,
                        'invoice_id': last_invoice,
                        'name': factor_name,
                        'uos_id': uom,
                        'account_analytic_id': account.id,
                    }
                    product = product_obj.browse(cr, uid, product_id, context=context2)
                    if product:
                        factor_name = product_obj.name_get(cr, uid, [product_id], context=context2)[0][1]
                        if factor.customer_name:
                            factor_name += ' - ' + factor.customer_name

                        general_account = product.property_account_income or product.categ_id.property_account_income_categ
                        if not general_account:
                            raise osv.except_osv(_("Configuration Error!"), _("Please define income account for product '%s'.") % product.name)
                        taxes = product.taxes_id or general_account.tax_ids
                        tax = fiscal_pos_obj.map_tax(cr, uid, account.partner_id.property_account_position, taxes)
                        curr_line.update({
                            'invoice_line_tax_id': [(6,0,tax )],
                            'name': factor_name,
                            'invoice_line_tax_id': [(6,0,tax)],
                            'account_id': general_account.id,
                        })
                    #
                    # Compute for lines
                    #
                    cr.execute("SELECT * FROM account_analytic_line WHERE account_id = %s and id IN %s AND product_id=%s and to_invoice=%s ORDER BY account_analytic_line.date", (account.id, tuple(ids), product_id, factor_id))

                    line_ids = cr.dictfetchall()
                    note = []
                    for line in line_ids:
                        # set invoice_line_note
                        details = []
                        if data.get('date', False):
                            details.append(line['date'])
                        if data.get('time', False):
                            if line['product_uom_id']:
                                details.append("%s %s" % (line['unit_amount'], product_uom_obj.browse(cr, uid, [line['product_uom_id']],context2)[0].name))
                            else:
                                details.append("%s" % (line['unit_amount'], ))
                        if data.get('name', False):
                            details.append(line['name'])
                        if details:
                            note.append(u' - '.join(map(lambda x: unicode(x) or '',details)))
                    if note:
                        curr_line['name'] += "\n" + ("\n".join(map(lambda x: unicode(x) or '',note)))
                    invoice_line_obj.create(cr, uid, curr_line, context=context)
                    cr.execute("update account_analytic_line set invoice_id=%s WHERE account_id = %s and id IN %s", (last_invoice, account.id, tuple(ids)))
                    self.invalidate_cache(cr, uid, ['invoice_id'], ids, context=context)

                invoice_obj.button_reset_taxes(cr, uid, [last_invoice], context)
        return invoices
class sale_purchase_journal_report(osv.osv_memory):
    _name = 'sale.purchase.journal.report'
    _description = 'Sale/Purchase Journal Report'

    def onchange_period_id(self, cr, uid, ids, period_id=False, context=None):
        res = {}
        if period_id:
            period = self.pool.get('account.period').browse(cr, uid, period_id, context=context)
            res['value'] = {'date_from': period.date_start, 'date_to': period.date_stop}
        return res
    
    
    _columns = {
        'company_id': fields.many2one('res.company', 'Company', required=True),
        'journal': fields.selection(
            [('purchase', 'Purchase'), ('sale', 'Sale')],
            'Journal type',
            select=True
        ),
        'periods': fields.many2one('account.period', 'Period', required=True),
        'date_from': fields.date("Start Date", required=True),
        'date_to': fields.date("End Date", required=True),        
    }

    def _get_period(self, cr, uid, context=None):
        if context is None:
            context = {}
        now = datetime.date.today()
        periods = self.pool.get('account.period').find(cr, uid, now + dateutil.relativedelta.relativedelta(months=-1))
        return periods and periods[0] or False

    _defaults = {
        "company_id": lambda obj, cr, uid, context: obj.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id,
        'journal': 'sale',
        'periods': _get_period,
    }

    def print_report(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        data = self.read(cr, uid, ids)[0]
        context['data'] = data
        context['landscape'] = True
        period = self.pool.get('account.period').browse(cr, uid, data['periods'][0], context=context)
        if data['date_from'] < period.date_start or data['date_from'] > period.date_stop or \
                data['date_to'] < period.date_start or data['date_to'] > period.date_stop:
            raise osv.except_osv(_('Error!'),_('Dates selected must be in the same period.'))
        if data['journal'] == 'sale':
            return self.pool['report'].get_action(cr, uid, [], 'l10n_ro_account_report.report_sale_journal', data=data, context=context)
        else:
            return self.pool['report'].get_action(cr, uid, [], 'l10n_ro_account_report.report_purchase_journal', data=data, context=context)

    def print_html_report(self, cr, uid, ids, context=None):
        if context is None:
            context = {}
        data = self.read(cr, uid, ids)[0]
        context['data'] = data
        context['landscape'] = True
        if data['journal'] == 'sale':
            return self.pool['report'].get_action(cr, uid, [], 'l10n_ro_account_report.report_sale_journal_html', data=data, context=context)
        else:
            return self.pool['report'].get_action(cr, uid, [], 'l10n_ro_account_report.report_purchase_journal_html', data=data, context=context)
Beispiel #10
0
class magento_sale_comment(orm.Model):
    _name = 'magento.sale.comment'
    _inherit = 'magento.binding'
    _description = 'Magento Sale Comment'
    _inherits = {'mail.message': 'odoo_id'}

    MAGENTO_HELP = "This field is a technical / configuration field for the " \
                   "sale comment on Magento. \nPlease refer to the Magento " \
                   "documentation for details. "

    def _get_comments_from_order(self, cr, uid, ids, context=None):
        return self.pool['magento.sale.comment'].search(
            cr, uid, [('magento_sale_order_id', 'in', ids)], context=context)

    _columns = {
        'odoo_id': fields.many2one(
            'mail.message',
            string='Sale Comment',
            required=True,
            ondelete='cascade'),
        'magento_sale_order_id': fields.many2one(
            'magento.sale.order',
            'Magento Sale Order',
            required=True,
            ondelete='cascade',
            select=True),
        'is_customer_notified': fields.boolean(
            'Customer notified',
            help=MAGENTO_HELP),
        'is_visible_on_front': fields.boolean(
            'Visible on front',
            help=MAGENTO_HELP),
        'status': fields.char(
            'Order status',
            size=64,
            help=MAGENTO_HELP),
        'backend_id': fields.related(
            'magento_sale_order_id', 'backend_id',
            type='many2one',
            relation='magento.backend',
            string='Magento Backend',
            store={
                'magento.sale.comment': (
                    lambda self, cr, uid, ids, c=None:
                    ids,
                    ['magento_sale_order_id'],
                    10),
                'magento.sale.order': (
                    _get_comments_from_order,
                    ['backend_id'],
                    20),
                },
            readonly=True),
        'storeid': fields.char(
            'Store id',
            help=MAGENTO_HELP),
    }

    def create(self, cr, uid, vals, context=None):
        if 'res_id' not in vals:
            info = self.pool['magento.sale.order'].read(
                cr, uid, vals['magento_sale_order_id'],
                ['odoo_id'],
                context=context)
            vals.update({
                'res_id': info['odoo_id'][0],
                'model': 'sale.order',
                })
        return super(magento_sale_comment, self).create(
            cr, uid, vals, context=context)