def view_init(self, cr, uid, fields_list, context=None): """ Creates view dynamically and adding fields at runtime. @param self: The object pointer. @param cr: A database cursor @param uid: ID of the user currently logged in @param context: A standard dictionary @return: New arch of view with new columns. """ if context is None: context = {} res = super(stock_return_picking, self).view_init(cr, uid, fields_list, context=context) record_id = context and context.get('active_id', False) if record_id: pick_obj = self.pool.get('stock.picking') pick = pick_obj.browse(cr, uid, record_id, context=context) if pick.state not in ['done','confirmed','assigned']: raise osv.except_osv(_('Warning !'), _("You may only return pickings that are Confirmed, Available or Done!")) return_history = {} valid_lines = 0 for m in [line for line in pick.move_lines]: if m.state == 'done': return_history[m.id] = 0 for rec in m.move_history_ids2: return_history[m.id] += (rec.product_qty * rec.product_uom.factor) if m.product_qty * m.product_uom.factor >= return_history[m.id]: valid_lines += 1 if 'return%s'%(m.id) not in self._columns: self._columns['return%s'%(m.id)] = fields.float(string=m.name, required=True) if 'invoice_state' not in self._columns: self._columns['invoice_state'] = fields.selection([('2binvoiced', 'To be refunded/invoiced'), ('none', 'No invoicing')], string='Invoicing', required=True) if not valid_lines: raise osv.except_osv(_('Warning !'), _("There are no products to return (only lines in Done state and not fully returned yet can be returned)!")) return res
def __init__(self, pool, cr): """ Dynamically add columns """ super(report_prompt_class, self).__init__(pool, cr) for counter in range(0, MAX_PARAMS): field_name = PARAM_XXX_STRING_VALUE % counter self._columns[field_name] = fields.char('String Value', size=64) field_name = PARAM_XXX_BOOLEAN_VALUE % counter self._columns[field_name] = fields.boolean('Boolean Value') field_name = PARAM_XXX_INTEGER_VALUE % counter self._columns[field_name] = fields.integer('Integer Value') field_name = PARAM_XXX_NUMBER_VALUE % counter self._columns[field_name] = fields.float('Number Value') field_name = PARAM_XXX_DATE_VALUE % counter self._columns[field_name] = fields.date('Date Value') field_name = PARAM_XXX_TIME_VALUE % counter self._columns[field_name] = fields.datetime('Time Value') self.paramfile = False
def view_init(self, cr, uid, fields_list, context=None): """ Creates view dynamically and adding fields at runtime. @param self: The object pointer. @param cr: A database cursor @param uid: ID of the user currently logged in @param context: A standard dictionary @return: New arch of view with new columns. """ res = super(stock_split_move_line, self).view_init(cr, uid, fields_list, context=context) record_id = context and context.get('active_id', False) or False if record_id: pick_obj = self.pool.get('stock.picking') try: pick = pick_obj.browse(cr, uid, record_id, context=context) for m in [line for line in pick.move_lines]: if 'move%s' % m.id not in self._columns: self._columns['move%s' % m.id] = fields.float(string=m.product_id.name) except: return res return res
def view_init(self, cr, uid, fields_list, context=None): """ Creates view dynamically and adding fields at runtime. @param self: The object pointer. @param cr: A database cursor @param uid: ID of the user currently logged in @param context: A standard dictionary @return: New arch of view with new columns. """ res = super(pos_return, self).view_init(cr, uid, fields_list, context=context) order_obj=self.pool.get('pos.order') if context is None: context={} active_ids=context.get('active_ids') for order in order_obj.browse(cr, uid, active_ids, context=context): for line in order.lines: if 'return%s'%(line.id) not in self._columns: self._columns['return%s'%(line.id)] = fields.float("Quantity") return res
class tcv_municipal_tax_wh_lines(osv.osv): _name = 'tcv.municipal.tax.wh.lines' _description = '' ##------------------------------------------------------------------------- def default_get(self, cr, uid, fields, context=None): context = context or {} data = super(tcv_municipal_tax_wh_lines, self).default_get(cr, uid, fields, context) if context.get('lines'): for line_record in context['lines']: if not isinstance(line_record, (tuple, list)): line_record_detail = self.browse(cr, uid, line_record, context=context) else: line_record_detail = line_record[2] if line_record_detail: data.update( {'muni_tax_id': line_record_detail['muni_tax_id']}) return data ##------------------------------------------------------- _internal methods def _get_invoice(self, cr, uid, invoice_id, context=None): res = {} if not invoice_id: return res obj_inv = self.pool.get('account.invoice') invoice = obj_inv.browse(cr, uid, invoice_id, context=context) res.update({ 'number': invoice.number, 'inv_name': invoice.name, 'supplier_invoice_number': invoice.supplier_invoice_number, 'nro_ctrl': invoice.nro_ctrl, 'date_invoice': invoice.date_invoice, 'date_document': invoice.date_document, 'amount_total': invoice.amount_total, 'amount_untaxed': invoice.amount_untaxed, 'residual': invoice.residual, }) return res def _get_muni_tax(self, cr, uid, muni_tax_id, amount_untaxed, residual, context=None): res = {} if not muni_tax_id: return res obj_mtx = self.pool.get('tcv.municipal.taxes.config') muni_tax = obj_mtx.browse(cr, uid, muni_tax_id, context=context) wh_rate = muni_tax and muni_tax.wh_rate or 0 amount_ret = round((amount_untaxed * wh_rate) / 100, 2) res.update({ 'amount_untaxed': amount_untaxed, 'wh_rate': wh_rate, 'amount_ret': amount_ret, 'amount_pay': residual - amount_ret, }) return res ##--------------------------------------------------------- function fields _columns = { 'line_id': fields.many2one('tcv.municipal.tax.wh', 'String', required=True, ondelete='cascade'), 'invoice_id': fields.many2one('account.invoice', 'Invoice Reference', ondelete='restrict', select=True, domain=[('state', 'in', ('open', 'paid'))]), 'inv_name': fields.related('invoice_id', 'name', type='char', string='Description', size=64, store=False, readonly=True), 'number': fields.related('invoice_id', 'number', type='char', string='Number', size=64, store=False, readonly=True), 'supplier_invoice_number': fields.related('invoice_id', 'supplier_invoice_number', type='char', string='Supplier Invoice Number', size=64, store=False, readonly=True), 'nro_ctrl': fields.related('invoice_id', 'nro_ctrl', type='char', string='Control Number', size=64, store=False, readonly=True), 'date_invoice': fields.related('invoice_id', 'date_invoice', type='date', string='Invoice Date', store=False, readonly=True), 'date_document': fields.related('invoice_id', 'date_document', type='date', string='Document\'s Date', store=False, readonly=True), 'amount_total': fields.float('Total', required=False, readonly=True, digits_compute=dp.get_precision('Withhold'), help="Amount total withheld"), 'muni_tax_id': fields.many2one('tcv.municipal.taxes.config', 'Municipal tax', ondelete='restrict', required=True), 'amount_untaxed': fields.float('Untaxed', required=False, readonly=False, digits_compute=dp.get_precision('Withhold'), help="Amount base for withholding"), 'wh_rate': fields.float('Wh rate', digits_compute=dp.get_precision('Account'), readonly=True, required=True, help="Tax rate for supplier withholding"), 'amount_pay': fields.float('Payed', required=False, readonly=True, digits_compute=dp.get_precision('Withhold')), 'amount_ret': fields.float('Withhold', required=False, readonly=True, digits_compute=dp.get_precision('Withhold')), 'residual': fields.float('Residual', required=False, readonly=True, digits_compute=dp.get_precision('Withhold')), 'move_id': fields.many2one('account.move', 'Accounting entries', ondelete='restrict', help="The move of this entry line.", select=True, readonly=True), } _defaults = {} _sql_constraints = [ ('invoice_uniq', 'UNIQUE(invoice_id)', 'The invoice must be unique!'), ] ##------------------------------------------------------------------------- ##---------------------------------------------------------- public methods ##-------------------------------------------------------- buttons (object) ##------------------------------------------------------------ on_change... def on_change_invoice_id(self, cr, uid, ids, invoice_id, muni_tax_id, amount_untaxed): res = {} if invoice_id: res.update(self._get_invoice(cr, uid, invoice_id, context=None)) if muni_tax_id: res.update( self._get_muni_tax(cr, uid, muni_tax_id, amount_untaxed or res['amount_untaxed'], res['residual'], context=None)) return {'value': res} def on_change_muni_tax_id(self, cr, uid, ids, muni_tax_id, amount_untaxed, residual): res = {} if muni_tax_id: res.update( self._get_muni_tax(cr, uid, muni_tax_id, amount_untaxed, residual, context=None)) return {'value': res} ##----------------------------------------------------- create write unlink def create(self, cr, uid, vals, context=None): #autoref amount_untaxed = vals.get('amount_untaxed', 0) if vals.get('invoice_id'): vals.update(self._get_invoice(cr, uid, vals['invoice_id'], context)) if amount_untaxed: vals.update({'amount_untaxed': amount_untaxed}) if vals.get('muni_tax_id') and vals.get('amount_untaxed'): vals.update( self._get_muni_tax(cr, uid, vals['muni_tax_id'], vals['amount_untaxed'], vals['residual'], context)) res = super(tcv_municipal_tax_wh_lines, self).create(cr, uid, vals, context) return res def write(self, cr, uid, ids, vals, context=None): amount_untaxed = vals.get('amount_untaxed', 0) if vals.get('invoice_id'): vals.update(self._get_invoice(cr, uid, vals['invoice_id'], context)) if amount_untaxed: vals.update({'amount_untaxed': amount_untaxed}) if vals.get('muni_tax_id') and vals.get('amount_untaxed'): vals.update( self._get_muni_tax(cr, uid, vals['muni_tax_id'], vals['amount_untaxed'], vals['residual'], context)) res = super(tcv_municipal_tax_wh_lines, self).write(cr, uid, ids, vals, context) return res
else: raise osv.except_osv(_('Warning !'),'No products found on Amazon as per your search query. Please try again') return True _columns = { 'amazon_sku': fields.char('Amazon SKU', size=126), 'amazon_asin': fields.char('ASIN', size=16,readonly=True), 'orderitemid': fields.char('Orderitemid', size=16), 'product_order_item_id': fields.char('Order_item_id', size=256), 'amazon_export':fields.boolean('Exported to Amazon'), 'amazon_category':fields.many2one('amazon.category','Amazon Category'), 'amz_type': fields.selection([('',''),('IBSN','IBSN'),('UPC','UPC'),('EAN','EAN'),('ASIN','ASIN')],'Type'), 'amz_type_value': fields.char('Amazon Type Value', size=126), 'amzn_condtn': fields.selection([('',''),('New','New'),('UsedLikeNew','Used Like New'),('UsedVeryGood','Used Very Good'),('UsedGood','UsedGood') ,('UsedAcceptable','Used Acceptable'),('CollectibleLikeNew','Collectible Like New'),('CollectibleVeryGood','Collectible Very Good'),('CollectibleGood','Collectible Good') ,('CollectibleAcceptable','Collectible Acceptable'),('Refurbished','Refurbished'),('Club','Club')],'Amazon Condition'), 'prod_query': fields.char('Product Search Query', size=200, help="A search string with the same support as that is provided on Amazon marketplace websites."), 'prod_query_contextid': fields.selection(_amazon_browse_node_get,'Query ContextId', help="An identifier for the context within which the given search will be performed."), 'amazon_instance_id': fields.selection(_amazon_instance_get,'Amazon Instance', help="Select the Amazon instance where you want to perform search."), 'amazon_products_ids': fields.one2many('amazon.products.master', 'product_id', 'Amazon Searched Products'), 'amazon_prod_status': fields.selection([('active','Active'),('fail','Failure')],'Status',readonly="True"), 'operation_performed': fields.char('Operation Performed', size=126), 'submit_feed_result' : fields.text('Submit Feed Result',readonly=True), 'amazon_updated_price':fields.float('Amazon Updated Price',digits=(16,2)), 'condition_note' : fields.text('Condition Note'), } _defaults = { 'amzn_condtn':'', 'amazon_instance_id': _assign_default_amazon_instance } product_product()
def __init__(self,*args): # from wizards.hc_common import humancapital_fields for key in self._import_columns: self._columns[key]=humancapital_fields[key]['object_class'](*(humancapital_fields[key]['object_contruct_params'])) super(autoimport,self).__init__(*args) humancapital_fields={ 'knownlanguages': { 'object_class': fields.many2many , 'object_contruct_params' : ['humancapital.languages','rel_knownlanguagescandidate','candidate_id','language_id','Langues maîtrisées'], 'object_comparison_fct' : compare_many2many, }, 'approxlanguages': fields.float('Langues connues'), 'sectors': fields.float('Secteurs'), 'functions': fields.float('Fonctions'), 'formations': fields.float('Formations'), 'workpermits': fields.float('Permis de travail'), 'contracttypes': fields.float('Types de contrat'), 'nationalities': fields.float('Nationalités'), 'age_min': fields.float("Age"), 'experience': fields.float("Années minimum d'expérience"), } # # # 'knownlanguages': { # 'object': fields.many2many('humancapital.languages','rel_knownlanguagescandidate','candidate_id','language_id','Langues maîtrisées'),
class hr_recruitment_report(osv.osv): _name = "hr.recruitment.report" _description = "Recruitments Statistics" _auto = False _rec_name = 'date' _columns = { 'user_id': fields.many2one('res.users', 'User', readonly=True), 'nbr': fields.integer('# of Cases', readonly=True), 'state': fields.selection(AVAILABLE_STATES, 'State', size=16, readonly=True), 'month':fields.selection([('01', 'January'), ('02', 'February'), \ ('03', 'March'), ('04', 'April'),\ ('05', 'May'), ('06', 'June'), \ ('07', 'July'), ('08', 'August'),\ ('09', 'September'), ('10', 'October'),\ ('11', 'November'), ('12', 'December')], 'Month', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True), 'day': fields.char('Day', size=128, readonly=True), 'year': fields.char('Year', size=4, readonly=True), 'date': fields.date('Date', readonly=True), 'date_closed': fields.date('Closed', readonly=True), 'job_id': fields.many2one('hr.job', 'Applied Job',readonly=True), 'stage_id': fields.many2one ('hr.recruitment.stage', 'Stage'), 'type_id': fields.many2one('hr.recruitment.degree', 'Degree'), 'department_id': fields.many2one('hr.department','Department',readonly=True), 'priority': fields.selection(hr_recruitment.AVAILABLE_PRIORITIES, 'Appreciation'), 'salary_prop' : fields.float("Salary Proposed", digits_compute=dp.get_precision('Account')), 'salary_prop_avg' : fields.float("Avg Salary Proposed", group_operator="avg", digits_compute=dp.get_precision('Account')), 'salary_exp' : fields.float("Salary Expected", digits_compute=dp.get_precision('Account')), 'partner_id': fields.many2one('res.partner', 'Partner',readonly=True), 'partner_address_id': fields.many2one('res.partner.address', 'Partner Contact Name',readonly=True), 'available': fields.float("Availability"), 'delay_open': fields.float('Avg. Delay to Open', digits=(16,2), readonly=True, group_operator="avg", help="Number of Days to close the project issue"), 'delay_close': fields.float('Avg. Delay to Close', digits=(16,2), readonly=True, group_operator="avg", help="Number of Days to close the project issue"), } _order = 'date desc' def init(self, cr): tools.drop_view_if_exists(cr, 'hr_recruitment_report') cr.execute(""" create or replace view hr_recruitment_report as ( select min(s.id) as id, date_trunc('day',s.create_date) as date, date_trunc('day',s.date_closed) as date_closed, to_char(s.create_date, 'YYYY') as year, to_char(s.create_date, 'MM') as month, to_char(s.create_date, 'YYYY-MM-DD') as day, s.state, s.partner_id, s.company_id, s.partner_address_id, s.user_id, s.job_id, s.type_id, sum(s.availability) as available, s.department_id, s.priority, s.stage_id, sum(salary_proposed) as salary_prop, (sum(salary_proposed)/count(*)) as salary_prop_avg, sum(salary_expected) as salary_exp, extract('epoch' from (s.date_open-s.create_date))/(3600*24) as delay_open, extract('epoch' from (s.date_closed-s.create_date))/(3600*24) as delay_close, count(*) as nbr from hr_applicant s group by to_char(s.create_date, 'YYYY'), to_char(s.create_date, 'MM'), to_char(s.create_date, 'YYYY-MM-DD') , date_trunc('day',s.create_date), date_trunc('day',s.date_closed), s.date_open, s.create_date, s.date_closed, s.state, s.partner_id, s.partner_address_id, s.company_id, s.user_id, s.stage_id, s.type_id, s.priority, s.job_id, s.department_id ) """)
class product_sorting(osv.osv_memory): def reorder(self, cr, uid, ids, context=None): print 'context entrando, ', context product_obj = self.pool.get('product.product') categ_obj = self.pool.get('product.category') obj_model = self.pool.get('ir.model.data') if context is None: context = {} form = self.read(cr, uid, ids, [])[0] if not form['product_ids']: raise osv.except_osv(_('UserError'), _('You must select products to reorder')) vals = { 'categ_id' : form['categ_id'], } if not form['acc_prod_id']: if categ_obj.browse(cr, uid, form['categ_id']).acc_prod_id: vals.update({'acc_prod_id': categ_obj.browse(cr, uid, form['categ_id']).acc_prod_id.id}) else: raise osv.except_osv(_('UserError'), _("The Category You have selected lacks of Accounting Category \n Solve the problem in the Category or Select an Accounting Category")) else: vals.update({'acc_prod_id' : form['acc_prod_id']}) if not form.get('override_unique',False): vals.update({'unique_account' : categ_obj.browse(cr, uid, form['categ_id']).unique_account}) else: vals.update({ 'unique_account' : form.get('unique_account',False), 'purchase_ok' : form.get('purchase_ok',False), 'sale_ok' : form.get('sale_ok',False), 'type' : form.get('type',False), }) partial = 0 for prod_id in form['product_ids']: partial+=1 total = len(form['product_ids']) print '%s/%s'%(partial,total) product_obj.write(cr, uid, prod_id, vals) obj_model = self.pool.get('ir.model.data') model_data_ids = obj_model.search(cr,uid,[('model','=','ir.ui.view'),('name','=','product_sorting_view')]) resource_id = obj_model.read(cr, uid, model_data_ids, fields=['res_id'])[0]['res_id'] return{ 'domain': "[]", 'target': 'new', 'view_type': 'form', 'view_mode': 'form,tree', 'res_model': 'product.sorting', 'views': [(resource_id,'form')], 'type': 'ir.actions.act_window' } _name = "product.sorting" _description = "Product Sorting" _columns = { 'product_ids': fields.many2many('product.product', 'product_product_rel','sort_id','product_id','Products'), 'categ_id': fields.many2one('product.category','Category', required=True), 'acc_prod_id': fields.many2one('account.product','Accounting Category'), 'purchase_ok': fields.boolean('Can be Purchased'), 'sale_ok': fields.boolean('Can be sold'), 'type': fields.selection([('product','Stockable Product'),('consu', 'Consumable'),('service','Service')], 'Product Type', required=True, help="Will change the way procurements are processed. Consumables are stockable products with infinite stock, or for use when you have no stock management in the system."), 'unique_account':fields.boolean( 'Require Unique Account', help='Selecting this field allow you to create Unique Accounts for this Record, Taking into Account the Accounting Classification, not doing so, Will asign those ones in the Product Category' ), 'override_unique':fields.boolean( 'Override Unique Account Requirement', help='Selecting this field will allow you to override the Unique Account Requirement set in the Product Category for these Records' ), 'progress':fields.float(string='Progress', readonly=True,digits_compute= dp.get_precision('Progress')), }
class hotel_folio(osv.osv): def _incoterm_get(self, cr, uid, context={}): return self.pool.get('sale.order')._incoterm_get(cr, uid, context={}) def copy(self, cr, uid, id, default=None, context={}): return self.pool.get('sale.order').copy(cr, uid, id, default=None, context={}) def _invoiced(self, cursor, user, ids, name, arg, context=None): return self.pool.get('sale.order')._invoiced(cursor, user, ids, name, arg, context=None) def _invoiced_search(self, cursor, user, obj, name, args): return self.pool.get('sale.order')._invoiced_search( cursor, user, obj, name, args) def _amount_untaxed(self, cr, uid, ids, field_name, arg, context): return self.pool.get('sale.order')._amount_untaxed( cr, uid, ids, field_name, arg, context) def _amount_tax(self, cr, uid, ids, field_name, arg, context): return self.pool.get('sale.order')._amount_tax(cr, uid, ids, field_name, arg, context) def _amount_total(self, cr, uid, ids, field_name, arg, context): return self.pool.get('sale.order')._amount_total( cr, uid, ids, field_name, arg, context) _name = 'hotel.folio' _description = 'hotel folio new' _inherits = {'sale.order': 'order_id'} _columns = { 'order_id': fields.many2one('sale.order', 'order_id', required=True, ondelete='cascade'), 'checkin_date': fields.datetime('Check In', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'checkout_date': fields.datetime('Check Out', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'room_lines': fields.one2many('hotel_folio.line', 'folio_id'), 'service_lines': fields.one2many('hotel_service.line', 'folio_id'), 'hotel_policy': fields.selection([('prepaid', 'On Booking'), ('manual', 'On Check In'), ('picking', 'On Checkout')], 'Hotel Policy', required=True), 'duration': fields.float('Duration'), } _defaults = {'hotel_policy': 'manual'} _sql_constraints = [ ('check_in_out', 'CHECK (checkin_date<=checkout_date)', 'Check in Date Should be lesser than the Check Out Date!'), ] def onchange_dates(self, cr, uid, ids, checkin_date=False, checkout_date=False, duration=False): value = {} if not duration: duration = 0 if checkin_date and checkout_date: chkin_dt = datetime.datetime.strptime(checkin_date, '%Y-%m-%d %H:%M:%S') chkout_dt = datetime.datetime.strptime(checkout_date, '%Y-%m-%d %H:%M:%S') dur = chkout_dt - chkin_dt duration = dur.days value.update({'value': {'duration': duration}}) else: if checkin_date: chkin_dt = datetime.datetime.strptime(checkin_date, '%Y-%m-%d %H:%M:%S') chkout_dt = chkin_dt + datetime.timedelta(days=duration) checkout_date = datetime.datetime.strftime( chkout_dt, '%Y-%m-%d %H:%M:%S') value.update({'value': {'checkout_date': checkout_date}}) return value def create(self, cr, uid, vals, context=None, check=True): tmp_room_lines = vals.get('room_lines', []) tmp_service_lines = vals.get('service_lines', []) vals['order_policy'] = vals.get('hotel_policy', 'manual') if not vals.has_key("folio_id"): vals.update({'room_lines': [], 'service_lines': []}) folio_id = super(hotel_folio, self).create(cr, uid, vals, context) for line in tmp_room_lines: line[2].update({'folio_id': folio_id}) for line in tmp_service_lines: line[2].update({'folio_id': folio_id}) vals.update({ 'room_lines': tmp_room_lines, 'service_lines': tmp_service_lines }) super(hotel_folio, self).write(cr, uid, [folio_id], vals, context) else: folio_id = super(hotel_folio, self).create(cr, uid, vals, context) return folio_id def onchange_shop_id(self, cr, uid, ids, shop_id): return self.pool.get('sale.order').onchange_shop_id( cr, uid, ids, shop_id) def onchange_partner_id(self, cr, uid, ids, part): return self.pool.get('sale.order').onchange_partner_id( cr, uid, ids, part) def button_dummy(self, cr, uid, ids, context={}): return self.pool.get('sale.order').button_dummy(cr, uid, ids, context={}) def action_invoice_create(self, cr, uid, ids, grouped=False, states=['confirmed', 'done']): i = self.pool.get('sale.order').action_invoice_create( cr, uid, ids, grouped=False, states=['confirmed', 'done']) for line in self.browse(cr, uid, ids, context={}): self.write(cr, uid, [line.id], {'invoiced': True}) if grouped: self.write(cr, uid, [line.id], {'state': 'progress'}) else: self.write(cr, uid, [line.id], {'state': 'progress'}) return i def action_invoice_cancel(self, cr, uid, ids, context={}): res = self.pool.get('sale.order').action_invoice_cancel(cr, uid, ids, context={}) for sale in self.browse(cr, uid, ids): for line in sale.order_line: self.pool.get('sale.order.line').write(cr, uid, [line.id], {'invoiced': invoiced}) self.write(cr, uid, ids, { 'state': 'invoice_except', 'invoice_id': False }) return res def action_cancel(self, cr, uid, ids, context={}): c = self.pool.get('sale.order').action_cancel(cr, uid, ids, context={}) ok = True for sale in self.browse(cr, uid, ids): for r in self.read(cr, uid, ids, ['picking_ids']): for pick in r['picking_ids']: wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'stock.picking', pick, 'button_cancel', cr) for r in self.read(cr, uid, ids, ['invoice_ids']): for inv in r['invoice_ids']: wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'account.invoice', inv, 'invoice_cancel', cr) self.write(cr, uid, ids, {'state': 'cancel'}) return c def action_wait(self, cr, uid, ids, *args): res = self.pool.get('sale.order').action_wait(cr, uid, ids, *args) for o in self.browse(cr, uid, ids): if (o.order_policy == 'manual') and (not o.invoice_ids): self.write(cr, uid, [o.id], {'state': 'manual'}) else: self.write(cr, uid, [o.id], {'state': 'progress'}) return res def test_state(self, cr, uid, ids, mode, *args): write_done_ids = [] write_cancel_ids = [] res = self.pool.get('sale.order').test_state(cr, uid, ids, mode, *args) if write_done_ids: self.pool.get('sale.order.line').write(cr, uid, write_done_ids, {'state': 'done'}) if write_cancel_ids: self.pool.get('sale.order.line').write(cr, uid, write_cancel_ids, {'state': 'cancel'}) return res def procurement_lines_get(self, cr, uid, ids, *args): res = self.pool.get('sale.order').procurement_lines_get( cr, uid, ids, *args) return res def action_ship_create(self, cr, uid, ids, *args): res = self.pool.get('sale.order').action_ship_create( cr, uid, ids, *args) return res def action_ship_end(self, cr, uid, ids, context={}): res = self.pool.get('sale.order').action_ship_end(cr, uid, ids, context={}) for order in self.browse(cr, uid, ids): val = {'shipped': True} self.write(cr, uid, [order.id], val) return res def _log_event(self, cr, uid, ids, factor=0.7, name='Open Order'): return self.pool.get('sale.order')._log_event(cr, uid, ids, factor=0.7, name='Open Order') def has_stockable_products(self, cr, uid, ids, *args): return self.pool.get('sale.order').has_stockable_products( cr, uid, ids, *args) def action_cancel_draft(self, cr, uid, ids, *args): d = self.pool.get('sale.order').action_cancel_draft( cr, uid, ids, *args) self.write(cr, uid, ids, { 'state': 'draft', 'invoice_ids': [], 'shipped': 0 }) self.pool.get('sale.order.line').write(cr, uid, ids, { 'invoiced': False, 'state': 'draft', 'invoice_lines': [(6, 0, [])] }) return d
class stock_picking(osv.osv): _inherit = 'stock.picking' def _cal_weight(self, cr, uid, ids, name, args, context=None): res = {} uom_obj = self.pool.get('product.uom') for picking in self.browse(cr, uid, ids, context=context): total_weight = total_weight_net = 0.00 for move in picking.move_lines: total_weight += move.weight total_weight_net += move.weight_net res[picking.id] = { 'weight': total_weight, 'weight_net': total_weight_net, } return res def _get_picking_line(self, cr, uid, ids, context=None): result = {} for line in self.pool.get('stock.move').browse(cr, uid, ids, context=context): result[line.picking_id.id] = True return result.keys() _columns = { 'carrier_id': fields.many2one("delivery.carrier", "Carrier"), 'volume': fields.float('Volume'), 'weight': fields.function(_cal_weight, type='float', string='Weight', digits_compute=dp.get_precision('Stock Weight'), multi='_cal_weight', store={ 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20), 'stock.move': (_get_picking_line, [ 'product_id', 'product_qty', 'product_uom', 'product_uos_qty' ], 20), }), 'weight_net': fields.function(_cal_weight, type='float', string='Net Weight', digits_compute=dp.get_precision('Stock Weight'), multi='_cal_weight', store={ 'stock.picking': (lambda self, cr, uid, ids, c={}: ids, ['move_lines'], 20), 'stock.move': (_get_picking_line, [ 'product_id', 'product_qty', 'product_uom', 'product_uos_qty' ], 20), }), 'carrier_tracking_ref': fields.char('Carrier Tracking Ref', size=32), 'number_of_packages': fields.integer('Number of Packages'), } def _prepare_shipping_invoice_line(self, cr, uid, picking, invoice, context=None): """Prepare the invoice line to add to the shipping costs to the shipping's invoice. :param browse_record picking: the stock picking being invoiced :param browse_record invoice: the stock picking's invoice :return: dict containing the values to create the invoice line, or None to create nothing """ carrier_obj = self.pool.get('delivery.carrier') grid_obj = self.pool.get('delivery.grid') if not picking.carrier_id or \ any(inv_line.product_id.id == picking.carrier_id.product_id.id for inv_line in invoice.invoice_line): return None grid_id = carrier_obj.grid_get(cr, uid, [picking.carrier_id.id], picking.partner_id.id, context=context) if not grid_id: raise osv.except_osv(_('Warning'), _('The carrier %s (id: %d) has no delivery grid!') \ % (picking.carrier_id.name, picking.carrier_id.id)) price = grid_obj.get_price_from_picking(cr, uid, grid_id, invoice.amount_untaxed, picking.weight, picking.volume, context=context) account_id = picking.carrier_id.product_id.property_account_income.id if not account_id: account_id = picking.carrier_id.product_id.categ_id\ .property_account_income_categ.id taxes = picking.carrier_id.product_id.taxes_id partner = picking.partner_id or False if partner: account_id = self.pool.get('account.fiscal.position').map_account( cr, uid, partner.property_account_position, account_id) taxes_ids = self.pool.get('account.fiscal.position').map_tax( cr, uid, partner.property_account_position, taxes) else: taxes_ids = [x.id for x in taxes] return { 'name': picking.carrier_id.name, 'invoice_id': invoice.id, 'uos_id': picking.carrier_id.product_id.uos_id.id, 'product_id': picking.carrier_id.product_id.id, 'account_id': account_id, 'price_unit': price, 'quantity': 1, 'invoice_line_tax_id': [(6, 0, taxes_ids)], } def action_invoice_create(self, cr, uid, ids, journal_id=False, group=False, type='out_invoice', context=None): invoice_obj = self.pool.get('account.invoice') picking_obj = self.pool.get('stock.picking') invoice_line_obj = self.pool.get('account.invoice.line') result = super(stock_picking, self).action_invoice_create(cr, uid, ids, journal_id=journal_id, group=group, type=type, context=context) for picking in picking_obj.browse(cr, uid, result.keys(), context=context): invoice = invoice_obj.browse(cr, uid, result[picking.id], context=context) invoice_line = self._prepare_shipping_invoice_line(cr, uid, picking, invoice, context=context) if invoice_line: invoice_line_obj.create(cr, uid, invoice_line) invoice_obj.button_compute(cr, uid, [invoice.id], context=context) return result
class account_invoice(osv.osv): _inherit = 'account.invoice' def _check_paid(self, cr, uid, ids, name, args, context=None): res = {} voucher_lines = self.pool.get('account.voucher.line') res[id] = True return res def test_check(self, cr, uid, ids, *args): ok = False voucher_lines = self.pool.get('account.voucher.line') for line in self.browse(cr, uid, ids): res = voucher_lines.search(cr, uid, [('name', 'like', line.number), ('instrument_number', '!=', '')]) if res: ok = True else: ok = False return ok def test_allowed(self, cr, uid, ids, *args): ok = False inv = self.pool.get('account.invoice') for line in self.browse(cr, uid, ids): allowed = line.allow_out print allowed return allowed def _reconciled_check(self, cr, uid, ids, name, args, context=None): res = {} for id in ids: res[id] = self.test_check(cr, uid, [id]) return res def _check_allow_out(self, cr, uid, ids, name, args, context=None): res = {} for id in ids: res[id] = self.test_allowed(cr, uid, [id]) return res _columns = { 'check_state': fields.function(_reconciled_check, method=True, string='Reglé', type='boolean'), 'out_allowed': fields.function(_check_allow_out, method=True, string='Sortie Autorisee', type='boolean'), 'allow_out': fields.boolean('Autorisation de Sortie'), 'transmitted': fields.boolean('Transmis'), 'name_divers': fields.char('Nom Occasionel', size=64), 'tel_divers': fields.char('Telephone Occasionel', size=64), 'address_divers': fields.char('Addresse Occasionel', size=64), 'validator': fields.many2one('res.users', 'Validation'), 'printed': fields.boolean('Printed'), 'reviens_state': fields.selection( [('calculated', 'Calculé'), ('fixed', 'Prix de vente établie'), ('confirmed', 'Confirmé')], 'Calcul du reviens', readonly=True, size=32, ), 'cur_rate': fields.float('Cours Devise'), } _defaults = { 'cur_rate': 1, } def printed(self, cr, uid, ids, context=None): return 'Printing'
class auction_lots_invoice(osv.osv_memory): _name = 'auction.lots.invoice' _description = "Auction Lots Invoice" _columns = { 'amount': fields.float('Invoiced Amount', required=True, readonly=True), 'amount_topay': fields.float('Amount to pay', required=True, readonly=True), 'amount_paid': fields.float('Amount paid', readonly=True), 'objects': fields.integer('# of objects', required=True, readonly=True), 'ach_uid': fields.many2one('res.partner', 'Buyer Name', required=True), 'number': fields.integer('Invoice Number'), } def default_get(self, cr, uid, fields, context=None): """ To get default values for the object. @param self: The object pointer. @param cr: A database cursor @param uid: ID of the user currently logged in @param fields: List of fields for which we want default values @param context: A standard dictionary @return: A dictionary which of fields with values. """ if context is None: context = {} res = super(auction_lots_invoice, self).default_get(cr, uid, fields, context=context) lots = self.pool.get('auction.lots').read( cr, uid, context.get('active_ids', [])) auction = self.pool.get('auction.dates').read( cr, uid, [lots[0]['auction_id'][0]])[0] price = 0.0 price_topay = 0.0 price_paid = 0.0 for lot in lots: price_lot = lot['obj_price'] or 0.0 costs = self.pool.get('auction.lots').compute_buyer_costs( cr, uid, [lot['id']]) price_lot += costs['amount'] price += price_lot if lot['ach_uid']: if uid and (lot['ach_uid'][0] <> uid): raise osv.except_osv( _('UserError'), _('Two different buyers for the same invoice !\nPlease correct this problem before invoicing' )) uid = lot['ach_uid'][0] elif lot['ach_login']: refs = self.pool.get('res.partner').search( cr, uid, [('ref', '=', lot['ach_login'])]) if len(refs): uid = refs[-1] if 'ach_pay_id' in lot and lot['ach_pay_id']: price_paid += price_lot #*tax else: price_topay += price_lot #*tax #TODO: recuperer id next invoice (de la sequence)??? invoice_number = False for lot in self.pool.get('auction.lots').browse(cr, uid, context.get( 'active_ids', []), context=context): if 'objects' in fields: res.update({'objects': len(context.get('active_ids', []))}) if 'amount' in fields: res.update({'amount': price}) if 'ach_uid' in fields: res.update({'ach_uid': uid}) if 'amount_topay' in fields: res.update({'amount_topay': price_topay}) if 'amount_paid' in fields: res.update({'amount_paid': price_paid}) if 'number' in fields: res.update({'number': invoice_number}) return res def print_report(self, cr, uid, ids, context=None): """ Create an invoice report. @param cr: the current row, from the database cursor. @param uid: the current user’s ID for security checks. @param ids: List of Auction lots make invoice buyer’s IDs @return: dictionary of account invoice form. """ if context is None: context = {} datas = {'ids': context.get('active_ids', [])} res = self.read(cr, uid, ids, ['number', 'ach_uid']) res = res and res[0] or {} datas['form'] = res return { 'type': 'ir.actions.report.xml', 'report_name': 'auction.invoice', 'datas': datas, }
class fleet_vehicles(osv.osv): """ To add admin affaire information """ STATE_SELECTION = [ ('draft', 'Draft'), ('confirmed', 'Confirmed'), ('cancel', 'Cancel'), ] _inherit = "fleet.vehicle" _columns = { #'name': fields.function(_complete_name, type='char', size=256, string="Vehicle Name",store=True), 'year': fields.many2one('manufacturing.year', 'Year', states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'depracc': fields.many2one('account.account', string='Depreciation Account', required=False, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), #'schedname':fields.many2one('fleet.service.templ','PM Schedule',help="Preventive maintainance schedule for this vehicle",required=False,states={'confirmed':[('readonly',True)],'cancel':[('readonly',True)]}), must be check with car maintenance module 'type': fields.selection( [('truck', 'Truck'), ('bus', 'Bus'), ('car', 'Car'), ('generator', 'Generator')], 'Class', required=True, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }, ), 'status': fields.selection( [ ('active', 'Active'), ('inactive', 'InActive'), ('outofservice', 'Out of Service'), ], 'status', required=True, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }, ), 'ownership': fields.selection( [ ('owned', 'Owned'), ('rented', 'Rented'), ('generator', 'Generator'), ('mile', 'Instead mile'), ], 'Ownership', required=True, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }, ), 'primarymeter': fields.selection( [ ('odometer', 'Odometer'), ('hourmeter', 'Hour Meter'), ], 'Primary Meter', required=True, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }, ), 'company_id': fields.many2one( 'res.company', 'Company', required=True, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }, ), 'startodometer': fields.integer('Start Odometer', required=True, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'cmil': fields.float('Current Mileage', digits=(16, 3), states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'bmil': fields.float('Base Mileage', digits=(16, 3), help="The last recorded mileage", states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'bdate': fields.date('Recorded Date', help="Date on which the mileage is recorded", states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), #'location':fields.many2one('stock.location','Stk Location',help="Select the stock location or create one for each vehicle(recommended) so that the spares, tyres etc are assossiated with the vehicle when issued",required=False,states={'confirmed':[('readonly',True)],'cancel':[('readonly',True)]}), 'department_id': fields.many2one('hr.department', 'Department', states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'machine_no': fields.char('Machine No', size=64, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'employee_id': fields.many2one('hr.employee', 'Employee', states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'state': fields.selection(STATE_SELECTION, 'State', readonly=True, select=True), 'user_id': fields.many2one( 'res.users', 'Responsible', readonly=True, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }, ), 'notes': fields.text('Notes', size=256, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'serial': fields.char('productSerial #', size=50, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), 'machine_capacity': fields.char('Machine Capacity', size=50, states={ 'confirmed': [('readonly', True)], 'cancel': [('readonly', True)] }), } _defaults = { 'state': 'draft', 'user_id': lambda self, cr, uid, context: uid, } def confirmed(self, cr, uid, ids, context=None): """ Workflow function to change state to confirmed. @return: Boolean True """ self.write(cr, uid, ids, {'state': 'confirmed'}) return True def cancel(self, cr, uid, ids, notes='', context=None): """ Workflow function changes order state to cancel and writes note which contains Date and username who do cancellation. @param notes: contains information of who & when cancelling order. @return: Boolean True """ notes = "" u = self.browse(cr, uid, ids)[0].user_id.name notes = notes + '\n' + 'vehicle Cancelled at : ' + time.strftime( '%Y-%m-%d') + ' by ' + u self.write(cr, uid, ids, {'state': 'cancel', 'notes': notes}) return True def ir_action_cancel_draft(self, cr, uid, ids, context=None): """ Changes state to Draft and reset the workflow. @return: Boolean True """ if not len(ids): return False wf_service = netsvc.LocalService("workflow") for s_id in ids: self.write(cr, uid, s_id, {'state': 'draft'}) wf_service.trg_delete(uid, 'fleet.vehicle', s_id, cr) wf_service.trg_create(uid, 'fleet.vehicle', s_id, cr) return True
class report_account_analytic_planning_stat(osv.osv): _name = "report_account_analytic.planning.stat" _description = "Planning stat" _rec_name = 'user_id' _auto = False _log_access = False _order = 'planning_id,user_id' def _sum_amount_real(self, cr, uid, ids, name, args, context=None): users_obj = self.pool.get('res.users') result = {} tm2 = users_obj.browse( cr, uid, uid, context=context).company_id.planning_time_mode_id if tm2 and tm2.factor: div2 = tm2.factor else: div2 = 1.0 for line in self.browse(cr, uid, ids, context=context): if line.user_id: cr.execute( '''SELECT sum(acc.unit_amount/uom.factor) FROM account_analytic_line acc LEFT JOIN product_uom uom ON (uom.id = acc.product_uom_id) WHERE user_id=%s and account_id=%s and date>=%s and date<=%s''', (line.user_id.id, line.account_id and line.account_id.id or None, line.planning_id.date_from, line.planning_id.date_to)) else: cr.execute( 'SELECT sum(unit_amount) FROM account_analytic_line WHERE account_id=%s AND date>=%s AND date<=%s', (line.account_id and line.account_id.id or None, line.planning_id.date_from, line.planning_id.date_to)) sum = cr.fetchone() if sum and sum[0]: result[line.id] = sum[0] * div2 return result def _sum_amount_tasks(self, cr, uid, ids, name, args, context=None): users_obj = self.pool.get('res.users') result = {} tm = users_obj.browse(cr, uid, uid, context=context).company_id.project_time_mode_id if tm and tm.factor: div = tm.factor else: div = 1.0 tm2 = users_obj.browse( cr, uid, uid, context=context).company_id.planning_time_mode_id if tm2 and tm2.factor: div2 = tm2.factor else: div2 = 1.0 for line in self.browse(cr, uid, ids, context=context): where = '' if line.user_id: where = 'user_id=' + str(line.user_id.id) + ' and ' cr.execute( '''select sum(planned_hours) FROM project_task WHERE ''' + where + ''' project_id IN (select id from project_project where analytic_account_id=%s) AND date_end>=%s AND date_end<=%s''', (line.account_id and line.account_id.id or None, line.planning_id.date_from, line.planning_id.date_to)) sum = cr.fetchone() if sum and sum[0]: result[line.id] = sum[0] / div * div2 return result _columns = { 'planning_id': fields.many2one('report_account_analytic.planning', 'Planning'), 'user_id': fields.many2one('res.users', 'User'), 'manager_id': fields.many2one('res.users', 'Manager'), 'account_id': fields.many2one('account.analytic.account', 'Account'), 'sum_amount': fields.float('Planned Days', required=True), 'sum_amount_real': fields.function(_sum_amount_real, method=True, string='Timesheet'), 'sum_amount_tasks': fields.function(_sum_amount_tasks, method=True, string='Tasks'), } def init(self, cr): cr.execute(""" create or replace view report_account_analytic_planning_stat as ( SELECT min(l.id) as id, l.user_id as user_id, a.user_id as manager_id, l.account_id as account_id, sum(l.amount/u.factor) as sum_amount, l.planning_id FROM report_account_analytic_planning_line l LEFT JOIN report_account_analytic_planning a on (a.id = l.planning_id) LEFT JOIN product_uom u on (l.amount_unit = u.id) GROUP BY l.planning_id, l.user_id, l.account_id, a.user_id ) """)
class report_account_analytic_planning_account(osv.osv): _name = "report_account_analytic.planning.account" _description = "Planning by Account" _rec_name = 'account_id' _auto = False def _get_tasks(self, cr, uid, ids, name, args, context=None): users_obj = self.pool.get('res.users') result = {} tm = users_obj.browse(cr, uid, uid, context=context).company_id.project_time_mode_id if tm and tm.factor: div = tm.factor else: div = 1.0 tm2 = users_obj.browse( cr, uid, uid, context=context).company_id.planning_time_mode_id if tm2 and tm2.factor: div2 = tm2.factor else: div2 = 1.0 for line in self.browse(cr, uid, ids, context=context): cr.execute( """ SELECT COALESCE(sum(tasks.remaining_hours),0) FROM project_task tasks WHERE tasks.planning_line_id IN ( SELECT id FROM report_account_analytic_planning_line WHERE planning_id = %s AND account_id=%s )""", (line.planning_id.id, line.account_id and line.account_id.id or None)) result[line.id] = cr.fetchall()[0][0] / div * div2 return result def _get_timesheets(self, cr, uid, ids, name, args, context=None): users_obj = self.pool.get('res.users') result = {} tm2 = users_obj.browse( cr, uid, uid, context=context).company_id.planning_time_mode_id if tm2 and tm2.factor: div2 = tm2.factor else: div2 = 1.0 for line in self.browse(cr, uid, ids, context=context): cr.execute( """ SELECT SUM(unit_amount/uom.factor) FROM account_analytic_line acc LEFT JOIN product_uom uom ON (uom.id = acc.product_uom_id) WHERE acc.date>=%s and acc.date<=%s and acc.account_id=%s""", (line.planning_id.date_from, line.planning_id.date_to, line.account_id and line.account_id.id or None)) res = cr.fetchall()[0][0] if res: result[line.id] = res * div2 else: result[line.id] = 0 return result _columns = { 'planning_id': fields.many2one('report_account_analytic.planning', 'Planning'), 'account_id': fields.many2one('account.analytic.account', 'Analytic account', readonly=True), 'tasks': fields.function( _get_tasks, method=True, string='Remaining Tasks', help= 'This value is given by the sum of work remaining to do on the task for this planning, expressed in days.' ), 'plan_tasks': fields.float( 'Time Allocation of Tasks', readonly=True, help= 'This value is given by the sum of time allocation with the checkbox \'Assigned in Taks\' set to TRUE expressed in days.' ), 'plan_open': fields.float( 'Time Allocation without Tasks', readonly=True, help= 'This value is given by the sum of time allocation with the checkbox \'Assigned in Taks\' set to FALSE, expressed in days.' ), 'timesheet': fields.function( _get_timesheets, method=True, string='Timesheet', help= 'This value is given by the sum of all work encoded in the timesheet(s) between the \'Date From\' and \'Date To\' of the planning.' ), } def init(self, cr): cr.execute( """ CREATE OR REPLACE VIEW report_account_analytic_planning_account AS ( SELECT MIN(l.id) AS id, l.account_id AS account_id, SUM(l.amount) AS quantity, l.planning_id AS planning_id, ( SELECT SUM(line1.amount_in_base_uom) FROM report_account_analytic_planning_line line1 WHERE ( SELECT COUNT(1) FROM project_task task WHERE task.planning_line_id = line1.id ) > 0 AND l.account_id = line1.account_id AND l.planning_id = line1.planning_id ) AS plan_tasks, ( SELECT SUM(line1.amount_in_base_uom) FROM report_account_analytic_planning_line line1 WHERE ( SELECT COUNT(1) FROM project_task task WHERE task.planning_line_id = line1.id ) = 0 AND l.account_id = line1.account_id AND planning.id = line1.planning_id ) AS plan_open FROM report_account_analytic_planning_line l INNER JOIN report_account_analytic_planning planning ON planning.id=l.planning_id GROUP BY l.account_id, l.planning_id, planning.date_from, planning.date_to, planning.id ) """)
class report_account_analytic_planning_user(osv.osv): _name = "report_account_analytic.planning.user" _description = "Planning by User" _rec_name = 'user_id' _auto = False def _get_tasks(self, cr, uid, ids, name, args, context=None): users_obj = self.pool.get('res.users') result = {} tm = users_obj.browse(cr, uid, uid, context=context).company_id.project_time_mode_id if tm and tm.factor: div = tm.factor else: div = 1.0 tm2 = users_obj.browse( cr, uid, uid, context=context).company_id.planning_time_mode_id if tm2 and tm2.factor: div2 = tm2.factor else: div2 = 1.0 for line in self.browse(cr, uid, ids, context=context): if line.user_id: cr.execute( """select COALESCE(sum(tasks.remaining_hours),0) from project_task tasks \ where tasks.planning_line_id IN (select id from report_account_analytic_planning_line\ where planning_id = %s and user_id=%s)""", ( line.planning_id.id, line.user_id.id, )) result[line.id] = cr.fetchall()[0][0] / div * div2 else: result[line.id] = 0 return result def _get_free(self, cr, uid, ids, name, args, context=None): result = {} for line in self.browse(cr, uid, ids, context=context): if line.user_id: result[ line. id] = line.planning_id.business_days - line.plan_tasks - line.plan_open - line.holiday else: result[line.id] = 0.0 return result def _get_timesheets(self, cr, uid, ids, name, args, context=None): users_obj = self.pool.get('res.users') result = {} tm2 = users_obj.browse( cr, uid, uid, context=context).company_id.planning_time_mode_id if tm2 and tm2.factor: div2 = tm2.factor else: div2 = 1.0 for line in self.browse(cr, uid, ids, context=context): if line.user_id: cr.execute( """ SELECT sum(unit_amount/uom.factor) FROM account_analytic_line acc LEFT JOIN product_uom uom ON (uom.id = acc.product_uom_id) WHERE acc.date>=%s and acc.date<=%s and acc.user_id=%s""", (line.planning_id.date_from, line.planning_id.date_to, line.user_id.id)) res = cr.fetchall() result[line.id] = res[0][0] and res[0][0] * div2 or False else: result[line.id] = 0 return result _columns = { 'planning_id': fields.many2one('report_account_analytic.planning', 'Planning'), 'user_id': fields.many2one('res.users', 'User', readonly=True), 'tasks': fields.function( _get_tasks, method=True, string='Remaining Tasks', help= 'This value is given by the sum of work remaining to do on the task for this planning, expressed in days.' ), 'plan_tasks': fields.float( 'Time Planned on Tasks', readonly=True, help= 'This value is given by the sum of time allocation with task(s) linked, expressed in days.' ), 'free': fields.function(_get_free, method=True, string='Unallocated Time', readonly=True, help='Computed as \ Business Days - (Time Allocation of Tasks + Time Allocation without Tasks + Holiday Leaves)' ), 'plan_open': fields.float( 'Time Allocation without Tasks', readonly=True, help= 'This value is given by the sum of time allocation without task(s) linked, expressed in days.' ), 'holiday': fields.float( 'Leaves', help= 'This value is given by the total of validated leaves into the \'Date From\' and \'Date To\' of the planning.' ), 'timesheet': fields.function( _get_timesheets, method=True, string='Timesheet', help= 'This value is given by the sum of all work encoded in the timesheet(s) between the \'Date From\' and \'Date To\' of the planning.' ), } def init(self, cr): cr.execute( """ CREATE OR REPLACE VIEW report_account_analytic_planning_user AS ( SELECT planning.id AS planning_id, (1000*(planning.id) + users.id)::integer AS id, planning.business_days, users.id AS user_id, (SELECT sum(line1.amount_in_base_uom) FROM report_account_analytic_planning_line line1 WHERE ( SELECT COUNT(1) FROM project_task task WHERE task.planning_line_id = line1.id ) > 0 AND line1.user_id = users.id AND line1.planning_id = planning.id )AS plan_tasks, (SELECT SUM(line1.amount_in_base_uom) FROM report_account_analytic_planning_line line1 WHERE ( SELECT COUNT(1) FROM project_task task WHERE task.planning_line_id = line1.id ) = 0 AND line1.user_id = users.id AND line1.planning_id = planning.id ) AS plan_open, (SELECT -(SUM(holidays.number_of_days)) FROM hr_holidays holidays WHERE holidays.employee_id IN ( SELECT emp.id FROM hr_employee emp, resource_resource res WHERE emp.resource_id = res.id and res.user_id = users.id ) AND holidays.state IN ('validate') AND holidays.type = 'remove' AND holidays.date_from >= planning.date_from AND holidays.date_to <= planning.date_to ) AS holiday FROM report_account_analytic_planning planning LEFT JOIN report_account_analytic_planning_line line ON (line.planning_id = planning.id), res_users users GROUP BY planning.id, planning.business_days, users.id, planning.date_from, planning.date_to UNION SELECT planning.id AS planning_id, (1000*(planning.id) - 1)::integer AS id, planning.business_days, line.user_id, (SELECT SUM(line1.amount_in_base_uom) FROM report_account_analytic_planning_line line1 WHERE (SELECT COUNT(1) FROM project_task task WHERE task.planning_line_id = line1.id) > 0 AND line1.user_id IS NULL ) AS plan_tasks, (SELECT SUM(line1.amount_in_base_uom) FROM report_account_analytic_planning_line line1 WHERE (SELECT COUNT(1) FROM project_task task WHERE task.planning_line_id = line1.id) = 0 AND line1.user_id IS NULL ) AS plan_open, '0' AS holiday FROM report_account_analytic_planning planning INNER JOIN report_account_analytic_planning_line line ON line.planning_id = planning.id AND line.user_id IS NULL GROUP BY planning.id, planning.business_days, line.user_id, planning.date_from, planning.date_to ) """)
class report_account_analytic_planning_line(osv.osv): _name = "report_account_analytic.planning.line" _description = "Planning Line" _rec_name = 'user_id' def name_get(self, cr, uid, ids, context=None): if not len(ids): return [] reads = self.read(cr, uid, ids, ['user_id', 'planning_id', 'note'], context=context) res = [] for record in reads: name = '[' + record['planning_id'][1] if record['user_id']: name += " - " + record['user_id'][1] + '] ' else: name += '] ' if record['note']: name += record['note'] res.append((record['id'], name)) return res def _amount_base_uom(self, cr, uid, ids, name, args, context=None): users_obj = self.pool.get('res.users') result = {} tm = users_obj.browse(cr, uid, uid, context=context).company_id.planning_time_mode_id if tm and tm.factor: div = tm.factor else: div = 1.0 for line in self.browse(cr, uid, ids, context=context): result[line.id] = line.amount / line.amount_unit.factor * div return result _columns = { 'account_id': fields.many2one('account.analytic.account', 'Analytic account'), 'planning_id': fields.many2one('report_account_analytic.planning', 'Planning', required=True, ondelete='cascade'), 'user_id': fields.many2one('res.users', 'User'), 'amount': fields.float('Quantity', required=True), 'amount_unit': fields.many2one('product.uom', 'Qty UoM', required=True), 'note': fields.text('Note', size=64), 'amount_in_base_uom': fields.function(_amount_base_uom, method=True, string='Quantity in base uom', store=True), 'task_ids': fields.one2many('project.task', 'planning_line_id', 'Planning Tasks'), } _order = 'user_id, account_id'
class fleet_fuellog(osv.osv): _name = "fleet.fuellog" _description = "Records the fuelling entries" _rec_name = "vehicle" def _get_period(self, cr, uid, context): periods = self.pool.get('account.period').find(cr, uid) if periods: return periods[0] else: return False def cancel_voucher(self, cr, uid, ids, context={}): self.action_cancel(cr, uid, ids) self.write(cr, uid, ids, {'state': 'cancel'}) return True def action_cancel_draft(self, cr, uid, ids, *args): self.write(cr, uid, ids, {'state': 'draft'}) return True def calc_amount(self, cr, uid, ids, totalcost, qty): res = {} #print "totalcost>>",totalcost #print "qty>>>",qty if qty: res['costpl'] = totalcost / qty else: res['costpl'] = 0.0 #print "costpl>>>",costpl # self.write(cr,uid,ids,{'costpl':costpl}) return {'value': res} def calc_amount2(self, cr, uid, ids, field, unknown, context={}): res = {} for obj in self.browse(cr, uid, ids): #print "totalcost>>",totalcost #print "qty>>>",qty if obj.qty: res[obj.id] = obj.totalcost / obj.qty else: res[obj.id] = 0.0 #print "costpl>>>",costpl # self.write(cr,uid,ids,{'costpl':costpl}) return res def _get_journal(self, cr, uid, context): type_inv = context.get('type', 'rec_voucher') journal_obj = self.pool.get('account.journal') res = False res = journal_obj.search(cr, uid, [('type', '=', 'purchase')], limit=1) if res: return res[0] else: return False def _get_currency(self, cr, uid, context): user = pooler.get_pool(cr.dbname).get('res.users').browse( cr, uid, [uid])[0] if user.company_id: return user.company_id.currency_id.id else: return pooler.get_pool(cr.dbname).get('res.currency').search( cr, uid, [('rate', '=', 1.0)])[0] def copy(self, cr, uid, id, default=None, context={}): if not default: default = {} default.update({ 'state': 'draft', 'log_no': self.pool.get('ir.sequence').get(cr, uid, 'fleet.fuel'), 'move_id': False, }) return super(fleet_fuellog, self).copy(cr, uid, id, default, context) _columns = { 'log_no': fields.char('Log Entry#', size=12), 'vehicle': fields.many2one('fleet.vehicles', 'Vehicle Name', required=True), 'vendor': fields.many2one('res.partner', 'Fuel Station', required=True), 'date': fields.date('Date', required=True), 'invno': fields.char('Invoice no', size=10, required=True), 'costpl': fields.function(calc_amount2, method=True, string='Cost Per Ltr', digits=(16, 2), store=True), 'qty': fields.float('Quantity', digits=(16, 3), required=True), 'totalcost': fields.float('Total Cost', digits=(16, 2), required=True), 'odometer': fields.integer('Odometer', required=True), 'emp_resp': fields.many2one('hr.employee', 'Employee Responsible', required=True, help="Employee reporting fuelling details"), 'driver': fields.many2one( 'hr.employee', 'Driver', required=True, help="Driver who has driven the vehice before this fuelling"), 'currency_id': fields.many2one( 'res.currency', 'Currency', ), 'journal_id': fields.many2one( 'account.journal', 'Journal', required=True, ), 'move_id': fields.many2one('account.move', 'Account Entry', readonly=True), 'period_id': fields.many2one( 'account.period', 'Period', required=True, ), 'state': fields.selection([('draft', 'Draft'), ('cancel', 'Cancel'), ('proforma', 'Proforma'), ('posted', 'Posted')], readonly=True) #'voucher':fields.many2one('account.voucher','Rel Voucher',domain=[('state','=','posted')],help="Select the related accounts voucher"), } _defaults = { 'date': lambda *a: time.strftime('%Y-%m-%d'), 'period_id': _get_period, 'journal_id': _get_journal, 'currency_id': _get_currency, 'state': lambda *a: 'draft', 'log_no': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get( cr, uid, 'fleet.fuel'), } #This function is used for transition from draft to proforma def open_fuellog(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'proforma'}) # dani def unlink(self, cr, uid, ids): # vouchers = self.read(cr, uid, ids, ['state']) # unlink_ids = [] # for t in vouchers: # if t['state'] in ('draft', 'cancel'): # unlink_ids.append(t['id']) # else: # raise osv.except_osv('Invalid action !', 'Cannot delete invoice(s) which are already opened or paid !') # osv.osv.unlink(self, cr, uid, unlink_ids) # return True #This function is used to set the state to cancelled def cancel_voucher(self, cr, uid, ids, context={}): self.write(cr, uid, ids, {'state': 'cancel'}) return True def _cancel_moves(self, cr, uid, ids, context={}): # dani for obj in self.browse(cr, uid, ids): # dani self.pool.get('account.move').unlink(cr,uid,[obj.move_id.id]) return self.write(cr, uid, ids, {'state': 'cancel'}) #This function will create a new account move and the corresponding account move lines def _create_moves(self, cr, uid, ids, context={}): for log in self.browse(cr, uid, ids): journal = self.pool.get('account.journal').browse( cr, uid, log.journal_id) name = False if journal.sequence_id: name = self.pool.get('ir.sequence').get_id( cr, uid, journal.sequence_id.id) move = {'name': name, 'journal_id': log.journal_id.id} else: move = { 'name': 'Fuel' + str(log.id), 'journal_id': log.journal_id.id } move['period_id'] = log.period_id.id #print ">>>",move move_id = self.pool.get('account.move').create(cr, uid, move) debit_move_line = { 'name': log.vehicle.id, 'debit': log.totalcost, 'credit': False, 'account_id': log.journal_id.default_debit_account_id.id or False, 'move_id': move_id, 'journal_id': log.journal_id.id, 'period_id': log.period_id.id, 'partner_id': log.vendor.id, 'ref': str(log.id) + log.vehicle.name, 'date': log.date } self.pool.get('account.move.line').create(cr, uid, debit_move_line) credit_move_line = { 'name': log.vehicle.id, 'debit': False, 'credit': log.totalcost, 'account_id': log.vendor.property_account_payable.id or False, 'move_id': move_id, 'journal_id': log.journal_id.id, 'period_id': log.period_id.id, 'partner_id': log.vendor.id, 'ref': str(log.id) + log.vehicle.name, 'date': log.date } #print "credit_move_line>>>",credit_move_line self.pool.get('account.move.line').create(cr, uid, credit_move_line) self.write(cr, uid, log.id, { 'move_id': move_id, 'state': 'posted' }) return True
domain=[('type', '=', 'service')], select="1"), 'package_det': fields.one2many('ups.shippingregister.package', 'shipping_register_rel', string='Packages',), 'to_address': fields.many2one('res.partner.address', 'Shipping Address', required=True), 'from_address': fields.many2one('res.partner.address', 'From Address', required=True), 'shipper_address': fields.many2one('res.partner.address', 'Shipper Address', required=True), 'saturday_delivery': fields.boolean('Saturday Delivery?'), 'description': fields.text('Description'), 'state':fields.selection(STATE_SELECTION, 'Status', readonly=True,), # The following are UPS filled information 'billed_weight':fields.float('Billed Weight', digits=(10, 4), readonly=True, help=( 'The billed weght may be different from the actual weight.' 'This is computed by UPS.')), 'billed_weight_uom':fields.many2one('product.uom', 'Billed Weight UOM', readonly=True), 'total_amount':fields.float('Total Amount', digits=(14, 4), select="1", readonly=True), 'total_amount_currency':fields.many2one('res.currency', 'Total Amount Currency', select="2", readonly=True,), 'digest': fields.binary('Information digest for DIGEST'), 'notificationemailaddr': fields.char('Notification eMail Addresses', size=255, help='Separated by commas(,).'), } _defaults = { 'name': lambda *a: 'Not Processed', 'state': lambda *a: 'draft'
class fleet_vehicles(osv.osv): _name = "fleet.vehicles" _description = "Holds records of Vehicles" def copy(self, cr, uid, id, default=None, context={}): if not default: default = {} default.update({ 'name': 'New Vehicle Name', 'regnno': 'New Registration no', }) return super(fleet_vehicles, self).copy(cr, uid, id, default, context) #def _lastodometer(self,cr,uid,ids,context={}): # return(0.00) #def _lastododate(self,cr,uid,ids,context={}): # datetime.datetime.now() _columns = { 'name': fields.char('Vehicle Name', size=20, required=True), 'regnno': fields.char('Vehicle Registration #', size=11, required=True), 'company': fields.many2one('res.company', 'Company', required=True), 'assetacc': fields.many2one('account.account', string='Asset Account', domain=[('type', '=', 'vehicle')], required=True), 'depracc': fields.many2one('account.account', string='Depreciation Account', required=True), 'year': fields.char('Year', size=4), 'make': fields.char('Make', size=10), 'model': fields.char('Model', size=15), 'serial': fields.char('productSerial #', size=50), 'type': fields.selection( [('truck', 'Truck'), ('bus', 'Bus'), ('car', 'Car'), ('van', 'Van')], 'Class', required=True, ), 'status': fields.selection( [ ('active', 'Active'), ('inactive', 'InActive'), ('outofservice', 'Out of Service'), ], 'status', required=True, ), 'ownership': fields.selection([ ('owned', 'Owned'), ('leased', 'Leased'), ('rented', 'Rented'), ], 'Ownership', required=True), 'schedname': fields.many2one( 'fleet.service.templ', 'PM Schedule', help="Preventive maintainance schedule for this vehicle", required=True), 'cmil': fields.float('Current Mileage', digits=(16, 3)), 'bmil': fields.float('Base Mileage', digits=(16, 3), help="The last recorded mileage"), 'bdate': fields.date('Recorded Date', help="Date on which the mileage is recorded"), 'pdate': fields.date('Purchase Date', help="Date of Purchase of vehicle"), 'pcost': fields.float('Purchase Value', digits=(16, 2)), 'ppartner': fields.many2one('res.partner', 'Purchased From'), 'pinvoice': fields.many2one('account.invoice', 'Purchase Invoice', size=15), 'podometer': fields.integer('Odometer at Purchase'), 'startodometer': fields.integer('Start Odometer', required=True), #'lastodometer':fields.function(_lastodometer , method=True ,string='Last Odometer',digits=(11,0)), #'lastrecdate':fields.function(_lastododate , method=True , string='on date'), 'deprecperc': fields.float('Depreciation in %', digits=(10, 2), required=True), 'deprecperd': fields.selection([('monthly', 'Monthly'), ('quarterly', 'Quarterly'), ('halfyearly', 'Half Yearly'), ('annual', 'Yearly')], 'Depr. period', required=True), 'primarymeter': fields.selection([ ('odometer', 'Odometer'), ('hourmeter', 'Hour Meter'), ], 'Primary Meter', required=True), 'fueltype': fields.selection([('hyrbrid', 'Hybrid'), ('diesel', 'Diesel'), ('gasoline', 'Gasoline'), ('cng', 'C.N.G'), ('lpg', 'L.P.G'), ('electric', 'Electric')], 'Fuel Used', required=True), #'fuelcardno':fields.one2one('fleet.fuelcards','Fuel Card #'), 'fueltankcap': fields.float('Fuel Tank Capacity'), 'warrexp': fields.date('Date', help="Expiry date for warranty of product"), 'warrexpmil': fields.integer('(or) Mileage', help="Expiry mileage for warranty of product"), 'location': fields.many2one( 'stock.location', 'Stk Location', help= "Select the stock location or create one for each vehicle(recommended) so that the spares, tyres etc are assossiated with the vehicle when issued", required=True), } _defaults = { 'type': lambda *a: 'vehicle', 'status': lambda *a: 'active', 'ownership': lambda *a: 'owned', 'fueltype': lambda *a: 'diesel', 'primarymeter': lambda *a: 'odometer', 'deprecperd': lambda *a: 'annual' } _sql_constraints = [('uniq_regn_no', 'unique (regnno)', 'The registration no of the vehicle must be unique !') ]
class mrp_production_workcenter_line(osv.osv): def _get_date_date(self, cr, uid, ids, field_name, arg, context=None): """ Finds starting date. @return: Dictionary of values. """ res = {} for op in self.browse(cr, uid, ids, context=context): if op.date_start: res[op.id] = op.date_start[:10] else: res[op.id] = False return res def _get_date_end(self, cr, uid, ids, field_name, arg, context=None): """ Finds ending date. @return: Dictionary of values. """ ops = self.browse(cr, uid, ids, context=context) date_and_hours_by_cal = [(op.date_planned, op.hour, op.workcenter_id.calendar_id.id) for op in ops if op.date_planned] intervals = self.pool.get('resource.calendar').interval_get_multi( cr, uid, date_and_hours_by_cal) res = {} for op in ops: res[op.id] = False if op.date_planned: i = intervals.get((op.date_planned, op.hour, op.workcenter_id.calendar_id.id)) if i: res[op.id] = i[-1][1].strftime('%Y-%m-%d %H:%M:%S') else: res[op.id] = op.date_planned return res _inherit = 'mrp.production.workcenter.line' _order = "sequence, date_planned" _columns = { 'state': fields.selection([('draft','Draft'),('startworking', 'In Progress'),('pause','Pause'),('cancel','Cancelled'),('done','Finished')],'State', readonly=True, help="* When a work order is created it is set in 'Draft' state.\n" \ "* When user sets work order in start mode that time it will be set in 'In Progress' state.\n" \ "* When work order is in running mode, during that time if user wants to stop or to make changes in order then can set in 'Pause' state.\n" \ "* When the user cancels the work order it will be set in 'Canceled' state.\n" \ "* When order is completely processed that time it is set in 'Finished' state."), 'date_start_date': fields.function(_get_date_date, method=True, string='Start Date', type='date'), 'date_planned': fields.datetime('Scheduled Date'), 'date_planned_end': fields.function(_get_date_end, method=True, string='End Date', type='datetime'), 'date_start': fields.datetime('Start Date'), 'date_finished': fields.datetime('End Date'), 'delay': fields.float('Working Hours',help="This is lead time between operation start and stop in this workcenter",readonly=True), 'production_state':fields.related('production_id','state', type='selection', selection=[('draft','Draft'),('picking_except', 'Picking Exception'),('confirmed','Waiting Goods'),('ready','Ready to Produce'),('in_production','In Production'),('cancel','Canceled'),('done','Done')], string='Production State', readonly=True), 'product':fields.related('production_id','product_id',type='many2one',relation='product.product',string='Product', readonly=True), 'qty':fields.related('production_id','product_qty',type='float',string='Qty',readonly=True, store=True), 'uom':fields.related('production_id','product_uom',type='many2one',relation='product.uom',string='UOM',readonly=True), } _defaults = {'state': lambda *a: 'draft', 'delay': lambda *a: 0.0} def modify_production_order_state(self, cr, uid, ids, action): """ Modifies production order state if work order state is changed. @param action: Action to perform. @return: Nothing """ wf_service = netsvc.LocalService("workflow") oper_obj = self.browse(cr, uid, ids)[0] prod_obj = oper_obj.production_id if action == 'start': if prod_obj.state == 'confirmed': self.pool.get('mrp.production').force_production( cr, uid, [prod_obj.id]) wf_service.trg_validate(uid, 'mrp.production', prod_obj.id, 'button_produce', cr) elif prod_obj.state == 'ready': wf_service.trg_validate(uid, 'mrp.production', prod_obj.id, 'button_produce', cr) elif prod_obj.state == 'in_production': return else: raise osv.except_osv( _('Error!'), _('Production Order Cannot start in [%s] state') % (prod_obj.state, )) else: oper_ids = self.search(cr, uid, [('production_id', '=', prod_obj.id)]) obj = self.browse(cr, uid, oper_ids) flag = True for line in obj: if line.state != 'done': flag = False if flag: wf_service.trg_validate(uid, 'mrp.production', oper_obj.production_id.id, 'button_produce_done', cr) return def write(self, cr, uid, ids, vals, context=None, update=True): result = super(mrp_production_workcenter_line, self).write(cr, uid, ids, vals, context=context) prod_obj = self.pool.get('mrp.production') if vals.get('date_planned', False) and update: for prod in self.browse(cr, uid, ids, context=context): if prod.production_id.workcenter_lines: dstart = min( vals['date_planned'], prod.production_id.workcenter_lines[0]['date_planned']) prod_obj.write(cr, uid, [prod.production_id.id], {'date_start': dstart}, context=context, mini=False) return result def action_draft(self, cr, uid, ids): """ Sets state to draft. @return: True """ self.write(cr, uid, ids, {'state': 'draft'}) return True def action_start_working(self, cr, uid, ids): """ Sets state to start working and writes starting date. @return: True """ self.modify_production_order_state(cr, uid, ids, 'start') self.write( cr, uid, ids, { 'state': 'startworking', 'date_start': time.strftime('%Y-%m-%d %H:%M:%S') }) return True def action_done(self, cr, uid, ids): """ Sets state to done, writes finish date and calculates delay. @return: True """ delay = 0.0 date_now = time.strftime('%Y-%m-%d %H:%M:%S') obj_line = self.browse(cr, uid, ids[0]) date_start = datetime.strptime(obj_line.date_start, '%Y-%m-%d %H:%M:%S') date_finished = datetime.strptime(date_now, '%Y-%m-%d %H:%M:%S') delay += (date_finished - date_start).days * 24 delay += (date_finished - date_start).seconds / float(60 * 60) self.write(cr, uid, ids, { 'state': 'done', 'date_finished': date_now, 'delay': delay }) self.modify_production_order_state(cr, uid, ids, 'done') return True def action_cancel(self, cr, uid, ids): """ Sets state to cancel. @return: True """ self.write(cr, uid, ids, {'state': 'cancel'}) return True def action_pause(self, cr, uid, ids): """ Sets state to pause. @return: True """ self.write(cr, uid, ids, {'state': 'pause'}) return True def action_resume(self, cr, uid, ids): """ Sets state to startworking. @return: True """ self.write(cr, uid, ids, {'state': 'startworking'}) return True
class stock_production_lot(osv.osv): _name = 'stock.production.lot' _inherit = 'stock.production.lot' _order = 'life_date' def _get_future_stock_forecast(self, cr, uid, ids, field_name, arg, context=None): """ Gets stock of products for locations @return: Dictionary of values """ if context is None: context = {} if 'location_id' not in context or context['location_id'] is None: locations = self.pool.get('stock.location').search( cr, uid, [('usage', '=', 'internal')], context=context) elif context.get('search_in_child', False): locations = self.pool.get('stock.location').search( cr, uid, [('location_id', 'child_of', context['location_id']) ]) or [context['location_id']] else: locations = [context['location_id']] if isinstance(ids, (int, long)): ids = [ids] res = {}.fromkeys(ids, 0.0) if locations: cr.execute( '''select prodlot_id, sum(qty) from batch_stock_future_forecast where location_id IN %s and prodlot_id IN %s group by prodlot_id''', ( tuple(locations), tuple(ids), )) res.update(dict(cr.fetchall())) product_uom_id = context.get('product_uom', None) if (product_uom_id): product_uom = self.pool.get('product.uom').browse( cr, uid, product_uom_id, context) for key in res: res[key] = res[key] * product_uom.factor return res def name_get(self, cr, uid, ids, context=None): if context is None: context = {} if isinstance(ids, (int, long)): ids = [ids] res = [] for record in self.browse(cr, uid, ids, context=context): name = record.name if (record.life_date): expiry_date = datetime.strptime(record.life_date, '%Y-%m-%d %H:%M:%S') expiry = expiry_date.strftime("%b,%Y") name = "%s [%s]" % (name, expiry) if (context.get('show_future_forcast', False)): name = "%s %s" % (name, record.future_stock_forecast) res.append((record.id, name)) return res def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): args = args or [] ids = [] if (context.get('only_available_batch', False)): batch_stock_query = 'select prodlot_id from batch_stock_future_forecast where qty > 0' for column, operator, value in args: if (column == "product_id"): batch_stock_query += " and product_id = %s" % value if context.get('location_id', False): batch_stock_query += " and location_id = %s" % context[ 'location_id'] cr.execute(batch_stock_query) args += [('id', 'in', [row[0] for row in cr.fetchall()])] if name: ids = self.search(cr, uid, [('prefix', '=', name)] + args, limit=limit, context=context) if not ids: ids = self.search(cr, uid, [('name', 'ilike', name)] + args, limit=limit, context=context) else: ids = self.search(cr, uid, args, limit=limit, context=context) return self.name_get(cr, uid, ids, context) def write(self, cr, uid, ids, values, context=None): val = super(stock_production_lot, self).write(cr, uid, ids, values, context) if val: current_product_lot = self.browse(cr, uid, ids[0], context=context) if current_product_lot.mrp < current_product_lot.sale_price: raise osv.except_osv(_('Error!'), _('MRP cannot be less than sale price')) product = current_product_lot.product_id updated_values = { 'list_price': current_product_lot.sale_price, 'standard_price': current_product_lot.cost_price } self.pool.get('product.template').write(cr, uid, product.product_tmpl_id.id, updated_values, context=context) return val _columns = { 'sale_price': fields.float('Sale Price', digits=(4, 2)), 'mrp': fields.float('MRP', digits=(4, 2)), 'cost_price': fields.float('Cost Price', digits=(4, 2)), 'future_stock_forecast': fields.function( _get_future_stock_forecast, type="float", string="Available forecast", select=True, help= "Future stock forecast quantity of products with this Serial Number available in company warehouses", digits_compute=dp.get_precision('Product Unit of Measure')), }
class product_product(osv.osv): _name = 'product.product' _inherit = 'product.product' # extending this method from stock.product to list only unexpired products def get_product_available(self, cr, uid, ids, context=None): """ Finds whether product is available or not in particular warehouse. @return: Dictionary of values """ if context is None: context = {} location_obj = self.pool.get('stock.location') warehouse_obj = self.pool.get('stock.warehouse') shop_obj = self.pool.get('sale.shop') states = context.get('states',[]) what = context.get('what',()) if not ids: ids = self.search(cr, uid, []) res = {}.fromkeys(ids, 0.0) if not ids: return res if context.get('shop', False): warehouse_ids = shop_obj.read(cr, uid, int(context['shop']), ['warehouse_id'])['warehouse_id'] warehouse_id = None; if(warehouse_ids and len(warehouse_ids) > 0): warehouse_id = shop_obj.read(cr, uid, int(context['shop']), ['warehouse_id'])['warehouse_id'][0] if warehouse_id: context['warehouse'] = warehouse_id if context.get('warehouse', False): lot_id = warehouse_obj.read(cr, uid, int(context['warehouse']), ['lot_stock_id'])['lot_stock_id'][0] if lot_id: context['location'] = lot_id if context.get('location', False): if type(context['location']) == type(1): location_ids = [context['location']] elif type(context['location']) in (type(''), type(u'')): location_ids = location_obj.search(cr, uid, [('name','ilike',context['location'])], context=context) else: location_ids = context['location'] else: location_ids = [] wids = warehouse_obj.search(cr, uid, [], context=context) for w in warehouse_obj.browse(cr, uid, wids, context=context): location_ids.append(w.lot_stock_id.id) # build the list of ids of children of the location given by id if context.get('compute_child',True): child_location_ids = location_obj.search(cr, uid, [('location_id', 'child_of', location_ids)]) location_ids = child_location_ids or location_ids # this will be a dictionary of the product UoM by product id product2uom = {} uom_ids = [] for product in self.read(cr, uid, ids, ['uom_id'], context=context): product2uom[product['id']] = product['uom_id'][0] uom_ids.append(product['uom_id'][0]) # this will be a dictionary of the UoM resources we need for conversion purposes, by UoM id uoms_o = {} for uom in self.pool.get('product.uom').browse(cr, uid, uom_ids, context=context): uoms_o[uom.id] = uom results = [] results2 = [] from_date = context.get('from_date',False) to_date = context.get('to_date',False) date_str = False date_values = False where = [tuple(location_ids),tuple(location_ids),tuple(ids),tuple(states)] if from_date and to_date: date_str = "sm.date>=%s and sm.date<=%s" where.append(tuple([from_date])) where.append(tuple([to_date])) elif from_date: date_str = "sm.date>=%s" date_values = [from_date] elif to_date: date_str = "sm.date<=%s" date_values = [to_date] if date_values: where.append(tuple(date_values)) prodlot_id = context.get('prodlot_id', False) prodlot_clause = ' and (spl.life_date is null or spl.life_date > now()) ' if prodlot_id: prodlot_clause = ' and prodlot_id = %s ' where += [prodlot_id] # TODO: perhaps merge in one query. if 'in' in what: # all moves from a location out of the set to a location in the set cr.execute( 'select sum(sm.product_qty), sm.product_id, sm.product_uom '\ 'from stock_move sm '\ 'left outer join stock_production_lot spl on sm.prodlot_id = spl.id '\ 'where '\ 'sm.location_id NOT IN %s '\ 'and sm.location_dest_id IN %s '\ 'and sm.product_id IN %s '\ 'and sm.state IN %s ' + (date_str and 'and '+date_str+' ' or '') +' '\ + prodlot_clause + 'group by sm.product_id,sm.product_uom',tuple(where)) results = cr.fetchall() if 'out' in what: # all moves from a location in the set to a location out of the set cr.execute( 'select sum(sm.product_qty), sm.product_id, sm.product_uom '\ 'from stock_move sm '\ 'left outer join stock_production_lot spl on sm.prodlot_id = spl.id '\ 'where '\ 'sm.location_id IN %s '\ 'and sm.location_dest_id NOT IN %s '\ 'and sm.product_id IN %s '\ 'and sm.state in %s ' + (date_str and 'and '+date_str+' ' or '') + ' '\ + prodlot_clause + 'group by sm.product_id,sm.product_uom',tuple(where)) results2 = cr.fetchall() # Get the missing UoM resources uom_obj = self.pool.get('product.uom') uoms = map(lambda x: x[2], results) + map(lambda x: x[2], results2) if context.get('uom', False): uoms += [context['uom']] uoms = filter(lambda x: x not in uoms_o.keys(), uoms) if uoms: uoms = uom_obj.browse(cr, uid, list(set(uoms)), context=context) for o in uoms: uoms_o[o.id] = o #TOCHECK: before change uom of product, stock move line are in old uom. context.update({'raise-exception': False}) # Count the incoming quantities for amount, prod_id, prod_uom in results: amount = uom_obj._compute_qty_obj(cr, uid, uoms_o[prod_uom], amount, uoms_o[context.get('uom', False) or product2uom[prod_id]], context=context) res[prod_id] += amount # Count the outgoing quantities for amount, prod_id, prod_uom in results2: amount = uom_obj._compute_qty_obj(cr, uid, uoms_o[prod_uom], amount, uoms_o[context.get('uom', False) or product2uom[prod_id]], context=context) res[prod_id] -= amount return res def _check_low_stock(self, cr, uid, ids, field_name, arg, context=None): orderpoint_obj = self.pool.get('stock.warehouse.orderpoint') for product in self.browse(cr, uid, ids, context=context): orderpoints = sorted(product.orderpoint_ids, key=lambda orderpoint: orderpoint.product_min_qty, reverse=True) if (len(orderpoints) > 0 and product.virtual_available < orderpoints[0].product_min_qty): return True else: return False return False def _search_low_stock(self, cr, uid, obj, name, args, context=None): ids = set() context = context or {} location = context.get('location', False) location_condition = "" if(location): location_condition = "where location_id=" + str(location) for cond in args: cr.execute("select product_id from stock_warehouse_orderpoint " + location_condition) product_ids = set(id[0] for id in cr.fetchall()) for product in self.browse(cr, uid, list(product_ids), context=context): orderpoints = sorted(product.orderpoint_ids, key=lambda orderpoint: orderpoint.product_min_qty, reverse=True) if (len(orderpoints) > 0 and product.virtual_available < orderpoints[0].product_min_qty): ids.add(product.id) if ids: return [('id', 'in', tuple(ids))] return [('id', '=', '0')] def _get_actual_stock(self, cr, uid, ids, field_name, arg, context=None): context = context or {} ctx = context.copy() ctx.update({ 'states': ('done',), 'what': ('in', 'out')}) if(ctx.get('location', False)): ctx.update({'compute_child': False}) return self.get_product_available(cr, uid, ids, context=ctx) def unlink(self, cr, uid, ids, context=None): for id in ids: self.raise_event(cr, uid,{'isDeleted' : True}, id) res = super(product_product, self).unlink(cr,uid,ids,context) return res def create(self, cr, uid, data, context=None): if data.get("uuid") is None: data['uuid'] = str(uuid.uuid4()) prod_id = super(product_product, self).create(cr, uid, data, context) data_to_be_published = { 'uuid':data.get('uuid',''), 'name':data.get('name',''), 'list_price':data.get('list_price' ,0.0), 'standard_price':data.get('standard_price',0.0) , 'life_time':data.get('life_time',None), 'drug':data.get('drug',''), 'default_code':data.get('default_code',''), 'manufacturer':data.get('manufacturer',''), 'description':data.get('description',False), 'category':data.get('category',''), 'categ_id':data.get('categ_id',''), } self.raise_event(cr, uid,data_to_be_published, prod_id) return prod_id def write(self, cr, uid, ids, vals, context=None): status = super(product_product, self).write(cr, uid, ids, vals, context=context) if (len(vals)==1) and (("message_follower_ids" in vals) or "image" in vals) : return status self.raise_event(cr, uid,vals, ids[0]) return status def raise_event(self, cr,uid, data, prod_id): data['id'] = prod_id prod_obj = self.pool.get('product.product') prod = prod_obj.browse(cr,uid,prod_id) # if((data.get('uuid',None) == None) or (data.get('uuid',None) == False)): data.pop('uuid',None) if(prod.uuid == False or prod.uuid == None): return data['uuid'] = prod.uuid description = data.get('description',False) data.pop('description',None) if(description == False) else None data.pop('categ_id',None) data['category'] = prod.categ_id.name data.pop('active', None) data['status'] = 'active' if(prod.active) else 'inactive' if(data.get('isDeleted',False)): data.pop('isDeleted', None) data['status'] = 'deleted' event_publisher_obj = self.pool.get('event.publisher') event_publisher_obj.publish_event(cr, uid, 'product', data) def get_mrp(self, cr, uid, ids, supplier_id, context=None): product = self.browse(cr, uid, ids[0], context=context) seller_ids = [seller_id.name.id for seller_id in product.seller_ids] if(supplier_id and supplier_id in seller_ids): return self.pool.get('product.supplierinfo').price_get(cr, uid, supplier_id, ids[0], context=context).get(supplier_id, False) return product and product.mrp def set_mrp(self, cr, uid, ids, supplier_id, qty, mrp, context=None): supplierinfo_obj = self.pool.get('product.supplierinfo') pricelist_obj = self.pool.get('pricelist.partnerinfo') product = self.browse(cr, uid, ids[0], context=context) seller_ids = [seller_id.name.id for seller_id in product.seller_ids] if(product is None or supplier_id is None or mrp is None): return if(supplier_id in seller_ids): supplier_info_ids = supplierinfo_obj.search(cr, uid, [('name','=',supplier_id),('product_id','=',product.id)]) if(supplier_info_ids): pricelist_ids = pricelist_obj.search(cr, uid, [('suppinfo_id', 'in', supplier_info_ids), ('min_quantity', '<=', qty)]) if(pricelist_ids): pricelist_obj.write(cr, uid, pricelist_ids, {'price': mrp}, context=context) else: supplierinfo_obj.write(cr, uid, supplier_info_ids, {'pricelist_ids': [(0, 0, {'min_quantity': 0.0, 'price': mrp})]}) else: new_pricelist_tuple = (0, 0, {'min_quantity': 0.0, 'price': mrp}) supplierinfo_obj.create(cr, uid, {'name': supplier_id, 'product_id': ids[0], 'pricelist_ids': [new_pricelist_tuple], 'min_qty': 0.0}) _columns = { 'uuid': fields.char('UUID', size=64), 'drug':fields.char('Drug Name', size=64), 'manufacturer':fields.char('Manufacturer', size=64), 'mrp': fields.float('MRP', required=False, digits_compute= dp.get_precision('Product Price')), 'low_stock': fields.function(_check_low_stock, type="boolean", string="Low Stock", fnct_search=_search_low_stock), 'actual_stock': fields.function(_get_actual_stock, type="float", string="Actual Stock"), } _defaults = { 'procure_method': 'make_to_stock' }
class search_product_quotation(osv.osv): _name = "search.product.quotation" def _get_company(self, cr, uid, context=None): return self.pool.get('res.users').browse(cr, uid, uid).company_id.id _columns = { 'company_id': fields.many2one('res.company', 'Company ID'), 'name': fields.char('Customer / Company Name', size=30), 'quotation_no': fields.char('Quotation Number', size=256), 'from_date': fields.date('From Date'), 'to_date': fields.date('To Date'), 'contact_number': fields.char('Contact Number', size=256), 'request_id': fields.char('Request ID', size=256), 'product_id': fields.many2one('product.generic.name', 'Product'), 'sku_name_id': fields.many2one('product.product', 'Product Name'), 'landline': fields.char('Landline', size=256), 'status': fields.selection([ ('new', 'New'), ('pending', 'Pending'), ('quoted', 'Quoted'), ('ordered', 'Ordered'), ('lost', 'Lost'), ('revised', 'Revised'), ], 'Status'), 'search_product_quot_lines': fields.one2many('psd.sales.product.quotation', 'search_product_quot_id', 'Product Quotations'), 'not_found': fields.boolean('not found'), 'address': fields.char('Address', size=500), 'created_by': fields.many2one('res.users', 'Created By'), 'pse': fields.many2one('hr.employee', 'PSE'), 'quotation_value_from': fields.float('Quotation Value From'), 'quotation_value_to': fields.float('Quotation Value To'), } _defaults = {'company_id': _get_company} def clear_product_quotation(self, cr, uid, ids, context=None): for k in self.browse(cr, uid, ids): self.write(cr, uid, k.id, { 'name': None, 'request_id': None, 'product_type': False, 'contact_number': None, 'status': False, 'from_date': False, 'to_date': False, 'not_found': False, 'quotation_no': None, 'address': False, 'created_by': False, 'pse': False, 'quotation_value_from': False, 'quotation_value_to': False, 'sku_name_id': None, 'product_id': None }, context=context) for req in k.search_product_quot_lines: self.pool.get('psd.sales.product.quotation').write( cr, uid, req.id, {'search_product_quot_id': None}) return True def search_product_quotation(self, cr, uid, ids, context=None): product_quotation_obj = self.pool.get('psd.sales.product.quotation') sale_quotation_line_obj = self.pool.get('psd.sales.lines') res_partner_add_obj = self.pool.get('res.partner.address') res_partner_obj = self.pool.get('res.partner') res = False domain = [] true_items = [] rec = self.browse(cr, uid, ids[0]) self.write(cr, uid, ids[0], { 'not_found': False, 'search_product_quot_lines': [(6, 0, 0)] }) if rec.name: true_items.append('name') if rec.request_id: true_items.append('request_id') if rec.status: true_items.append('status') if rec.quotation_no: true_items.append('quotation_no') if rec.contact_number: true_items.append('contact_number') if rec.product_id: true_items.append('product_id') if rec.address: true_items.append('address') if rec.created_by: true_items.append('created_by') if rec.sku_name_id: true_items.append('sku_name_id') if rec.pse: true_items.append('pse') if rec.quotation_value_from: true_items.append('quotation_value_from') if rec.quotation_value_to: true_items.append('quotation_value_to') if rec.from_date and not rec.to_date: raise osv.except_osv(("Alert!"), ("Please enter 'To date'!")) if not rec.from_date and rec.to_date: raise osv.except_osv(("Alert!"), ("Please enter 'From date'!")) if rec.from_date and rec.to_date: domain.append(('quotation_date', '>=', rec.from_date)) domain.append(('quotation_date', '<=', rec.to_date)) if rec.quotation_value_from and rec.quotation_value_to: if rec.quotation_value_from > rec.quotation_value_to: raise osv.except_osv(("Alert!"), ( "'Quotation value From' cannot be greater than 'Quotation Value To'!" )) domain.append( ('quotation_grand_total', '>=', rec.quotation_value_from)) domain.append( ('quotation_grand_total', '<=', rec.quotation_value_to)) for true_item in true_items: if true_item == 'name': domain.append(('name', 'ilike', rec.name)) if true_item == 'status': domain.append(('state', 'ilike', rec.status)) if true_item == 'quotation_no': domain.append(('quotation_no', 'ilike', rec.quotation_no)) if true_item == 'request_id': domain.append(('request_id', 'ilike', rec.request_id)) if true_item == 'pse': domain.append(('pse_id', '=', rec.pse.id)) if true_item == 'address': search_address = res_partner_add_obj.search( cr, uid, [ '|', ('premise_type', 'ilike', rec.address), '|', ('apartment', 'ilike', rec.address), '|', ('sub_area', 'ilike', rec.address), '|', ('street', 'ilike', rec.address), '|', ('landmark', 'ilike', rec.address), '|', ('apartment', 'ilike', rec.address), '|', ('building', 'ilike', rec.address), '|', ('sub_area', 'ilike', rec.address), ('zip', '=', rec.address) ]) # search_address = res_partner_add_obj.search(cr,uid,[('premise_type','ilike',rec.address)]) domain.append(('delivery_location_id', 'in', search_address)) domain.append(('billing_location_id', 'in', search_address)) if true_item == 'created_by': domain.append(('user_id', '=', rec.created_by.id)) if true_item == 'quotation_value_from': domain.append( ('quotation_grand_total', '>=', rec.quotation_value_from)) if true_item == 'quotation_value_to': domain.append( ('quotation_grand_total', '<=', rec.quotation_value_to)) if true_item == 'contact_number': search_number = res_partner_add_obj.search( cr, uid, [('phone_m2m_xx.name', 'ilike', rec.contact_number)]) partner_list = [] for x in res_partner_add_obj.browse(cr, uid, search_number): partner_list.append(x.partner_id.id) search_quotation = product_quotation_obj.search( cr, uid, [('partner_id.id', 'in', partner_list)]) domain.append(('id', 'in', search_quotation)) if true_item == 'product_id': search_prod = sale_quotation_line_obj.search( cr, uid, [('product_name_id', '=', rec.product_id.id)]) lines_list = [] for x in sale_quotation_line_obj.browse(cr, uid, search_prod): if not x.psd_sales_lines_id.id in lines_list: lines_list.append(x.psd_sales_lines_id.id) search_quotation_prod = product_quotation_obj.search( cr, uid, [('id', 'in', lines_list)]) domain.append(('id', 'in', search_quotation_prod)) if true_item == 'sku_name_id': search_prod = sale_quotation_line_obj.search( cr, uid, [('product_name_id', '=', rec.sku_name_id.id)]) lines_list = [] for x in sale_quotation_line_obj.browse(cr, uid, search_prod): if not x.psd_sales_lines_id.id in lines_list: lines_list.append(x.psd_sales_lines_id.id) search_quotation_sku = product_quotation_obj.search( cr, uid, [('id', 'in', lines_list)]) domain.append(('id', 'in', search_quotation_sku)) product_quotation_ids = product_quotation_obj.search(cr, uid, domain, context=context) if not product_quotation_ids: self.write(cr, uid, ids[0], {'not_found': True}) return res else: res = self.write( cr, uid, ids[0], {'search_product_quot_lines': [(6, 0, product_quotation_ids)]}) return res
class shared_calendar(osv.osv): _name = "shared.calendar" _description = "Shared Calendar" _columns = { 'name': fields.char('Name', size=50, required=True), 'description': fields.text('Description'), 'responsible': fields.many2one('res.users', 'Responsible'), 'startingdate': fields.datetime('Starting Date', required=True), 'endingdate': fields.datetime('Ending Date'), 'duration': fields.float('Duration'), 'type': fields.char('Type', size=50, readonly=True), 'id': fields.integer('ID'), 'object_id': fields.integer('Original id'), 'mod': fields.char('Model', size=50), 'resp_name': fields.char('Name responsible', size=50, readonly=True), 'location': fields.char('Location', size=50, readonly=True), 'attendee': fields.char('Attendee', size=50, readonly=True), 'mail': fields.char('Mail', size=50, readonly=True), } _defaults = { 'startingdate': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), 'type': 'Shared calendar', 'mod': 'shared.calendar', 'responsible': lambda obj, cr, uid, context: uid, } ## Surcharge write method for save data in original object # @param self The object pointer. # @param cr The database connection(cursor) # @param uid The id of user performing the operation # @param ids The list of record ids or single integer when there is only one id # @param vals The dictionary of field values to update # @param context The optional dictionary of contextual parameters such as user language # def write(self, cr, uid, ids, vals, context=None): obj = self.browse(cr, uid, ids[0], context=context) conf_obj = self.pool.get('shared.calendar.conf.information') conf_ids = conf_obj.search(cr, uid, [('object', '=', obj.type)]) conf_rec = conf_obj.browse(cr, uid, conf_ids) o_obj = self.pool.get(obj.type) o_ids = o_obj.search(cr, uid, []) o_rec = o_obj.browse(cr, uid, o_ids) for objor in o_rec: if objor.id == obj.object_id: if objor.state: if objor.state != 'done': if vals.get('name') and conf_rec[0].name.name: self.pool.get(obj.type).write( cr, uid, objor.id, {conf_rec[0].name.name: vals.get('name')}, context=None) if vals.get('description' ) and conf_rec[0].description.name: self.pool.get(obj.type).write( cr, uid, objor.id, { conf_rec[0].description.name: vals.get('description') }, context=None) if vals.get('responsible' ) and conf_rec[0].responsible.name: self.pool.get(obj.type).write( cr, uid, objor.id, { conf_rec[0].responsible.name: vals.get('responsible') }, context=None) if vals.get('startingdate' ) and conf_rec[0].startingdate.name: self.pool.get(obj.type).write( cr, uid, objor.id, { conf_rec[0].startingdate.name: vals.get('startingdate') }, context=None) if vals.get( 'endingdate') and conf_rec[0].endingdate.name: self.pool.get(obj.type).write( cr, uid, objor.id, { conf_rec[0].endingdate.name: vals.get('endingdate') }, context=None) if vals.get('duration') and conf_rec[0].duration.name: self.pool.get( obj.type).write(cr, uid, objor.id, { conf_rec[0].duration.name: vals.get('duration') }, context=None) if vals.get('location') and conf_rec[0].location.name: self.pool.get( obj.type).write(cr, uid, objor.id, { conf_rec[0].location.name: vals.get('location') }, context=None) if vals.get('attendee') and conf_rec[0].attendee.name: self.pool.get( obj.type).write(cr, uid, objor.id, { conf_rec[0].attendee.name: vals.get('attendee') }, context=None) if vals.get('mail') and conf_rec[0].mail.name: self.pool.get(obj.type).write( cr, uid, objor.id, {conf_rec[0].mail.name: vals.get('mail')}, context=None) return super(shared_calendar, self).write(cr, uid, ids, vals, context=context) ## Method to check the original object # @param self The object pointer. # @param cr The database connection(cursor) # @param uid The id of user performing the operation # @param ids The list of record ids or single integer when there is only one id # @param context The optional dictionary of contextual parameters such as user language # method to check the original object def check_original_object(self, cr, uid, ids, context=None): if context is None: context = {} obj = self.browse(cr, uid, ids[0], context=context) idobj = obj.object_id return { 'name': 'Edit original object', 'view_type': 'form', 'view_mode': 'form', 'view_id': None, 'res_model': obj.type, 'res_id': idobj, 'target': 'current', 'type': 'ir.actions.act_window', 'nodestroy': True, 'context': context, }
class account_analytic_account(osv.osv): _name = "account.analytic.account" _inherit = "account.analytic.account" def _analysis_all(self, cr, uid, ids, fields, arg, context=None): dp = 2 res = dict([(i, {}) for i in ids]) parent_ids = tuple( ids ) #We don't want consolidation for each of these fields because those complex computation is resource-greedy. accounts = self.browse(cr, uid, ids, context=context) for f in fields: if f == 'user_ids': cr.execute('SELECT MAX(id) FROM res_users') max_user = cr.fetchone()[0] if parent_ids: cr.execute('SELECT DISTINCT("user") FROM account_analytic_analysis_summary_user ' \ 'WHERE account_id IN %s AND unit_amount <> 0.0', (parent_ids,)) result = cr.fetchall() else: result = [] for id in ids: res[id][f] = [int((id * max_user) + x[0]) for x in result] elif f == 'month_ids': if parent_ids: cr.execute('SELECT DISTINCT(month_id) FROM account_analytic_analysis_summary_month ' \ 'WHERE account_id IN %s AND unit_amount <> 0.0', (parent_ids,)) result = cr.fetchall() else: result = [] for id in ids: res[id][f] = [ int(id * 1000000 + int(x[0])) for x in result ] elif f == 'last_worked_invoiced_date': for id in ids: res[id][f] = False if parent_ids: cr.execute( "SELECT account_analytic_line.account_id, MAX(date) \ FROM account_analytic_line \ WHERE account_id IN %s \ AND invoice_id IS NOT NULL \ GROUP BY account_analytic_line.account_id;", (parent_ids, )) for account_id, sum in cr.fetchall(): if account_id not in res: res[account_id] = {} res[account_id][f] = sum elif f == 'ca_to_invoice': for id in ids: res[id][f] = 0.0 res2 = {} if parent_ids: # Amount uninvoiced hours to invoice at sale price # Warning # This computation doesn't take care of pricelist ! # Just consider list_price cr.execute( """SELECT account_analytic_account.id, \ COALESCE(SUM (product_template.list_price * \ account_analytic_line.unit_amount * \ ((100-hr_timesheet_invoice_factor.factor)/100)), 0.0) \ AS ca_to_invoice \ FROM product_template \ JOIN product_product \ ON product_template.id = product_product.product_tmpl_id \ JOIN account_analytic_line \ ON account_analytic_line.product_id = product_product.id \ JOIN account_analytic_journal \ ON account_analytic_line.journal_id = account_analytic_journal.id \ JOIN account_analytic_account \ ON account_analytic_account.id = account_analytic_line.account_id \ JOIN hr_timesheet_invoice_factor \ ON hr_timesheet_invoice_factor.id = account_analytic_account.to_invoice \ WHERE account_analytic_account.id IN %s \ AND account_analytic_line.invoice_id IS NULL \ AND account_analytic_line.to_invoice IS NOT NULL \ AND account_analytic_journal.type = 'general' \ GROUP BY account_analytic_account.id;""", (parent_ids, )) for account_id, sum in cr.fetchall(): if account_id not in res: res[account_id] = {} res[account_id][f] = round(sum, dp) # sum both result on account_id for id in ids: res[id][f] = round(res.get(id, {}).get(f, 0.0), dp) + round(res2.get(id, 0.0), 2) elif f == 'last_invoice_date': for id in ids: res[id][f] = False if parent_ids: cr.execute( "SELECT account_analytic_line.account_id, \ DATE(MAX(account_invoice.date_invoice)) \ FROM account_analytic_line \ JOIN account_invoice \ ON account_analytic_line.invoice_id = account_invoice.id \ WHERE account_analytic_line.account_id IN %s \ AND account_analytic_line.invoice_id IS NOT NULL \ GROUP BY account_analytic_line.account_id", (parent_ids, )) for account_id, lid in cr.fetchall(): res[account_id][f] = lid elif f == 'last_worked_date': for id in ids: res[id][f] = False if parent_ids: cr.execute( "SELECT account_analytic_line.account_id, MAX(date) \ FROM account_analytic_line \ WHERE account_id IN %s \ AND invoice_id IS NULL \ GROUP BY account_analytic_line.account_id", (parent_ids, )) for account_id, lwd in cr.fetchall(): if account_id not in res: res[account_id] = {} res[account_id][f] = lwd elif f == 'hours_qtt_non_invoiced': for id in ids: res[id][f] = 0.0 if parent_ids: cr.execute( "SELECT account_analytic_line.account_id, COALESCE(SUM(unit_amount), 0.0) \ FROM account_analytic_line \ JOIN account_analytic_journal \ ON account_analytic_line.journal_id = account_analytic_journal.id \ WHERE account_analytic_line.account_id IN %s \ AND account_analytic_journal.type='general' \ AND invoice_id IS NULL \ AND to_invoice IS NOT NULL \ GROUP BY account_analytic_line.account_id;", (parent_ids, )) for account_id, sua in cr.fetchall(): if account_id not in res: res[account_id] = {} res[account_id][f] = round(sua, dp) for id in ids: res[id][f] = round(res[id][f], dp) elif f == 'hours_quantity': for id in ids: res[id][f] = 0.0 if parent_ids: cr.execute( "SELECT account_analytic_line.account_id, COALESCE(SUM(unit_amount), 0.0) \ FROM account_analytic_line \ JOIN account_analytic_journal \ ON account_analytic_line.journal_id = account_analytic_journal.id \ WHERE account_analytic_line.account_id IN %s \ AND account_analytic_journal.type='general' \ GROUP BY account_analytic_line.account_id", (parent_ids, )) ff = cr.fetchall() for account_id, hq in ff: if account_id not in res: res[account_id] = {} res[account_id][f] = round(hq, dp) for id in ids: res[id][f] = round(res[id][f], dp) elif f == 'ca_theorical': # TODO Take care of pricelist and purchase ! for id in ids: res[id][f] = 0.0 # Warning # This computation doesn't take care of pricelist ! # Just consider list_price if parent_ids: cr.execute( """SELECT account_analytic_line.account_id AS account_id, \ COALESCE(SUM((account_analytic_line.unit_amount * pt.list_price) \ - (account_analytic_line.unit_amount * pt.list_price \ * hr.factor)), 0.0) AS somme FROM account_analytic_line \ LEFT JOIN account_analytic_journal \ ON (account_analytic_line.journal_id = account_analytic_journal.id) \ JOIN product_product pp \ ON (account_analytic_line.product_id = pp.id) \ JOIN product_template pt \ ON (pp.product_tmpl_id = pt.id) \ JOIN account_analytic_account a \ ON (a.id=account_analytic_line.account_id) \ JOIN hr_timesheet_invoice_factor hr \ ON (hr.id=a.to_invoice) \ WHERE account_analytic_line.account_id IN %s \ AND a.to_invoice IS NOT NULL \ AND account_analytic_journal.type IN ('purchase', 'general') GROUP BY account_analytic_line.account_id""", (parent_ids, )) for account_id, sum in cr.fetchall(): res[account_id][f] = round(sum, dp) return res def _ca_invoiced_calc(self, cr, uid, ids, name, arg, context=None): res = {} res_final = {} child_ids = tuple( ids ) #We don't want consolidation for each of these fields because those complex computation is resource-greedy. for i in child_ids: res[i] = 0.0 if not child_ids: return res if child_ids: cr.execute( "SELECT account_analytic_line.account_id, COALESCE(SUM(amount), 0.0) \ FROM account_analytic_line \ JOIN account_analytic_journal \ ON account_analytic_line.journal_id = account_analytic_journal.id \ WHERE account_analytic_line.account_id IN %s \ AND account_analytic_journal.type = 'sale' \ GROUP BY account_analytic_line.account_id", (child_ids, )) for account_id, sum in cr.fetchall(): res[account_id] = round(sum, 2) res_final = res return res_final def _total_cost_calc(self, cr, uid, ids, name, arg, context=None): res = {} res_final = {} child_ids = tuple( ids ) #We don't want consolidation for each of these fields because those complex computation is resource-greedy. for i in child_ids: res[i] = 0.0 if not child_ids: return res if child_ids: cr.execute( """SELECT account_analytic_line.account_id, COALESCE(SUM(amount), 0.0) \ FROM account_analytic_line \ JOIN account_analytic_journal \ ON account_analytic_line.journal_id = account_analytic_journal.id \ WHERE account_analytic_line.account_id IN %s \ AND amount<0 \ GROUP BY account_analytic_line.account_id""", (child_ids, )) for account_id, sum in cr.fetchall(): res[account_id] = round(sum, 2) res_final = res return res_final def _remaining_hours_calc(self, cr, uid, ids, name, arg, context=None): res = {} for account in self.browse(cr, uid, ids, context=context): if account.quantity_max != 0: res[account.id] = account.quantity_max - account.hours_quantity else: res[account.id] = 0.0 for id in ids: res[id] = round(res.get(id, 0.0), 2) return res def _remaining_hours_to_invoice_calc(self, cr, uid, ids, name, arg, context=None): res = {} for account in self.browse(cr, uid, ids, context=context): res[account.id] = max( account.hours_qtt_est - account.timesheet_ca_invoiced, account.ca_to_invoice) return res def _hours_qtt_invoiced_calc(self, cr, uid, ids, name, arg, context=None): res = {} for account in self.browse(cr, uid, ids, context=context): res[account. id] = account.hours_quantity - account.hours_qtt_non_invoiced if res[account.id] < 0: res[account.id] = 0.0 for id in ids: res[id] = round(res.get(id, 0.0), 2) return res def _revenue_per_hour_calc(self, cr, uid, ids, name, arg, context=None): res = {} for account in self.browse(cr, uid, ids, context=context): if account.hours_qtt_invoiced == 0: res[account.id] = 0.0 else: res[account. id] = account.ca_invoiced / account.hours_qtt_invoiced for id in ids: res[id] = round(res.get(id, 0.0), 2) return res def _real_margin_rate_calc(self, cr, uid, ids, name, arg, context=None): res = {} for account in self.browse(cr, uid, ids, context=context): if account.ca_invoiced == 0: res[account.id] = 0.0 elif account.total_cost != 0.0: res[account. id] = -(account.real_margin / account.total_cost) * 100 else: res[account.id] = 0.0 for id in ids: res[id] = round(res.get(id, 0.0), 2) return res def _fix_price_to_invoice_calc(self, cr, uid, ids, name, arg, context=None): sale_obj = self.pool.get('sale.order') res = {} for account in self.browse(cr, uid, ids, context=context): res[account.id] = 0.0 sale_ids = sale_obj.search( cr, uid, [('project_id', '=', account.id), ('partner_id', '=', account.partner_id.id)], context=context) for sale in sale_obj.browse(cr, uid, sale_ids, context=context): if not sale.invoiced: res[account.id] += sale.amount_untaxed for invoice in sale.invoice_ids: if invoice.state not in ('draft', 'cancel'): res[account.id] -= invoice.amount_untaxed return res def _timesheet_ca_invoiced_calc(self, cr, uid, ids, name, arg, context=None): lines_obj = self.pool.get('account.analytic.line') res = {} for account in self.browse(cr, uid, ids, context=context): res[account.id] = 0.0 line_ids = lines_obj.search(cr, uid, [('account_id', '=', account.id), ('invoice_id', '!=', False), ('to_invoice', '!=', False), ('journal_id.type', '=', 'general')], context=context) for line in lines_obj.browse(cr, uid, line_ids, context=context): res[account.id] += line.invoice_id.amount_untaxed return res def _remaining_ca_calc(self, cr, uid, ids, name, arg, context=None): res = {} for account in self.browse(cr, uid, ids, context=context): res[account.id] = max(account.amount_max - account.ca_invoiced, account.fix_price_to_invoice) return res def _real_margin_calc(self, cr, uid, ids, name, arg, context=None): res = {} for account in self.browse(cr, uid, ids, context=context): res[account.id] = account.ca_invoiced + account.total_cost for id in ids: res[id] = round(res.get(id, 0.0), 2) return res def _theorical_margin_calc(self, cr, uid, ids, name, arg, context=None): res = {} for account in self.browse(cr, uid, ids, context=context): res[account.id] = account.ca_theorical + account.total_cost for id in ids: res[id] = round(res.get(id, 0.0), 2) return res def _is_overdue_quantity(self, cr, uid, ids, fieldnames, args, context=None): result = dict.fromkeys(ids, 0) for record in self.browse(cr, uid, ids, context=context): if record.quantity_max > 0.0: result[record.id] = int( record.hours_quantity >= record.quantity_max) else: result[record.id] = 0 return result def _get_analytic_account(self, cr, uid, ids, context=None): result = set() for line in self.pool.get('account.analytic.line').browse( cr, uid, ids, context=context): result.add(line.account_id.id) return list(result) def _get_total_estimation(self, account): tot_est = 0.0 if account.fix_price_invoices: tot_est += account.amount_max if account.invoice_on_timesheets: tot_est += account.hours_qtt_est return tot_est def _get_total_invoiced(self, account): total_invoiced = 0.0 if account.fix_price_invoices: total_invoiced += account.ca_invoiced if account.invoice_on_timesheets: total_invoiced += account.timesheet_ca_invoiced return total_invoiced def _get_total_remaining(self, account): total_remaining = 0.0 if account.fix_price_invoices: total_remaining += account.remaining_ca if account.invoice_on_timesheets: total_remaining += account.remaining_hours_to_invoice return total_remaining def _get_total_toinvoice(self, account): total_toinvoice = 0.0 if account.fix_price_invoices: total_toinvoice += account.fix_price_to_invoice if account.invoice_on_timesheets: total_toinvoice += account.ca_to_invoice return total_toinvoice def _sum_of_fields(self, cr, uid, ids, name, arg, context=None): res = dict([(i, {}) for i in ids]) for account in self.browse(cr, uid, ids, context=context): res[account.id]['est_total'] = self._get_total_estimation(account) res[account.id]['invoiced_total'] = self._get_total_invoiced( account) res[account.id]['remaining_total'] = self._get_total_remaining( account) res[account.id]['toinvoice_total'] = self._get_total_toinvoice( account) return res _columns = { 'is_overdue_quantity': fields.function(_is_overdue_quantity, method=True, type='boolean', string='Overdue Quantity', store={ 'account.analytic.line': (_get_analytic_account, None, 20), }), 'ca_invoiced': fields.function( _ca_invoiced_calc, type='float', string='Invoiced Amount', help="Total customer invoiced amount for this account.", digits_compute=dp.get_precision('Account')), 'total_cost': fields.function( _total_cost_calc, type='float', string='Total Costs', help= "Total of costs for this account. It includes real costs (from invoices) and indirect costs, like time spent on timesheets.", digits_compute=dp.get_precision('Account')), 'ca_to_invoice': fields.function( _analysis_all, multi='analytic_analysis', type='float', string='Uninvoiced Amount', help= "If invoice from analytic account, the remaining amount you can invoice to the customer based on the total costs.", digits_compute=dp.get_precision('Account')), 'ca_theorical': fields.function( _analysis_all, multi='analytic_analysis', type='float', string='Theoretical Revenue', help= "Based on the costs you had on the project, what would have been the revenue if all these costs have been invoiced at the normal sale price provided by the pricelist.", digits_compute=dp.get_precision('Account')), 'hours_quantity': fields.function( _analysis_all, multi='analytic_analysis', type='float', string='Total Worked Time', help= "Number of time you spent on the analytic account (from timesheet). It computes quantities on all journal of type 'general'." ), 'last_invoice_date': fields.function( _analysis_all, multi='analytic_analysis', type='date', string='Last Invoice Date', help= "If invoice from the costs, this is the date of the latest invoiced." ), 'last_worked_invoiced_date': fields.function( _analysis_all, multi='analytic_analysis', type='date', string='Date of Last Invoiced Cost', help= "If invoice from the costs, this is the date of the latest work or cost that have been invoiced." ), 'last_worked_date': fields.function(_analysis_all, multi='analytic_analysis', type='date', string='Date of Last Cost/Work', help="Date of the latest work done on this account."), 'hours_qtt_non_invoiced': fields.function( _analysis_all, multi='analytic_analysis', type='float', string='Uninvoiced Time', help= "Number of time (hours/days) (from journal of type 'general') that can be invoiced if you invoice based on analytic account." ), 'hours_qtt_invoiced': fields.function( _hours_qtt_invoiced_calc, type='float', string='Invoiced Time', help= "Number of time (hours/days) that can be invoiced plus those that already have been invoiced." ), 'remaining_hours': fields.function( _remaining_hours_calc, type='float', string='Remaining Time', help="Computed using the formula: Maximum Time - Total Worked Time" ), 'remaining_hours_to_invoice': fields.function( _remaining_hours_to_invoice_calc, type='float', string='Remaining Time', help= "Computed using the formula: Maximum Time - Total Invoiced Time"), 'fix_price_to_invoice': fields.function(_fix_price_to_invoice_calc, type='float', string='Remaining Time', help="Sum of quotations for this contract."), 'timesheet_ca_invoiced': fields.function( _timesheet_ca_invoiced_calc, type='float', string='Remaining Time', help="Sum of timesheet lines invoiced for this contract."), 'remaining_ca': fields.function( _remaining_ca_calc, type='float', string='Remaining Revenue', help= "Computed using the formula: Max Invoice Price - Invoiced Amount.", digits_compute=dp.get_precision('Account')), 'revenue_per_hour': fields.function( _revenue_per_hour_calc, type='float', string='Revenue per Time (real)', help="Computed using the formula: Invoiced Amount / Total Time", digits_compute=dp.get_precision('Account')), 'real_margin': fields.function( _real_margin_calc, type='float', string='Real Margin', help="Computed using the formula: Invoiced Amount - Total Costs.", digits_compute=dp.get_precision('Account')), 'theorical_margin': fields.function( _theorical_margin_calc, type='float', string='Theoretical Margin', help= "Computed using the formula: Theoretical Revenue - Total Costs", digits_compute=dp.get_precision('Account')), 'real_margin_rate': fields.function( _real_margin_rate_calc, type='float', string='Real Margin Rate (%)', help= "Computes using the formula: (Real Margin / Total Costs) * 100.", digits_compute=dp.get_precision('Account')), 'fix_price_invoices': fields.boolean('Fix Price Invoices'), 'invoice_on_timesheets': fields.boolean("Invoice On Timesheets"), 'month_ids': fields.function(_analysis_all, multi='analytic_analysis', type='many2many', relation='account_analytic_analysis.summary.month', string='Month'), 'user_ids': fields.function(_analysis_all, multi='analytic_analysis', type="many2many", relation='account_analytic_analysis.summary.user', string='User'), 'hours_qtt_est': fields.float('Estimation of Hours to Invoice'), 'est_total': fields.function(_sum_of_fields, type="float", multi="sum_of_all", string="Total Estimation"), 'invoiced_total': fields.function(_sum_of_fields, type="float", multi="sum_of_all", string="Total Invoiced"), 'remaining_total': fields.function( _sum_of_fields, type="float", multi="sum_of_all", string="Total Remaining", help= "Expectation of remaining income for this contract. Computed as the sum of remaining subtotals which, in turn, are computed as the maximum between '(Estimation - Invoiced)' and 'To Invoice' amounts" ), 'toinvoice_total': fields.function( _sum_of_fields, type="float", multi="sum_of_all", string="Total to Invoice", help=" Sum of everything that could be invoiced for this contract." ), } def open_sale_order_lines(self, cr, uid, ids, context=None): if context is None: context = {} sale_ids = self.pool.get('sale.order').search( cr, uid, [('project_id', '=', context.get('search_default_project_id', False)), ('partner_id', '=', context.get('search_default_partner_id', False))]) names = [ record.name for record in self.browse(cr, uid, ids, context=context) ] name = _('Sale Order Lines of %s') % ','.join(names) return { 'type': 'ir.actions.act_window', 'name': name, 'view_type': 'form', 'view_mode': 'tree,form', 'context': context, 'domain': [('order_id', 'in', sale_ids)], 'res_model': 'sale.order.line', 'nodestroy': True, } def on_change_template(self, cr, uid, ids, template_id, context=None): if not template_id: return {} res = super(account_analytic_account, self).on_change_template(cr, uid, ids, template_id, context=context) if template_id and 'value' in res: template = self.browse(cr, uid, template_id, context=context) res['value']['fix_price_invoices'] = template.fix_price_invoices res['value'][ 'invoice_on_timesheets'] = template.invoice_on_timesheets res['value']['hours_qtt_est'] = template.hours_qtt_est res['value']['amount_max'] = template.amount_max res['value']['to_invoice'] = template.to_invoice.id res['value']['pricelist_id'] = template.pricelist_id.id return res
class jmdconcliacion(osv.Model): _name = "ea.conciliacion" _inherit = "mail.thread" def actualiza(self, cr, uid, ids, context=None): facturas_obj = self.pool.get("ea.conciliacion.facturas") inv_obj = self.pool.get("account.invoice") acuerdo_obj = self.pool.get("ea.acuerdo") solicitadas_obj = self.pool.get("ea.conciliacion.solicitadas") avance_obj = self.pool.get("ea.avance") realizadas_obj = self.pool.get("ea.conciliacion.realizadas") for i in self.browse(cr, uid, ids, context): #Borrando for k in i.factura_ids: facturas_obj.unlink(cr, uid, [k.id]) for k in i.realizadas_ids: realizadas_obj.unlink(cr, uid, [k.id]) for k in i.solicitadas_ids: solicitadas_obj.unlink(cr, uid, [k.id]) facturado = 0.0 solicitadas = 0 canceladas = 0 realizadas = 0 #Buscamos las facturas de provedor for j in inv_obj.browse( cr, uid, inv_obj.search(cr, uid, [('partner_id', '=', i.name.id), ('proyecto_id', '=', i.proyecto_id.id)])): facturado += j.amount_total facturas_obj.create( cr, uid, { 'name': j.name, 'fecha': j.date_invoice, 'monto': j.amount_total, 'conciliacion_id': i.id }) #Entrevistas solicitadas for j in acuerdo_obj.browse( cr, uid, acuerdo_obj.search( cr, uid, [('partner_id', '=', i.name.id), ('proyecto_id', '=', i.proyecto_id.id)])): solicitadas += j.cantidad solicitadas_obj.create( cr, uid, { 'name': j.name, 'cantidad': j.cantidad, 'conciliacion_id': i.id }) #Entrevistas realizadas for j in avance_obj.browse( cr, uid, avance_obj.search(cr, uid, [('codigo_sea', '=', i.name.id), ('proyecto', '=', i.proyecto_id.id)])): conteo = 0 for k in j.cuota: if j.rechazada: canceladas += 1 continue conteo += 1 realizadas += 1 realizadas_obj.create( cr, uid, { 'name': j.folio, 'cantidad': conteo, 'fecha': j.fecha, 'conciliacion_id': i.id }) self.write( cr, uid, [i.id], { 'facturado': facturado, 'solicitadas': solicitadas, 'canceladas': canceladas, 'realizadas': realizadas }) _columns = { 'name': fields.many2one("res.partner", string="Nombre del SEA"), 'proyecto_id': fields.many2one("project.project", string="Proyecto"), 'nombre_corto': fields.related('proyecto_id', 'nombre_corto', string="Nombre Corto", type="char"), 'cantidad_solicitada': fields.integer("Cantidad Solicitada"), 'precio_entrevista': fields.float("Precio por Entrevista"), 'monto_planeado': fields.float("Monto Planeado"), 'cantidad_realizada': fields.float("Cantidad Realizada"), 'monto_facturado': fields.float("Monto Facturado"), 'diferencia': fields.integer("Diferencia"), 'solicitadas': fields.integer("Entrevistas Solicitadas"), 'realizadas': fields.integer("Entrevistas Realizadas"), 'canceladas': fields.integer("Entrevistas Canceladas"), 'facturado': fields.float("Total Facturado"), 'factura_ids': fields.one2many("ea.conciliacion.facturas", "conciliacion_id", string="Facturas"), 'realizadas_ids': fields.one2many("ea.conciliacion.realizadas", "conciliacion_id", string="Realizadas"), 'solicitadas_ids': fields.one2many("ea.conciliacion.solicitadas", "conciliacion_id", string="Solicitadas"), }
""" unity = self.get(category_id__name='Duration', _object='product.uom') if not unity: _logger.warning("It seems that there isn't a reference unity in the 'Duration' UoM category. " "Please check that the category exists, and there's a refernce unity.") return unity.id if unity else False _name = 'product.product' _inherit = 'product.product' _columns = { 'can_be_rent' : fields.boolean('Can be rented', help='Enable this if you want to rent this product.'), 'rent_price' : fields.float('Rent price', help= 'The price is expressed for the duration unity defined in the company configuration.'), 'rent_price_unity' : fields.many2one('product.uom', 'Rent Price Unity', domain=[('category_id.name', '=', 'Duration')], help='Rent duration unity in which the price is defined.'), } _defaults = { 'can_be_rent' : True, 'rent_price' : 0, 'rent_price_unity' : default_price_unity, } _constraints = [(check_rent_price, _('The Rent price must be a positive value or 0 for free service or product.'), ['rent_price']),] Product()
class tcv_municipal_tax_wh(osv.osv): _name = 'tcv.municipal.tax.wh' _description = '' _order = 'name desc' ##------------------------------------------------------------------------- ##------------------------------------------------------- _internal methods def _get_type(self, cr, uid, context=None): context = context or {} return context.get('wh_muni_type', 'in_invoice') def _get_journal(self, cr, uid, context): context = context or {} type_inv = context.get('type', 'in_invoice') type2journal = { 'out_invoice': 'mun_sale', 'in_invoice': 'mun_purchase' } journal_obj = self.pool.get('account.journal') res = journal_obj.search( cr, uid, [('type', '=', type2journal.get(type_inv, 'mun_purchase'))], limit=1) if res: return res[0] else: return False def _validate_date_ret(self, cr, uid, ids, context=None): ids = isinstance(ids, (int, long)) and [ids] or ids whm = self.browse(cr, uid, ids[0], context=context) data = { 'date': whm.date if whm and whm.date else time.strftime('%Y-%m-%d'), 'date_ret': whm.date_ret if whm and whm.date_ret else time.strftime('%Y-%m-%d'), } if not whm.name: last_id = self.search(cr, uid, [('state', '=', 'done'), ('date', '>', '2016-01-01'), ('type', 'in', ('in_invoice', 'in_refund'))], order="number desc", limit=1) last = self.browse(cr, uid, last_id, context=context)[0] if last_id else {} if last and (last.date_ret > data['date_ret'] or last.date > data['date']): raise osv.except_osv( _('Error!'), _('The accounting date must be >= %s and ' + 'whithholding date must be >= %s') % (last.date_ret, last.date)) if not whm.period_id: obj_per = self.pool.get('account.period') data.update({'period_id': obj_per.find(cr, uid, data['date'])[0]}) self.write(cr, uid, ids, data, context=context) return False def _clear_wh_lines(self, cr, uid, ids, context=None): """ Clear lines of current withholding document and delete wh document information from the invoice. """ return True ##--------------------------------------------------------- function fields _columns = { 'name': fields.char('Number', size=32, readonly=True, help="Withholding number"), 'type': fields.selection([ ('out_invoice', 'Customer Invoice'), ('in_invoice', 'Supplier Invoice'), ], 'Type', readonly=True, help="Withholding type"), 'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Estado', readonly=True, help="Estado del Comprobante"), 'date_ret': fields.date('Withholding date', readonly=True, states={'draft': [('readonly', False)]}, help="Keep empty to use the current date"), 'date': fields.date('Acc date', readonly=True, states={'draft': [('readonly', False)]}, help="Accounting date"), 'period_id': fields.many2one( 'account.period', 'Force Period', readonly=True, states={'draft': [('readonly', False)]}, help="Keep empty to use the period of the validation " + "(Withholding date) date."), 'partner_id': fields.many2one('res.partner', 'Partner', readonly=True, required=True, states={'draft': [('readonly', False)]}, help="Withholding customer/supplier"), 'account_id': fields.many2one('account.account', 'Account', required=True, ondelete='restrict', readonly=True, states={'draft': [('readonly', False)]}), 'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Currency"), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Journal entry"), 'company_id': fields.many2one('res.company', 'Company', required=True, readonly=True, ondelete='restrict'), 'munici_line_ids': fields.one2many('tcv.municipal.tax.wh.lines', 'line_id', 'Local withholding lines', readonly=True, states={'draft': [('readonly', False)]}, help="Invoices to will be made local withholdings"), 'amount_base': fields.float('Amount base', required=False, readonly=True, digits_compute=dp.get_precision('Withhold'), help="Amount base withheld"), 'amount_tax': fields.float('Amount tax', required=False, readonly=True, digits_compute=dp.get_precision('Withhold'), help="Amount tax withheld"), } _defaults = { 'company_id': lambda self, cr, uid, c: self.pool.get('res.company'). _company_default_get(cr, uid, self._name, context=c), 'currency_id': lambda self, cr, uid, c: self.pool.get('res.users').browse( cr, uid, uid, c).company_id.currency_id.id, 'type': _get_type, 'state': lambda *a: 'draft', 'journal_id': _get_journal, } _sql_constraints = [ ('name_uniq', 'UNIQUE(name)', 'The Number must be unique!'), ] ##------------------------------------------------------------------------- ##---------------------------------------------------------- public methods def _gen_account_move(self, cr, uid, ids, context=None): obj_move = self.pool.get('account.move') obj_per = self.pool.get('account.period') obj_mtl = self.pool.get('tcv.municipal.tax.wh.lines') move_id = None types = { 'out_invoice': -1, 'in_invoice': 1, 'out_refund': 1, 'in_refund': -1 } for item in self.browse(cr, uid, ids, context={}): lines = [] for line in item.munici_line_ids: # move line for deposit lines move = { 'ref': item.name, 'journal_id': item.journal_id.id, 'date': item.date, 'period_id': obj_per.find(cr, uid, item.date)[0], 'company_id': item.company_id.id, 'state': 'draft', 'to_check': False, 'narration': _('Municipal tax withholding: %s') % item.name, } direction = types[line.invoice_id.type] invoice = line.invoice_id journal = item.journal_id if invoice.type in ['in_invoice', 'in_refund']: name = 'COMP. RET. MUNI. %s FCT. %s' % ( item.name, invoice.supplier_invoice_number or '') else: name = 'COMP. RET. MUNI. %s FCT. %s' % ( item.name, invoice.number or '') # Get move account from journal acc2 = journal.default_credit_account_id and \ journal.default_credit_account_id.id \ if direction == 1 else \ journal.default_debit_account_id and \ journal.default_debit_account_id.id if not acc2: raise osv.except_osv( _('Error!'), _('No account selected, please check journal\'s ' + 'accounts (%s)') % journal.name) lines.append({ 'name': name, 'account_id': acc2, 'partner_id': item.partner_id.id, 'ref': item.name, 'date': item.date, 'currency_id': False, 'debit': line.amount_ret if direction == -1 else 0, 'credit': line.amount_ret if direction != -1 else 0, }) lines.append({ 'name': name, 'account_id': invoice.account_id.id, 'partner_id': item.partner_id.id, 'ref': item.name, 'date': item.date, 'currency_id': False, 'debit': line.amount_ret if direction == 1 else 0, 'credit': line.amount_ret if direction != 1 else 0, }) move.update({'line_id': [(0, 0, l) for l in lines]}) move_id = obj_move.create(cr, uid, move, context) if move_id: obj_move.post(cr, uid, [move_id], context=context) obj_mtl.write(cr, uid, [line.id], {'move_id': move_id}, context=context) self.do_reconcile(cr, uid, line, move_id, context) return move_id def do_reconcile(self, cr, uid, mwl, move_id, context): obj_move = self.pool.get('account.move') obj_aml = self.pool.get('account.move.line') move = obj_move.browse(cr, uid, move_id, context) rec_ids = [] # Get "payable" move line from invoice account_id = mwl.invoice_id.account_id.id # Add invoice's move payable line rec_amount = 0 for line in mwl.invoice_id.move_id.line_id: if line.account_id.id == account_id: rec_ids.append(line.id) if line.reconcile_partial_id: for m in line.reconcile_partial_id.line_partial_ids: rec_amount += m.debit or 0.0 - m.credit or 0.0 rp_id = line.reconcile_partial_id.id rec_ids.extend( obj_aml.search(cr, uid, [('reconcile_partial_id', '=', rp_id), ('id', '!=', line.id)])) # Add new move pay line for line in move.line_id: if line.account_id.id == account_id: rec_ids.append(line.id) if rec_ids: # reconcile if wh muni = balance else reconcile_partial if abs(mwl.amount_ret + rec_amount) < 0.001: obj_aml.reconcile(cr, uid, rec_ids, context=context) else: obj_aml.reconcile_partial(cr, uid, rec_ids, context=context) return True ##-------------------------------------------------------- buttons (object) def compute_amount_wh(self, cr, uid, ids, context=None): """ Calculate withholding amount each line """ if context is None: context = {} mtwl_obj = self.pool.get('tcv.municipal.tax.wh.lines') for retention in self.browse(cr, uid, ids, context): data = {'amount_base': 0, 'amount_tax': 0} for line in retention.munici_line_ids: value = mtwl_obj.on_change_invoice_id( cr, uid, [line.id], line.invoice_id and line.invoice_id.id or 0, line.muni_tax_id and line.muni_tax_id.id or 0, line.amount_untaxed).get('value', {}) if value: mtwl_obj.write(cr, uid, line.id, value, context=context) data['amount_base'] += value.get('amount_untaxed', 0) data['amount_tax'] += value.get('amount_ret', 0) self.write(cr, uid, [retention.id], data, context=context) return True ##------------------------------------------------------------ on_change... def onchange_partner_id(self, cr, uid, ids, type, partner_id): res = {} if not partner_id: return res obj_pnr = self.pool.get('res.partner') partner = obj_pnr.browse(cr, uid, partner_id, context=None) account_id = partner.property_account_payable and \ partner.property_account_payable.id if type == 'in_invoice' \ else partner.property_account_receivable and \ partner.property_account_receivable.id res.update({'account_id': account_id or 0}) return {'value': res} def on_change_date(self, cr, uid, ids, date, date_ret): res = {} if date and not date_ret: res.update({'date_ret': date}) return {'value': res} ##----------------------------------------------------- create write unlink def unlink(self, cr, uid, ids, context=None): unlink_ids = [] for wh_doc in self.browse(cr, uid, ids, context=context): if wh_doc.state != 'cancel': raise osv.except_osv( _("Invalid Procedure!!"), _("The withholding document needs to be in cancel " + "state to be deleted.")) else: unlink_ids.append(wh_doc.id) if unlink_ids: self._clear_wh_lines(cr, uid, unlink_ids, context) return super(tcv_municipal_tax_wh, self).unlink(cr, uid, unlink_ids, context) ##---------------------------------------------------------------- Workflow def button_draft(self, cr, uid, ids, context=None): vals = {'state': 'draft'} return self.write(cr, uid, ids, vals, context) def button_confirmed(self, cr, uid, ids, context=None): self.compute_amount_wh(cr, uid, ids, context=None) vals = {'state': 'confirmed'} return self.write(cr, uid, ids, vals, context) def button_done(self, cr, uid, ids, context=None): for item in self.browse(cr, uid, ids, context={}): if not item.name: number = self.pool.get('ir.sequence').get( cr, uid, 'tcv.municipal.tax.wh.%s' % item.type) if item.date_ret: date = time.strptime(item.date_ret, '%Y-%m-%d') name = 'DHMAP-%04d%02d%s' % (date.tm_year, date.tm_mon, number) cr.execute( 'UPDATE tcv_municipal_tax_wh SET ' + 'name=%(name)s ' + 'WHERE id=%(id)s', { 'name': name, 'id': item.id }) self._gen_account_move(cr, uid, [item.id], context=context) vals = {'state': 'done'} return self.write(cr, uid, ids, vals, context) def button_cancel(self, cr, uid, ids, context=None): unlink_move_ids = [] obj_move = self.pool.get('account.move') obj_mwl = self.pool.get('tcv.municipal.tax.wh.lines') for item in self.browse(cr, uid, ids, context={}): for line in item.munici_line_ids: if line.move_id and line.move_id.state != 'posted': unlink_move_ids.append(line.move_id.id) obj_mwl.write(cr, uid, [line.id], {'move_id': 0}, context=context) obj_move.unlink(cr, uid, unlink_move_ids, context=context) vals = {'state': 'cancel'} return self.write(cr, uid, ids, vals, context) def test_draft(self, cr, uid, ids, *args): return True def test_confirmed(self, cr, uid, ids, *args): return True def test_done(self, cr, uid, ids, *args): self._validate_date_ret(cr, uid, ids, context=None) return True def test_cancel(self, cr, uid, ids, *args): for item in self.browse(cr, uid, ids, context={}): for line in item.munici_line_ids: if line.move_id and line.move_id.state == 'posted': raise osv.except_osv( _('Error!'), _('You can not cancel a deposit while the account ' + 'move is posted.')) return True
class purchase_order(osv.osv): _inherit = 'purchase.order' def get_shop(self, cr, uid, ids): user = self.pool.get('res.users').browse(cr, uid, uid) if user.shop.name == 'Importation': return user.shop.name else: return 'Locaux' _columns = { 'order_line': fields.one2many('purchase.order.line', 'order_id', 'Order Lines', readonly=True, states={ 'draft': [('readonly', False)], 'start': [('readonly', False)] }), 'create': fields.many2one('res.users', 'Demandeur'), 'daf': fields.many2one('res.users', 'Direction Financiere'), 'dg': fields.many2one('res.users', 'Direction Generale'), 'sb': fields.many2one('res.users', 'Service Budget'), 'date_daf': fields.date('Date Appr. DAF'), 'date_dg': fields.date('Date Appr. DG'), 'date_sb': fields.date('Date Appr. SB'), 'ref': fields.char('Reference Commande', size=64), 'cur_rate': fields.float('Cours Devise'), 'containers': fields.float('Conteneurs'), 'estimated_freight': fields.float('Meilleur taux de fret Estimatif'), 'incoterm': fields.many2one('stock.incoterms', 'Incoterm'), 'product_origin': fields.many2one('res.country', 'Origine'), 'shop_id': fields.many2one('sale.shop', 'Souche', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'payment_term': fields.many2one('account.payment.term', 'Condition de Reglement'), } def onchange_partner_id(self, cr, uid, ids, part): if not part: return { 'value': { 'partner_address_id': False, 'fiscal_position': False } } addr = self.pool.get('res.partner').address_get( cr, uid, [part], ['default']) part = self.pool.get('res.partner').browse(cr, uid, part) pricelist = part.property_product_pricelist_purchase.id fiscal_position = part.property_account_position and part.property_account_position.id or False payment_term = part.property_payment_term and part.property_payment_term.id or False return { 'value': { 'partner_address_id': addr['default'], 'pricelist_id': pricelist, 'fiscal_position': fiscal_position, 'payment_term': payment_term } } _defaults = { 'create': lambda obj, cr, uid, context: uid, 'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get( cr, uid, obj.get_shop(cr, uid, obj)), }
class project_scrum_product_backlog(osv.osv): _name = 'project.scrum.product.backlog' _description = 'Product Backlog' def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name: match = re.match('^S\(([0-9]+)\)$', name) if match: ids = self.search(cr, uid, [('sprint_id', '=', int(match.group(1)))], limit=limit, context=context) return self.name_get(cr, uid, ids, context=context) return super(project_scrum_product_backlog, self).name_search(cr, uid, name, args, operator, context, limit=limit) def _compute(self, cr, uid, ids, fields, arg, context=None): res = {}.fromkeys(ids, 0.0) progress = {} if not ids: return res for backlog in self.browse(cr, uid, ids, context=context): tot = 0.0 prog = 0.0 effective = 0.0 task_hours = 0.0 progress = 0.0 for task in backlog.tasks_id: task_hours += task.total_hours effective += task.effective_hours tot += task.planned_hours prog += task.planned_hours * task.progress / 100.0 if tot > 0: progress = round(prog / tot * 100) res[backlog.id] = { 'progress': progress, 'effective_hours': effective, 'task_hours': task_hours } return res def button_cancel(self, cr, uid, ids, context=None): obj_project_task = self.pool.get('project.task') self.write(cr, uid, ids, {'state': 'cancel'}, context=context) for backlog in self.browse(cr, uid, ids, context=context): obj_project_task.write(cr, uid, [i.id for i in backlog.tasks_id], {'state': 'cancelled'}) return True def button_draft(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'draft'}, context=context) return True def button_open(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'open'}, context=context) return True def button_close(self, cr, uid, ids, context=None): obj_project_task = self.pool.get('project.task') self.write(cr, uid, ids, {'state': 'done'}, context=context) for backlog in self.browse(cr, uid, ids, context=context): obj_project_task.write(cr, uid, [i.id for i in backlog.tasks_id], {'state': 'done'}) return True def button_pending(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'pending'}, context=context) return True def button_postpone(self, cr, uid, ids, context=None): for product in self.browse(cr, uid, ids, context=context): tasks_id = [] for task in product.tasks_id: if task.state != 'done': tasks_id.append(task.id) self.copy( cr, uid, product.id, { 'name': 'PARTIAL:' + product.name, 'sprint_id': False, 'tasks_id': [(6, 0, tasks_id)], }) self.write(cr, uid, ids, {'state': 'cancel'}, context=context) return True _columns = { 'name': fields.char('Feature', size=64, required=True), 'note': fields.text('Note'), 'active': fields.boolean( 'Active', help= "If Active field is set to true, it will allow you to hide the product backlog without removing it." ), 'project_id': fields.many2one('project.project', 'Project', required=True, domain=[('scrum', '=', 1)]), 'user_id': fields.many2one('res.users', 'Author'), 'sprint_id': fields.many2one('project.scrum.sprint', 'Sprint'), 'sequence': fields.integer( 'Sequence', help= "Gives the sequence order when displaying a list of product backlog." ), 'tasks_id': fields.one2many('project.task', 'product_backlog_id', 'Tasks Details'), 'state': fields.selection([('draft', 'Draft'), ('open', 'Open'), ('pending', 'Pending'), ('done', 'Done'), ('cancel', 'Cancelled')], 'State', required=True), 'progress': fields.function(_compute, multi="progress", group_operator="avg", type='float', method=True, string='Progress', help="Computed as: Time Spent / Total Time."), 'effective_hours': fields.function( _compute, multi="effective_hours", method=True, string='Spent Hours', help= "Computed using the sum of the time spent on every related tasks", store=True), 'expected_hours': fields.float('Planned Hours', help='Estimated total time to do the Backlog'), 'create_date': fields.datetime("Creation Date", readonly=True), 'task_hours': fields.function(_compute, multi="task_hours", method=True, string='Task Hours', help='Estimated time of the total hours of the tasks') } _defaults = { 'state': 'draft', 'active': 1, 'user_id': lambda self, cr, uid, context: uid, } _order = "sequence"
'active':fields.function(_get_active, method=True,type='boolean', store=False), 'ask_id': fields.many2one('openstc.ask', 'Demande', ondelete='set null', select="1"), 'project_id': fields.many2one('project.project', 'Intervention', ondelete='set null'), 'equipment_ids':fields.many2many('openstc.equipment', 'openstc_equipment_task_rel', 'task_id', 'equipment_id', 'Equipments'), 'consumable_ids':fields.many2many('openbase.consumable', 'openbase_consumable_task_rel', 'task_id', 'consumable_id', 'Fournitures'), 'parent_id': fields.many2one('project.task', 'Parent Task'), 'intervention_assignement_id':fields.many2one('openstc.intervention.assignement', 'Assignement'), 'absent_type_id':fields.many2one('openstc.absent.type', 'Type d''abscence'), 'category_id':fields.many2one('openstc.task.category', 'Category'), 'state': fields.selection([('absent', 'Absent'),('draft', 'New'),('open', 'In Progress'),('pending', 'Pending'), ('done', 'Done'), ('cancelled', 'Cancelled')], 'State', readonly=True, required=True, help='If the task is created the state is \'Draft\'.\n If the task is started, the state becomes \'In Progress\'.\n If review is needed the task is in \'Pending\' state.\ \n If the task is over, the states is set to \'Done\'.'), 'team_id': fields.many2one('openstc.team', 'Team'), 'km': fields.integer('Km', select=1), 'oil_qtity': fields.float('oil quantity', select=1), 'oil_price': fields.float('oil price', select=1), 'site1':fields.related('project_id','site1',type='many2one',relation='openstc.site', string='Site',store={'project.task':[lambda self,cr,uid,ids,ctx={}:ids, ['project_id'], 10], 'project.project':[_get_task_from_inter, ['site1'],11]}), 'inter_desc': fields.related('project_id', 'description', type='char'), 'inter_equipment': fields.related('project_id', 'equipment_id', type='many2one',relation='openstc.equipment'), 'cancel_reason': fields.text('Cancel reason'), 'agent_or_team_name':fields.function(_get_agent_or_team_name, type='char', method=True, store=False), 'cost':fields.float('Cost', type='float', digits=(5,2)), 'hr_cost':fields.float('Cost', type='float', digits=(5,2)), 'equipment_cost':fields.float('Cost', type='float', digits=(5,2)), 'consumable_cost':fields.float('Cost', type='float', digits=(5,2)), } _defaults = {'active': lambda *a: True, 'user_id':None}
class account_analytic_account_summary_user(osv.osv): _name = "account_analytic_analysis.summary.user" _description = "Hours Summary by User" _order = 'user' _auto = False _rec_name = 'user' def _unit_amount(self, cr, uid, ids, name, arg, context=None): res = {} account_obj = self.pool.get('account.analytic.account') cr.execute('SELECT MAX(id) FROM res_users') max_user = cr.fetchone()[0] account_ids = [ int(str(x / max_user - (x % max_user == 0 and 1 or 0))) for x in ids ] user_ids = [ int( str(x - ((x / max_user - (x % max_user == 0 and 1 or 0)) * max_user))) for x in ids ] parent_ids = tuple( account_ids ) #We don't want consolidation for each of these fields because those complex computation is resource-greedy. if parent_ids: cr.execute('SELECT id, unit_amount ' \ 'FROM account_analytic_analysis_summary_user ' \ 'WHERE account_id IN %s ' \ 'AND "user" IN %s',(parent_ids, tuple(user_ids),)) for sum_id, unit_amount in cr.fetchall(): res[sum_id] = unit_amount for id in ids: res[id] = round(res.get(id, 0.0), 2) return res _columns = { 'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True), 'unit_amount': fields.float('Total Time'), 'user': fields.many2one('res.users', 'User'), } def init(self, cr): tools.sql.drop_view_if_exists( cr, 'account_analytic_analysis_summary_user') cr.execute( '''CREATE OR REPLACE VIEW account_analytic_analysis_summary_user AS ( with mu as (select max(id) as max_user from res_users) , lu AS (SELECT l.account_id AS account_id, coalesce(l.user_id, 0) AS user_id, SUM(l.unit_amount) AS unit_amount FROM account_analytic_line AS l, account_analytic_journal AS j WHERE (j.type = 'general' ) and (j.id=l.journal_id) GROUP BY l.account_id, l.user_id ) select (lu.account_id * mu.max_user) + lu.user_id as id, lu.account_id as account_id, lu.user_id as "user", unit_amount from lu, mu)''')
class product_product(osv.osv): _inherit = 'product.product' _columns = { 'prix1': fields.float('Prix 1'), 'prix2': fields.float('Prix 2'), 'prix3': fields.float('Prix 3'), 'prix4': fields.float('Prix 4'), 'prix5': fields.float('Prix 5'), 'prix6': fields.float('Prix 6'), 'prix7': fields.float('Prix 7'), 'prix8': fields.float('Prix 8'), 'prix9': fields.float('Prix 9'), 'prix10': fields.float('Prix 10'), 'prix11': fields.float('Prix 11'), } _sql_constraints = [('ref', 'unique(ref)', 'Unique!')]
import time from osv import osv, fields import decimal_precision as dp FISCAL_RULE_COLUMNS = { 'partner_fiscal_type_id': fields.many2one('l10n_br_account.partner.fiscal.type', 'Tipo Fiscal do Parceiro'), 'fiscal_operation_category_id': fields.many2one('l10n_br_account.fiscal.operation.category', 'Categoria', requeried=True), 'fiscal_type': fields.selection([('1', 'Simples Nacional'), ('2', 'Simples Nacional – excesso de sublimite de receita bruta'), ('3', 'Regime Normal')], 'Regime Tributário', required=True), 'revenue_start': fields.float('Faturamento Inicial', digits_compute=dp.get_precision('Account'), help="Faixa inicial de faturamento bruto"), 'revenue_end': fields.float('Faturamento Final', digits_compute=dp.get_precision('Account'), help="Faixa inicial de faturamento bruto"),} FISCAL_RULE_DEFAULTS = { 'fiscal_type': '3', 'revenue_start': 0.00, 'revenue_end': 0.00,} class account_fiscal_position_rule_template(osv.osv): _inherit = 'account.fiscal.position.rule.template' _columns = FISCAL_RULE_COLUMNS _defaults = FISCAL_RULE_DEFAULTS
class account_analytic_account_summary_month(osv.osv): _name = "account_analytic_analysis.summary.month" _description = "Hours summary by month" _auto = False _rec_name = 'month' _columns = { 'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True), 'unit_amount': fields.float('Total Time'), 'month': fields.char('Month', size=32, readonly=True), } def init(self, cr): tools.sql.drop_view_if_exists( cr, 'account_analytic_analysis_summary_month') cr.execute('CREATE VIEW account_analytic_analysis_summary_month AS (' \ 'SELECT ' \ '(TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') + (d.account_id * 1000000::bigint))::bigint AS id, ' \ 'd.account_id AS account_id, ' \ 'TO_CHAR(d.month, \'Mon YYYY\') AS month, ' \ 'TO_NUMBER(TO_CHAR(d.month, \'YYYYMM\'), \'999999\') AS month_id, ' \ 'COALESCE(SUM(l.unit_amount), 0.0) AS unit_amount ' \ 'FROM ' \ '(SELECT ' \ 'd2.account_id, ' \ 'd2.month ' \ 'FROM ' \ '(SELECT ' \ 'a.id AS account_id, ' \ 'l.month AS month ' \ 'FROM ' \ '(SELECT ' \ 'DATE_TRUNC(\'month\', l.date) AS month ' \ 'FROM account_analytic_line AS l, ' \ 'account_analytic_journal AS j ' \ 'WHERE j.type = \'general\' ' \ 'GROUP BY DATE_TRUNC(\'month\', l.date) ' \ ') AS l, ' \ 'account_analytic_account AS a ' \ 'GROUP BY l.month, a.id ' \ ') AS d2 ' \ 'GROUP BY d2.account_id, d2.month ' \ ') AS d ' \ 'LEFT JOIN ' \ '(SELECT ' \ 'l.account_id AS account_id, ' \ 'DATE_TRUNC(\'month\', l.date) AS month, ' \ 'SUM(l.unit_amount) AS unit_amount ' \ 'FROM account_analytic_line AS l, ' \ 'account_analytic_journal AS j ' \ 'WHERE (j.type = \'general\') and (j.id=l.journal_id) ' \ 'GROUP BY l.account_id, DATE_TRUNC(\'month\', l.date) ' \ ') AS l ' 'ON (' \ 'd.account_id = l.account_id ' \ 'AND d.month = l.month' \ ') ' \ 'GROUP BY d.month, d.account_id ' \ ')')
'type_id': fields.many2one('bag.type', 'Tipo'), 'format_id': fields.many2one('bag.format', 'Formato'), 'color_id': fields.many2one('bag.color', 'Color'), 'material_id': fields.many2one('bag.material', 'Material'), 'size_id': fields.many2one('bag.size', 'Tamano'), 'description': fields.char('Descripcion', size=64), 'brand': fields.char('Marca', size=64), 'model': fields.char('Modelo', size=64), 'airline_id': fields.many2one('bag.airline', 'Aerolinea', required=True), 'branch': fields.char('Sucursal', size=32), 'scale_id': fields.many2one('bag.scale', 'Escala'), 'incoming_guide': fields.char('Guia Entrante', size=32), 'case_number': fields.char('Numero Caso', size=32), 'outgoing_guide': fields.char('Guia Saliente', size=32), 'internal_notes': fields.text('Nota'), 'estimated_price': fields.float('Costo Estimado', digits=(12, 2)), 'price_buffer': fields.float('Buffer Importe', digits=(12, 2)), 'base_discount': fields.float('Descuento', digits=(4, 2)), #'prepayment': fields.function(_get_total_sena, string='Sena', store=True, readonly=True), 'prepayment': fields.float(digits=(12,2)), 'shipping_cost': fields.float('Costo Envio', digits=(12, 2)), 'action': fields.selection([('reparar', 'Reparar'), ('reemplazar', 'Reemplazar')], 'Action', required=True), 'user_id': fields.many2one('res.users', 'Usuario'), 'state_id': fields.many2one('bag.state', 'Estado', required=True), 'shelving_id': fields.many2one('bag.shelving', 'Estanteria'), 'urgent': fields.boolean('Urgente'), 'papers': fields.boolean('Papeles'), 'attention': fields.boolean('Atencion'), 'monitoring': fields.boolean('Seguimiento'), 'send': fields.boolean('Enviar'), 'send_id': fields.many2one('bag.sending', 'Envio'),
class zoook_sale_shop_payment_type(osv.osv): _name = "zoook.sale.shop.payment.type" _description = "Zoook Sale Shop Payment Type" _rec_name = "payment_type_id" _columns = { 'payment_type_id': fields.many2one('payment.type','Payment Type', required=True), 'shop_id': fields.many2one('sale.shop','Shop', required=True), 'picking_policy': fields.selection([('direct', 'Partial Delivery'), ('one', 'Complete Delivery')], 'Packing Policy', required=True), 'order_policy': fields.selection([ ('prepaid', 'Payment Before Delivery'), ('manual', 'Shipping & Manual Invoice'), ('postpaid', 'Invoice on Order After Delivery'), ('picking', 'Invoice from the Packing'), ], 'Shipping Policy', required=True), 'invoice_quantity': fields.selection([('order', 'Ordered Quantities'), ('procurement', 'Shipped Quantities')], 'Invoice on', required=True), 'app_payment': fields.char('App Payment', size=255, required=True, help='Name App Payment module (example, paypal, servired, cash_on_delivery,...)'), 'confirm': fields.boolean('Confirm', help="Confirm order. Sale Order change state draft to done, and generate picking and/or invoice automatlly"), 'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of payments."), 'virtual': fields.boolean('Virtual', help="Virtual payment. Example: Paypal"), 'commission': fields.boolean('Commission', help="Commission Payment. Add extra price in sale order"), 'commission_product_id': fields.many2one('product.product', 'Product', help='Product commission in sale order line.'), 'commission_type': fields.selection([ ('fix', 'Fix'), ('percentage', 'Percentage'), ], 'Commission Type'), 'commission_operator': fields.selection([ ('add', '(+) Add'), ('subtract', '(-) Substract'), ], 'Commission Operator'), 'commission_price': fields.float('Price', help="Fix price or percentatge. Percentat is over 100. 10% is 0.10"), } _defaults = { 'commission_type': 'fix', 'commission_operator': 'add', } def get_payment_commission(self, cr, uid, order): """ Get payments by sale shop and get payment comission - order: Id Order :return list [{'sequence','app_payment','name'}] """ if not order: return [] payment_esale = [] sale_payment_type = self.pool.get('zoook.sale.shop.payment.type') order = self.pool.get('sale.order').browse(cr, uid, order) sale_shop_payments = sale_payment_type.search(cr, uid, [('shop_id','=',order.shop_id.id)]) if not len(sale_shop_payments)>0: return [] for payment in sale_payment_type.browse(cr, uid, sale_shop_payments): name = '%s' % (payment.payment_type_id.name) if payment.commission: if payment.commission_operator == 'subtract': operator = '-' else: operator = '+' if payment.commission_type == 'percentage': price = order.amount_untaxed*payment.commission_price else: price = payment.commission_price price = round(price,self.pool.get('decimal.precision').precision_get(cr, uid, 'Sale Price')) name = '%(name)s (%(operator)s%(price)s %(currency)s)' % { 'name': payment.payment_type_id.name, 'operator': operator, 'price': price, 'currency': order.shop_id.pricelist_id.currency_id.symbol, } payment_esale.append({'sequence':payment.sequence,'app_payment':payment.app_payment,'name':name}) return payment_esale def set_payment_commission(self, cr, uid, order, payment): """ Set payment commission in sale line - order: Id Order - payment: Str Payment :return True """ if not order and not payment: return False order = self.pool.get('sale.order').browse(cr, uid, order) if order.state != 'draft' and order.payment_state != 'draft': return False payment = self.pool.get('zoook.sale.shop.payment.type').search(cr, uid, [('shop_id','=',order.shop_id.id),('app_payment','=',payment)]) if not len(payment)>0: return False price = False payment = self.pool.get('zoook.sale.shop.payment.type').browse(cr, uid, payment)[0] if payment.commission: if payment.commission_type == 'percentage': price = order.amount_untaxed*payment.commission_price else: price = payment.commission_price if payment.commission_operator == 'subtract': price = -price price = round(price,self.pool.get('decimal.precision').precision_get(cr, uid, 'Sale Price')) if price: values = { 'order_id': order.id, 'name': '%s - %s' % (payment.payment_type_id.name, payment.commission_product_id.name), 'product_id': payment.commission_product_id.id, 'product_uom_qty': 1, 'product_uom': payment.commission_product_id.product_tmpl_id.uom_id.id, 'price_unit': price, 'commission_line': True, } try: self.pool.get('sale.order.line').create(cr, uid, values) comment = "Add commission payment %s - %s: %s" % (order.id, payment.payment_type_id.name, price) LOGGER.notifyChannel('e-Sale', netsvc.LOG_INFO, comment) self.pool.get('esale.log').create_log(cr, uid, order.shop_id.id, 'sale.order', order.id, 'done', comment) except: comment = "Add commission payment %s - %s: %s" % (order.id, payment.payment_type_id.name, price) LOGGER.notifyChannel('e-Sale', netsvc.LOG_ERROR, comment) self.pool.get('esale.log').create_log(cr, uid, order.shop_id.id, 'sale.order', order.id, 'error', comment) return True
class account_wh_munici(osv.osv): def _get_type(self, cr, uid, context=None): if context is None: context = {} type = context.get('type', 'in_invoice') return type def _get_journal(self, cr, uid, context): if context is None: context = {} type_inv = context.get('type', 'in_invoice') type2journal = { 'out_invoice': 'mun_sale', 'in_invoice': 'mun_purchase' } journal_obj = self.pool.get('account.journal') res = journal_obj.search( cr, uid, [('type', '=', type2journal.get(type_inv, 'mun_purchase'))], limit=1) if res: return res[0] else: return False def _get_currency(self, cr, uid, context): user = self.pool.get('res.users').browse(cr, uid, [uid])[0] if user.company_id: return user.company_id.currency_id.id else: return self.pool.get('res.currency').search( cr, uid, [('rate', '=', 1.0)])[0] _name = "account.wh.munici" _description = "Local Withholding" _columns = { 'name': fields.char('Description', size=64, readonly=True, states={'draft': [('readonly', False)]}, required=True, help="Description of withholding"), 'code': fields.char('Code', size=32, readonly=True, states={'draft': [('readonly', False)]}, help="Withholding reference"), 'number': fields.char('Number', size=32, readonly=True, states={'draft': [('readonly', False)]}, help="Withholding number"), 'type': fields.selection([ ('out_invoice', 'Customer Invoice'), ('in_invoice', 'Supplier Invoice'), ], 'Type', readonly=True, help="Withholding type"), 'state': fields.selection([('draft', 'Draft'), ('confirmed', 'Confirmed'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Estado', readonly=True, help="Estado del Comprobante"), 'date_ret': fields.date('Withholding date', readonly=True, states={'draft': [('readonly', False)]}, help="Keep empty to use the current date"), 'date': fields.date('Date', readonly=True, states={'draft': [('readonly', False)]}, help="Date"), 'period_id': fields.many2one( 'account.period', 'Force Period', domain=[('state', '<>', 'done')], readonly=True, states={'draft': [('readonly', False)]}, help= "Keep empty to use the period of the validation(Withholding date) date." ), 'account_id': fields.many2one('account.account', 'Account', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="The pay account used for this withholding."), 'partner_id': fields.many2one('res.partner', 'Partner', readonly=True, required=True, states={'draft': [('readonly', False)]}, help="Withholding customer/supplier"), 'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Currency"), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="Journal entry"), 'company_id': fields.many2one('res.company', 'Company', required=True, help="Company"), 'munici_line_ids': fields.one2many('account.wh.munici.line', 'retention_id', 'Local withholding lines', readonly=True, states={'draft': [('readonly', False)]}, help="Invoices to will be made local withholdings"), 'amount': fields.float('Amount', required=False, digits_compute=dp.get_precision('Withhold'), help="Amount withheld"), 'move_id': fields.many2one('account.move', 'Account Entry'), } _defaults = { 'type': _get_type, 'state': lambda *a: 'draft', 'journal_id': _get_journal, 'currency_id': _get_currency, 'company_id': lambda self, cr, uid, context: \ self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id, } _sql_constraints = [('ret_num_uniq', 'unique (number)', 'number must be unique !')] def action_confirm(self, cr, uid, ids, context={}): obj = self.pool.get('account.wh.munici').browse(cr, uid, ids) total = 0 for i in obj[0].munici_line_ids: if i.amount >= i.invoice_id.check_total * 0.15: raise osv.except_osv( _('Invalid action !'), _("The line containing the document '%s' looks as if the amount withheld was wrong please check.!" ) % (i.invoice_id.reference)) total += i.amount self.write(cr, uid, ids, {'amount': total}) return True def action_number(self, cr, uid, ids, *args): obj_ret = self.browse(cr, uid, ids)[0] if obj_ret.type == 'in_invoice': cr.execute('SELECT id, number ' \ 'FROM account_wh_munici ' \ 'WHERE id IN ('+','.join(map(str,ids))+')') for (id, number) in cr.fetchall(): if not number: number = self.pool.get('ir.sequence').get( cr, uid, 'account.wh.muni.%s' % obj_ret.type) cr.execute('UPDATE account_wh_munici SET number=%s ' \ 'WHERE id=%s', (number, id)) return True def action_done(self, cr, uid, ids, context={}): self.action_number(cr, uid, ids) self.action_move_create(cr, uid, ids) return True def action_move_create(self, cr, uid, ids, context=None): inv_obj = self.pool.get('account.invoice') if context is None: context = {} context.update({'muni_wh': True}) for ret in self.browse(cr, uid, ids): for line in ret.munici_line_ids: if line.move_id or line.invoice_id.wh_local: raise osv.except_osv( _('Invoice already withhold !'), _("You must omit the follow invoice '%s' !") % (line.invoice_id.name, )) return False acc_id = ret.partner_id.property_wh_munici_payable.id if not ret.date_ret: self.write(cr, uid, [ret.id], {'date_ret': time.strftime('%Y-%m-%d')}) period_id = ret.period_id and ret.period_id.id or False journal_id = ret.journal_id.id if not period_id: period_ids = self.pool.get('account.period').search( cr, uid, [('date_start', '<=', ret.date_ret or time.strftime('%Y-%m-%d')), ('date_stop', '>=', ret.date_ret or time.strftime('%Y-%m-%d'))]) if len(period_ids): period_id = period_ids[0] else: raise osv.except_osv( _('Warning !'), _("No se encontro un periodo fiscal para esta fecha: '%s' por favor verificar.!" ) % (ret.date_ret or time.strftime('%Y-%m-%d'))) if ret.munici_line_ids: for line in ret.munici_line_ids: writeoff_account_id = False writeoff_journal_id = False amount = line.amount name = 'COMP. RET. MUN ' + ret.number ret_move = inv_obj.ret_and_reconcile( cr, uid, [line.invoice_id.id], amount, acc_id, period_id, journal_id, writeoff_account_id, period_id, writeoff_journal_id, ret.date_ret, name, line, context) # make the retencion line point to that move rl = { 'move_id': ret_move['move_id'], } lines = [(1, line.id, rl)] self.write(cr, uid, [ret.id], { 'munici_line_ids': lines, 'period_id': period_id }) inv_obj.write(cr, uid, [line.invoice_id.id], {'wh_muni_id': ret.id}) return True def onchange_partner_id(self, cr, uid, ids, type, partner_id): acc_id = False if partner_id: p = self.pool.get('res.partner').browse(cr, uid, partner_id) if type in ('out_invoice', 'out_refund'): acc_id = p.property_wh_munici_receivable.id else: acc_id = p.property_wh_munici_payable.id self._update_check(cr, uid, ids, partner_id) result = {'value': {'account_id': acc_id}} return result def _update_check(self, cr, uid, ids, partner_id, context={}): if ids: ret = self.browse(cr, uid, ids[0]) inv_str = '' for line in ret.munici_line_ids: if line.invoice_id.partner_id.id != partner_id: inv_str += '%s' % '\n' + line.invoice_id.name if inv_str: raise osv.except_osv( 'Incorrect Invoices !', "The following invoices are not the selected partner: %s " % (inv_str, )) return True def _new_check(self, cr, uid, values, context={}): lst_inv = [] if 'munici_line_ids' in values and values['munici_line_ids']: if 'partner_id' in values and values['partner_id']: for l in values['munici_line_ids']: if 'invoice_id' in l[2] and l[2]['invoice_id']: lst_inv.append(l[2]['invoice_id']) if lst_inv: invoices = self.pool.get('account.invoice').browse( cr, uid, lst_inv) inv_str = '' for inv in invoices: if inv.partner_id.id != values['partner_id']: inv_str += '%s' % '\n' + inv.name if inv_str: raise osv.except_osv( 'Incorrect Invoices !', "The following invoices are not the selected partner: %s " % (inv_str, )) return True def write(self, cr, uid, ids, vals, context=None, check=True, update_check=True): if not context: context = {} ret = self.browse(cr, uid, ids[0]) if update_check: if 'partner_id' in vals and vals['partner_id']: self._update_check(cr, uid, ids, vals['partner_id'], context) else: self._update_check(cr, uid, ids, ret.partner_id.id, context) return super(account_wh_munici, self).write(cr, uid, ids, vals, context=context) def create(self, cr, uid, vals, context=None, check=True): if not context: context = {} if check: self._new_check(cr, uid, vals, context) return super(account_wh_munici, self).create(cr, uid, vals, context)
class account_wh_munici_line(osv.osv): def default_get(self, cr, uid, fields, context={}): data = super(account_wh_munici_line, self).default_get(cr, uid, fields, context) self.munici_context = context return data #TODO #necesito crear el campo y tener la forma de calcular el monto del impuesto #munici retenido en la factura _name = "account.wh.munici.line" _description = "Local Withholding Line" _columns = { 'name': fields.char('Description', size=64, required=True, help="Local Withholding line Description"), 'retention_id': fields.many2one('account.wh.munici', 'Local withholding', ondelete='cascade', help="Local withholding"), 'invoice_id': fields.many2one('account.invoice', 'Invoice', required=True, ondelete='set null', help="Withholding invoice"), 'amount': fields.float('Amount', digits_compute=dp.get_precision('Withhold')), 'move_id': fields.many2one('account.move', 'Account Entry', readonly=True, help="Account Entry"), 'wh_loc_rate': fields.float('Rate', help="Local withholding rate"), 'concepto_id': fields.integer('Concept', size=3, help="Local withholding concept"), } _defaults = { 'concepto_id': lambda *a: 1, } _sql_constraints = [( 'munici_fact_uniq', 'unique (invoice_id)', 'The invoice has already assigned in local withholding, you cannot assigned it twice!' )] def onchange_invoice_id(self, cr, uid, ids, invoice_id, context={}): lines = [] if hasattr(self, 'munici_context') and ('lines' in self.munici_context): lines = [x[2] for x in self.munici_context['lines']] if not invoice_id: return {'value': {'amount': 0.0}} else: ok = True res = self.pool.get('account.invoice').browse( cr, uid, invoice_id, context) cr.execute( 'select retention_id from account_wh_munici_line where invoice_id=%s', (invoice_id, )) ret_ids = cr.fetchone() ok = ok and bool(ret_ids) if ok: ret = self.pool.get('account.wh.munici').browse( cr, uid, ret_ids[0], context) raise osv.except_osv( 'Assigned Invoice !', "The invoice has already assigned in local withholding code: '%s' !" % (ret.code, )) total = res.amount_total return {'value': {'amount': total}}
'amount_untaxed': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Untaxed Amount', store={ 'purchase.order.line': (_get_order, None, 10), 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['discount_total'], 20), }, multi="sums", help="The amount without tax"), 'amount_tax': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Taxes', store={ 'purchase.order.line': (_get_order, None, 10), 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['discount_total'], 20), }, multi="sums", help="The tax amount"), 'amount_total': fields.function(_amount_all, method=True, digits_compute= dp.get_precision('Purchase Price'), string='Total', store={ 'purchase.order.line': (_get_order, None, 10), 'purchase.order': (lambda self, cr, uid, ids, c={}: ids, ['discount_total'], 20), }, multi="sums",help="The total amount"), 'discount_total': fields.float('Discount Total(%)', digits=(16,2)), ################################### 'approve_status': fields.function(_get_approve_status, method=True, string='To be Approve By',type= 'char', size=64), } ################################################# def create_date_manager_proc(self, cr, uid, ids): self.write(cr, uid, ids, {'manager_proc_app_date':time.strftime('%Y-%m-%d')}) return True def create_date_div_proc(self, cr, uid, ids): self.write(cr, uid, ids, {'head_of_div_proc_app_date':time.strftime('%Y-%m-%d')}) return True def create_date_div_req(self, cr, uid, ids):
_columns = _columns account_tax_code() def change_digit_tax(cr): res = pooler.get_pool(cr.dbname).get('decimal.precision').precision_get(cr, 1, 'Account') return (16, res + 2) _columns_tax = { 'tax_discount': fields.boolean('Tax Discounted in Price', help="Mark it for Brazilian legal Taxes(ICMS, PIS e etc.)."), 'tax_add': fields.boolean('Add the Tax Amount in Price', help="Mark it to add the Tax Amount in Price."), 'tax_include': fields.boolean('Include the Tax Amount in Price', help="Mark it to include the Tax Amount in Price."), 'tax_retain': fields.boolean('Discount the Tax Amount in Price', help="Mark it to for clients who retain the Taxes."), 'base_reduction': fields.float('Redution', required=True, digits_compute=change_digit_tax, help="Um percentual decimal em % entre 0-1."), 'amount_mva': fields.float('MVA Percent', required=True, digits_compute=change_digit_tax, help="Um percentual decimal em % entre 0-1."), 'type': fields.selection([('percent', 'Percentage'), ('fixed', 'Fixed Amount'), ('none', 'None'), ('code', 'Python Code'), ('balance', 'Balance'), ('quantity', 'Quantity')], 'Tax Type', required=True, help="The computation method for the tax amount."), } _defaults_tax = { 'base_reduction': 0, 'amount_mva': 0, } class account_tax_common(object): tax_code_name = 'account.tax.code.template'