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)
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)
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']) ]
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 }
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
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)
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)