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 __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') field_name = PARAM_XXX_2M_VALUE % counter self._columns[field_name] = fields.function(self._multi_select_values.im_func, arg={"entry_num": counter}, fnct_inv=self._multi_select_values_store.im_func, fnct_inv_arg={"entry_num": counter}, method=False, type='many2many', relation='ir.actions.report.multivalues.promptwizard', string='Multi-Select')
('04', 'UNKNOWN'), (' ', ' ') ], 'Option'), 'prod_company': fields.char('CompanyName', size=256, help='Only applicable when producer option is empty or not present.'), 'prod_tax_id_no': fields.char('TaxIdentificationNumber', size=256, help='Only applicable when producer option is empty or not present.'), 'prod_address_id': fields.many2one('res.partner', 'Producer Address', help='Only applicable when producer option is empty or not present.'), 'inv_option': fields.selection([ ('01', 'Unknown'), ('02', 'Various'), (' ', ' ') ], 'Sold to Option'), 'inv_company': fields.char('CompanyName', size=256, help='Only applicable when Sold to option is empty or not present.'), 'inv_tax_id_no': fields.char('TaxIdentificationNumber', size=256, help='Only applicable when Sold to option is empty or not present.'), 'inv_att_name': fields.char('AttentionName', size=256, help='Only applicable when Sold to option is empty or not present.'), 'inv_address_id': fields.many2one('res.partner', 'Sold To Address', help='Only applicable when Sold to option is empty or not present.'), 'blanket_begin_date': fields.date('Blanket Begin Date'), 'blanket_end_date': fields.date('Blanket End Date'), <<<<<<< HEAD 'comm_code': fields.char('Commodity Code', size=256,), ======= # 'comm_code': fields.char('Commodity Code', size=256,), 'comm_code':fields.many2one('ups.commodity.code','Commodity Code'), >>>>>>> c1979f64b3360c86d60e00c92be0271d89f97f2d 'exp_carrier': fields.char('ExportingCarrier', size=256), 'ship_company_code': fields.selection(_get_company_code, 'Ship Company', method=True, size=64), 'ship_charge': fields.float('Value', digits_compute=dp.get_precision('Account')) } _defaults = { 'address_validate': 'nonvalidate',
class hr_timesheet_sheet_sheet_day(osv.osv): _name = "hr_timesheet_sheet.sheet.day" _description = "Timesheets by Period" _auto = False _order='name' _columns = { 'name': fields.date('Date', readonly=True), 'sheet_id': fields.many2one('hr_timesheet_sheet.sheet', 'Sheet', readonly=True, select="1"), 'total_timesheet': fields.float('Total Timesheet', readonly=True), 'total_attendance': fields.float('Attendance', readonly=True), 'total_difference': fields.float('Difference', readonly=True), } def init(self, cr): cr.execute("""create or replace view hr_timesheet_sheet_sheet_day as SELECT id, name, sheet_id, total_timesheet, total_attendance, cast(round(cast(total_attendance - total_timesheet as Numeric),2) as Double Precision) AS total_difference FROM (( SELECT MAX(id) as id, name, sheet_id, SUM(total_timesheet) as total_timesheet, CASE WHEN SUM(total_attendance) < 0 THEN (SUM(total_attendance) + CASE WHEN current_date <> name THEN 1440 ELSE (EXTRACT(hour FROM current_time AT TIME ZONE 'UTC') * 60) + EXTRACT(minute FROM current_time AT TIME ZONE 'UTC') END ) ELSE SUM(total_attendance) END /60 as total_attendance FROM (( select min(hrt.id) as id, l.date::date as name, s.id as sheet_id, sum(l.unit_amount) as total_timesheet, 0.0 as total_attendance from hr_analytic_timesheet hrt JOIN account_analytic_line l ON l.id = hrt.line_id LEFT JOIN hr_timesheet_sheet_sheet s ON s.id = hrt.sheet_id group by l.date::date, s.id ) union ( select -min(a.id) as id, a.name::date as name, s.id as sheet_id, 0.0 as total_timesheet, SUM(((EXTRACT(hour FROM a.name) * 60) + EXTRACT(minute FROM a.name)) * (CASE WHEN a.action = 'sign_in' THEN -1 ELSE 1 END)) as total_attendance from hr_attendance a LEFT JOIN hr_timesheet_sheet_sheet s ON s.id = a.sheet_id WHERE action in ('sign_in', 'sign_out') group by a.name::date, s.id )) AS foo GROUP BY name, sheet_id )) AS bar""")
class bank_statement_imported_lines(osv.Model): """ OpenERP Model : ClassName """ _name = 'bank.statement.imported.lines' _description = 'Imported lines for banks files' # def _balance(self, cr, uid,ids,field_name,args,context=None): # res = {} # # for i in ids: # debit = 0.0 # amt_unt = 0.0 # bsil_brw = self.browse(cr,uid,i,context=context) # counterpart_id = bsil_brw.counterpart_id # for aml in bsil_brw.aml_ids: # if aml.account_id == counterpart_id: # debit += aml.debit or aml.credit # for inv in bsil_brw.invoice_ids: # if inv.account_id == counterpart_id: # amt_unt += inv.amount_total # for amls in bsil_brw.acc_move_line_ids: # if amls.account_id == counterpart_id: # amt_unt+=amls[aml.debit and 'credit' or 'debit'] # # res[i]=debit-amt_unt # return res _columns = { 'name': fields.char('Description', size=255, required=True, readonly=False), 'date': fields.date('Date', required=True), 'numdocument': fields.char('Num Document', size=64, required=True, readonly=False), 'debit': fields.float('Debit', digits_compute=dp.get_precision('Account'), required=True), 'invo_move_line': fields.boolean('Chek', help='Chek if invoice and account move line exist'), 'move_id': fields.many2one('account.move', 'Account Move'), 'credit': fields.float('Credit', digits_compute=dp.get_precision('Account'), required=True), 'office': fields.char('Office', size=16, required=False, readonly=False), 'bank_statement_id': fields.many2one('account.bank.statement', 'Bank Statement', required=True), 'acc_move_line_ids': fields.many2many('account.move.line', 'account_move_line_rel', 'aml_ids', 'aml_id'), 'company_id': fields.many2one('res.company', 'Company', required=False), 'aml_ids': fields.one2many('account.move.line', 'stff_id', 'Account Move Lines'), 'counterpart_id': fields.many2one( 'account.account', 'Account Counterpart', required=False, help="This will be the account to make the account move line as\ counterpart."), 'partnercounterpart_id': fields.many2one('res.partner', 'Partner Counterpart', required=False, help="This will be the partner to make written on the\ account move line as counterpart., if you change this value,\ the account payable or receivable will be automatic selected on\ Account Move Lines related, specially usefull when you pay\ several things in the same invoice, Petty cash for example, just\ select your partner petty cash"), 'state': fields.selection( [('draft', 'Draft'), ('done', 'Done')], 'State', help='If this bank statement line is confirmed or not, to help\ useability issues', readonly=True, select=True), 'invoice_ids': fields.many2many( 'account.invoice', 'bs_invoice_rel', 'st_id_id', 'invoice_id', 'Invoices', help="Invoices to be reconciled with this line", ), # TODO: Resolve: We should use date as filter, is a question of POV #'balance':fields.function(_balance,method=True,digits_compute=dp.get_precision('Account'),type='float',string='Balance',store=False), } _defaults = { 'name': lambda *a: None, 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get( cr, uid, 'account.account', context=c), 'state': 'draft', } # def explode_aml(self,cr,uid,ids,,context=None): # if context is None: # context={} def change_account(self, cr, uid, ids, context=None): if context is None: context = {} acc_journal = [] bank_line_brw = self.browse(cr, uid, ids, context=context) account_move_line_obj = self.pool.get('account.move.line') for line in bank_line_brw: if line.invoice_ids or line.acc_move_line_ids: raise osv.except_osv( _("Warning"), _("You can not change account because this bank statement\ have documents")) if line.state != 'done': for aml in line.aml_ids: acc_journal.append(line.bank_statement_id.journal_id and line.bank_statement_id.journal_id. default_debit_account_id and line.bank_statement_id.journal_id. default_debit_account_id.id) acc_journal.append(line.bank_statement_id.journal_id and line.bank_statement_id.journal_id. default_credit_account_id and line.bank_statement_id.journal_id. default_credit_account_id.id) if aml.account_id and aml.account_id.id not in acc_journal: account_move_line_obj.copy( cr, uid, aml.id, { 'account_id': line.counterpart_id and line.counterpart_id.id }) account_move_line_obj.unlink(cr, uid, [aml.id], context=context) def prepare(self, cr, uid, ids, context=None): if context is None: context = {} res = [] aml = False total = 0 invoice_obj = self.pool.get('account.invoice') account_move_line_obj = self.pool.get('account.move.line') for abs_brw in self.browse(cr, uid, ids, context=context): for line in abs_brw.aml_ids: if context.get('button_confirm'): if line.account_id == abs_brw.counterpart_id and not\ line.reconcile_partial_id and not\ line.reconcile_id: aml = line else: if line.account_id == abs_brw.counterpart_id: aml = line if aml: aml_ids = [ line.id for i in abs_brw.invoice_ids if i.state == 'open' for line in i.move_id.line_id if i.account_id.id == line.account_id.id and not line.reconcile_id ] aml_ids += [i.id for i in abs_brw.acc_move_line_ids] aml_ids = aml_ids and account_move_line_obj.search( cr, uid, [('id', 'in', aml_ids)], order='date asc', context=context) if aml.debit and not context.get('cancel', False) or\ aml.credit and not context.get('cancel', False): total = aml.debit or aml.credit for aml_id in account_move_line_obj.browse( cr, uid, aml_ids, context=context): if aml_id.date_maturity and\ aml_id.date_maturity < abs_brw.date or True: partner_id = aml_id.partner_id and\ aml_id.partner_id.id if total > (aml_id.reconcile_partial_id and aml_id.invoice and aml_id.invoice.residual or aml_id[aml.debit and 'credit' or 'debit']): total = total - (aml_id.reconcile_partial_id and aml_id.invoice and aml_id.invoice.residual or aml_id[aml.debit and 'credit' or 'debit']) res.append((account_move_line_obj.copy( cr, uid, aml.id, { 'partner_id': aml_id.partner_id and aml_id.partner_id.id, '%s' % (aml.debit > 0 and 'debit' or aml.credit > 0 and 'credit'): (aml_id.reconcile_partial_id and aml_id.invoice and aml_id.invoice.residual or aml_id[aml.debit and 'credit' or 'debit']) }), aml_id.id)) elif total > 0 and (aml_id.reconcile_partial_id and aml_id.invoice and aml_id.invoice.residual or aml_id[aml.debit and 'credit' or 'debit']) >= total: res.append((account_move_line_obj.copy( cr, uid, aml.id, { 'partner_id': aml_id.partner_id and aml_id.partner_id.id, '%s' % (aml.debit > 0 and 'debit' or aml.credit > 0 and 'credit'): total }), aml_id.id)) total = 0 elif total <= 0: break if total > 0 and res: account_move_line_obj.copy( cr, uid, aml.id, { 'partner_id': partner_id, '%s' % (aml.debit > 0 and 'debit' or aml.credit > 0 and 'credit'): total }) res and account_move_line_obj.unlink( cr, uid, [aml.id], context=context) if context.get('cancel', False) and aml: invoice_ids = [i.id for i in abs_brw.invoice_ids] move_ids = [d.id for d in abs_brw.acc_move_line_ids] for invoice in invoice_obj.browse(cr, uid, invoice_ids, context=context): if abs_brw.move_id: res.append( account_move_line_obj.search( cr, uid, [('move_id', '=', abs_brw.move_id.id), ('account_id', '=', invoice.account_id.id)])) else: res.append( account_move_line_obj.search( cr, uid, [ ('invoice', 'in', invoice_ids), ('account_id', '=', invoice.account_id.id), ])) res.append('%s' % (aml.debit > 0 and 'debit' or aml.credit > 0 and 'credit')) break for move in account_move_line_obj.browse(cr, uid, move_ids, context=context): res.append( account_move_line_obj.search( cr, uid, [('move_id', '=', abs_brw.move_id.id), ('account_id', '=', move.account_id.id)])) res.append('%s' % (aml.debit > 0 and 'debit' or aml.credit > 0 and 'credit')) break res and [ res[0].append(i.id) for i in abs_brw.acc_move_line_ids ] # res.append(aml.id) return res def begin_move(self, cr, uid, ids, type, context=None): if context is None: context = {} total = 0 aml_id = [] account_move_line_obj = self.pool.get('account.move.line') for abs_brw in self.browse(cr, uid, ids, context=context): for line in abs_brw.aml_ids: total = total + line[type] # total = total + eval('line.%s'%type) line[type] and aml_id.append(line.id) # eval('line.%s'%type) and aml_id.append(line.id) account_move_line_obj.copy(cr, uid, aml_id[0], { type: total, 'partner_id': [] }) account_move_line_obj.unlink(cr, uid, aml_id, context=context) return True def invoice_or_move_line(self, cr, uid, ids, invoice_ids, acc_move_line_ids, context=None): if context is None: context = {} res = {'value': {}} if invoice_ids and\ invoice_ids[0][2] or acc_move_line_ids and acc_move_line_ids[0][2]: res['value'].update({'invo_move_line': True}) else: res['value'].update({'invo_move_line': False}) return res def button_validate(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'done'}, context=context) def button_cancel(self, cr, uid, ids, context=None): if context is None: context = {} account_move_line_obj = self.pool.get('account.move.line') account_move_obj = self.pool.get('account.move') context.update({'cancel': True}) for abs_brw in self.browse(cr, uid, ids, context=context): account_move_obj.button_cancel( cr, uid, [abs_brw.move_id and abs_brw.move_id.id], context=context) res = self.prepare(cr, uid, ids, context=context) if res and res[0]: account_move_line_obj._remove_move_reconcile(cr, uid, res[0], context=context) self.begin_move(cr, uid, ids, res[1], context=context) return self.write(cr, uid, ids, {'state': 'draft'}, context=context) return True def button_setinvoice(self, cr, uid, ids, context=None): if context is None: context = {} res = [] recon = [] account_move_line_obj = self.pool.get('account.move.line') account_move = self.pool.get('account.move') for abs_brw in self.browse(cr, uid, ids, context=context): res = self.prepare(cr, uid, ids, context=context) if res: for reconcile in res: recon = [] recon.append(reconcile[0]) recon.append(reconcile[1]) account_move_line_obj.reconcile_partial(cr, uid, recon, 'manual', context=context) self.button_validate(cr, uid, ids, context=context) account_move.button_validate( cr, uid, [abs_brw.move_id and abs_brw.move_id.id], context=context) return {}
class purchase_order_line_master(orm.Model): def onchange_product_id(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, context=None): return self.pool.get('purchase.order.line').onchange_product_id( cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=date_order, fiscal_position_id=fiscal_position_id, date_planned=date_planned, name=name, price_unit=price_unit, context=context) def onchange_product_uom(self, cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=False, fiscal_position_id=False, date_planned=False, name=False, price_unit=False, context=None): return self.pool.get('purchase.order.line').onchange_product_uom( cr, uid, ids, pricelist_id, product_id, qty, uom_id, partner_id, date_order=date_order, fiscal_position_id=fiscal_position_id, date_planned=date_planned, name=name, price_unit=price_unit, context=context) def _amount_line(self, cr, uid, ids, prop, arg, context=None): res = {} cur_obj = self.pool.get('res.currency') tax_obj = self.pool.get('account.tax') for line in self.browse(cr, uid, ids, context=context): taxes = tax_obj.compute_all( cr, uid, line.taxes_id, line.price_unit, line.product_qty) cur = line.order_id.pricelist_id.currency_id res[line.id] = cur_obj.round(cr, uid, cur, taxes['total']) return res _name = 'purchase.order.line.master' _columns = { 'order_id': fields.many2one( 'purchase.order', 'Order Reference', select=True, required=True, ondelete='cascade'), 'delivery_term_id': fields.many2one( 'purchase.delivery.term', 'Delivery term', required=True, ondelete='restrict'), 'name': fields.char( 'Description', size=256, required=True), 'product_id': fields.many2one( 'product.product', 'Product', domain=[('purchase_ok', '=', True)], change_default=True), 'price_unit': fields.float( 'Unit Price', required=True, digits_compute=dp.get_precision('Product Price')), 'price_subtotal': fields.function( _amount_line, string='Subtotal', digits_compute=dp.get_precision('Product Price')), 'product_qty': fields.float( 'Quantity', digits_compute=dp.get_precision('Product Unit of Measure'), required=True), 'product_uom': fields.many2one( 'product.uom', 'Product UOM', required=True), 'order_line_ids': fields.one2many('purchase.order.line', 'master_line_id', 'Detailed lines'), 'taxes_id': fields.many2many( 'account.tax', 'purchase_master_order_line_tax', 'ord_line_id', 'tax_id', 'Taxes'), 'date_planned': fields.date( 'Scheduled Date', required=True, select=True), } _defaults = { 'product_qty': 1.0, } def _prepare_order_line(self, cr, uid, term_line, master_line, group_index=0, context=None): order_line_pool = self.pool.get('purchase.order.line') group_pool = self.pool.get('purchase.order.line.group') group_ids = group_pool.search(cr, uid, []) product_qty = master_line.product_qty * term_line.quantity_perc order_line_vals = {} on_change_res = order_line_pool.onchange_product_id( cr, uid, [], master_line.order_id.pricelist_id.id, master_line.product_id.id, master_line.product_qty, master_line.product_uom.id, master_line.order_id.partner_id.id, date_order=master_line.order_id.date_order, fiscal_position_id=master_line.order_id.fiscal_position.id, date_planned=master_line.date_planned, name=master_line.name, price_unit=master_line.price_unit, context=context) order_line_vals.update(on_change_res['value']) date_planned = datetime.strptime( master_line.date_planned, DEFAULT_SERVER_DATE_FORMAT ) + timedelta(term_line.delay) order_line_vals.update({ 'order_id': master_line.order_id.id, 'name': master_line.name, 'price_unit': master_line.price_unit, 'product_qty': product_qty, 'product_uom': master_line.product_uom.id, 'product_id': (master_line.product_id.id if master_line.product_id else False), 'master_line_id': master_line.id, 'date_planned': date_planned, 'picking_group_id': group_ids[group_index], 'taxes_id': [(6, 0, [tax.id for tax in master_line.taxes_id])], }) return order_line_vals def generate_detailed_lines(self, cr, uid, ids, context=None): group_pool = self.pool.get('purchase.order.line.group') order_line_pool = self.pool.get('purchase.order.line') group_ids = group_pool.search(cr, uid, []) for master_line in self.browse(cr, uid, ids): if master_line.order_line_ids: raise orm.except_orm( _('Error'), _("Detailed lines generated yet (for master line '%s'). " "Remove them first") % master_line.name) if len(master_line.delivery_term_id.line_ids) > len(group_ids): raise orm.except_orm( _('Error'), _("Delivery term lines are %d. Order line groups are %d. " "Please create more groups") % (len(master_line.delivery_term_id.line_ids), len(group_ids))) if not master_line.delivery_term_id.is_total_percentage_correct(): raise orm.except_orm( _('Error'), _("Total percentage of delivery term %s is not equal to 1") % master_line.delivery_term_id.name) for group_index, term_line in enumerate( master_line.delivery_term_id.line_ids ): order_line_vals = self._prepare_order_line( cr, uid, term_line, master_line, group_index=group_index, context=context) order_line_pool.create(cr, uid, order_line_vals, context=context) return True def copy_data(self, cr, uid, id, default=None, context=None): if not default: default = {} default.update({ 'order_line_ids': [], }) return super(purchase_order_line_master, self).copy_data( cr, uid, id, default, context=context) def check_master_line_total(self, cr, uid, ids, context=None): for master_line in self.browse(cr, uid, ids, context): master_qty = master_line.product_qty total_qty = 0.0 for order_line in master_line.order_line_ids: total_qty += order_line.product_qty if master_qty != total_qty: raise orm.except_orm(_('Error'), _( 'Order lines total quantity %s is different from master ' 'line quantity %s') % (total_qty, master_qty))
class mrp_operator_registry(osv.osv): _description = 'MRP Operator Registry' _name = 'mrp.operator.registry' _columns = { 'name': fields.char('Reference', size=64, required=True, states={'draft':[('readonly',False)]}, readonly=True), 'date': fields.date('Date', required=True, select=True, states={'draft':[('readonly',False)]}, readonly=True), 'operator_id': fields.many2one('hr.employee', 'Operator', required=True, states={'draft':[('readonly',False)]}, readonly=True), 'workcenter_lines': fields.one2many('mrp.workcenter.registry', 'operator_registry_id', 'MRP Workcenter Registry', states={'draft':[('readonly',False)]}, readonly=True), 'state': fields.selection([('draft','Draft'),('confirmed','Confirmed'),('cancel','Cancelled')],'State', readonly=True), } _defaults = { 'name':lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'operator_registry'), 'date': lambda *a: time.strftime('%Y-%m-%d'), 'state': lambda *a: 'draft', } def action_confirm(self, cr, uid, ids, context=None): registry = self.browse(cr,uid,ids,context)[0] for workcenter_line in registry.workcenter_lines: if workcenter_line.production_id.id: sql = "SELECT MAX(sequence) FROM mrp_production_workcenter_line WHERE production_id = %s" % (workcenter_line.production_id.id) cr.execute(sql) sequence = cr.fetchone()[0] prod_obj = self.pool.get('mrp.production') stock_obj = self.pool.get('stock.move') if workcenter_line.production_id.state in ['draft','picking_except','confirmed','cancel','done']: raise osv.except_osv(_('Error'), _("Can't make production if the Manufacturing order is %s\nThe order must be ready or in production\nLine: %s") % (workcenter_line.production_id.state,workcenter_line.name)) if workcenter_line.product_id: if not workcenter_line.workcenter_line_id: raise osv.except_osv(_('Error'), _("Can't produce a product without Workcenter %s") % (workcenter_line.name)) if workcenter_line.workcenter_line_id: if not workcenter_line.product_id: raise osv.except_osv(_('Error'), _("Can't use a workcenter without product %s") % (workcenter_line.name)) prod_obj.action_in_production(cr,uid,workcenter_line.production_id.id) for workcenter_line2 in registry.workcenter_lines: if workcenter_line.production_id.id == workcenter_line2.production_id.id: if workcenter_line2.workcenter_line_id.sequence <= workcenter_line.workcenter_line_id.sequence: if workcenter_line.de_product_qty > 0: #mrp_routing_ids = self.pool.get('mrp.routing.workcenter').search(cr,uid,[('routing_id','=',workcenter_line2.production_id.routing_id.id)], order='sequence', context=context) #for mrp_routing_id in mrp_routing_ids: #product_line_id = self.pool.get('mrp.production.product.line').search(cr, uid, [('production_id','=',workcenter_line2.production_id.id),('consumed_on','=',mrp_routing_id)], context=context) #print product_line_id #if len(product_line_id) == 1: #break mrp_routing_id = self.pool.get('mrp.routing.workcenter').search(cr,uid,[('routing_id','=',workcenter_line2.production_id.routing_id.id),('workcenter_id','=',workcenter_line2.workcenter_id.id)], context=context) product_line_id = self.pool.get('mrp.production.product.line').search(cr, uid, [('production_id','=',workcenter_line2.production_id.id),('consumed_on','=',mrp_routing_id[0])], context=context) if len(product_line_id) > 0: product_line = self.pool.get('mrp.production.product.line').browse(cr, uid, product_line_id, context)[0] move_name = 'PROD:'+workcenter_line2.production_id.name stock_move_id = stock_obj.search(cr,uid,[('product_id','=',product_line.product_id.id),('state','=','assigned'),('name','=',move_name)],context=context) bom_id = self.pool.get('mrp.bom').search(cr, uid, [('bom_id','=',workcenter_line2.production_id.bom_id.id),('product_id','=',product_line.product_id.id),('consumed_on','=',mrp_routing_id[0])], context=context) bom = self.pool.get('mrp.bom').browse(cr, uid, bom_id, context)[0] defective_qty = bom.product_qty*bom.product_efficiency*workcenter_line.de_product_qty context = {'operator_registry':1,'location_src':workcenter_line2.production_id.location_src_id.id} stock_obj.action_scrap(cr, uid,stock_move_id,defective_qty,4,context) if sequence == workcenter_line.workcenter_line_id.sequence: if workcenter_line.go_product_qty > 0: prod_obj.action_produce(cr, uid,workcenter_line.production_id.id,workcenter_line.go_product_qty,'consume_produce',context) self.write(cr, uid, ids, {'state': 'confirmed'}) return True def action_cancel(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'cancel'}) return True def action_cancel_draft(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'draft'}) return True
return dict((id, 3) for id in ids) def function_fn_write(model, cr, uid, id, field_name, field_value, fnct_inv_arg, context): """ just so CreatorCase.export can be used """ pass models = [ ('boolean', fields.boolean()), ('integer', fields.integer()), ('float', fields.float()), ('decimal', fields.float(digits=(16, 3))), ('string.bounded', fields.char('unknown', size=16)), ('string.required', fields.char('unknown', size=None, required=True)), ('string', fields.char('unknown', size=None)), ('date', fields.date()), ('datetime', fields.datetime()), ('text', fields.text()), ('selection', fields.selection([(1, "Foo"), (2, "Bar"), (3, "Qux"), (4, '')])), # here use size=-1 to store the values as integers instead of strings ('selection.function', fields.selection(selection_fn, size=-1)), # just relate to an integer ('many2one', fields.many2one('export.integer')), ('one2many', fields.one2many('export.one2many.child', 'parent_id')), ('many2many', fields.many2many('export.many2many.other')), ('function', fields.function(function_fn, fnct_inv=function_fn_write, type="integer")), # related: specialization of fields.function, should work the same way # TODO: reference ] for name, field in models:
class timesheet_report(osv.osv): _name = "timesheet.report" _description = "Timesheet" _auto = False _columns = { 'year': fields.char('Year', size=64, required=False, 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), 'day': fields.char('Day', size=128, readonly=True), 'date': fields.date('Date', readonly=True), 'name': fields.char('Description', size=64, readonly=True), 'product_id': fields.many2one('product.product', 'Product'), 'general_account_id': fields.many2one('account.account', 'General Account', readonly=True), 'user_id': fields.many2one('res.users', 'User', readonly=True), 'to_invoice': fields.many2one('hr_timesheet_invoice.factor', 'Type of Invoicing', readonly=True), 'account_id': fields.many2one('account.analytic.account', 'Analytic Account', readonly=True), 'nbr': fields.integer('#Nbr', readonly=True), 'total_diff': fields.float('#Total Diff', readonly=True), 'total_timesheet': fields.float('#Total Timesheet', readonly=True), 'total_attendance': fields.float('#Total Attendance', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True), 'department_id': fields.many2one('hr.department', 'Department', readonly=True), 'date_from': fields.date( 'Date from', readonly=True, ), 'date_to': fields.date('Date to', readonly=True), 'date_current': fields.date('Current date', required=True), 'state': fields.selection([('new', 'New'), ('draft', 'Draft'), ('confirm', 'Confirmed'), ('done', 'Done')], 'Status', readonly=True), 'quantity': fields.float('Time', readonly=True), 'cost': fields.float('#Cost', readonly=True), } def init(self, cr): tools.drop_view_if_exists(cr, 'timesheet_report') cr.execute(""" create or replace view timesheet_report as ( select min(aal.id) as id, htss.name, aal.date as date, htss.date_from, htss.date_to, to_char(htss.date_from, 'YYYY-MM-DD') as day, to_char(htss.date_from, 'YYYY') as year, to_char(htss.date_from, 'MM') as month, count(*) as nbr, aal.unit_amount as quantity, aal.amount as cost, aal.account_id, aal.product_id, (SELECT sum(day.total_difference) FROM hr_timesheet_sheet_sheet AS sheet LEFT JOIN hr_timesheet_sheet_sheet_day AS day ON (sheet.id = day.sheet_id) where sheet.id=htss.id) as total_diff, (SELECT sum(day.total_timesheet) FROM hr_timesheet_sheet_sheet AS sheet LEFT JOIN hr_timesheet_sheet_sheet_day AS day ON (sheet.id = day.sheet_id) where sheet.id=htss.id) as total_timesheet, (SELECT sum(day.total_attendance) FROM hr_timesheet_sheet_sheet AS sheet LEFT JOIN hr_timesheet_sheet_sheet_day AS day ON (sheet.id = day.sheet_id) where sheet.id=htss.id) as total_attendance, aal.to_invoice, aal.general_account_id, htss.user_id, htss.company_id, htss.department_id, htss.state from account_analytic_line as aal left join hr_analytic_timesheet as hat ON (hat.line_id=aal.id) left join hr_timesheet_sheet_sheet as htss ON (hat.line_id=htss.id) group by aal.account_id, aal.date, htss.date_from, htss.date_to, aal.unit_amount, aal.amount, aal.to_invoice, aal.product_id, aal.general_account_id, htss.name, htss.company_id, htss.state, htss.id, htss.department_id, htss.user_id ) """)
class res_partner(osv.Model, format_address): _description = 'Partner' _name = "res.partner" def _address_display(self, cr, uid, ids, name, args, context=None): res = {} for partner in self.browse(cr, uid, ids, context=context): res[partner.id] = self._display_address(cr, uid, partner, context=context) return res @api.multi def _get_tz_offset(self, name, args): return dict(( p.id, datetime.datetime.now(pytz.timezone(p.tz or 'GMT')).strftime('%z')) for p in self) @api.multi def _get_image(self, name, args): return dict( (p.id, tools.image_get_resized_images(p.image)) for p in self) @api.one def _set_image(self, name, value, args): return self.write({'image': tools.image_resize_image_big(value)}) @api.multi def _has_image(self, name, args): return dict((p.id, bool(p.image)) for p in self) def _commercial_partner_compute(self, cr, uid, ids, name, args, context=None): """ Returns the partner that is considered the commercial entity of this partner. The commercial entity holds the master data for all commercial fields (see :py:meth:`~_commercial_fields`) """ result = dict.fromkeys(ids, False) for partner in self.browse(cr, uid, ids, context=context): current_partner = partner while not current_partner.is_company and current_partner.parent_id: current_partner = current_partner.parent_id result[partner.id] = current_partner.id return result def _display_name_compute(self, cr, uid, ids, name, args, context=None): context = dict(context or {}) context.pop('show_address', None) context.pop('show_address_only', None) context.pop('show_email', None) return dict(self.name_get(cr, uid, ids, context=context)) # indirections to avoid passing a copy of the overridable method when declaring the function field _commercial_partner_id = lambda self, *args, **kwargs: self._commercial_partner_compute( *args, **kwargs) _display_name = lambda self, *args, **kwargs: self._display_name_compute( *args, **kwargs) _commercial_partner_store_triggers = { 'res.partner': (lambda self, cr, uid, ids, context=None: self.search( cr, uid, [('id', 'child_of', ids)], context=dict(active_test=False)), ['parent_id', 'is_company'], 10) } _display_name_store_triggers = { 'res.partner': (lambda self, cr, uid, ids, context=None: self.search( cr, uid, [('id', 'child_of', ids)], context=dict(active_test=False)), ['parent_id', 'is_company', 'name'], 10) } _order = "display_name" _columns = { 'name': fields.char('Name', required=True, select=True), 'display_name': fields.function(_display_name, type='char', string='Name', store=_display_name_store_triggers, select=True), 'date': fields.date('Date', select=1), 'title': fields.many2one('res.partner.title', 'Title'), 'parent_id': fields.many2one('res.partner', 'Related Company', select=True), 'parent_name': fields.related('parent_id', 'name', type='char', readonly=True, string='Parent name'), 'child_ids': fields.one2many('res.partner', 'parent_id', 'Contacts', domain=[('active','=',True)]), # force "active_test" domain to bypass _search() override 'ref': fields.char('Contact Reference', select=1), 'lang': fields.selection(_lang_get, 'Language', help="If the selected language is loaded in the system, all documents related to this contact will be printed in this language. If not, it will be English."), 'tz': fields.selection(_tz_get, 'Timezone', size=64, help="The partner's timezone, used to output proper date and time values inside printed reports. " "It is important to set a value for this field. You should use the same timezone " "that is otherwise used to pick and render date and time values: your computer's timezone."), 'tz_offset': fields.function(_get_tz_offset, type='char', size=5, string='Timezone offset', invisible=True), 'user_id': fields.many2one('res.users', 'Salesperson', help='The internal user that is in charge of communicating with this contact if any.'), 'vat': fields.char('TIN', help="Tax Identification Number. Check the box if this contact is subjected to taxes. Used by the some of the legal statements."), 'bank_ids': fields.one2many('res.partner.bank', 'partner_id', 'Banks'), 'website': fields.char('Website', help="Website of Partner or Company"), 'comment': fields.text('Notes'), 'category_id': fields.many2many('res.partner.category', id1='partner_id', id2='category_id', string='Tags'), 'credit_limit': fields.float(string='Credit Limit'), 'ean13': fields.char('EAN13', size=13), 'active': fields.boolean('Active'), 'customer': fields.boolean('Customer', help="Check this box if this contact is a customer."), 'supplier': fields.boolean('Supplier', help="Check this box if this contact is a supplier. If it's not checked, purchase people will not see it when encoding a purchase order."), 'employee': fields.boolean('Employee', help="Check this box if this contact is an Employee."), 'function': fields.char('Job Position'), 'type': fields.selection([('default', 'Default'), ('invoice', 'Invoice'), ('delivery', 'Shipping'), ('contact', 'Contact'), ('other', 'Other')], 'Address Type', help="Used to select automatically the right address according to the context in sales and purchases documents."), 'street': fields.char('Street'), 'street2': fields.char('Street2'), 'zip': fields.char('Zip', size=24, change_default=True), 'city': fields.char('City'), 'state_id': fields.many2one("res.country.state", 'State', ondelete='restrict'), 'country_id': fields.many2one('res.country', 'Country', ondelete='restrict'), 'email': fields.char('Email'), 'phone': fields.char('Phone'), 'fax': fields.char('Fax'), 'mobile': fields.char('Mobile'), 'birthdate': fields.char('Birthdate'), 'is_company': fields.boolean('Is a Company', help="Check if the contact is a company, otherwise it is a person"), 'use_parent_address': fields.boolean('Use Company Address', help="Select this if you want to set company's address information for this contact"), # image: all image fields are base64 encoded and PIL-supported 'image': fields.binary("Image", help="This field holds the image used as avatar for this contact, limited to 1024x1024px"), 'image_medium': fields.function(_get_image, fnct_inv=_set_image, string="Medium-sized image", type="binary", multi="_get_image", store={ 'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10), }, help="Medium-sized image of this contact. It is automatically "\ "resized as a 128x128px image, with aspect ratio preserved. "\ "Use this field in form views or some kanban views."), 'image_small': fields.function(_get_image, fnct_inv=_set_image, string="Small-sized image", type="binary", multi="_get_image", store={ 'res.partner': (lambda self, cr, uid, ids, c={}: ids, ['image'], 10), }, help="Small-sized image of this contact. It is automatically "\ "resized as a 64x64px image, with aspect ratio preserved. "\ "Use this field anywhere a small image is required."), 'has_image': fields.function(_has_image, type="boolean"), 'company_id': fields.many2one('res.company', 'Company', select=1), 'color': fields.integer('Color Index'), 'user_ids': fields.one2many('res.users', 'partner_id', 'Users'), 'contact_address': fields.function(_address_display, type='char', string='Complete Address'), # technical field used for managing commercial fields 'commercial_partner_id': fields.function(_commercial_partner_id, type='many2one', relation='res.partner', string='Commercial Entity', store=_commercial_partner_store_triggers) } @api.model def _default_category(self): category_id = self.env.context.get('category_id', False) return [category_id] if category_id else False @api.model def _get_default_image(self, is_company, colorize=False): img_path = openerp.modules.get_module_resource( 'base', 'static/src/img', 'company_image.png' if is_company else 'avatar.png') with open(img_path, 'rb') as f: image = f.read() # colorize user avatars if not is_company: image = tools.image_colorize(image) return tools.image_resize_image_big(image.encode('base64')) def fields_view_get(self, cr, user, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): if (not view_id) and (view_type == 'form') and context and context.get( 'force_email', False): view_id = self.pool['ir.model.data'].get_object_reference( cr, user, 'base', 'view_partner_simple_form')[1] res = super(res_partner, self).fields_view_get(cr, user, view_id, view_type, context, toolbar=toolbar, submenu=submenu) if view_type == 'form': res['arch'] = self.fields_view_get_address(cr, user, res['arch'], context=context) return res @api.model def _default_company(self): return self.env['res.company']._company_default_get('res.partner') _defaults = { 'active': True, 'lang': api.model(lambda self: self.env.lang), 'tz': api.model(lambda self: self.env.context.get('tz', False)), 'customer': True, 'category_id': _default_category, 'company_id': _default_company, 'color': 0, 'is_company': False, 'type': 'contact', # type 'default' is wildcard and thus inappropriate 'use_parent_address': False, 'image': False, } _constraints = [ (osv.osv._check_recursion, 'You cannot create recursive Partner hierarchies.', ['parent_id']), ] @api.one def copy(self, default=None): default = dict(default or {}) default['name'] = _('%s (copy)') % self.name return super(res_partner, self).copy(default) @api.multi def onchange_type(self, is_company): value = {'title': False} if is_company: value['use_parent_address'] = False domain = {'title': [('domain', '=', 'partner')]} else: domain = {'title': [('domain', '=', 'contact')]} return {'value': value, 'domain': domain} def onchange_address(self, cr, uid, ids, use_parent_address, parent_id, context=None): def value_or_id(val): """ return val or val.id if val is a browse record """ return val if isinstance(val, (bool, int, long, float, basestring)) else val.id result = {} if parent_id: if ids: partner = self.browse(cr, uid, ids[0], context=context) if partner.parent_id and partner.parent_id.id != parent_id: result['warning'] = { 'title': _('Warning'), 'message': _('Changing the company of a contact should only be done if it ' 'was never correctly set. If an existing contact starts working for a new ' 'company then a new contact should be created under that new ' 'company. You can use the "Discard" button to abandon this change.' ) } if use_parent_address: parent = self.browse(cr, uid, parent_id, context=context) address_fields = self._address_fields(cr, uid, context=context) result['value'] = dict( (key, value_or_id(parent[key])) for key in address_fields) else: result['value'] = {'use_parent_address': False} return result @api.multi def onchange_state(self, state_id): if state_id: state = self.env['res.country.state'].browse(state_id) return {'value': {'country_id': state.country_id.id}} return {} def _check_ean_key(self, cr, uid, ids, context=None): for partner_o in self.pool['res.partner'].read(cr, uid, ids, [ 'ean13', ]): thisean = partner_o['ean13'] if thisean and thisean != '': if len(thisean) != 13: return False sum = 0 for i in range(12): if not (i % 2): sum += int(thisean[i]) else: sum += 3 * int(thisean[i]) if math.ceil(sum / 10.0) * 10 - sum != int(thisean[12]): return False return True # _constraints = [(_check_ean_key, 'Error: Invalid ean code', ['ean13'])] def _update_fields_values(self, cr, uid, partner, fields, context=None): """ Returns dict of write() values for synchronizing ``fields`` """ values = {} for fname in fields: field = self._fields[fname] if field.type == 'one2many': raise AssertionError( 'One2Many fields cannot be synchronized as part of `commercial_fields` or `address fields`' ) if field.type == 'many2one': values[fname] = partner[fname].id if partner[fname] else False elif field.type == 'many2many': values[fname] = [(6, 0, [r.id for r in partner[fname] or []])] else: values[fname] = partner[fname] return values def _address_fields(self, cr, uid, context=None): """ Returns the list of address fields that are synced from the parent when the `use_parent_address` flag is set. """ return list(ADDRESS_FIELDS) def update_address(self, cr, uid, ids, vals, context=None): address_fields = self._address_fields(cr, uid, context=context) addr_vals = dict( (key, vals[key]) for key in address_fields if key in vals) if addr_vals: return super(res_partner, self).write(cr, uid, ids, addr_vals, context) def _commercial_fields(self, cr, uid, context=None): """ Returns the list of fields that are managed by the commercial entity to which a partner belongs. These fields are meant to be hidden on partners that aren't `commercial entities` themselves, and will be delegated to the parent `commercial entity`. The list is meant to be extended by inheriting classes. """ return ['vat', 'credit_limit'] def _commercial_sync_from_company(self, cr, uid, partner, context=None): """ Handle sync of commercial fields when a new parent commercial entity is set, as if they were related fields """ commercial_partner = partner.commercial_partner_id if not commercial_partner: # On child partner creation of a parent partner, # the commercial_partner_id is not yet computed commercial_partner_id = self._commercial_partner_compute( cr, uid, [partner.id], 'commercial_partner_id', [], context=context)[partner.id] commercial_partner = self.browse(cr, uid, commercial_partner_id, context=context) if commercial_partner != partner: commercial_fields = self._commercial_fields(cr, uid, context=context) sync_vals = self._update_fields_values(cr, uid, commercial_partner, commercial_fields, context=context) partner.write(sync_vals) def _commercial_sync_to_children(self, cr, uid, partner, context=None): """ Handle sync of commercial fields to descendants """ commercial_fields = self._commercial_fields(cr, uid, context=context) commercial_partner = partner.commercial_partner_id if not commercial_partner: # On child partner creation of a parent partner, # the commercial_partner_id is not yet computed commercial_partner_id = self._commercial_partner_compute( cr, uid, [partner.id], 'commercial_partner_id', [], context=context)[partner.id] commercial_partner = self.browse(cr, uid, commercial_partner_id, context=context) sync_vals = self._update_fields_values(cr, uid, commercial_partner, commercial_fields, context=context) sync_children = [c for c in partner.child_ids if not c.is_company] for child in sync_children: self._commercial_sync_to_children(cr, uid, child, context=context) return self.write(cr, uid, [c.id for c in sync_children], sync_vals, context=context) def _fields_sync(self, cr, uid, partner, update_values, context=None): """ Sync commercial fields and address fields from company and to children after create/update, just as if those were all modeled as fields.related to the parent """ # 1. From UPSTREAM: sync from parent if update_values.get('parent_id') or update_values.get( 'use_parent_address'): # 1a. Commercial fields: sync if parent changed if update_values.get('parent_id'): self._commercial_sync_from_company(cr, uid, partner, context=context) # 1b. Address fields: sync if parent or use_parent changed *and* both are now set if partner.parent_id and partner.use_parent_address: onchange_vals = self.onchange_address( cr, uid, [partner.id], use_parent_address=partner.use_parent_address, parent_id=partner.parent_id.id, context=context).get('value', {}) partner.update_address(onchange_vals) # 2. To DOWNSTREAM: sync children if partner.child_ids: # 2a. Commercial Fields: sync if commercial entity if partner.commercial_partner_id == partner: commercial_fields = self._commercial_fields(cr, uid, context=context) if any(field in update_values for field in commercial_fields): self._commercial_sync_to_children(cr, uid, partner, context=context) # 2b. Address fields: sync if address changed address_fields = self._address_fields(cr, uid, context=context) if any(field in update_values for field in address_fields): domain_children = [('parent_id', '=', partner.id), ('use_parent_address', '=', True)] update_ids = self.search(cr, uid, domain_children, context=context) self.update_address(cr, uid, update_ids, update_values, context=context) def _handle_first_contact_creation(self, cr, uid, partner, context=None): """ On creation of first contact for a company (or root) that has no address, assume contact address was meant to be company address """ parent = partner.parent_id address_fields = self._address_fields(cr, uid, context=context) if parent and (parent.is_company or not parent.parent_id) and len(parent.child_ids) == 1 and \ any(partner[f] for f in address_fields) and not any(parent[f] for f in address_fields): addr_vals = self._update_fields_values(cr, uid, partner, address_fields, context=context) parent.update_address(addr_vals) if not parent.is_company: parent.write({'is_company': True}) def unlink(self, cr, uid, ids, context=None): orphan_contact_ids = self.search(cr, uid, [('parent_id', 'in', ids), ('id', 'not in', ids), ('use_parent_address', '=', True)], context=context) if orphan_contact_ids: # no longer have a parent address self.write(cr, uid, orphan_contact_ids, {'use_parent_address': False}, context=context) return super(res_partner, self).unlink(cr, uid, ids, context=context) def _clean_website(self, website): (scheme, netloc, path, params, query, fragment) = urlparse.urlparse(website) if not scheme: if not netloc: netloc, path = path, '' website = urlparse.urlunparse( ('http', netloc, path, params, query, fragment)) return website @api.multi def write(self, vals): # res.partner must only allow to set the company_id of a partner if it # is the same as the company of all users that inherit from this partner # (this is to allow the code from res_users to write to the partner!) or # if setting the company_id to False (this is compatible with any user # company) if vals.get('website'): vals['website'] = self._clean_website(vals['website']) if vals.get('company_id'): company = self.env['res.company'].browse(vals['company_id']) for partner in self: if partner.user_ids: companies = set(user.company_id for user in partner.user_ids) if len(companies) > 1 or company not in companies: raise osv.except_osv( _("Warning"), _("You can not change the company as the partner/user has multiple user linked with different companies." )) result = super(res_partner, self).write(vals) for partner in self: if any( u.has_group('base.group_user') for u in partner.user_ids if u != self.env.user): self.env['res.users'].check_access_rights('write') self._fields_sync(partner, vals) return result @api.model def create(self, vals): if vals.get('website'): vals['website'] = self._clean_website(vals['website']) partner = super(res_partner, self).create(vals) self._fields_sync(partner, vals) self._handle_first_contact_creation(partner) return partner def open_commercial_entity(self, cr, uid, ids, context=None): """ Utility method used to add an "Open Company" button in partner views """ partner = self.browse(cr, uid, ids[0], context=context) return { 'type': 'ir.actions.act_window', 'res_model': 'res.partner', 'view_mode': 'form', 'res_id': partner.commercial_partner_id.id, 'target': 'new', 'flags': { 'form': { 'action_buttons': True } } } def open_parent(self, cr, uid, ids, context=None): """ Utility method used to add an "Open Parent" button in partner views """ partner = self.browse(cr, uid, ids[0], context=context) return { 'type': 'ir.actions.act_window', 'res_model': 'res.partner', 'view_mode': 'form', 'res_id': partner.parent_id.id, 'target': 'new', 'flags': { 'form': { 'action_buttons': True } } } 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): ####### Added last name for mapping with HLS last_name = "" if record.last_name: last_name = record.last_name ############################################ name = record.name + ' ' + last_name if record.parent_id and not record.is_company: name = "%s, %s" % (record.parent_name, name) if context.get('show_address_only'): name = self._display_address(cr, uid, record, without_company=True, context=context) if context.get('show_address'): name = name + "\n" + self._display_address( cr, uid, record, without_company=True, context=context) name = name.replace('\n\n', '\n') name = name.replace('\n\n', '\n') if context.get('show_email') and record.email: name = "%s <%s>" % (name, record.email) res.append((record.id, name)) return res def _parse_partner_name(self, text, context=None): """ Supported syntax: - 'Raoul <*****@*****.**>': will find name and email address - otherwise: default, everything is set as the name """ emails = tools.email_split(text.replace(' ', ',')) if emails: email = emails[0] name = text[:text.index(email)].replace('"', '').replace('<', '').strip() else: name, email = text, '' return name, email def name_create(self, cr, uid, name, context=None): """ Override of orm's name_create method for partners. The purpose is to handle some basic formats to create partners using the name_create. If only an email address is received and that the regex cannot find a name, the name will have the email value. If 'force_email' key in context: must find the email address. """ if context is None: context = {} name, email = self._parse_partner_name(name, context=context) if context.get('force_email') and not email: raise osv.except_osv( _('Warning'), _("Couldn't create contact without email address!")) if not name and email: name = email rec_id = self.create(cr, uid, { self._rec_name: name or email, 'email': email or False }, context=context) return self.name_get(cr, uid, [rec_id], context)[0] def _search(self, cr, user, args, offset=0, limit=None, order=None, context=None, count=False, access_rights_uid=None): """ Override search() to always show inactive children when searching via ``child_of`` operator. The ORM will always call search() with a simple domain of the form [('parent_id', 'in', [ids])]. """ # a special ``domain`` is set on the ``child_ids`` o2m to bypass this logic, as it uses similar domain expressions if len(args) == 1 and len(args[0]) == 3 and args[0][:2] == ('parent_id','in') \ and args[0][2] != [False]: context = dict(context or {}, active_test=False) return super(res_partner, self)._search(cr, user, args, offset=offset, limit=limit, order=order, context=context, count=count, access_rights_uid=access_rights_uid) def name_search(self, cr, uid, name, args=None, operator='ilike', context=None, limit=100): if not args: args = [] if name and operator in ('=', 'ilike', '=ilike', 'like', '=like'): self.check_access_rights(cr, uid, 'read') where_query = self._where_calc(cr, uid, args, context=context) self._apply_ir_rules(cr, uid, where_query, 'read', context=context) from_clause, where_clause, where_clause_params = where_query.get_sql( ) where_str = where_clause and (" WHERE %s AND " % where_clause) or ' WHERE ' # search on the name of the contacts and of its company search_name = name if operator in ('ilike', 'like'): search_name = '%%%s%%' % name if operator in ('=ilike', '=like'): operator = operator[1:] unaccent = get_unaccent_wrapper(cr) query = """SELECT id FROM res_partner {where} ({email} {operator} {percent} OR {display_name} {operator} {percent}) ORDER BY {display_name} """.format(where=where_str, operator=operator, email=unaccent('email'), display_name=unaccent('display_name'), percent=unaccent('%s')) where_clause_params += [search_name, search_name] if limit: query += ' limit %s' where_clause_params.append(limit) cr.execute(query, where_clause_params) ids = map(lambda x: x[0], cr.fetchall()) if ids: return self.name_get(cr, uid, ids, context) else: return [] return super(res_partner, self).name_search(cr, uid, name, args, operator=operator, context=context, limit=limit) def find_or_create(self, cr, uid, email, context=None): """ Find a partner with the given ``email`` or use :py:method:`~.name_create` to create one :param str email: email-like string, which should contain at least one email, e.g. ``"Raoul Grosbedon <*****@*****.**>"``""" assert email, 'an email is required for find_or_create to work' emails = tools.email_split(email) if emails: email = emails[0] ids = self.search(cr, uid, [('email', '=ilike', email)], context=context) if not ids: return self.name_create(cr, uid, email, context=context)[0] return ids[0] def _email_send(self, cr, uid, ids, email_from, subject, body, on_error=None): partners = self.browse(cr, uid, ids) for partner in partners: if partner.email: tools.email_send(email_from, [partner.email], subject, body, on_error) return True def email_send(self, cr, uid, ids, email_from, subject, body, on_error=''): while len(ids): self.pool['ir.cron'].create( cr, uid, { 'name': 'Send Partner Emails', 'user_id': uid, 'model': 'res.partner', 'function': '_email_send', 'args': repr( [ids[:16], email_from, subject, body, on_error]) }) ids = ids[16:] return True def address_get(self, cr, uid, ids, adr_pref=None, context=None): """ Find contacts/addresses of the right type(s) by doing a depth-first-search through descendants within company boundaries (stop at entities flagged ``is_company``) then continuing the search at the ancestors that are within the same company boundaries. Defaults to partners of type ``'default'`` when the exact type is not found, or to the provided partner itself if no type ``'default'`` is found either. """ adr_pref = set(adr_pref or []) if 'default' not in adr_pref: adr_pref.add('default') result = {} visited = set() if isinstance(ids, (int, long)): ids = [ids] for partner in self.browse(cr, uid, filter(None, ids), context=context): current_partner = partner while current_partner: to_scan = [current_partner] # Scan descendants, DFS while to_scan: record = to_scan.pop(0) visited.add(record) if record.type in adr_pref and not result.get(record.type): result[record.type] = record.id if len(result) == len(adr_pref): return result to_scan = [ c for c in record.child_ids if c not in visited if not c.is_company ] + to_scan # Continue scanning at ancestor if current_partner is not a commercial entity if current_partner.is_company or not current_partner.parent_id: break current_partner = current_partner.parent_id # default to type 'default' or the partner itself default = result.get('default', ids and ids[0] or False) for adr_type in adr_pref: result[adr_type] = result.get(adr_type) or default return result def view_header_get(self, cr, uid, view_id, view_type, context): res = super(res_partner, self).view_header_get(cr, uid, view_id, view_type, context) if res: return res if not context.get('category_id', False): return False return _('Partners: ') + self.pool['res.partner.category'].browse( cr, uid, context['category_id'], context).name @api.model @api.returns('self') def main_partner(self): ''' Return the main partner ''' return self.env.ref('base.main_partner') def _display_address(self, cr, uid, address, without_company=False, context=None): ''' The purpose of this function is to build and return an address formatted accordingly to the standards of the country where it belongs. :param address: browse record of the res.partner to format :returns: the address formatted in a display that fit its country habits (or the default ones if not country is specified) :rtype: string ''' # get the information that will be injected into the display format # get the address format address_format = address.country_id.address_format or \ "%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s" args = { 'state_code': address.state_id.code or '', 'state_name': address.state_id.name or '', 'country_code': address.country_id.code or '', 'country_name': address.country_id.name or '', 'company_name': address.parent_name or '', } for field in self._address_fields(cr, uid, context=context): args[field] = getattr(address, field) or '' if without_company: args['company_name'] = '' elif address.parent_id: address_format = '%(company_name)s\n' + address_format return address_format % args
class vendor_ageing(osv.osv_memory): _name = "vendor.ageing" _columns = { 'date_from': fields.date('As of Date: '), 'vendor_group_id':fields.many2one('tpt.vendor.group','Vendor Class (Group)'), 'vendor_id': fields.many2one('res.partner','vendor'), } def print_report(self, cr, uid, ids, context=None): def convert_date(self, date): if date: date = datetime.strptime(date, DATE_FORMAT) return date.strftime('%d/%m/%Y') def get_date_from(self): wizard_data = self.localcontext['data']['form'] date = datetime.strptime(wizard_data['date_from'], DATE_FORMAT) return date.strftime('%d/%m/%Y') def get_vendor_group(self): vendor_group = '' wizard_data = self.localcontext['data']['form'] vendor_group = wizard_data['vendor_group'] if vendor_group == 'Spares': vendor_group = 'Spares' if vendor_group == 'Domestic': vendor_group = 'Domestic' if vendor_group == 'Foreign': vendor_group = 'Foreign' return vendor_group def get_balance (code, date): credit = 0 # sql = ''' # select case when SUM(debit-credit)=0 then 0 else SUM(debit-credit) end credit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') and date <= '%s' # '''%(code, date) # sql = ''' # select # (select case when sum(amount_total) is null then 0 else sum(amount_total) end as amount_total from account_invoice where # account_id=(select id from account_account where code = '0000'||'%s') and state!='draft' and date_invoice <= '%s')- # (select case when sum(debit) is null then 0 else sum(debit) end as debit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') and date<='%s' and doc_type='cash_rec') # as balance # '''%(code, date,code,date) # # cr.execute(sql) # credit = cr.fetchone() # if credit: # credit = credit[0] # return credit def get_balance_30 (code,date): credit = 0 # sql = ''' # select case when SUM(debit-credit)=0.00 or SUM(debit-credit) is null then 0.00 else SUM(debit-credit) end credit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') and # date between (select timestamp '%s' - interval '30 days')and(select timestamp '%s' - interval '1 day') # '''%(code,date,date) # sql = ''' # select (select case when sum(amount_total) is null then 0 else sum(amount_total) end as amount_total from account_invoice where # account_id=(select id from account_account where code = '0000'||'%s') and state!='draft' and # date_invoice between (select timestamp '%s' - interval '30 days')and(select timestamp '%s' - interval '1 day')) # -(select case when sum(debit) is null then 0 else sum(debit) end as debit from account_move_line where account_id=(select id from account_account where code = '0000'||'%s') # and doc_type='cash_rec' and date between (select timestamp '%s' - interval '30 days') # and(select timestamp '%s' - interval '1 day')) as balance_30 # '''%(code,date,date,code,date,date) # cr.execute(sql) # credit = cr.fetchone() # if credit: # credit = credit[0] # return credit def get_balance_31_45 (code,date): credit = 0 # sql = ''' # select case when SUM(debit-credit)=0.00 or SUM(debit-credit) is null then 0.00 else SUM(debit-credit) end credit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') and # date between (select timestamp '%s' - interval '31 days') and (select timestamp '%s' - interval '45 days') # '''%(code,date,date) # sql = ''' # select (select case when sum(amount_total) is null then 0 else sum(amount_total) end as amount_total from account_invoice where # account_id=(select id from account_account where code = '0000'||'%s') and state!='draft' and # date_invoice between (select timestamp '%s' - interval '45 days')and(select timestamp '%s' - interval '31 days')) # -(select case when sum(debit) is null then 0 else sum(debit) end as debit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') # and doc_type='cash_rec' and date between (select timestamp '%s' - interval '45 days') # and(select timestamp '%s' - interval '31 days')) as balance_45 # '''%(code,date,date,code,date,date) # cr.execute(sql) # credit = cr.fetchone() # if credit: # credit = credit[0] # return credit def get_balance_46_60 (code,date): credit = 0 # sql = ''' # select case when SUM(debit-credit)=0.00 or SUM(debit-credit) is null then 0.00 else SUM(debit-credit) end credit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') and # date between (select timestamp '%s' - interval '46 days') and (select timestamp '%s' - interval '60 days') # '''%(code,date,date) # sql = ''' # select (select case when sum(amount_total) is null then 0 else sum(amount_total) end as amount_total from account_invoice where # account_id=(select id from account_account where code = '0000'||'%s') and state!='draft' and # date_invoice between (select timestamp '%s' - interval '60 days')and(select timestamp '%s' - interval '46 days')) # -(select case when sum(debit) is null then 0 else sum(debit) end as debit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') # and doc_type='cash_rec' and date between (select timestamp '%s' - interval '60 days') # and(select timestamp '%s' - interval '46 days')) as balance_60 # '''%(code,date,date,code,date,date) # cr.execute(sql) # credit = cr.fetchone() # if credit: # credit = credit[0] # return credit def get_balance_61_90 (code,date): credit = 0 # sql = ''' # select case when SUM(debit-credit)=0.00 or SUM(debit-credit) is null then 0.00 else SUM(debit-credit) end credit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') and # date between (select timestamp '%s' - interval '61 days') and (select timestamp '%s' - interval '90 days') # '''%(code,date,date) # sql = ''' # select (select case when sum(amount_total) is null then 0 else sum(amount_total) end as amount_total from account_invoice where # account_id=(select id from account_account where code = '0000'||'%s') and state!='draft' and # date_invoice between (select timestamp '%s' - interval '90 days')and(select timestamp '%s' - interval '61 days')) # -(select case when sum(debit) is null then 0 else sum(debit) end as debit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') # and doc_type='cash_rec' and date between (select timestamp '%s' - interval '90 days') # and(select timestamp '%s' - interval '61 days')) as balance_90 # '''%(code,date,date,code,date,date) # cr.execute(sql) # credit = cr.fetchone() # if credit: # credit = credit[0] # return credit def get_balance_over_90 (code,date): credit = 0 # sql = ''' # select case when SUM(debit-credit)=0.00 or SUM(debit-credit) is null then 0.00 else SUM(debit-credit) end credit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') and # date <= (select timestamp '%s' - interval '90 days') # '''%(code,date) # sql = ''' # select # (select case when sum(amount_total) is null then 0 else sum(amount_total) end as amount_total from account_invoice where # account_id=(select id from account_account where code = '0000'||'%s') and state!='draft'and date_invoice <= (select timestamp '%s' - interval '90 days'))- # (select case when sum(debit) is null then 0 else sum(debit) end as debit from account_move_line where # account_id=(select id from account_account where code = '0000'||'%s') and date<=(select timestamp '%s' - interval '90 days') and doc_type='cash_rec') # as balance_over_90 # '''%(code, date,code,date) # # cr.execute(sql) # credit = cr.fetchone() # if credit: # credit = credit[0] # return credit def get_vendor(cb): # wizard_data = self.localcontext['data']['form'] # vendor_group = wizard_data['vendor_group'] # vendor_id = wizard_data['vendor_id'] # date = wizard_data['date_from'] vendor_group = cb.vendor_group_id.id vendor_id=cb.vendor_id.id date=cb.date_from #date1 = wizard_data['date_from'] bp_obj = self.pool.get('res.partner') if vendor_id and date: bp_ids = bp_obj.search(cr,uid, [('id','=',vendor_id) ]) if vendor_group: bp_ids = bp_obj.search(cr, uid, [('vendor_group_id','=',vendor_group) ]) if not vendor_id and not vendor_group: bp_ids = bp_obj.search(cr, uid, [('vendor_group_id','=','4') ]) if vendor_id and vendor_group and date: bp_ids = bp_obj.search(cr,uid, [('id','=',vendor_id), ('vendor_group_id','=',vendor_group) ]) res = [] for line in bp_obj.browse(cr, uid, bp_ids): res.append({ 'code': '0', 'name': 'Ram', 'balance': '0.00', '0_30_days': '0.00', '31_45_days':'0.00', '46_60_days': '0.00', 'over_90_days':'0.00', }) return res def get_amt(amt): locale.setlocale(locale.LC_NUMERIC, "en_IN") inr_comma_format = locale.format("%.2f", amt, grouping=True) return inr_comma_format cr.execute('delete from vendor_ageing_report') cb_obj = self.pool.get('vendor.ageing.report') cb = self.browse(cr, uid, ids[0]) cb_line = [] for line in get_vendor(cb): cb_line.append((0,0,{ 'code': '', 'name': '', 'balance': '', '0_30_days': '', '31_45_days':'', '46_60_days':'', '61_90_days':'', 'over_90_days':'', })) vals = { 'date_from': cb.date_from, 'vendor_id': cb.vendor_id.id or False, 'vendor_group':cb.vendor_group_id.id, 'ageing_line': cb_line, } cb_id = cb_obj.create(cr, uid, vals) #res = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'green_erp_arulmani_accounting', 'vendor_ageing_report_form') return { 'name': 'vendor Ageing Report', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'vendor.ageing.report', 'domain': [], 'type': 'ir.actions.act_window', 'target': 'current', 'res_id': cb_id, }
class report_stock_move(osv.osv): _name = "report.stock.move" _description = "Moves Statistics" _auto = False _columns = { 'date': fields.date('Date', readonly=True), 'year': fields.char('Year', size=4, readonly=True), 'day': fields.char('Day', size=128, 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), 'partner_id': fields.many2one('res.partner', 'Partner', readonly=True), 'product_id': fields.many2one('product.product', 'Product', readonly=True), 'company_id': fields.many2one('res.company', 'Company', readonly=True), 'picking_id': fields.many2one('stock.picking', 'Shipment', readonly=True), 'type': fields.selection( [('out', 'Sending Goods'), ('in', 'Getting Goods'), ('internal', 'Internal'), ('other', 'Others')], 'Shipping Type', required=True, select=True, help="Shipping type specify, goods coming in or going out."), 'location_id': fields.many2one( 'stock.location', 'Source Location', readonly=True, select=True, help= "Sets a location if you produce at a fixed location. This can be a partner location if you subcontract the manufacturing operations." ), 'location_dest_id': fields.many2one( 'stock.location', 'Dest. Location', readonly=True, select=True, help="Location where the system will stock the finished products." ), 'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting'), ('confirmed', 'Confirmed'), ('assigned', 'Available'), ('done', 'Done'), ('cancel', 'Cancelled')], 'Status', readonly=True, select=True), 'product_qty': fields.integer('Quantity', readonly=True), 'categ_id': fields.many2one( 'product.category', 'Product Category', ), 'product_qty_in': fields.integer('In Qty', readonly=True), 'product_qty_out': fields.integer('Out Qty', readonly=True), 'value': fields.float('Total Value', required=True), 'day_diff2': fields.float('Lag (Days)', readonly=True, digits_compute=dp.get_precision('Shipping Delay'), group_operator="avg"), 'day_diff1': fields.float('Planned Lead Time (Days)', readonly=True, digits_compute=dp.get_precision('Shipping Delay'), group_operator="avg"), 'day_diff': fields.float('Execution Lead Time (Days)', readonly=True, digits_compute=dp.get_precision('Shipping Delay'), group_operator="avg"), 'stock_journal': fields.many2one('stock.journal', 'Stock Journal', select=True), } def init(self, cr): tools.drop_view_if_exists(cr, 'report_stock_move') cr.execute(""" CREATE OR REPLACE view report_stock_move AS ( SELECT min(sm.id) as id, date_trunc('day', sm.date) as date, to_char(date_trunc('day',sm.date), 'YYYY') as year, to_char(date_trunc('day',sm.date), 'MM') as month, to_char(date_trunc('day',sm.date), 'YYYY-MM-DD') as day, avg(date(sm.date)-date(sm.create_date)) as day_diff, avg(date(sm.date_expected)-date(sm.create_date)) as day_diff1, avg(date(sm.date)-date(sm.date_expected)) as day_diff2, sm.location_id as location_id, sm.picking_id as picking_id, sm.company_id as company_id, sm.location_dest_id as location_dest_id, sum(sm.product_qty) as product_qty, sum( (CASE WHEN sp.type in ('out') THEN (sm.product_qty * pu.factor / pu2.factor) ELSE 0.0 END) ) as product_qty_out, sum( (CASE WHEN sp.type in ('in') THEN (sm.product_qty * pu.factor / pu2.factor) ELSE 0.0 END) ) as product_qty_in, sm.partner_id as partner_id, sm.product_id as product_id, sm.state as state, sm.product_uom as product_uom, pt.categ_id as categ_id , coalesce(sp.type, 'other') as type, sp.stock_journal_id AS stock_journal, sum( (CASE WHEN sp.type in ('in') THEN (sm.product_qty * pu.factor / pu2.factor) * pt.standard_price ELSE 0.0 END) - (CASE WHEN sp.type in ('out') THEN (sm.product_qty * pu.factor / pu2.factor) * pt.standard_price ELSE 0.0 END) ) as value FROM stock_move sm LEFT JOIN stock_picking sp ON (sm.picking_id=sp.id) LEFT JOIN product_product pp ON (sm.product_id=pp.id) LEFT JOIN product_uom pu ON (sm.product_uom=pu.id) LEFT JOIN product_uom pu2 ON (sm.product_uom=pu2.id) LEFT JOIN product_template pt ON (pp.product_tmpl_id=pt.id) GROUP BY coalesce(sp.type, 'other'), date_trunc('day', sm.date), sm.partner_id, sm.state, sm.product_uom, sm.date_expected, sm.product_id, pt.standard_price, sm.picking_id, sm.company_id, sm.location_id, sm.location_dest_id, pu.factor, pt.categ_id, sp.stock_journal_id, year, month, day ) """)
class protocollo_sender_receiver_wizard(osv.TransientModel): _name = 'protocollo.sender_receiver.wizard' def on_change_partner(self, cr, uid, ids, partner_id, context=None): values = {} if partner_id: partner = self.pool.get('res.partner'). \ browse(cr, uid, partner_id, context=context) values = { 'type': partner.is_company and 'individual' or 'legal', 'name': partner.name, 'street': partner.street, 'city': partner.city, 'country_id': partner.country_id and partner.country_id.id or False, 'email_from': partner.email, 'phone': partner.phone, 'mobile': partner.mobile, 'fax': partner.fax, 'zip': partner.zip, } return {'value': values} _columns = { # TODO: inserire anche AOO in type? 'wizard_id': fields.many2one('protocollo.pec.wizard', 'Crea Protocollo'), 'type': fields.selection( [ ('individual', 'Persona Fisica'), ('legal', 'Persona Giuridica'), ], 'Tipologia', size=32, required=True, ), 'partner_id': fields.many2one('res.partner', 'Anagrafica'), 'name': fields.char('Nome Cognome/Ragione Sociale', size=512, required=True), 'street': fields.char('Via/Piazza num civico', size=128), 'zip': fields.char('Cap', change_default=True, size=24), 'city': fields.char('Citta\'', size=128), 'country_id': fields.many2one('res.country', 'Paese'), 'email': fields.char('Email', size=240), 'pec_mail': fields.char('PEC', size=240, required=True, readonly=True), 'phone': fields.char('Telefono', size=64), 'fax': fields.char('Fax', size=64), 'mobile': fields.char('Cellulare', size=64), 'notes': fields.text('Note'), 'send_type': fields.many2one('protocollo.typology', 'Mezzo di Spedizione'), 'send_date': fields.date('Data Spedizione'), }
class rdm_reward_trans(osv.osv): _name = "rdm.reward.trans" _description = "Redemption Reward Transaction" def trans_reward_expired(self, cr, uid, ids, context=None): _logger.info('Start Reward Expired') id = ids[0] trans = self.get_trans(cr, uid, id, context) booking_expired_date = datetime.strptime(trans.booking_expired, '%Y-%m-%d') if trans.is_booking == True and booking_expired_date <= datetime.now(): values = {} values.update({'state': 'expired'}) self.write(cr, uid, ids, values, context=context) _logger.info('End Reward Expired') return True else: raise osv.except_osv(('Warning'), ('Transaction still active')) def check_reward_limit_count(self, cr, uid, customer_id, reward_id, context=None): reward = self.pool.get('rdm.reward').get_trans(cr, uid, [reward_id], context=context) if reward.limit_count == -1: return True else: #sql_req= "SELECT count(*) as total FROM rdm_reward_trans c WHERE c.customer_id=" + str(customer_id) + " AND c.reward_id=" + str(reward_id) + " AND c.trans_date='" + datetime.today().strftime('%Y-%m-%d') + "' AND c.state='done'" sql_req = "SELECT count(*) as total FROM rdm_reward_trans c WHERE c.customer_id=" + str( customer_id) + " AND c.reward_id=" + str( reward_id) + " AND c.state='done'" cr.execute(sql_req) sql_res = cr.dictfetchone() if sql_res: total = sql_res['total'] if total >= reward.limit_count: return False else: return True else: return False def check_reward_stock(self, cr, uid, reward_id, context=None): reward = self.pool.get('rdm.reward').get_trans(cr, uid, reward_id, context=context) if reward.stock > 0: return True else: return False def allow_redeem_reward(self, cr, uid, customer_id, reward_id, context=None): reward_config = self._reward_config(cr, uid, context) if reward_config.reward_limit_count == -1: return True else: limit_total = reward_config.reward_limit_count if reward_config.reward_limit: sql_req = "SELECT count(*) as total FROM rdm_reward_trans c WHERE c.customer_id=" + str( customer_id) + " AND c.trans_date='" + datetime.today( ).strftime('%Y-%m-%d') + "' AND c.state='done'" cr.execute(sql_req) sql_res = cr.dictfetchone() if sql_res: current_total = sql_res['total'] else: current_total = 0 _logger.info('Total Reward Trans : ' + str(current_total)) if current_total >= limit_total: return False else: return True if reward_config.reward_limit_product: sql_req = "SELECT count(*) as total FROM rdm_reward_trans c WHERE c.customer_id=" + str( customer_id) + " AND c.reward_id=" + str( reward_id) + " AND c.trans_date='" + datetime.today( ).strftime('%Y-%m-%d') + "' AND c.state='done'" cr.execute(sql_req) sql_res = cr.dictfetchone() if sql_res: current_total = sql_res['total'] else: current_total = 0 _logger.info('Total Reward Trans For Product : ' + str(current_total)) if current_total >= limit_total: return False else: return True def _reward_config(self, cr, uid, context=None): return self.pool.get('rdm.reward.config').get_config(cr, uid, context=context) def trans_close(self, cr, uid, ids, context=None): _logger.info("Close Transaction for ID : " + str(ids)) #Close Transaction self.write(cr, uid, ids, {'state': 'done'}, context=context) self._send_notification_to_customer(cr, uid, ids, context) return True def _update_print_status(self, cr, uid, ids, context=None): _logger.info("Start Update Print Status for ID : " + str(ids)) values = {} values.update({'bypass': True}) values.update({'method': '_update_print_status'}) values.update({'printed': True}) self.write(cr, uid, ids, values, context=context) _logger.info("End Update Print Status for ID : " + str(ids)) def trans_print_receipt(self, cr, uid, ids, context=None): _logger.info("Print Receipt for ID : " + str(ids)) trans_id = ids[0] serverUrl = 'http://' + reportserver + ':' + reportserverport + '/jasperserver' j_username = '******' j_password = '******' ParentFolderUri = '/rdm' reportUnit = '/rdm/trans_receipt' url = serverUrl + '/flow.html?_flowId=viewReportFlow&standAlone=true&_flowId=viewReportFlow&ParentFolderUri=' + ParentFolderUri + '&reportUnit=' + reportUnit + '&ID=' + str( trans_id ) + '&decorate=no&j_username='******'&j_password='******'&output=pdf' return { 'type': 'ir.actions.act_url', 'url': url, 'nodestroy': True, 'target': 'new' } def trans_re_print(self, cr, uid, ids, context=None): _logger.info("Re-Print Receipt for ID : " + str(ids)) trans_id = ids[0] trans = self._get_trans(cr, uid, trans_id, context) return True def trans_reset(self, cr, uid, ids, context=None): _logger.info("Start Reset for ID : " + str(ids)) values = {} values.update({'bypass': True}) values.update({'method': 'trans_reset'}) values.update({'state': 'open'}) self.write(cr, uid, ids, values, context=context) _logger.info("End Reset for ID : " + str(ids)) def onchange_reward_id(self, cr, uid, ids, reward_id, context=None): res = {} if reward_id: reward = self.pool.get('rdm.reward').browse(cr, uid, reward_id, context=context) res['point'] = reward.point return {'value': res} def onchange_is_booking(self, cr, uid, ids, is_booking, context=None): res = {} if is_booking == True: rdm_reward_config = self.pool.get('rdm.reward.config').get_config( cr, uid, context=context) expired_date = datetime.today() + timedelta( days=rdm_reward_config.reward_booking_expired_day) res['booking_expired'] = expired_date.strftime('%Y-%m-%d') else: res['booking_expired'] = None return {'value': res} def get_trans(self, cr, uid, trans_id, context=None): return self.browse(cr, uid, trans_id, context=context) def _get_reward(self, cr, uid, reward_id, context=None): reward = self.pool.get('rdm.reward').browse(cr, uid, reward_id, context=context) return reward def get_reward_usage(self, cr, uid, reward_id, context=None): _logger.info('Start Get Reward Usage') total = 0 sql_req = "SELECT count(*) as total FROM rdm_reward_trans WHERE reward_id=" + str( reward_id) + " AND state='done'" cr.execute(sql_req) sql_res = cr.dictfetchone() if sql_res is not None: if sql_res['total'] is not None: total = sql_res['total'] else: total_ = 0 _logger.info('End Get Reward Usage') return total def get_reward_booking(self, cr, uid, reward_id, context=None): _logger.info('Start Get Reward Booking') total = 0 sql_req = "SELECT count(*) as total FROM rdm_reward_trans WHERE is_booking=TRUE AND reward_id=" + str( reward_id) + " AND state='open'" cr.execute(sql_req) sql_res = cr.dictfetchone() if sql_res is not None: if sql_res['total'] is not None: total = sql_res['total'] else: total_ = 0 _logger.info('End Get Reward Booking') return total def process_reward_expired(self, cr, uid, context=None): _logger.info('Start Process Reward Expired') today = datetime.now() args = [('is_booking', '=', True), ('booking_expired', '<=', today.strftime('%Y-%m-%d'), ('state', '=', 'open'))] reward_trans_ids = self.search(cr, uid, args, context=context) values = {} values.update({'state': 'expired'}) self.write(cr, uid, reward_trans_ids, values, context=context) _logger.info('End Process Reward Expired') return True def _send_notification_to_customer(self, cr, uid, ids, context=None): _logger.info("Start Notification Process") trans_id = ids[0] trans = self.get_trans(cr, uid, trans_id, context) customer_id = trans.customer_id rdm_config = self.pool.get('rdm.config').get_config(cr, uid, context=context) rdm_reward_config = self.pool.get('rdm.reward.config').get_config( cr, uid, context=context) if rdm_config.enable_email and customer_id.receive_email: #Send Email _logger.info('Send Reward Transaction Notification') email_obj = self.pool.get('email.template') template_ids = rdm_reward_config.reward_trans_email_tmpl email = email_obj.browse(cr, uid, template_ids) email_obj.write( cr, uid, template_ids, { 'email_from': email.email_from, 'email_to': email.email_to, 'subject': email.subject, 'body_html': email.body_html, 'email_recipients': email.email_recipients }) email_obj.send_mail(cr, uid, template_ids, trans.id, True, context=context) return True def _send_booking_notitication_to_customer(self, cr, uid, ids, context=None): _logger.info("Start Booking Notification Process") trans_id = ids[0] trans = self.get_trans(cr, uid, trans_id, context) customer_id = trans.customer_id rdm_config = self.pool.get('rdm.config').get_config(cr, uid, context=context) rdm_reward_config = self.pool.get('rdm.reward.config').get_config( cr, uid, context=context) if rdm_config.enable_email and customer_id.receive_email: #Send Email _logger.info('Send Reward Booking Notification') email_obj = self.pool.get('email.template') template_ids = rdm_reward_config.reward_booking_email_tmpl email = email_obj.browse(cr, uid, template_ids) email_obj.write( cr, uid, template_ids, { 'email_from': email.email_from, 'email_to': email.email_to, 'subject': email.subject, 'body_html': email.body_html, 'email_recipients': email.email_recipients }) email_obj.send_mail(cr, uid, template_ids, trans.id, True, context=context) _logger.info("End Booking Notification Process") return True _columns = { 'trans_date': fields.date('Transaction Date', required=True, readonly=True), 'customer_id': fields.many2one('rdm.customer', 'Customer', required=True), 'reward_id': fields.many2one('rdm.reward', 'Reward', required=True), 'point': fields.integer('Point # Deduct', readonly=True), 'remarks': fields.text('Remarks'), 'is_booking': fields.boolean('Is Booking ?'), 'booking_expired': fields.date('Booking Expired'), 'printed': fields.boolean('Printed', readonly=True), 're_print': fields.integer('Re-Print'), 're_print_remarks': fields.text('Re-print Remarks'), 'state': fields.selection(AVAILABLE_STATES, 'Status', size=16, readonly=True), } _defaults = { 'trans_date': fields.date.context_today, 'state': lambda *a: 'draft', 'is_booking': lambda *a: False, 'printed': lambda *a: False, } def create(self, cr, uid, values, context=None): customer_id = values.get('customer_id') reward_id = values.get('reward_id') reward_stock = self.check_reward_stock(cr, uid, [reward_id], context=context) _logger.info("Reward Stock : " + str(reward_stock)) if not reward_stock: raise osv.except_osv(('Warning'), ('Reward has no stock')) check_reward_limit_count = self.check_reward_limit_count( cr, uid, customer_id, reward_id, context) if not check_reward_limit_count: raise osv.except_osv(('Warning'), ('Reward Limit Count Applied')) allow_redeem_reward = self.allow_redeem_reward(cr, uid, customer_id, reward_id, context=context) if not allow_redeem_reward: raise osv.except_osv(('Warning'), ('Redeem Limit Applied')) customer_id = self.pool.get('rdm.customer').get_trans(cr, uid, customer_id, context=context) reward = self._get_reward(cr, uid, reward_id, context) if customer_id.point < reward.point: raise osv.except_osv(('Warning'), ('Point not enough')) values.update({'point': reward.point}) values.update({'state': 'open'}) trans_id = super(rdm_reward_trans, self).create(cr, uid, values, context=context) if values.get('is_booking') == True: self.pool.get('rdm.customer.point').deduct_point( cr, uid, trans_id, customer_id.id, values.get('point'), context=context) self._send_booking_notitication_to_customer( cr, uid, [trans_id], context) return trans_id def write(self, cr, uid, ids, values, context=None): trans_id = ids[0] trans = self.get_trans(cr, uid, trans_id, context) if trans['state'] == 'done': #Modify Closed Transaction if values.get('bypass') == True: trans_data = {} if values.get('method') == 'trans_reset': trans_data.update({'state': values.get('state')}) if values.get('method') == 'trans_print_receipt': trans_data.update({'printed': values.get('printed')}) result = super(rdm_reward_trans, self).write(cr, uid, ids, trans_data, context=context) else: raise osv.except_osv( ('Warning'), ('Edit not allowed, Transaction already closed!')) else: #Close Transaction if values.get('state') == 'done': #Check Stock if not trans.is_booking: reward_id = trans.reward_id.id reward_stock = self.check_reward_stock( cr, uid, [reward_id], context) if not reward_stock: raise osv.except_osv(('Warning'), ('Reward has no stock')) #Close Transaction trans = self.get_trans(cr, uid, trans_id, context) result = super(rdm_reward_trans, self).write(cr, uid, ids, values, context=context) #Deduct Point customer_id = trans.customer_id.id #Deduct point if not booking transaction if not trans.is_booking: self.pool.get('rdm.customer.point').deduct_point( cr, uid, trans_id, customer_id, trans.point, context=context) #Expired Booking Transaction elif values.get('state') == 'expired': result = super(rdm_reward_trans, self).write(cr, uid, ids, values, context=context) #Other State else: trans = self.get_trans(cr, uid, trans_id, context) if 'customer_id' in values.keys(): customer_id = values.get('customer_id') else: customer_id = trans.customer_id.id if 'reward_id' in values.keys(): reward_id = values.get('reward_id') else: reward_id = trans.reward_id.id allow_redeem_reward = self.allow_redeem_reward(cr, uid, customer_id, reward_id, context=context) if allow_redeem_reward: customer = self.pool.get('rdm.customer').get_trans( cr, uid, customer_id, context=context) reward = self._get_reward(cr, uid, reward_id, context) if customer['point'] >= reward.point: values.update({'point': reward.point}) values.update({'state': 'open'}) result = super(rdm_reward_trans, self).write(cr, uid, [trans.id], values, context=context) else: raise osv.except_osv(('Warning'), ('Point not enough')) else: raise osv.except_osv(('Warning'), ('Redeem Limit Applied')) return result
class gamification_goal(osv.Model): """Goal instance for a user An individual goal for a user on a specified time period""" _name = 'gamification.goal' _description = 'Gamification goal instance' def _get_completion(self, cr, uid, ids, field_name, arg, context=None): """Return the percentage of completeness of the goal, between 0 and 100""" res = dict.fromkeys(ids, 0.0) for goal in self.browse(cr, uid, ids, context=context): if goal.definition_condition == 'higher': if goal.current >= goal.target_goal: res[goal.id] = 100.0 else: res[goal.id] = round(100.0 * goal.current / goal.target_goal, 2) elif goal.current < goal.target_goal: # a goal 'lower than' has only two values possible: 0 or 100% res[goal.id] = 100.0 else: res[goal.id] = 0.0 return res def on_change_definition_id(self, cr, uid, ids, definition_id=False, context=None): goal_definition = self.pool.get('gamification.goal.definition') if not definition_id: return {'value': {'definition_id': False}} goal_definition = goal_definition.browse(cr, uid, definition_id, context=context) return {'value': {'computation_mode': goal_definition.computation_mode, 'definition_condition': goal_definition.condition}} _columns = { 'definition_id': fields.many2one('gamification.goal.definition', string='Goal Definition', required=True, ondelete="cascade"), 'user_id': fields.many2one('res.users', string='User', required=True), 'line_id': fields.many2one('gamification.challenge.line', string='Challenge Line', ondelete="cascade"), 'challenge_id': fields.related('line_id', 'challenge_id', string="Challenge", type='many2one', relation='gamification.challenge', store=True, readonly=True, help="Challenge that generated the goal, assign challenge to users to generate goals with a value in this field."), 'start_date': fields.date('Start Date'), 'end_date': fields.date('End Date'), # no start and end = always active 'target_goal': fields.float('To Reach', required=True, track_visibility='always'), # no goal = global index 'current': fields.float('Current Value', required=True, track_visibility='always'), 'completeness': fields.function(_get_completion, type='float', string='Completeness'), 'state': fields.selection([ ('draft', 'Draft'), ('inprogress', 'In progress'), ('reached', 'Reached'), ('failed', 'Failed'), ('canceled', 'Canceled'), ], string='State', required=True, track_visibility='always'), 'to_update': fields.boolean('To update'), 'closed': fields.boolean('Closed goal', help="These goals will not be recomputed."), 'computation_mode': fields.related('definition_id', 'computation_mode', type='char', string="Computation mode"), 'remind_update_delay': fields.integer('Remind delay', help="The number of days after which the user assigned to a manual goal will be reminded. Never reminded if no value is specified."), 'last_update': fields.date('Last Update', help="In case of manual goal, reminders are sent if the goal as not been updated for a while (defined in challenge). Ignored in case of non-manual goal or goal not linked to a challenge."), 'definition_description': fields.related('definition_id', 'description', type='char', string='Definition Description', readonly=True), 'definition_condition': fields.related('definition_id', 'condition', type='char', string='Definition Condition', readonly=True), 'definition_suffix': fields.related('definition_id', 'full_suffix', type="char", string="Suffix", readonly=True), 'definition_display': fields.related('definition_id', 'display_mode', type="char", string="Display Mode", readonly=True), } _defaults = { 'current': 0, 'state': 'draft', 'start_date': fields.date.today, } _order = 'create_date desc, end_date desc, definition_id, id' def _check_remind_delay(self, cr, uid, goal, context=None): """Verify if a goal has not been updated for some time and send a reminder message of needed. :return: data to write on the goal object """ if goal.remind_update_delay and goal.last_update: delta_max = timedelta(days=goal.remind_update_delay) last_update = datetime.strptime(goal.last_update, DF).date() if date.today() - last_update > delta_max: # generate a remind report temp_obj = self.pool.get('email.template') template_id = self.pool['ir.model.data'].get_object(cr, uid, 'gamification', 'email_template_goal_reminder', context) body_html = temp_obj.render_template(cr, uid, template_id.body_html, 'gamification.goal', goal.id, context=context) self.pool['mail.thread'].message_post(cr, uid, 0, body=body_html, partner_ids=[goal.user_id.partner_id.id], context=context, subtype='mail.mt_comment') return {'to_update': True} return {} def update(self, cr, uid, ids, context=None): """Update the goals to recomputes values and change of states If a manual goal is not updated for enough time, the user will be reminded to do so (done only once, in 'inprogress' state). If a goal reaches the target value, the status is set to reached If the end date is passed (at least +1 day, time not considered) without the target value being reached, the goal is set as failed.""" if context is None: context = {} commit = context.get('commit_gamification', False) goals_by_definition = {} all_goals = {} for goal in self.browse(cr, uid, ids, context=context): if goal.state in ('draft', 'canceled'): # draft or canceled goals should not be recomputed continue goals_by_definition.setdefault(goal.definition_id, []).append(goal) all_goals[goal.id] = goal for definition, goals in goals_by_definition.items(): goals_to_write = dict((goal.id, {}) for goal in goals) if definition.computation_mode == 'manually': for goal in goals: goals_to_write[goal.id].update(self._check_remind_delay(cr, uid, goal, context)) elif definition.computation_mode == 'python': # TODO batch execution for goal in goals: # execute the chosen method cxt = { 'self': self.pool.get('gamification.goal'), 'object': goal, 'pool': self.pool, 'cr': cr, 'context': dict(context), # copy context to prevent side-effects of eval 'uid': uid, 'date': date, 'datetime': datetime, 'timedelta': timedelta, 'time': time } code = definition.compute_code.strip() safe_eval(code, cxt, mode="exec", nocopy=True) # the result of the evaluated codeis put in the 'result' local variable, propagated to the context result = cxt.get('result') if result is not None and type(result) in (float, int, long): if result != goal.current: goals_to_write[goal.id]['current'] = result else: _logger.exception(_('Invalid return content from the evaluation of code for definition %s' % definition.name)) else: # count or sum obj = self.pool.get(definition.model_id.model) field_date_name = definition.field_date_id and definition.field_date_id.name or False if definition.computation_mode == 'count' and definition.batch_mode: # batch mode, trying to do as much as possible in one request general_domain = safe_eval(definition.domain) field_name = definition.batch_distinctive_field.name subqueries = {} for goal in goals: start_date = field_date_name and goal.start_date or False end_date = field_date_name and goal.end_date or False subqueries.setdefault((start_date, end_date), {}).update({goal.id:safe_eval(definition.batch_user_expression, {'user': goal.user_id})}) # the global query should be split by time periods (especially for recurrent goals) for (start_date, end_date), query_goals in subqueries.items(): subquery_domain = list(general_domain) subquery_domain.append((field_name, 'in', list(set(query_goals.values())))) if start_date: subquery_domain.append((field_date_name, '>=', start_date)) if end_date: subquery_domain.append((field_date_name, '<=', end_date)) if field_name == 'id': # grouping on id does not work and is similar to search anyway user_ids = obj.search(cr, uid, subquery_domain, context=context) user_values = [{'id': user_id, 'id_count': 1} for user_id in user_ids] else: user_values = obj.read_group(cr, uid, subquery_domain, fields=[field_name], groupby=[field_name], context=context) # user_values has format of read_group: [{'partner_id': 42, 'partner_id_count': 3},...] for goal in [g for g in goals if g.id in query_goals.keys()]: for user_value in user_values: queried_value = field_name in user_value and user_value[field_name] or False if isinstance(queried_value, tuple) and len(queried_value) == 2 and isinstance(queried_value[0], (int, long)): queried_value = queried_value[0] if queried_value == query_goals[goal.id]: new_value = user_value.get(field_name+'_count', goal.current) if new_value != goal.current: goals_to_write[goal.id]['current'] = new_value else: for goal in goals: # eval the domain with user replaced by goal user object domain = safe_eval(definition.domain, {'user': goal.user_id}) # add temporal clause(s) to the domain if fields are filled on the goal if goal.start_date and field_date_name: domain.append((field_date_name, '>=', goal.start_date)) if goal.end_date and field_date_name: domain.append((field_date_name, '<=', goal.end_date)) if definition.computation_mode == 'sum': field_name = definition.field_id.name res = obj.read_group(cr, uid, domain, [field_name], [field_name], context=context) new_value = res and res[0][field_name] or 0.0 else: # computation mode = count new_value = obj.search(cr, uid, domain, context=context, count=True) # avoid useless write if the new value is the same as the old one if new_value != goal.current: goals_to_write[goal.id]['current'] = new_value for goal_id, value in goals_to_write.items(): if not value: continue goal = all_goals[goal_id] # check goal target reached if (goal.definition_condition == 'higher' and value.get('current', goal.current) >= goal.target_goal) \ or (goal.definition_condition == 'lower' and value.get('current', goal.current) <= goal.target_goal): value['state'] = 'reached' # check goal failure elif goal.end_date and fields.date.today() > goal.end_date: value['state'] = 'failed' value['closed'] = True if value: self.write(cr, uid, [goal.id], value, context=context) if commit: cr.commit() return True def action_start(self, cr, uid, ids, context=None): """Mark a goal as started. This should only be used when creating goals manually (in draft state)""" self.write(cr, uid, ids, {'state': 'inprogress'}, context=context) return self.update(cr, uid, ids, context=context) def action_reach(self, cr, uid, ids, context=None): """Mark a goal as reached. If the target goal condition is not met, the state will be reset to In Progress at the next goal update until the end date.""" return self.write(cr, uid, ids, {'state': 'reached'}, context=context) def action_fail(self, cr, uid, ids, context=None): """Set the state of the goal to failed. A failed goal will be ignored in future checks.""" return self.write(cr, uid, ids, {'state': 'failed'}, context=context) def action_cancel(self, cr, uid, ids, context=None): """Reset the completion after setting a goal as reached or failed. This is only the current state, if the date and/or target criterias match the conditions for a change of state, this will be applied at the next goal update.""" return self.write(cr, uid, ids, {'state': 'inprogress'}, context=context) def create(self, cr, uid, vals, context=None): """Overwrite the create method to add a 'no_remind_goal' field to True""" if context is None: context = {} context['no_remind_goal'] = True return super(gamification_goal, self).create(cr, uid, vals, context=context) def write(self, cr, uid, ids, vals, context=None): """Overwrite the write method to update the last_update field to today If the current value is changed and the report frequency is set to On change, a report is generated """ if context is None: context = {} vals['last_update'] = fields.date.today() result = super(gamification_goal, self).write(cr, uid, ids, vals, context=context) for goal in self.browse(cr, uid, ids, context=context): if goal.state != "draft" and ('definition_id' in vals or 'user_id' in vals): # avoid drag&drop in kanban view raise osv.except_osv(_('Error!'), _('Can not modify the configuration of a started goal')) if vals.get('current'): if 'no_remind_goal' in context: # new goals should not be reported continue if goal.challenge_id and goal.challenge_id.report_message_frequency == 'onchange': self.pool.get('gamification.challenge').report_progress(cr, SUPERUSER_ID, goal.challenge_id, users=[goal.user_id], context=context) return result def get_action(self, cr, uid, goal_id, context=None): """Get the ir.action related to update the goal In case of a manual goal, should return a wizard to update the value :return: action description in a dictionnary """ goal = self.browse(cr, uid, goal_id, context=context) if goal.definition_id.action_id: # open a the action linked to the goal action = goal.definition_id.action_id.read()[0] if goal.definition_id.res_id_field: current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context) action['res_id'] = safe_eval(goal.definition_id.res_id_field, {'user': current_user}) # if one element to display, should see it in form mode if possible action['views'] = [(view_id, mode) for (view_id, mode) in action['views'] if mode == 'form'] or action['views'] return action if goal.computation_mode == 'manually': # open a wizard window to update the value manually action = { 'name': _("Update %s") % goal.definition_id.name, 'id': goal_id, 'type': 'ir.actions.act_window', 'views': [[False, 'form']], 'target': 'new', 'context': {'default_goal_id': goal_id, 'default_current': goal.current}, 'res_model': 'gamification.goal.wizard' } return action return False
return result _columns = { 'name' : fields.char('Name', required=True), 'partner_id' : fields.many2one('res.partner','Principle',domain=[('supplier','=',True)],required=True), 'product_id' : fields.many2one('product.product','Bonus Product'), 'qty_2' : fields.float('Bonus Qty2', digits_compute=dp.get_precision('Product Unit of Measure')), 'qty' : fields.function(_qty_all_1,type="float",string='Bonus Qty',digits_compute=dp.get_precision('Product Unit of Measure')), 'uom_id' : fields.many2one('product.uom','UoM',required=True), 'uom_id2' : fields.many2one('product.uom','UoM',required=True), 'value' : fields.float('Price Value',domain=[('is_percent','=',False)]), 'per_product' : fields.boolean('Per Product'), 'persentase' : fields.float('Percent Value', digits_compute= dp.get_precision('Discount'),domain=[('is_percent','=',True)]), 'multi' : fields.boolean('Multiples'), 'is_active' : fields.boolean('Active?'), 'date_from' : fields.date('Start Date', required=True), 'date_to' : fields.date('End Date', required=True), 'condition_ids' : fields.one2many('master.condition','discount_id','Value Condition'), 'condition2_ids' : fields.one2many('master.condition2','discount_id','Product Condition'), 'condition3_ids' : fields.one2many('master.condition3','discount_id','Product Condition 2'), 'condition4_ids' : fields.one2many('master.condition4','discount_id','Product Condition 3'), 'condition5_ids' : fields.one2many('master.condition5','discount_id','Product Condition 4'), 'group_price_ids' : fields.many2many('res.partner.category', id1='discount_id', id2='category_id', string='Group Price Category'), 'is_percent' : fields.boolean('Is Percent'), 'is_flat' : fields.boolean('Flat'), 'type' :fields.selection([('regular','Regular Discount'),('promo','Promo Discount'),('extra','Extra Discount'),('cash','Cash Discount'),('mix','Mix Discount')],string='Type Discount',required=True), 'min_qty_product' : fields.float('Min. Product Item',digits_compute=dp.get_precision('Product Unit of Measure')), 'multi2' : fields.boolean('Value Condition'), 'multi3' : fields.boolean('Multiples for New Product'), # 'multi_sel' : fields.selection([('general','General Multiples'),('specific','Specific Multiples for New Product')],string="Multiples"), 'product_id2' : fields.many2one('product.product','Bonus New Product'),
resu[order.id] = clock_ids_exist except Exception,e: traceback.print_exc() pass return resu _columns = { 'employee_id': fields.many2one('hr.employee', 'Employee', required=True, select=True), 'department_id':fields.related('employee_id','department_id', type='many2one', relation='hr.department', string='Department', store=True), 'job_id':fields.related('employee_id','job_id', type='many2one', relation='hr.job', string='Title', store=True), 'emp_code':fields.related('employee_id','emp_code', type='char', string='Employee Code', store=True), 'mobile_phone':fields.related('employee_id','mobile_phone', type='char', string='Work Mobile', store=True), 'borrow_money_residual':fields.related('employee_id','money_residual', type='float', string='Borrowed residual', readonly=True), 'dimmission_reason':fields.text('Dimission Reason', required=True), 'advice_to_company':fields.text('Advice to company'), 'employment_start':fields.date('Employment Started'), 'date_request':fields.date('Request Date', required=True), 'date_done':fields.date('Done Date', required=False, readonly=True), 'approve_ids': fields.one2many('hr.dimission.item', 'dimission_id', 'Approvals', domain=[('type','=','approve')]), 'transfer_ids': fields.one2many('hr.dimission.item', 'dimission_id', 'Transfers', domain=[('type','=','transfer')]), 'payslip_id': fields.many2many('hr.emppay', string='Payslip'), 'attrpt_ids': fields.many2many('hr.rpt.attend.month', string='Attendance Reports'), 'hr_clock_ids': fields.function(_emp_clocks, string='HR Clocks', type='many2many', relation='hr.clock', readonly=True), 'attachment_lines': fields.one2many('ir.attachment', 'hr_admission_id','Attachment'), 'company_id':fields.many2one('res.company', 'Company', required=True), 'state': fields.selection([ ('draft', 'Draft'), ('in_progress', 'In Progress'),
class cuti_kuliah(osv.Model): _name = 'cuti.kuliah' _columns = { 'name': fields.char('Kode Cuti', size=36, required=True), 'partner_id': fields.many2one('res.partner', 'Mahasiswa', required=True, readonly=True, domain="[('status_mahasiswa','=','Mahasiswa')]"), 'from_semester_id': fields.many2one('master.semester', 'Dari Semester', required=True), 'to_semester_id': fields.many2one('master.semester', 'Sampai Semester', required=True), 'kelas_id': fields.many2one('master.kelas', string='Kelas', required=False), 'prodi_id': fields.many2one('master.prodi', 'Program Studi', required=True), # 'jurusan_id':fields.many2one('master.jurusan','Jurusan',required=True,readonly=True, states={'draft': [('readonly', False)]}), 'fakultas_id': fields.many2one('master.fakultas', 'Fakultas', required=True), 'tahun_ajaran_id': fields.many2one('academic.year', 'Angkatan', required=True), 'state': fields.selection([('draft', 'Draft'), ('waiting', 'Waiting Approval'), ('confirm', 'Confirmed'), ('cancel', 'Canceled'), ('refuse', 'Refused'), ('done', 'Done')], 'Status'), 'notes': fields.text('Alasan', required=True), 'user_id': fields.many2one('res.users', 'User', readonly=True), 'date': fields.date('Tanggal Aktif Kembali'), 'automatic_done': fields.boolean('Automatic Done'), } _defaults = { 'state': 'draft', 'user_id': lambda obj, cr, uid, context: uid, 'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get( cr, uid, 'cuti.kuliah'), } _sql_constraints = [('name_uniq', 'unique(name)', 'Kode cuti kuliah tidak boleh sama')] # def onchange_partner(self, cr, uid, ids, tahun_ajaran_id, fakultas_id, jurusan_id, prodi_id, kelas_id, partner_id, context=None): def onchange_partner(self, cr, uid, ids, tahun_ajaran_id, fakultas_id, prodi_id, kelas_id, partner_id, context=None): results = {} if not partner_id: return results par_obj = self.pool.get('res.partner') par_ids = par_obj.search(cr, uid, [('id', '=', partner_id)], context=context) #import pdb;pdb.set_trace() par_id = par_obj.browse(cr, uid, par_ids, context=context)[0] kelas_id = par_id.kelas_id.id tahun_ajaran_id = par_id.tahun_ajaran_id.id fakultas_id = par_id.fakultas_id.id # jurusan_id = par_id.jurusan_id.id prodi_id = par_id.prodi_id.id results = { 'value': { 'kelas_id': kelas_id, 'tahun_ajaran_id': tahun_ajaran_id, 'fakultas_id': fakultas_id, # 'jurusan_id' : jurusan_id, 'prodi_id': prodi_id, } } return results def confirm(self, cr, uid, ids, context=None): for ct in self.browse(cr, uid, ids): self.write(cr, uid, ct.id, {'state': 'waiting'}, context=context) return True def approve(self, cr, uid, ids, context=None): for ct in self.browse(cr, uid, ids): mhs_id = ct.partner_id.id self.pool.get('res.partner').write(cr, uid, mhs_id, {'status_mahasiswa': 'cuti'}, context=context) self.write(cr, uid, ct.id, {'state': 'confirm'}, context=context) return True def cancel(self, cr, uid, ids, context=None): for ct in self.browse(cr, uid, ids): self.write(cr, uid, ct.id, {'state': 'cancel'}, context=context) return True def set_draft(self, cr, uid, ids, context=None): for ct in self.browse(cr, uid, ids): self.write(cr, uid, ct.id, {'state': 'draft'}, context=context) return True def refuse(self, cr, uid, ids, context=None): for ct in self.browse(cr, uid, ids): self.write(cr, uid, ct.id, {'state': 'refuse'}, context=context) return True def done(self, cr, uid, ids, context=None): for ct in self.browse(cr, uid, ids): mhs_id = ct.partner_id.id self.pool.get('res.partner').write( cr, uid, mhs_id, {'status_mahasiswa': 'Mahasiswa'}, context=context) self.write(cr, uid, ct.id, {'state': 'done'}, context=context) return True def unlink(self, cr, uid, ids, context=None): if context is None: context = {} """Allows to delete in draft state""" for rec in self.browse(cr, uid, ids, context=context): if rec.state != 'draft': raise osv.except_osv( _('Error!'), _('Data yang dapat dihapus hanya yang berstatus draft')) return super(cuti_kuliah, self).unlink(cr, uid, ids, context=context) #################################################################################################### # Cron Job untuk activate otomatis mahasiswa yang habis masa cutinya #################################################################################################### def cron_aktivasi_cuti_mahasiswa(self, cr, uid, ids=None, context=None): partner_obj = self.pool.get('res.partner') #import pdb;pdb.set_trace() mahasiswa_cuti = self.search( cr, uid, [('date', '=', time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)[:10]), ('state', '=', 'confirm'), ('automatic_done', '=', True)], context=context) if mahasiswa_cuti: for mhs in self.browse(cr, uid, mahasiswa_cuti): self.write(cr, uid, mhs.id, {'state': 'done'}) partner_obj.write(cr, uid, mhs.partner_id.id, {'status_mahasiswa': 'Mahasiswa'}) return True #################################################################################################### # Cron Job untuk generate cuti jika mahasiswa telat bayar uang ujian (UAS) #################################################################################################### def cron_cuti_mahasiswa_karena_nunggak(self, cr, uid, ids=None, context=None): partner_obj = self.pool.get('res.partner') invoice_obj = self.pool.get('account.invoice') event_obj = self.pool.get('event.event') now = time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) date_now = datetime.strptime(now[:10], "%Y-%m-%d") start_date = date_now.strftime("%Y-%m-%d 00:00:00") start_end = date_now.strftime("%Y-%m-%d 23:59:59") event_exist = event_obj.search(cr, uid, [('date_begin', '>=', start_date), ('date_begin', '<=', start_end), ('state', '=', 'confirm')]) if event_exist: mahasiswa_nunggak = invoice_obj.search( cr, uid, [('date_invoice', '=', now[:10]), ('state', '=', 'open'), ('krs_id', '!=', False)]) if mahasiswa_nunggak: mhs_ids = [] for inv in invoice_obj.browse(cr, uid, mahasiswa_nunggak): if inv.id not in mhs_ids: mhs_ids.append(inv.partner_id.id) self.create( cr, uid, { 'partner_id': inv.partner_id.id, 'tahun_ajaran_id': inv.partner_id.tahun_ajaran_id.id, 'fakultas_id': inv.partner_id.fakultas_id.id, 'prodi_id': inv.partner_id.prodi_id.id, 'kelas_id': inv.partner_id.kelas_id.id or False, 'state': 'confirm', 'notes': 'Ada tunggakan invoice ' + str(inv.number), 'from_semester_id': inv.krs_id.semester_id.id, 'to_semester_id': 8 }) partner_obj.write(cr, uid, inv.partner_id.id, {'status_mahasiswa': 'cuti'}) invoice_obj.write( cr, uid, inv.id, { 'comment': 'Mahasiswa ini sedang dicutikan oleh sistem karena ada keterlambatan pembayaran atas invoice ini' }) return True
'physical_location_id': kail.location_id.id if kail.location_id else False, 'usedtime': kail.date, 'remarks': kail.remarks } kail.asset_id.write({'asset_usage_ids':[(0,0, create_data)]}) kail.write({'state':'done'}) except Exception, e: kail.write({'reason':e}) done = False if done: kai.write({'state':'done'}) pass IMPORT_TYPE = (('lq','Liquidation'),('usage','Usage'),('spec','Specification')) _columns={ 'name':fields.date("Import Date", states={'done':[('readonly',True)]}, required=True), 'remarks':fields.char('Remarks',size=256, states={'done':[('readonly',True)]}), 'state':fields.selection((('draft','Draft'),('done','Completed')),'State',readonly=True), 'detail_ids':fields.one2many('kderp.import.asset.detail','import_id','Details',states={'done':[('readonly',True)]}), 'detail_spec_ids':fields.one2many('kderp.import.asset.detail','import_id','Details',states={'done':[('readonly',True)]}), 'detail_usage_ids':fields.one2many('kderp.import.asset.detail','import_id','Details',states={'done':[('readonly',True)]}), 'import_type':fields.selection(IMPORT_TYPE,'Import type',states={'done':[('readonly',True)]}), } _defaults={ 'name':lambda *a: time.strftime('%Y-%m-%d'), 'state':lambda *a: 'draft' }
class purchase_order_rate_currency(osv.osv): _inherit = 'purchase.order' def _get_currency_default(self, cr, uid, ids, context=None): if context is None: context = {} res_company = self.pool.get('res.company') company_default = res_company._company_default_get(cr, uid, context=context) company_currency_id = res_company.browse(cr, uid, company_default).currency_id.id return company_currency_id _columns = { 'date_currency': fields.date('Fecha Tasa de Cambio'), 'res_currency_rate': fields.float('Tasa de cambio', digits=(6,6), readonly = True), 'company_currency_id_default': fields.many2one('res.currency', string='Moneda por defecto de la compañia', store=False), 'flag_currency': fields.boolean('Bandera de seleccion de tasa', store=False), } _defaults = { 'company_currency_id_default': _get_currency_default, 'flag_currency': False } def onchange_pricelist_id(self, cr, uid, ids, pricelist_id, company_currency_id_default, context=None): if not context: context = {} if not pricelist_id: return False res = {} currency_id = self.pool.get('product.pricelist').browse(cr, uid, pricelist_id, context).currency_id.id if currency_id: res = {'value': {'currency_id': currency_id, 'flag_currency': False}} if currency_id != company_currency_id_default: res['value'].update({'flag_currency': True}) return res def onchange_date_currency(self, cr, uid, ids, date_currency, currency_id, company_currency_id_default, context=None): ctx = isinstance(context, dict) and context.copy() or {} val = {'date_currency': False, 'res_currency_rate': False} warn = {} if currency_id and currency_id != company_currency_id_default: currency_rate_obj = self.pool.get('res.currency.rate') rate_list_ids = currency_rate_obj.search(cr, uid, [('currency_id','=', currency_id),('name','ilike', str(date_currency) + '%')]) if len(rate_list_ids) > 1: warn = {'title': 'Error de Validacion', 'message': 'Se encontro mas de una tasa para la fecha especificada. Debe haber solo una tasa por dia. Comuniquese con el departamento de Contabilidad'} elif len(rate_list_ids) == 1: rate_id = currency_rate_obj.browse(cr, uid, rate_list_ids[0], ctx) if rate_id.rate > 0.0: val.update({'date_currency': date_currency, 'res_currency_rate': rate_id.rate}) else: warn = {'title': 'Error de Validacion', 'message': 'La tasa registrada en la fecha indicada no es válida, se le recomienda contactar al departamento de contabilidad'} elif len(rate_list_ids) == 0: warn = {'title': 'Error de Validacion', 'message': 'La fecha ingresada no esta registrada en la moneda configurada en la tarifa de compra. Seleccione una fecha distinta o contacte al departamento de Contabilidad'} return {'value': val, 'warning': warn} def action_invoice_create(self, cr, uid, ids, context=None): if not context: context = {} res = super(purchase_order_rate_currency, self).action_invoice_create(cr, uid, ids, context=context) if res: inv_brw = self.pool.get('account.invoice').browse(cr, uid, res, context=context) date_c = self.browse(cr, uid, ids[0], context).date_currency rate = self.browse(cr, uid, ids[0], context).res_currency_rate inv_brw.write({'date_currency': date_c, 'res_currency_rate': rate, 'flag_currency': True}) return res
class sale_order_line(orm.Model): _inherit = "sale.order.line" _columns = { 'wanted_date': fields.date('Wanted date'), }
class hr_expense_expense(osv.osv): def _amount(self, cr, uid, ids, field_name, arg, context=None): res= {} for expense in self.browse(cr, uid, ids, context=context): total = 0.0 for line in expense.line_ids: total += line.unit_amount * line.unit_quantity res[expense.id] = total return res def _get_expense_from_line(self, cr, uid, ids, context=None): return [line.expense_id.id for line in self.pool.get('hr.expense.line').browse(cr, uid, ids, context=context)] def _get_currency(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, [uid], context=context)[0] return user.company_id.currency_id.id _name = "hr.expense.expense" _inherit = ['mail.thread'] _description = "Expense" _order = "id desc" _track = { 'state': { 'hr_expense.mt_expense_approved': lambda self, cr, uid, obj, ctx=None: obj.state == 'accepted', 'hr_expense.mt_expense_refused': lambda self, cr, uid, obj, ctx=None: obj.state == 'cancelled', 'hr_expense.mt_expense_confirmed': lambda self, cr, uid, obj, ctx=None: obj.state == 'confirm', }, } _columns = { 'name': fields.char('Description', size=128, required=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'id': fields.integer('Sheet ID', readonly=True), 'date': fields.date('Date', select=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'journal_id': fields.many2one('account.journal', 'Force Journal', help = "The journal used when the expense is done."), 'employee_id': fields.many2one('hr.employee', "Employee", required=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'user_id': fields.many2one('res.users', 'User', required=True), 'date_confirm': fields.date('Confirmation Date', select=True, help="Date of the confirmation of the sheet expense. It's filled when the button Confirm is pressed."), 'date_valid': fields.date('Validation Date', select=True, help="Date of the acceptation of the sheet expense. It's filled when the button Accept is pressed."), 'user_valid': fields.many2one('res.users', 'Validation By', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'account_move_id': fields.many2one('account.move', 'Ledger Posting'), 'line_ids': fields.one2many('hr.expense.line', 'expense_id', 'Expense Lines', readonly=True, states={'draft':[('readonly',False)]} ), 'note': fields.text('Note'), 'amount': fields.function(_amount, string='Total Amount', digits_compute=dp.get_precision('Account'), store={ 'hr.expense.line': (_get_expense_from_line, ['unit_amount','unit_quantity'], 10) }), 'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'department_id':fields.many2one('hr.department','Department', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'company_id': fields.many2one('res.company', 'Company', required=True), 'state': fields.selection([ ('draft', 'New'), ('cancelled', 'Refused'), ('confirm', 'Waiting Approval'), ('accepted', 'Approved'), ('done', 'Waiting Payment'), ('paid', 'Paid'), ], 'Status', readonly=True, track_visibility='onchange', help='When the expense request is created the status is \'Draft\'.\n It is confirmed by the user and request is sent to admin, the status is \'Waiting Confirmation\'.\ \nIf the admin accepts it, the status is \'Accepted\'.\n If the accounting entries are made for the expense request, the status is \'Waiting Payment\'.'), } _defaults = { 'company_id': lambda s, cr, uid, c: s.pool.get('res.company')._company_default_get(cr, uid, 'hr.employee', context=c), 'date': fields.date.context_today, 'state': 'draft', 'employee_id': _employee_get, 'user_id': lambda cr, uid, id, c={}: id, 'currency_id': _get_currency, } def copy(self, cr, uid, id, default=None, context=None): if default is None: default = {} default.update( account_move_id=False, date_confirm=False, date_valid=False, user_valid=False) return super(hr_expense_expense, self).copy(cr, uid, id, default=default, context=context) def unlink(self, cr, uid, ids, context=None): for rec in self.browse(cr, uid, ids, context=context): if rec.state != 'draft': raise osv.except_osv(_('Warning!'),_('You can only delete draft expenses!')) return super(hr_expense_expense, self).unlink(cr, uid, ids, context) def onchange_currency_id(self, cr, uid, ids, currency_id=False, company_id=False, context=None): res = {'value': {'journal_id': False}} journal_ids = self.pool.get('account.journal').search(cr, uid, [('type','=','purchase'), ('currency','=',currency_id), ('company_id', '=', company_id)], context=context) if journal_ids: res['value']['journal_id'] = journal_ids[0] return res def onchange_employee_id(self, cr, uid, ids, employee_id, context=None): emp_obj = self.pool.get('hr.employee') department_id = False company_id = False if employee_id: employee = emp_obj.browse(cr, uid, employee_id, context=context) department_id = employee.department_id.id company_id = employee.company_id.id return {'value': {'department_id': department_id, 'company_id': company_id}} def expense_confirm(self, cr, uid, ids, context=None): for expense in self.browse(cr, uid, ids): if expense.employee_id and expense.employee_id.parent_id.user_id: self.message_subscribe_users(cr, uid, [expense.id], user_ids=[expense.employee_id.parent_id.user_id.id]) return self.write(cr, uid, ids, {'state': 'confirm', 'date_confirm': time.strftime('%Y-%m-%d')}, context=context) def expense_accept(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'accepted', 'date_valid': time.strftime('%Y-%m-%d'), 'user_valid': uid}, context=context) def expense_canceled(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'cancelled'}, context=context) def account_move_get(self, cr, uid, expense_id, context=None): ''' This method prepare the creation of the account move related to the given expense. :param expense_id: Id of expense for which we are creating account_move. :return: mapping between fieldname and value of account move to create :rtype: dict ''' journal_obj = self.pool.get('account.journal') expense = self.browse(cr, uid, expense_id, context=context) company_id = expense.company_id.id date = expense.date_confirm ref = expense.name journal_id = False if expense.journal_id: journal_id = expense.journal_id.id else: journal_id = journal_obj.search(cr, uid, [('type', '=', 'purchase'), ('company_id', '=', company_id)]) if not journal_id: raise osv.except_osv(_('Error!'), _("No expense journal found. Please make sure you have a journal with type 'purchase' configured.")) journal_id = journal_id[0] return self.pool.get('account.move').account_move_prepare(cr, uid, journal_id, date=date, ref=ref, company_id=company_id, context=context) def line_get_convert(self, cr, uid, x, part, date, context=None): partner_id = self.pool.get('res.partner')._find_accounting_partner(part).id return { 'date_maturity': x.get('date_maturity', False), 'partner_id': partner_id, 'name': x['name'][:64], 'date': date, 'debit': x['price']>0 and x['price'], 'credit': x['price']<0 and -x['price'], 'account_id': x['account_id'], 'analytic_lines': x.get('analytic_lines', False), 'amount_currency': x['price']>0 and abs(x.get('amount_currency', False)) or -abs(x.get('amount_currency', False)), 'currency_id': x.get('currency_id', False), 'tax_code_id': x.get('tax_code_id', False), 'tax_amount': x.get('tax_amount', False), 'ref': x.get('ref', False), 'quantity': x.get('quantity',1.00), 'product_id': x.get('product_id', False), 'product_uom_id': x.get('uos_id', False), 'analytic_account_id': x.get('account_analytic_id', False), } def compute_expense_totals(self, cr, uid, exp, company_currency, ref, account_move_lines, context=None): ''' internal method used for computation of total amount of an expense in the company currency and in the expense currency, given the account_move_lines that will be created. It also do some small transformations at these account_move_lines (for multi-currency purposes) :param account_move_lines: list of dict :rtype: tuple of 3 elements (a, b ,c) a: total in company currency b: total in hr.expense currency c: account_move_lines potentially modified ''' cur_obj = self.pool.get('res.currency') if context is None: context={} context.update({'date': exp.date_confirm or time.strftime('%Y-%m-%d')}) total = 0.0 total_currency = 0.0 for i in account_move_lines: if exp.currency_id.id != company_currency: i['currency_id'] = exp.currency_id.id i['amount_currency'] = i['price'] i['price'] = cur_obj.compute(cr, uid, exp.currency_id.id, company_currency, i['price'], context=context) else: i['amount_currency'] = False i['currency_id'] = False total -= i['price'] total_currency -= i['amount_currency'] or i['price'] return total, total_currency, account_move_lines def action_move_create(self, cr, uid, ids, context=None): ''' main function that is called when trying to create the accounting entries related to an expense ''' move_obj = self.pool.get('account.move') for exp in self.browse(cr, uid, ids, context=context): if not exp.employee_id.address_home_id: raise osv.except_osv(_('Error!'), _('The employee must have a home address.')) if not exp.employee_id.address_home_id.property_account_payable.id: raise osv.except_osv(_('Error!'), _('The employee must have a payable account set on his home address.')) company_currency = exp.company_id.currency_id.id diff_currency_p = exp.currency_id.id <> company_currency #create the move that will contain the accounting entries move_id = move_obj.create(cr, uid, self.account_move_get(cr, uid, exp.id, context=context), context=context) #one account.move.line per expense line (+taxes..) eml = self.move_line_get(cr, uid, exp.id, context=context) #create one more move line, a counterline for the total on payable account total, total_currency, eml = self.compute_expense_totals(cr, uid, exp, company_currency, exp.name, eml, context=context) acc = exp.employee_id.address_home_id.property_account_payable.id eml.append({ 'type': 'dest', 'name': '/', 'price': total, 'account_id': acc, 'date_maturity': exp.date_confirm, 'amount_currency': diff_currency_p and total_currency or False, 'currency_id': diff_currency_p and exp.currency_id.id or False, 'ref': exp.name }) #convert eml into an osv-valid format lines = map(lambda x:(0,0,self.line_get_convert(cr, uid, x, exp.employee_id.address_home_id, exp.date_confirm, context=context)), eml) journal_id = move_obj.browse(cr, uid, move_id, context).journal_id # post the journal entry if 'Skip 'Draft' State for Manual Entries' is checked if journal_id.entry_posted: move_obj.button_validate(cr, uid, [move_id], context) move_obj.write(cr, uid, [move_id], {'line_id': lines}, context=context) self.write(cr, uid, ids, {'account_move_id': move_id, 'state': 'done'}, context=context) return True def move_line_get(self, cr, uid, expense_id, context=None): res = [] tax_obj = self.pool.get('account.tax') cur_obj = self.pool.get('res.currency') if context is None: context = {} exp = self.browse(cr, uid, expense_id, context=context) company_currency = exp.company_id.currency_id.id for line in exp.line_ids: mres = self.move_line_get_item(cr, uid, line, context) if not mres: continue res.append(mres) tax_code_found= False #Calculate tax according to default tax on product taxes = [] #Taken from product_id_onchange in account.invoice if line.product_id: fposition_id = False fpos_obj = self.pool.get('account.fiscal.position') fpos = fposition_id and fpos_obj.browse(cr, uid, fposition_id, context=context) or False product = line.product_id taxes = product.supplier_taxes_id #If taxes are not related to the product, maybe they are in the account if not taxes: a = product.property_account_expense.id #Why is not there a check here? if not a: a = product.categ_id.property_account_expense_categ.id a = fpos_obj.map_account(cr, uid, fpos, a) taxes = a and self.pool.get('account.account').browse(cr, uid, a, context=context).tax_ids or False tax_id = fpos_obj.map_tax(cr, uid, fpos, taxes) if not taxes: continue #Calculating tax on the line and creating move? for tax in tax_obj.compute_all(cr, uid, taxes, line.unit_amount , line.unit_quantity, line.product_id, exp.user_id.partner_id)['taxes']: tax_code_id = tax['base_code_id'] tax_amount = line.total_amount * tax['base_sign'] if tax_code_found: if not tax_code_id: continue res.append(self.move_line_get_item(cr, uid, line, context)) res[-1]['price'] = 0.0 res[-1]['account_analytic_id'] = False elif not tax_code_id: continue tax_code_found = True res[-1]['tax_code_id'] = tax_code_id res[-1]['tax_amount'] = cur_obj.compute(cr, uid, exp.currency_id.id, company_currency, tax_amount, context={'date': exp.date_confirm}) ## is_price_include = tax_obj.read(cr,uid,tax['id'],['price_include'],context)['price_include'] if is_price_include: ## We need to deduce the price for the tax res[-1]['price'] = res[-1]['price'] - (tax['amount'] * tax['base_sign'] or 0.0) assoc_tax = { 'type':'tax', 'name':tax['name'], 'price_unit': tax['price_unit'], 'quantity': 1, 'price': tax['amount'] * tax['base_sign'] or 0.0, 'account_id': tax['account_collected_id'] or mres['account_id'], 'tax_code_id': tax['tax_code_id'], 'tax_amount': tax['amount'] * tax['base_sign'], } res.append(assoc_tax) return res def move_line_get_item(self, cr, uid, line, context=None): company = line.expense_id.company_id property_obj = self.pool.get('ir.property') if line.product_id: acc = line.product_id.property_account_expense if not acc: acc = line.product_id.categ_id.property_account_expense_categ if not acc: raise osv.except_osv(_('Error!'), _('No purchase account found for the product %s (or for his category), please configure one.') % (line.product_id.name)) else: acc = property_obj.get(cr, uid, 'property_account_expense_categ', 'product.category', context={'force_company': company.id}) if not acc: raise osv.except_osv(_('Error!'), _('Please configure Default Expense account for Product purchase: `property_account_expense_categ`.')) return { 'type':'src', 'name': line.name.split('\n')[0][:64], 'price_unit':line.unit_amount, 'quantity':line.unit_quantity, 'price':line.total_amount, 'account_id':acc.id, 'product_id':line.product_id.id, 'uos_id':line.uom_id.id, 'account_analytic_id':line.analytic_account.id, } def action_view_move(self, cr, uid, ids, context=None): ''' This function returns an action that display existing account.move of given expense ids. ''' assert len(ids) == 1, 'This option should only be used for a single id at a time' expense = self.browse(cr, uid, ids[0], context=context) assert expense.account_move_id try: dummy, view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'view_move_form') except ValueError, e: view_id = False result = { 'name': _('Expense Account Move'), 'view_type': 'form', 'view_mode': 'form', 'view_id': view_id, 'res_model': 'account.move', 'type': 'ir.actions.act_window', 'nodestroy': True, 'target': 'current', 'res_id': expense.account_move_id.id, } return result
class tms_advance(osv.osv): _name = 'tms.advance' _inherit = ['mail.thread', 'ir.needaction_mixin'] _description = 'Money advance payments for Travel expenses' def _paid(self, cr, uid, ids, field_name, args, context=None): res = {} for record in self.browse(cr, uid, ids, context=context): val = False if record.move_id.id: for ml in record.move_id.line_id: if ml.credit > 0 and record.employee_id.address_home_id.id == ml.partner_id.id: val = (ml.reconcile_id.id or ml.reconcile_partial_id.id) res[record.id] = val return res def _amount(self, cr, uid, ids, field_name, args, context=None): res = {} for record in self.browse(cr, uid, ids, context=context): tax_factor = 0.00 for line in record.product_id.supplier_taxes_id: tax_factor = ( tax_factor + line.amount) if line.amount != 0.0 else tax_factor subtotal = record.price_unit * record.product_uom_qty tax_amount = subtotal * tax_factor res[record.id] = { 'subtotal': subtotal, 'tax_amount': tax_amount, #'total' : total, } return res def _get_move_line_from_reconcile(self, cr, uid, ids, context=None): move = {} for r in self.pool.get('account.move.reconcile').browse( cr, uid, ids, context=context): for line in r.line_partial_ids: move[line.move_id.id] = True for line in r.line_id: move[line.move_id.id] = True advance_ids = [] if move: advance_ids = self.pool.get('tms.advance').search( cr, uid, [('move_id', 'in', move.keys())], context=context) return advance_ids _columns = { 'operation_id': fields.many2one('tms.operation', 'Operation', ondelete='restrict', required=False, readonly=False, states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), 'name': fields.char('Anticipo', size=64, required=False), 'state': fields.selection([('draft', 'Draft'), ('approved', 'Approved'), ('confirmed', 'Confirmed'), ('closed', 'Closed'), ('cancel', 'Cancelled')], 'State', readonly=True), 'date': fields.date('Date', states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }, required=True), 'travel_id': fields.many2one('tms.travel', 'Travel', required=True, states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), 'unit_id': fields.related('travel_id', 'unit_id', type='many2one', relation='fleet.vehicle', string='Unit', store=True, readonly=True), 'employee1_id': fields.related('travel_id', 'employee_id', type='many2one', relation='hr.employee', string='Driver', store=True, readonly=True), 'employee2_id': fields.related('travel_id', 'employee2_id', type='many2one', relation='hr.employee', string='Driver Helper', store=True, readonly=True), 'employee_id': fields.many2one('hr.employee', 'Driver', states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }, required=True), 'shop_id': fields.many2one('sale.shop', string='Shop'), 'product_id': fields.many2one('product.product', 'Product', domain=[('purchase_ok', '=', 1), ('tms_category', '=', 'real_expense')], required=True, states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }, ondelete='restrict'), 'product_uom_qty': fields.float('Quantity', digits=(16, 4), required=True, states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), 'product_uom': fields.many2one('product.uom', 'Unit of Measure ', required=True, states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), 'price_unit': fields.float('Price Unit', required=True, digits_compute=dp.get_precision('Sale Price')), 'price_unit_control': fields.float('Price Unit', digits_compute=dp.get_precision('Sale Price'), readonly=True), 'subtotal': fields.function(_amount, method=True, string='Subtotal', type='float', digits_compute=dp.get_precision('Sale Price'), multi=True, store=True), 'tax_amount': fields.function(_amount, method=True, string='Tax Amount', type='float', digits_compute=dp.get_precision('Sale Price'), multi=True, store=True), 'total': fields.float('Total', required=True, digits_compute=dp.get_precision('Sale Price'), states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), 'notes': fields.text('Notes', states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), 'create_uid': fields.many2one('res.users', 'Created by', readonly=True), 'create_date': fields.datetime('Creation Date', readonly=True, select=True), 'cancelled_by': fields.many2one('res.users', 'Cancelled by', readonly=True), 'date_cancelled': fields.datetime('Date Cancelled', readonly=True), 'approved_by': fields.many2one('res.users', 'Approved by', readonly=True), 'date_approved': fields.datetime('Date Approved', readonly=True), 'confirmed_by': fields.many2one('res.users', 'Confirmed by', readonly=True), 'date_confirmed': fields.datetime('Date Confirmed', readonly=True), 'closed_by': fields.many2one('res.users', 'Closed by', readonly=True), 'date_closed': fields.datetime('Date Closed', readonly=True), 'drafted_by': fields.many2one('res.users', 'Drafted by', readonly=True), 'date_drafted': fields.datetime('Date Drafted', readonly=True), 'move_id': fields.many2one( 'account.move', 'Journal Entry', readonly=True, select=1, ondelete='restrict', help= "Link to the automatically generated Journal Items.\nThis move is only for Travel Expense Records with balance < 0.0" ), 'paid': fields.function(_paid, method=True, string='Paid', type='boolean', multi=False, store={ 'account.move.reconcile': (_get_move_line_from_reconcile, None, 50) }), 'currency_id': fields.many2one('res.currency', 'Currency', required=True, states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), 'auto_expense': fields.boolean( 'Auto Expense', help= "Check this if you want this product and amount to be automatically created when Travel Expense Record is created.", states={ 'cancel': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), 'driver_helper': fields.boolean( 'For Driver Helper', help= "Check this if you want to give this advance to Driver Helper.", states={ 'cancel': [('readonly', True)], 'approved': [('readonly', True)], 'confirmed': [('readonly', True)], 'closed': [('readonly', True)] }), } _defaults = { 'date': lambda *a: time.strftime(DEFAULT_SERVER_DATE_FORMAT), 'state': lambda *a: 'draft', 'currency_id': lambda self, cr, uid, c: self.pool.get('res.users').browse( cr, uid, uid, c).company_id.currency_id.id, 'product_uom_qty': 1, } _sql_constraints = [ ('name_uniq', 'unique(name)', 'Advance number must be unique !'), ] _order = "name desc, date desc" def on_change_price_total(self, cr, uid, ids, product_id, product_uom_qty, price_total): res = {} if not (product_uom_qty and product_id and price_total): return res tax_factor = 0.00 prod_obj = self.pool.get('product.product') for line in prod_obj.browse(cr, uid, [product_id], context=None)[0].supplier_taxes_id: tax_factor = (tax_factor + line.amount) if line.amount <> 0.0 else tax_factor price_unit = price_total / (1.0 + tax_factor) / product_uom_qty price_subtotal = price_unit * product_uom_qty tax_amount = price_subtotal * tax_factor res = { 'value': { 'price_unit': price_unit, 'price_unit_control': price_unit, 'price_subtotal': price_subtotal, 'tax_amount': tax_amount, } } return res def on_change_product_id(self, cr, uid, ids, product_id): res = {} if not product_id: return {} prod_obj = self.pool.get('product.product') prod = prod_obj.browse(cr, uid, [product_id], context=None) return {'value': {'product_uom': prod[0].uom_id.id}} def on_change_driver_helper(self, cr, uid, ids, driver_helper, employee1_id, employee2_id): return { 'value': { 'employee_id': employee2_id, } } if driver_helper else { 'value': { 'employee_id': employee1_id, } } def on_change_driver(self, cr, uid, ids, employee_id, employee1_id, employee2_id): return { 'value': { 'driver_helper': (employee_id == employee2_id), } } def on_change_travel_id(self, cr, uid, ids, travel_id): res = {} if not travel_id: return { 'value': { 'employee_id': False, 'employee1_id': False, 'employee2_id': False, 'unit_id': False, 'operation_id': False, 'shop_id': False, } } travel = self.pool.get('tms.travel').browse(cr, uid, [travel_id], context=None)[0] return { 'value': { 'employee_id': travel.employee_id.id, 'employee1_id': travel.employee_id.id, 'employee2_id': travel.employee2_id.id, 'unit_id': travel.unit_id.id, 'operation_id': travel.operation_id.id, 'shop_id': travel.shop_id.id, } } def create(self, cr, uid, vals, context=None): travel = self.pool.get('tms.travel').browse(cr, uid, vals['travel_id']) shop_id = travel.shop_id.id shop = self.pool.get('sale.shop').browse(cr, uid, [shop_id])[0] seq_id = shop.tms_advance_seq.id if shop.tms_advance_seq: seq_number = self.pool.get('ir.sequence').get_id(cr, uid, seq_id) vals['name'] = seq_number else: raise osv.except_osv( _('Travel Sequence Error !'), _('You have not defined Advance Sequence for shop ' + shop.name)) return super(tms_advance, self).create(cr, uid, vals, context=context) def action_cancel_draft(self, cr, uid, ids, *args): if not len(ids): return False for advance in self.browse(cr, uid, ids): if advance.travel_id.state in ('cancel', 'closed'): raise osv.except_osv( _('Could not set to draft this Advance !'), _('Travel is Closed or Cancelled !!!')) else: self.write( cr, uid, ids, { 'state': 'draft', 'drafted_by': uid, 'date_drafted': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) }) return True def action_cancel(self, cr, uid, ids, context=None): for advance in self.browse(cr, uid, ids, context=context): if advance.travel_id.state in ('closed'): raise osv.except_osv( _('Could not cancel Advance !'), _('This Advance is already linked to Travel Expenses record' )) elif advance.move_id.id: move_obj = self.pool.get('account.move') move_id = advance.move_id.id if not advance.paid: #(move_line.reconcile_id.id or move_line.reconcile_partial_id.id): if advance.move_id.state == 'posted': move_obj.button_cancel(cr, uid, [move_id]) self.write( cr, uid, ids, { 'move_id': False, 'state': 'cancel', 'cancelled_by': uid, 'date_cancelled': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) }) move_obj.unlink(cr, uid, [move_id]) else: raise osv.except_osv(_('Could not cancel Advance !'), _('This Advance is already paid')) else: self.write( cr, uid, ids, { 'move_id': False, 'state': 'cancel', 'cancelled_by': uid, 'date_cancelled': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) }) return True def action_approve(self, cr, uid, ids, context=None): for advance in self.browse(cr, uid, ids, context=context): if advance.state in ('draft'): if advance.total <= 0.0: raise osv.except_osv( _('Could not approve Advance !'), _('Total Amount must be greater than zero.')) self.write( cr, uid, ids, { 'state': 'approved', 'approved_by': uid, 'date_approved': time.strftime(DEFAULT_SERVER_DATETIME_FORMAT) }) return True def action_confirm(self, cr, uid, ids, context=None): adv_invoice = self.pool.get('tms.advance.invoice') adv_invoice.makeInvoices(cr, uid, ids, context=None) return True def copy(self, cr, uid, id, default=None, context=None): default = default or {} default.update({ 'cancelled_by': False, 'date_cancelled': False, 'approved_by': False, 'date_approved': False, 'confirmed_by': False, 'date_confirmed': False, 'closed_by': False, 'date_closed': False, 'drafted_by': False, 'date_drafted': False, 'move_id': False, 'notes': False, 'expense_id': False, 'expense2_id': False, }) return super(tms_advance, self).copy(cr, uid, id, default, context)
class account_move_line_reconcile_writeoff(osv.osv_memory): """ It opens the write off wizard form, in that user can define the journal, account, analytic account for reconcile """ _name = 'account.move.line.reconcile.writeoff' _description = 'Account move line reconcile (writeoff)' _columns = { 'journal_id': fields.many2one('account.journal','Write-Off Journal', required=True), 'writeoff_acc_id': fields.many2one('account.account','Write-Off account', required=True), 'date_p': fields.date('Date'), 'comment': fields.char('Comment', size= 64, required=True), 'analytic_id': fields.many2one('account.analytic.account', 'Analytic Account', domain=[('parent_id', '!=', False)]), } _defaults = { 'date_p': lambda *a: time.strftime('%Y-%m-%d'), 'comment': 'Write-off', } def trans_rec_addendum(self, cr, uid, ids, context=None): mod_obj = self.pool.get('ir.model.data') if context is None: context = {} model_data_ids = mod_obj.search(cr, uid,[('model','=','ir.ui.view'),('name','=','account_move_line_reconcile_writeoff')], context=context) resource_id = mod_obj.read(cr, uid, model_data_ids, fields=['res_id'], context=context)[0]['res_id'] return { 'name': _('Reconcile Writeoff'), 'context': context, 'view_type': 'form', 'view_mode': 'form', 'res_model': 'account.move.line.reconcile.writeoff', 'views': [(resource_id,'form')], 'type': 'ir.actions.act_window', 'target': 'new', } def trans_rec_reconcile_partial(self, cr, uid, ids, context=None): account_move_line_obj = self.pool.get('account.move.line') if context is None: context = {} account_move_line_obj.reconcile_partial(cr, uid, context['active_ids'], 'manual', context=context) return {'type': 'ir.actions.act_window_close'} def trans_rec_reconcile(self, cr, uid, ids, context=None): account_move_line_obj = self.pool.get('account.move.line') period_obj = self.pool.get('account.period') if context is None: context = {} data = self.read(cr, uid, ids,context=context)[0] account_id = data['writeoff_acc_id'][0] context['date_p'] = data['date_p'] journal_id = data['journal_id'][0] context['comment'] = data['comment'] if data['analytic_id']: context['analytic_id'] = data['analytic_id'][0] if context['date_p']: date = context['date_p'] ids = period_obj.find(cr, uid, dt=date, context=context) if ids: period_id = ids[0] account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id, period_id, journal_id, context=context) return {'type': 'ir.actions.act_window_close'}
class daily_report(osv.osv_memory): def _get_active_session(self, cr, uid, context={}): ssn = self.pool.get('sms.session').search(cr, uid, [('state', '=', 'Active')]) if ssn: return ssn[0] _name = "daily.report" _description = "admits student in a selected class" _columns = { "session": fields.many2one( 'sms.session', 'Session', help= "Select A session , you can also print reprts from previous session." ), 'fee_manager': fields.many2one( 'res.users', 'Fee Manager', help= "Select A Fee Manager to check his fee collection.Leave it blank if you want to print for all Managers." ), 'fee_approved_by': fields.many2one( 'res.users', 'Fee approved Manager', help= "Select A Fee Manager to check his fee collection.Leave it blank if you want to print for all Managers." ), 'advance_search': fields.boolean("Advance search"), # "class_id": fields.many2one('sms.academiccalendar', 'Class', domain="[('fee_defined','=',1)]", help="Select A class to check its fee collection.Leave it blank if you want to print for all classes"), 'from_date': fields.date('From'), 'to_date': fields.date('To'), 'program_category_id': fields.many2one('sms.program.category', 'Program category'), 'category': fields.selection([('Academics', 'Academics'), ('Transport', 'Transport')], 'Fee Category'), } _defaults = { 'session': _get_active_session, } def print_daily_report(self, cr, uid, ids, data): result = [] thisform = self.read(cr, uid, ids)[0] datas = { 'ids': [], 'active_ids': '', 'model': 'smsfee.classfees.register', 'form': self.read(cr, uid, ids)[0], } return { 'type': 'ir.actions.report.xml', 'report_name': 'smsfee.dailyfee.report.name', 'datas': datas, }
class account_common_report(osv.osv_memory): _name = "account.common.report" _description = "Account Common Report" def onchange_chart_id(self, cr, uid, ids, chart_account_id=False, context=None): res = {} if chart_account_id: company_id = self.pool.get('account.account').browse( cr, uid, chart_account_id, context=context).company_id.id now = time.strftime('%Y-%m-%d') domain = [('company_id', '=', company_id), ('date_start', '<', now), ('date_stop', '>', now)] fiscalyears = self.pool.get('account.fiscalyear').search(cr, uid, domain, limit=1) res['value'] = { 'company_id': company_id, 'fiscalyear_id': fiscalyears and fiscalyears[0] or False } return res _columns = { 'download_excel': fields.binary('Download Excel', readonly=True), 'chart_account_id': fields.many2one('account.account', 'Chart of Account', help='Select Charts of Accounts', required=True, domain=[('parent_id', '=', False)]), 'company_id': fields.related('chart_account_id', 'company_id', type='many2one', relation='res.company', string='Company', readonly=True), 'fiscalyear_id': fields.many2one('account.fiscalyear', 'Fiscal Year', help='Keep empty for all open fiscal year'), 'filter': fields.selection([('filter_no', 'No Filters'), ('filter_date', 'Date'), ('filter_period', 'Periods')], "Filter by", required=True), 'period_from': fields.many2one('account.period', 'Start Period'), 'period_to': fields.many2one('account.period', 'End Period'), 'journal_ids': fields.many2many('account.journal', string='Journals', required=True), 'date_from': fields.date("Start Date"), 'date_to': fields.date("End Date"), 'target_move': fields.selection([ ('posted', 'All Posted Entries'), ('all', 'All Entries'), ], 'Target Moves', required=True), } def _check_company_id(self, cr, uid, ids, context=None): for wiz in self.browse(cr, uid, ids, context=context): company_id = wiz.company_id.id if wiz.fiscalyear_id and company_id != wiz.fiscalyear_id.company_id.id: return False if wiz.period_from and company_id != wiz.period_from.company_id.id: return False if wiz.period_to and company_id != wiz.period_to.company_id.id: return False return True _constraints = [ (_check_company_id, 'The fiscalyear, periods or chart of account chosen have to belong to the same company.', ['chart_account_id', 'fiscalyear_id', 'period_from', 'period_to']), ] def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): if context is None: context = {} res = super(account_common_report, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=False) if context.get('active_model', False) == 'account.account': doc = etree.XML(res['arch']) nodes = doc.xpath("//field[@name='chart_account_id']") for node in nodes: node.set('readonly', '1') node.set( 'help', 'If you print the report from Account list/form view it will not consider Charts of account' ) setup_modifiers(node, res['fields']['chart_account_id']) nodes2 = doc.xpath("//field[@name='filtrar_cuenta']") if nodes2: for node2 in nodes2: node2.set('invisible', '1') setup_modifiers(node2, res['fields']['filtrar_cuenta']) res['arch'] = etree.tostring(doc) return res def onchange_filter(self, cr, uid, ids, filter='filter_no', fiscalyear_id=False, context=None): res = {'value': {}} if filter == 'filter_no': res['value'] = { 'period_from': False, 'period_to': False, 'date_from': False, 'date_to': False } if filter == 'filter_date': res['value'] = { 'period_from': False, 'period_to': False, 'date_from': time.strftime('%Y-01-01'), 'date_to': time.strftime('%Y-%m-%d') } if filter == 'filter_period' and fiscalyear_id: start_period = end_period = False cr.execute( ''' SELECT * FROM (SELECT p.id FROM account_period p LEFT JOIN account_fiscalyear f ON (p.fiscalyear_id = f.id) WHERE f.id = %s AND p.special = false ORDER BY p.date_start ASC, p.special ASC LIMIT 1) AS period_start UNION ALL SELECT * FROM (SELECT p.id FROM account_period p LEFT JOIN account_fiscalyear f ON (p.fiscalyear_id = f.id) WHERE f.id = %s AND p.date_start < NOW() AND p.special = false ORDER BY p.date_stop DESC LIMIT 1) AS period_stop''', (fiscalyear_id, fiscalyear_id)) periods = [i[0] for i in cr.fetchall()] if periods and len(periods) > 1: start_period = periods[0] end_period = periods[1] res['value'] = { 'period_from': start_period, 'period_to': end_period, 'date_from': False, 'date_to': False } return res def _get_account(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) accounts = self.pool.get('account.account').search( cr, uid, [('parent_id', '=', False), ('company_id', '=', user.company_id.id)], limit=1) return accounts and accounts[0] or False def _get_fiscalyear(self, cr, uid, context=None): if context is None: context = {} now = time.strftime('%Y-%m-%d') company_id = False ids = context.get('active_ids', []) if ids and context.get('active_model') == 'account.account': company_id = self.pool.get('account.account').browse( cr, uid, ids[0], context=context).company_id.id else: # use current company id company_id = self.pool.get('res.users').browse( cr, uid, uid, context=context).company_id.id domain = [('company_id', '=', company_id), ('date_start', '<', now), ('date_stop', '>', now)] fiscalyears = self.pool.get('account.fiscalyear').search(cr, uid, domain, limit=1) return fiscalyears and fiscalyears[0] or False def _get_all_journal(self, cr, uid, context=None): return self.pool.get('account.journal').search(cr, uid, []) _defaults = { 'fiscalyear_id': _get_fiscalyear, 'company_id': lambda self, cr, uid, c: self.pool.get('res.company'). _company_default_get(cr, uid, 'account.common.report', context=c), 'journal_ids': _get_all_journal, 'filter': 'filter_no', 'chart_account_id': _get_account, 'target_move': 'posted', } def _build_contexts(self, cr, uid, ids, data, context=None): if context is None: context = {} result = {} result['fiscalyear'] = 'fiscalyear_id' in data['form'] and data[ 'form']['fiscalyear_id'] or False result['journal_ids'] = 'journal_ids' in data['form'] and data['form'][ 'journal_ids'] or False result['chart_account_id'] = 'chart_account_id' in data[ 'form'] and data['form']['chart_account_id'] or False result['state'] = 'target_move' in data['form'] and data['form'][ 'target_move'] or '' if data['form']['filter'] == 'filter_date': result['date_from'] = data['form']['date_from'] result['date_to'] = data['form']['date_to'] elif data['form']['filter'] == 'filter_period': if not data['form']['period_from'] or not data['form']['period_to']: raise osv.except_osv( _('Error!'), _('Select a starting and an ending period.')) result['period_from'] = data['form']['period_from'] result['period_to'] = data['form']['period_to'] return result def _print_report(self, cr, uid, ids, data, context=None): raise (_('Error!'), _('Not implemented.')) def check_report(self, cr, uid, ids, context=None): if context is None: context = {} data = {} data['ids'] = context.get('active_ids', []) data['model'] = context.get('active_model', 'ir.ui.menu') data['form'] = self.read( cr, uid, ids, [ 'date_from', 'date_to', 'fiscalyear_id', 'journal_ids', 'period_from', 'period_to', 'filter', 'chart_account_id', 'target_move' ], context=context)[0] for field in [ 'fiscalyear_id', 'chart_account_id', 'period_from', 'period_to' ]: if isinstance(data['form'][field], tuple): data['form'][field] = data['form'][field][0] used_context = self._build_contexts(cr, uid, ids, data, context=context) data['form']['periods'] = used_context.get( 'periods', False) and used_context['periods'] or [] data['form']['used_context'] = dict(used_context, lang=context.get('lang', 'en_US')) return self._print_report(cr, uid, ids, data, context=context)
class hr_timesheet_sheet(osv.osv): _name = "hr_timesheet_sheet.sheet" _inherit = "mail.thread" _table = 'hr_timesheet_sheet_sheet' _order = "id desc" _description="Timesheet" def _total(self, cr, uid, ids, name, args, context=None): """ Compute the attendances, analytic lines timesheets and differences between them for all the days of a timesheet and the current day """ res = {} for sheet in self.browse(cr, uid, ids, context=context or {}): res.setdefault(sheet.id, { 'total_attendance': 0.0, 'total_timesheet': 0.0, 'total_difference': 0.0, }) for period in sheet.period_ids: res[sheet.id]['total_attendance'] += period.total_attendance res[sheet.id]['total_timesheet'] += period.total_timesheet res[sheet.id]['total_difference'] += period.total_attendance - period.total_timesheet return res def check_employee_attendance_state(self, cr, uid, sheet_id, context=None): ids_signin = self.pool.get('hr.attendance').search(cr,uid,[('sheet_id', '=', sheet_id),('action','=','sign_in')]) ids_signout = self.pool.get('hr.attendance').search(cr,uid,[('sheet_id', '=', sheet_id),('action','=','sign_out')]) if len(ids_signin) != len(ids_signout): raise osv.except_osv(('Warning!'),_('The timesheet cannot be validated as it does not contain an equal number of sign ins and sign outs.')) return True def copy(self, cr, uid, ids, *args, **argv): raise osv.except_osv(_('Error!'), _('You cannot duplicate a timesheet.')) def create(self, cr, uid, vals, *args, **argv): if 'employee_id' in vals: if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).user_id: raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link him/her to a user.')) if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).product_id: raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link the employee to a product, like \'Consultant\'.')) if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).journal_id: raise osv.except_osv(_('Configuration Error!'), _('In order to create a timesheet for this employee, you must assign an analytic journal to the employee, like \'Timesheet Journal\'.')) return super(hr_timesheet_sheet, self).create(cr, uid, vals, *args, **argv) def write(self, cr, uid, ids, vals, *args, **argv): if 'employee_id' in vals: new_user_id = self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).user_id.id or False if not new_user_id: raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link him/her to a user.')) if not self._sheet_date(cr, uid, ids, forced_user_id=new_user_id): raise osv.except_osv(_('Error!'), _('You cannot have 2 timesheets that overlap!\nYou should use the menu \'My Timesheet\' to avoid this problem.')) if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).product_id: raise osv.except_osv(_('Error!'), _('In order to create a timesheet for this employee, you must link the employee to a product.')) if not self.pool.get('hr.employee').browse(cr, uid, vals['employee_id']).journal_id: raise osv.except_osv(_('Configuration Error!'), _('In order to create a timesheet for this employee, you must assign an analytic journal to the employee, like \'Timesheet Journal\'.')) return super(hr_timesheet_sheet, self).write(cr, uid, ids, vals, *args, **argv) def button_confirm(self, cr, uid, ids, context=None): for sheet in self.browse(cr, uid, ids, context=context): if sheet.employee_id and sheet.employee_id.parent_id and sheet.employee_id.parent_id.user_id: self.message_subscribe_users(cr, uid, [sheet.id], user_ids=[sheet.employee_id.parent_id.user_id.id], context=context) self.check_employee_attendance_state(cr, uid, sheet.id, context=context) di = sheet.user_id.company_id.timesheet_max_difference if (abs(sheet.total_difference) < di) or not di: self.signal_confirm(cr, uid, [sheet.id]) else: raise osv.except_osv(_('Warning!'), _('Please verify that the total difference of the sheet is lower than %.2f.') %(di,)) return True def attendance_action_change(self, cr, uid, ids, context=None): hr_employee = self.pool.get('hr.employee') employee_ids = [] for sheet in self.browse(cr, uid, ids, context=context): if sheet.employee_id.id not in employee_ids: employee_ids.append(sheet.employee_id.id) return hr_employee.attendance_action_change(cr, uid, employee_ids, context=context) _columns = { 'name': fields.char('Note', size=64, select=1, states={'confirm':[('readonly', True)], 'done':[('readonly', True)]}), 'employee_id': fields.many2one('hr.employee', 'Employee', required=True), 'user_id': fields.related('employee_id', 'user_id', type="many2one", relation="res.users", store=True, string="User", required=False, readonly=True),#fields.many2one('res.users', 'User', required=True, select=1, states={'confirm':[('readonly', True)], 'done':[('readonly', True)]}), 'date_from': fields.date('Date from', required=True, select=1, readonly=True, states={'new':[('readonly', False)]}), 'date_to': fields.date('Date to', required=True, select=1, readonly=True, states={'new':[('readonly', False)]}), 'timesheet_ids' : fields.one2many('hr.analytic.timesheet', 'sheet_id', 'Timesheet lines', readonly=True, states={ 'draft': [('readonly', False)], 'new': [('readonly', False)]} ), 'attendances_ids' : fields.one2many('hr.attendance', 'sheet_id', 'Attendances'), 'state' : fields.selection([ ('new', 'New'), ('draft','Open'), ('confirm','Waiting Approval'), ('done','Approved')], 'Status', select=True, required=True, readonly=True, help=' * The \'Draft\' status is used when a user is encoding a new and unconfirmed timesheet. \ \n* The \'Confirmed\' status is used for to confirm the timesheet by user. \ \n* The \'Done\' status is used when users timesheet is accepted by his/her senior.'), 'state_attendance' : fields.related('employee_id', 'state', type='selection', selection=[('absent', 'Absent'), ('present', 'Present')], string='Current Status', readonly=True), 'total_attendance': fields.function(_total, method=True, string='Total Attendance', multi="_total"), 'total_timesheet': fields.function(_total, method=True, string='Total Timesheet', multi="_total"), 'total_difference': fields.function(_total, method=True, string='Difference', multi="_total"), 'period_ids': fields.one2many('hr_timesheet_sheet.sheet.day', 'sheet_id', 'Period', readonly=True), 'account_ids': fields.one2many('hr_timesheet_sheet.sheet.account', 'sheet_id', 'Analytic accounts', readonly=True), 'company_id': fields.many2one('res.company', 'Company'), 'department_id':fields.many2one('hr.department','Department'), } def _default_date_from(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) r = user.company_id and user.company_id.timesheet_range or 'month' if r=='month': return time.strftime('%Y-%m-01') elif r=='week': return (datetime.today() + relativedelta(weekday=0, days=-6)).strftime('%Y-%m-%d') elif r=='year': return time.strftime('%Y-01-01') return time.strftime('%Y-%m-%d') def _default_date_to(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) r = user.company_id and user.company_id.timesheet_range or 'month' if r=='month': return (datetime.today() + relativedelta(months=+1,day=1,days=-1)).strftime('%Y-%m-%d') elif r=='week': return (datetime.today() + relativedelta(weekday=6)).strftime('%Y-%m-%d') elif r=='year': return time.strftime('%Y-12-31') return time.strftime('%Y-%m-%d') def _default_employee(self, cr, uid, context=None): emp_ids = self.pool.get('hr.employee').search(cr, uid, [('user_id','=',uid)], context=context) return emp_ids and emp_ids[0] or False _defaults = { 'date_from' : _default_date_from, 'date_to' : _default_date_to, 'state': 'new', 'employee_id': _default_employee, 'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(cr, uid, 'hr_timesheet_sheet.sheet', context=c) } def _sheet_date(self, cr, uid, ids, forced_user_id=False, context=None): for sheet in self.browse(cr, uid, ids, context=context): new_user_id = forced_user_id or sheet.user_id and sheet.user_id.id if new_user_id: cr.execute('SELECT id \ FROM hr_timesheet_sheet_sheet \ WHERE (date_from <= %s and %s <= date_to) \ AND user_id=%s \ AND id <> %s',(sheet.date_to, sheet.date_from, new_user_id, sheet.id)) if cr.fetchall(): return False return True _constraints = [ (_sheet_date, 'You cannot have 2 timesheets that overlap!\nPlease use the menu \'My Current Timesheet\' to avoid this problem.', ['date_from','date_to']), ] def action_set_to_draft(self, cr, uid, ids, *args): self.write(cr, uid, ids, {'state': 'draft'}) self.create_workflow(cr, uid, ids) return True def name_get(self, cr, uid, ids, context=None): if not ids: return [] if isinstance(ids, (long, int)): ids = [ids] return [(r['id'], _('Week ')+datetime.strptime(r['date_from'], '%Y-%m-%d').strftime('%U')) \ for r in self.read(cr, uid, ids, ['date_from'], context=context, load='_classic_write')] def unlink(self, cr, uid, ids, context=None): sheets = self.read(cr, uid, ids, ['state','total_attendance'], context=context) for sheet in sheets: if sheet['state'] in ('confirm', 'done'): raise osv.except_osv(_('Invalid Action!'), _('You cannot delete a timesheet which is already confirmed.')) elif sheet['total_attendance'] <> 0.00: raise osv.except_osv(_('Invalid Action!'), _('You cannot delete a timesheet which have attendance entries.')) return super(hr_timesheet_sheet, self).unlink(cr, uid, ids, context=context) def onchange_employee_id(self, cr, uid, ids, employee_id, context=None): department_id = False user_id = False if employee_id: empl_id = self.pool.get('hr.employee').browse(cr, uid, employee_id, context=context) department_id = empl_id.department_id.id user_id = empl_id.user_id.id return {'value': {'department_id': department_id, 'user_id': user_id,}} # ------------------------------------------------ # OpenChatter methods and notifications # ------------------------------------------------ def _needaction_domain_get(self, cr, uid, context=None): emp_obj = self.pool.get('hr.employee') empids = emp_obj.search(cr, uid, [('parent_id.user_id', '=', uid)], context=context) if not empids: return False dom = ['&', ('state', '=', 'confirm'), ('employee_id', 'in', empids)] return dom
class contract_init(orm.Model): _name = 'hr.contract.init' _description = 'Initial Contract Settings' _inherit = 'ir.needaction_mixin' _columns = { 'name': fields.char( 'Name', size=64, required=True, readonly=True, states={'draft': [('readonly', False)]}, ), 'date': fields.date( 'Effective Date', required=True, readonly=True, states={'draft': [('readonly', False)]}, ), 'wage_ids': fields.one2many( 'hr.contract.init.wage', 'contract_init_id', 'Starting Wages', readonly=True, states={'draft': [('readonly', False)]}, ), 'struct_id': fields.many2one( 'hr.payroll.structure', 'Payroll Structure', readonly=True, states={'draft': [('readonly', False)]}, ), 'trial_period': fields.integer( 'Trial Period', readonly=True, states={'draft': [('readonly', False)]}, help="Length of Trial Period, in days", ), 'active': fields.boolean('Active', ), 'state': fields.selection( [ ('draft', 'Draft'), ('approve', 'Approved'), ('decline', 'Declined'), ], 'State', readonly=True, ), } _defaults = { 'trial_period': 0, 'active': True, 'state': 'draft', } # Return records with latest date first _order = 'date desc' def _needaction_domain_get(self, cr, uid, context=None): users_obj = self.pool.get('res.users') if users_obj.has_group(cr, uid, 'base.group_hr_director'): domain = [('state', 'in', ['draft'])] return domain return False def unlink(self, cr, uid, ids, context=None): if isinstance(ids, (int, long)): ids = [ids] data = self.read(cr, uid, ids, ['state'], context=context) for d in data: if d['state'] in ['approve', 'decline']: raise orm.except_orm( _('Error'), _('You may not a delete a record that is not in a ' '"Draft" state')) return super(contract_init, self).unlink(cr, uid, ids, context=context) def set_to_draft(self, cr, uid, ids, context=None): self.write(cr, uid, ids, { 'state': 'draft', }, context=context) wf_service = netsvc.LocalService("workflow") for i in ids: wf_service.trg_delete(uid, 'hr.contract.init', i, cr) wf_service.trg_create(uid, 'hr.contract.init', i, cr) return True def state_approve(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'approve'}, context=context) return True def state_decline(self, cr, uid, ids, context=None): self.write(cr, uid, ids, {'state': 'decline'}, context=context) return True
class sale_order(osv.osv): _inherit = 'sale.order' def _get_total(self, cr, uid, ids, name, arg, context=None): res = {} for order in self.browse(cr, uid, ids, context=context): total = 0.0 for line in order.order_line: total += (line.product_uom_qty * line.price_unit) res[order.id] = total return res _columns = { 'access_token': fields.char('Security Token', required=True, copy=False), 'template_id': fields.many2one('sale.quote.template', 'Quote Template', readonly=True, states={ 'draft': [('readonly', False)], 'sent': [('readonly', False)] }), 'website_description': fields.html('Description'), 'options': fields.one2many('sale.order.option', 'order_id', 'Optional Products Lines'), 'validity_date': fields.date('Expiry Date'), 'amount_undiscounted': fields.function(_get_total, string='Amount Before Discount', type="float", digits_compute=dp.get_precision('Account')) } _defaults = { 'access_token': lambda self, cr, uid, ctx={}: str(uuid.uuid4()) } def open_quotation(self, cr, uid, quote_id, context=None): quote = self.browse(cr, uid, quote_id[0], context=context) return { 'type': 'ir.actions.act_url', 'target': 'self', 'url': '/quote/%s' % (quote.id) } def onchange_template_id(self, cr, uid, ids, template_id, partner=False, fiscal_position=False, context=None): if not template_id: return True if context is None: context = {} context = dict(context, lang=self.pool.get('res.partner').browse( cr, uid, partner, context).lang) lines = [(5, )] quote_template = self.pool.get('sale.quote.template').browse( cr, uid, template_id, context=context) for line in quote_template.quote_line: res = self.pool.get('sale.order.line').product_id_change( cr, uid, False, False, line.product_id.id, line.product_uom_qty, line.product_uom_id.id, line.product_uom_qty, line.product_uom_id.id, line.name, partner, False, True, time.strftime('%Y-%m-%d'), False, fiscal_position, True, context) data = res.get('value', {}) if 'tax_id' in data: data['tax_id'] = [(6, 0, data['tax_id'])] data.update({ 'name': line.name, 'price_unit': line.price_unit, 'discount': line.discount, 'product_uom_qty': line.product_uom_qty, 'product_id': line.product_id.id, 'product_uom': line.product_uom_id.id, 'website_description': line.website_description, 'state': 'draft', }) lines.append((0, 0, data)) options = [] for option in quote_template.options: options.append((0, 0, { 'product_id': option.product_id.id, 'name': option.name, 'quantity': option.quantity, 'uom_id': option.uom_id.id, 'price_unit': option.price_unit, 'discount': option.discount, 'website_description': option.website_description, })) date = False if quote_template.number_of_days > 0: date = (datetime.datetime.now() + datetime.timedelta( quote_template.number_of_days)).strftime("%Y-%m-%d") data = { 'order_line': lines, 'website_description': quote_template.website_description, 'note': quote_template.note, 'options': options, 'validity_date': date } return {'value': data} def recommended_products(self, cr, uid, ids, context=None): order_line = self.browse(cr, uid, ids[0], context=context).order_line product_pool = self.pool.get('product.product') products = [] for line in order_line: products += line.product_id.product_tmpl_id.recommended_products( context=context) return products def get_access_action(self, cr, uid, id, context=None): """ Override method that generated the link to access the document. Instead of the classic form view, redirect to the online quote if exists. """ quote = self.browse(cr, uid, id, context=context) if not quote.template_id: return super(sale_order, self).get_access_action(cr, uid, id, context=context) return { 'type': 'ir.actions.act_url', 'url': '/quote/%s' % id, 'target': 'self', 'res_id': id, } def action_quotation_send(self, cr, uid, ids, context=None): action = super(sale_order, self).action_quotation_send(cr, uid, ids, context=context) ir_model_data = self.pool.get('ir.model.data') quote_template_id = self.read(cr, uid, ids, ['template_id'], context=context)[0]['template_id'] if quote_template_id: try: template_id = ir_model_data.get_object_reference( cr, uid, 'website_quote', 'email_template_edi_sale')[1] except ValueError: pass else: action['context'].update({ 'default_template_id': template_id, 'default_use_template': True }) return action
class op_faculty(osv.osv): _name = 'op.faculty' _inherits = {'res.partner': 'partner_id'} def create_employee(self, cr, uid, ids, context=None): self_obj = self.browse(cr, uid, ids, context=None) emp_obj = self.pool.get('hr.employee') vals = { 'name': self_obj[0].name + ' ' + self_obj[0].middle_name + ' ' + self_obj[0].last_name, 'nationality': self_obj[0].country_id, 'gender': self_obj[0].gender, } emp_id = emp_obj.create(cr, uid, vals, context=None) self.pool.get('op.faculty').write(cr, uid, ids, {'emp_id': emp_id}) return True _columns = { 'partner_id': fields.many2one('res.partner', 'Partner', required=True, ondelete="cascade"), 'middle_name': fields.char(size=128, string='Middle Name', required=True), 'last_name': fields.char(size=128, string='Last Name', required=True), 'birth_date': fields.date(string='Birth Date', required=True), 'blood_group': fields.selection([('A+', 'A+ve'), ('B+', 'B+ve'), ('O+', 'O+ve'), ('AB+', 'AB+ve'), ('A-', 'A-ve'), ('B-', 'B-ve'), ('O-', 'O-ve'), ('AB-', 'AB-ve')], string='Blood Group'), 'gender': fields.selection([('male', 'Male'), ('female', 'Female')], 'Gender', required=True), 'nationality': fields.many2one('res.country', string='Nationality'), 'language': fields.many2one('res.lang', string='Language'), 'category': fields.many2one('op.category', string='Category', required=True), 'religion': fields.many2one('op.religion', string='Religion'), 'library_card': fields.char(size=64, string='Library Card'), 'emergency_contact': fields.many2one('res.partner', string='Emergency Contact'), 'pan_card': fields.char(size=64, string='PAN Card'), 'bank_acc_num': fields.char(size=64, string='Bank Acc Number'), 'visa_info': fields.char(size=64, string='Visa Info'), 'id_number': fields.char(size=64, string='ID Card Number'), 'photo': fields.binary(string='Photo'), 'login': fields.related('user_id', 'login', type='char', string='Login', readonly=1), 'last_login': fields.related('user_id', 'date', type='datetime', string='Latest Connection', readonly=1), 'timetable_ids': fields.one2many('op.timetable', 'faculty_id', 'Time table'), 'health_faculty_lines': fields.one2many('op.health', 'faculty_id', 'Health Detail'), 'faculty_subject_ids': fields.many2many('op.subject', 'faculty_subject_rel', 'op_faculty_id', 'op_subject_id', string='Subjects'), 'emp_id': fields.many2one('hr.employee', string='Employee'), }
val[total.id]=val1 >>>>>>> 08375b10183304dea2ebfe2187b2858b17177cbb return val STATE_SELECTION = [ ('draft', 'New'), ('open', 'Accepted'), ('cancel', 'Refused'), ('close', 'Done') ] _name='devil.formulas' _description='Formula Calculation' _columns={ 'name': fields.char('Transaction Code',size=124), 'date': fields.date('Transaction Date'), 'cust_id': fields.many2one('devil.customer','Customer'), 'formula_line': fields.one2many('devil.items.lines','formula_id','FormulaLines'), <<<<<<< HEAD 'total_amt_disc': fields.float('Amount Discount', required=True, ), ======= >>>>>>> 08375b10183304dea2ebfe2187b2858b17177cbb 'total_amount': fields.function(_amount_all, string='TotalAmount'), 'state': fields.selection(STATE_SELECTION, 'Status', readonly=True, select=True), } _defaults = { 'state': lambda *a: 'draft', } def button_dummy(self, cr, uid, ids, context=None): return True
class tms_expense_loan(osv.osv): _name = 'tms.expense.loan' _inherit = ['mail.thread', 'ir.needaction_mixin'] _description = 'TMS Driver Loan Mgmnt' def _balance(self, cr, uid, ids, field_name, args, context=None): res = {} for record in self.browse(cr, uid, ids, context=context): cr.execute('select sum(coalesce(price_total, 0.0))::float from tms_expense_line where loan_id = %s' % (record.id)) data = filter(None, map(lambda x:x[0], cr.fetchall())) or [0.0] res[record.id] = { 'balance' : record.amount + data[0], 'paid' : not (record.amount + data[0]) > 0, } return res def _get_loan_discounts_from_expense_lines(self, cr, uid, ids, context=None): expense_line = {} for line in self.pool.get('tms.expense.line').browse(cr, uid, ids, context=context): expense_line[line.loan_id.id] = True expense_line_ids = [] if expense_line: expense_line_ids = self.pool.get('tms.expense.loan').search(cr, uid, [('id','in',expense_line.keys())], context=context) return expense_line_ids _columns = { 'name' : fields.char('Name', size=64, select=True, readonly=True), 'description' : fields.char('Description', size=128, select=True, required=True, readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}), 'date' : fields.date('Date', required=True, select=True, readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}), 'employee_id' : fields.many2one('hr.employee', 'Driver', required=True, domain=[('tms_category', '=', 'driver')] , readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}), 'expense_line_ids' : fields.one2many('tms.expense.line', 'loan_id', 'Expense Line', readonly=True), 'state' : fields.selection([ ('draft', 'Draft'), ('approved', 'Approved'), ('confirmed', 'Confirmed'), ('closed', 'Closed'), ('cancel', 'Cancelled') ], 'State', readonly=True, help="State of the Driver Loan. ", select=True), 'discount_method' : fields.selection([ ('each', 'Each Travel Expense Record'), ('weekly', 'Weekly'), ('fortnightly', 'Fortnightly'), ('monthly', 'Monthly'), ], 'Discount Method', readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}, help="""Select Loan Recovery Method: - Weekly: Discount will be applied every week, considering only 4 weeks in each month - Fortnightly: Discount will be applied forthnightly, considering only 2 discounts in each month, applied the 14th and 28th day of the month. - Monthy: Discount will be applied only once a month, applied the 28th day of the month. . """, select=True, required=True), 'discount_type' : fields.selection([ ('fixed', 'Fixed'), ('percent', 'Loan Percentage'), ], 'Discount Type', readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}, required=True, help="""Select Loan Recovery Type: - Fixed: Discount will a fixed amount - Percent: Discount will be a percentage of total Loan Amount """, select=True), 'notes' : fields.text('Notes'), 'origin' : fields.char('Source Document', size=64, help="Reference of the document that generated this Expense Record", readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}), 'amount' : fields.float('Amount', digits_compute=dp.get_precision('Sale Price'), required=True, readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}), 'percent_discount' : fields.float('Percent (%)', digits_compute=dp.get_precision('Sale Price'), required=False, help="Please set percent as 10.00%", readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}), 'fixed_discount' : fields.float('Fixed Discount', digits_compute=dp.get_precision('Sale Price'), required=False, readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}), 'balance' : fields.function(_balance, method=True, digits_compute=dp.get_precision('Sale Price'), string='Balance', type='float', multi=True, store={ 'tms.expense.loan': (lambda self, cr, uid, ids, c={}: ids, ['notes', 'amount','state','expense_line_ids'], 10), 'tms.expense.line': (_get_loan_discounts_from_expense_lines, ['product_uom_qty', 'price_unit'], 10), }), #store = {'tms.expense.line': (_get_loan_discounts_from_expense_lines, None, 50)}), 'paid' : fields.function(_balance, method=True, string='Paid', type='boolean', multi=True, store={ 'tms.expense.loan': (lambda self, cr, uid, ids, c={}: ids, ['notes','amount','state','expense_line_ids'], 10), 'tms.expense.line': (_get_loan_discounts_from_expense_lines, ['product_uom_qty', 'price_unit'], 10), }), #store = {'tms.expense.line': (_get_loan_discounts_from_expense_lines, None, 50)}), 'product_id' : fields.many2one('product.product', 'Discount Product', readonly=True, states={'draft':[('readonly',False)], 'approved':[('readonly',False)]}, required=True, domain=[('tms_category', '=', ('salary_discount'))], ondelete='restrict'), 'shop_id' : fields.related('employee_id', 'shop_id', type='many2one', relation='sale.shop', string='Shop', store=True, readonly=True), 'company_id' : fields.related('shop_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True), 'create_uid' : fields.many2one('res.users', 'Created by', readonly=True), 'create_date' : fields.datetime('Creation Date', readonly=True, select=True), 'cancelled_by' : fields.many2one('res.users', 'Cancelled by', readonly=True), 'date_cancelled': fields.datetime('Date Cancelled', readonly=True), 'approved_by' : fields.many2one('res.users', 'Approved by', readonly=True), 'date_approved' : fields.datetime('Date Approved', readonly=True), 'confirmed_by' : fields.many2one('res.users', 'Confirmed by', readonly=True), 'date_confirmed': fields.datetime('Date Confirmed', readonly=True), 'closed_by' : fields.many2one('res.users', 'Closed by', readonly=True), 'date_closed' : fields.datetime('Date Closed', readonly=True), } _defaults = { 'date' : lambda *a: time.strftime(DEFAULT_SERVER_DATE_FORMAT), 'state' : lambda *a: 'draft', } _sql_constraints = [ ('name_uniq', 'unique(name)', 'Loan record must be unique !'), ] def create(self, cr, uid, vals, context=None): values = vals if 'employee_id' in vals and vals['employee_id']: employee = self.pool.get('hr.employee').browse(cr, uid, [vals['employee_id']])[0] seq_id = employee.shop_id.tms_loan_seq.id if seq_id: seq_number = self.pool.get('ir.sequence').get_id(cr, uid, seq_id) values['name'] = seq_number else: raise osv.except_osv(_('Loan Sequence Error !'), _('You have not defined Loan Sequence for shop ' + employee.shop_id.name)) return super(tms_expense_loan, self).create(cr, uid, values, context=context) def action_approve(self, cr, uid, ids, context=None): for rec in self.browse(cr, uid, ids, context=context): if rec.amount <= 0.0: raise osv.except_osv( _('Could not approve Loan !'), _('Amount must be greater than zero.')) self.write(cr, uid, ids, {'state':'approved', 'approved_by' : uid, 'date_approved':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) for (id,name) in self.name_get(cr, uid, ids): message = _("Loan '%s' is set to Approved.") % name self.log(cr, uid, id, message) return True def action_confirm(self, cr, uid, ids, context=None): for rec in self.browse(cr, uid, ids, context=context): self.write(cr, uid, ids, {'state':'confirmed', 'confirmed_by' : uid, 'date_confirmed':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) for (id,name) in self.name_get(cr, uid, ids): message = _("Loan '%s' is set to Confirmed.") % name self.log(cr, uid, id, message) return True def action_cancel(self, cr, uid, ids, context=None): for rec in self.browse(cr, uid, ids, context=context): self.write(cr, uid, ids, {'state':'cancel', 'cancelled_by' : uid, 'date_cancelled':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) for (id,name) in self.name_get(cr, uid, ids): message = _("Loan '%s' is set to Cancel.") % name self.log(cr, uid, id, message) return True def action_close(self, cr, uid, ids, context=None): for rec in self.browse(cr, uid, ids, context=context): self.write(cr, uid, ids, {'state':'closed', 'closed_by' : uid, 'date_closed':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) for (id,name) in self.name_get(cr, uid, ids): message = _("Loan '%s' is set to Closed even when it is not paid.") % name if rec.balance > 0.0 else _("Loan '%s' is set to Closed.") % name self.log(cr, uid, id, message) return True def get_loan_discounts(self, cr, uid, employee_id, expense_id, context=None): expense_line_obj = self.pool.get('tms.expense.line') expense_obj = self.pool.get('tms.expense') res = expense_line_obj.search(cr, uid, [('expense_id', '=', expense_id),('control','=', 1),('loan_id','!=',False)]) #print "res: ", res if len(res): loan_ids = [] expense_line_ids = [] for x in expense_obj.browse(cr, uid, [expense_id])[0].expense_line: if x.loan_id.id: loan_ids.append(x.loan_id.id) expense_line_ids.append(x.id) if len(loan_ids): expense_line_obj.unlink(cr, uid, expense_line_ids) self.write(cr, uid,loan_ids, {'state':'confirmed', 'closed_by' : False, 'date_closed':False} ) prod_obj = self.pool.get('product.product') loan_ids = self.search(cr, uid, [('employee_id', '=', employee_id),('state','=','confirmed'),('balance', '>', 0.0)]) flag_each = True fecha_liq = expense_obj.read(cr, uid, [expense_id], ['date'])[0]['date'] for rec in self.browse(cr, uid, loan_ids, context=context): if rec.discount_method in ('weekly','fortnightly','monthy'): cr.execute('select date from tms_expense_line where loan_id = %s order by date desc limit 1' % (rec.id)) data = filter(None, map(lambda x:x[0], cr.fetchall())) date = data[0] if data else rec.date #print "fecha_liq: ", fecha_liq dur = datetime.strptime(fecha_liq, '%Y-%m-%d') - datetime.strptime(date, '%Y-%m-%d') product = prod_obj.browse(cr, uid, [rec.product_id.id])[0] xfactor = 7 if rec.discount_method == 'weekly' else 14.0 if rec.discount_method == 'fortnightly' else 28.0 rango = 1 if not int(dur.days / xfactor) else int(dur.days / xfactor) + 1 balance = rec.balance while rango and balance: rango -= 1 discount = rec.fixed_discount if rec.discount_type == 'fixed' else rec.amount * rec.percent_discount / 100.0 discount = balance if discount > balance else discount balance -= discount xline = { 'expense_id' : expense_id, 'line_type' : product.tms_category, 'name' : product.name + ' - ' + rec.name, 'sequence' : 100, 'product_id' : product.id, 'product_uom' : product.uom_id.id, 'product_uom_qty' : 1, 'price_unit' : discount * -1.0, 'control' : True, 'loan_id' : rec.id, #'operation_id' : travel.operation_id.id, #'tax_id' : [(6, 0, [x.id for x in product.supplier_taxes_id])], } res = expense_line_obj.create(cr, uid, xline) if discount >= rec.balance: self.write(cr, uid, [rec.id], {'state':'closed', 'closed_by' : uid, 'date_closed':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) for (id,name) in self.name_get(cr, uid, [rec.id]): message = _("Loan '%s' has been Closed.") % rec.name self.log(cr, uid, id, message) elif rec.discount_method == 'each' and flag_each: # Buscaoms el ultimo descuento de prestamo de tipo "En cada liquidacion" cr.execute("""select date from tms_expense_line where loan_id in (select id from tms_expense_loan where employee_id=%s and discount_method='each' and state in ('closed','confirmed')) order by date desc limit 1; """ % (rec.employee_id.id)) data = filter(None, map(lambda x:x[0], cr.fetchall())) date = data and data[0] or rec.date if date >= fecha_liq: continue flag_each = False cr.execute('select date from tms_expense_line where loan_id = %s order by date desc limit 1' % (rec.id)) data = filter(None, map(lambda x:x[0], cr.fetchall())) date = data[0] if data else rec.date #print "fecha_liq: ", fecha_liq dur = datetime.strptime(fecha_liq, '%Y-%m-%d') - datetime.strptime(date, '%Y-%m-%d') product = prod_obj.browse(cr, uid, [rec.product_id.id])[0] balance = rec.balance discount = rec.fixed_discount if rec.discount_type == 'fixed' else rec.amount * rec.percent_discount / 100.0 discount = balance if discount > balance else discount balance -= discount xline = { 'expense_id' : expense_id, 'line_type' : product.tms_category, 'name' : product.name + ' - ' + rec.name, 'sequence' : 100, 'product_id' : product.id, 'product_uom' : product.uom_id.id, 'product_uom_qty' : 1, 'price_unit' : discount * -1.0, 'control' : True, 'loan_id' : rec.id, #'operation_id' : travel.operation_id.id, #'tax_id' : [(6, 0, [x.id for x in product.supplier_taxes_id])], } res = expense_line_obj.create(cr, uid, xline) if discount >= rec.balance: self.write(cr, uid, [rec.id], {'state':'closed', 'closed_by' : uid, 'date_closed':time.strftime(DEFAULT_SERVER_DATETIME_FORMAT)}) for (id,name) in self.name_get(cr, uid, [rec.id]): message = _("Loan '%s' has been Closed.") % rec.name self.log(cr, uid, id, message) return
if list_update_error: raise osv.except_osv("KDERP Notification",list_update_error) else: kip_ids=",".join(map(str,ids)) cr.execute("Select payment_import_id id from kderp_import_payment_line where payment_import_id in (%s) and state='draft'" % (kip_ids)) list_error=[] for new_id in cr.fetchall(): list_error.append(new_id[0]) for id in ids: if id not in list_error: self.write(cr, uid, [id], {'state':'done'}) return True _columns={ 'date':fields.date('Date', required=True, states={'done':[('readonly',True)]}, help="Date of Accounting Import Payment to Supplier to ERP"), 'name':fields.char('Code Import',size=32,required=True,select=True,states={'done':[('readonly',True)]}), 'description':fields.char('Desc.',size=128,states={'done':[('readonly',True)]}), 'import_line':fields.one2many('kderp.import.payment.line','payment_import_id','Details',states={'done':[('readonly',True)]}), 'state':fields.selection([('draft','Draft'),('done','Done')],'State',readonly=True,select=True) } _sql_constraints = [ ('supplier_payment_import_unique',"unique(name)","KDERP Error: The Code Import must be unique !") ] _defaults = { 'state': 'draft', 'date': lambda *a: time.strftime('%Y-%m-%d'), 'name':lambda *a: time.strftime('AISP-%Y%b%d.%H%M') } def load(self, cr, uid, fields, data, context=None):
class crea8s_warranty(osv.osv): _name = "crea8s.warranty" _inherit = ['mail.thread', 'ir.needaction_mixin'] def compute_total(self, cr, uid, ids, field_names, arg=None, context=None, query='', query_params=()): result = 0 res = {} for record in self.browse(cr, uid, ids): result = record.labor_charge + record.trans_charge res[record.id] = result return res _columns = { 'name': fields.char('Warranty No', size=128), 'cus_war_id': fields.many2one('res.partner.repair', 'customer'), 'cus_name': fields.related('cus_war_id','type', type='char', string='''Customer's Name'''), 'block': fields.char('Block and Street', size=256), 'pos_code': fields.related('cus_war_id','postal_code', type='char', string='Postal Code'), 'street': fields.related('cus_war_id','name', type='char', string='Street Name'), 'unit_no': fields.related('cus_war_id','unit_no', type='char', string='Unit No.'), 'telephone': fields.related('cus_war_id','telephone1', type='char', string='Telephone'), 'telephone2': fields.related('cus_war_id','telephone2', type='char', string='2'), 'pur_inv_no': fields.char('Purchase Invoice No', size=256), 'model_no': fields.char('Model No.', size=256), 'purchase_date': fields.date('Date of Purchase'), 'install_date': fields.date('Date of Installation'), 'install_by': fields.char('Installed By', size=256), 'dealer_id': fields.many2one('res.partner', '''Dealer's Name'''), 'contact_no1': fields.char('Contact No.1', size=256), 'contact_no2': fields.char('Contact No.2', size=256), 'contact_no3': fields.char('Contact No.3', size=256), 'email': fields.related('cus_war_id','email', type='char', string='Email'), 'state': fields.selection([('draft', 'Draft'), ('open', 'Open'), ('confirm', 'Confirm')], 'State'), 'remark': fields.text('Remark'), } def default_name(self, cr, uid, context={}): return self.pool.get('ir.sequence').get(cr, uid, 'crea8s.warranty') or '/' _defaults = { 'purchase_date': lambda *a: time.strftime('%Y-%m-%d'), 'state': 'draft', 'name': '/', } def create(self, cr, uid, vals, context={}): if vals.get('name', False) == '/': vals['name'] = self.default_name(cr, uid, context) return super(crea8s_warranty, self).create(cr, uid, vals, context) def action_open(self, cr, uid, ids, context={}): self.write(cr, uid, ids, {'state': 'open'}) return 1 def action_confirm(self, cr, uid, ids, context={}): self.write(cr, uid, ids, {'state': 'confirm'}) return 1 def action_cancel(self, cr, uid, ids, context={}): self.write(cr, uid, ids, {'state': 'draft'}) return 1 def button_dummy(self,cr, uid, ids, context={}): return 1
class manuscrito(orm.Model): _name = 'res.manuscrito' _description = 'Manuscrito' _columns = { 'autor': fields.many2one('res.partner', 'Autor', track_visibility='onchange',required=True, select=True),domain="[('author','=',True)]"), 'partner_id': fields.many2one('res.partner', 'Partner', ondelete='set null', track_visibility='onchange', select=True, help="Linked partner (optional). Usually created when converting the lead."), 'titulo': fields.char('Título', size=50, required=True), 'isbn':fields.char('ISBN', size=30, required=True), 'formato':fields.char('Formato', size=30), 'genero':fields.selection([('ciencia-ficcion','Ciencia-Ficcion'),('novela','Novela'),('poesia','Poesía'),('cuento','Cuento'),('historia','Historia'),('miedo','Miedo'),('otro','Otros')],'Género', required=True), 'email':fields.char('E-MAIL',size=20), 'comment': fields.text('Descripción'), 'image': fields.binary("Image", help="Select image here"), 'date': fields.date('Date', select=1), 'idioma':fields.selection([('cas','Castellano'),('en','Inglés'),('fr','Francés')],'Idioma'), 'state': fields.selection([('recibo', 'Acuse recibo'),('eval', 'Evaluación'),('confirmacion','Pendiente confirmación'),('cancelled', 'Cancelado'),('firma', 'Firma Contrato'),('corregir', 'Corrección'),('reenvio', 'Visto bueno autor'),('envio imprenta', 'Enviado a imprenta'), ('done', 'Hecho')]), } def set_recibo(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'eval'}, context=context) def set_evaluar(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'confirmacion'}, context=context) def set_aceptar(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'firma'}, context=context) def set_firmar(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'corregir'}, context=context) def set_corregir(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'reenvio'}, context=context) def set_visto(self, cr, uid, ids, context=None): return self.write(cr, uid, ids, {'state': 'done'}, context=context)
class crea8s_repair(osv.osv): _name = "crea8s.repair" _inherit = ['mail.thread', 'ir.needaction_mixin'] def compute_total(self, cr, uid, ids, field_names, arg=None, context=None, query='', query_params=()): result = 0 res = {} for record in self.browse(cr, uid, ids): result = record.labor_charge + record.trans_charge + sum([x.amount for x in record.repair_line]) res[record.id] = result return res def onchange_customer(self,cr, uid, ids, customer_id): partner_obj = self.pool.get('res.partner.repair') partner_br = partner_obj.browse(cr, uid, customer_id) return {'value': {'unit_no': partner_br.unit_no and partner_br.unit_no or '', 'pos_code': partner_br.postal_code and partner_br.postal_code or '', 'block': partner_br.name and partner_br.name or '',}} _columns = { 'name': fields.char('Job Number', size=128), 'customer_id': fields.many2one('res.partner', 'Customer'), 'cus_repair_id': fields.many2one('res.partner.repair', 'Customer'), 'block': fields.char('Block and Street', size=256), #related('cus_repair_id','block', type='char', store=True, string='Block'), 'pos_code': fields.char('Postal Code', size=128), 'unit_no': fields.char('Unit No', size=128), #related('cus_repair_id','postal_code', type='char', store=True, string='Postal Code'), 'dealer_id': fields.char('Dealer', size=256), 'telephone1': fields.related('cus_repair_id','telephone1', type='char', string='Telephone', store=True), 'telephone2': fields.related('cus_repair_id','telephone2', type='char', string='2'), 'telephone3': fields.related('cus_repair_id','telephone3', type='char', string='3'), 'date': fields.date('Date'), 'appointment_date': fields.datetime('Appointment Date'), 'tech_person': fields.many2one('crea8s.repair.user', 'Technician'), 'model_no': fields.char('Model No', size=256), 'purchase_date': fields.char('Purchase Date', size=128), 'attend_by': fields.many2one('crea8s.repair.user', 'Attend By'), 'type': fields.selection([('INSTALLING', 'INSTALLING'), ('SERVICING', 'SERVICING')], 'Type'), 'description': fields.text('Description'), 'remark': fields.text('Remark'), 'trans_charge': fields.float('Transport Charge', digits=(16,2)), 'labor_charge': fields.float('Labour Charge', digits=(16,2)), 'subtotal_charge': fields.float('Sub-Total Charge', digits=(16,2)), #fields.function(compute_total, digits_compute=dp.get_precision('Account'), store=True, string='Sub-Total Charge'), 'state': fields.selection([('draft', 'Draft'), ('open', 'Open'), ('confirm', 'Confirm')], 'State'), 'repair_line': fields.one2many('crea8s.repair.line', 'repair_id', 'Repair Line'), 'is_cash': fields.boolean('CASH'), 'is_cheque': fields.boolean('CHEQUE'), 'cheque_num': fields.char('Cheque Number'), 'hide_remark': fields.text('Internal Remark'), 'amount_total': fields.function(compute_total, digits_compute=dp.get_precision('Account'), string='Total'), } def default_name(self, cr, uid, context={}): return self.pool.get('ir.sequence').get(cr, uid, 'crea8s.repair') or '/' _defaults = { 'date': lambda *a: time.strftime('%Y-%m-%d'), 'state': 'draft', 'name': '/', } def insert_telephone(self, cr, uid, ids, partner_id, telephone): partner_obj = self.pool.get('res.partner.repair') return partner_obj.write(cr, uid, partner_id, {'telephone1': telephone}) def get_partner(self, cr, uid, ids, partner_name, partner_unitno, telephone): partner_obj = self.pool.get('res.partner.repair') partner_id = partner_obj.search(cr, uid, [('name', '=',partner_name), ('unit_no', '=', partner_unitno)]) partner_id = partner_id and partner_id[0] or 0 if not partner_id: partner_id = partner_obj.search(cr, uid, [('name', '=',partner_name), ('telephone1', '=', telephone)]) partner_id = partner_id and partner_id[0] or 0 return partner_id def get_user(self, cr, uid, ids, user_name): user_obj = self.pool.get('crea8s.repair.user') user_id = user_obj.search(cr, uid, [('name', '=', user_name)]) user_id = user_id and user_id[0] or 0 if not user_id: user_id = user_obj.create(cr, uid, {'name': user_name}) return user_id def get_date(self, date_or): result = datetime.date(int(date_or[:4]), int(date_or[5:7]), int(date_or[8:10])) return result def get_date_time(self, date_or): result = datetime.datetime(int(date_or[:4]), int(date_or[5:7]), int(date_or[8:10]), int(date_or[11:13]), int(date_or[14:16]), int(date_or[17:19])) return result def get_state(self, cr, uid, ids, state): result = '' if state == 'Draft': result = 'draft' elif state == 'Open': result = 'open' else: result = 'confirm' return result def import_csv_file(self, cr, uid, ids, context={}): user_obj = self.pool.get('crea8s.repair.user') partner_obj = self.pool.get('res.partner.repair') for record in self.browse(cr, uid, ids): ifile = open('C:\\Users\\tri\\Desktop\\import\\July15\\import_fanco.csv', 'rb') reader = csv.reader(ifile) a = 0 for row in reader: a += 1 if a > 1: if 2>1: # try: cus_id = self.get_partner(cr, uid, ids, row[2], row[5], row[23]) attend_id = self.get_user(cr, uid, ids, row[1]) tech_id = self.get_user(cr, uid, ids, row[3]) vals_re = { 'name': row[4], 'cus_repair_id': cus_id, 'block': row[9], 'pos_code': row[19], 'unit_no': row[5], 'dealer_id': row[14], 'tech_person': tech_id, 'model_no': row[18], 'purchase_date': row[20], 'attend_by': attend_id, 'type': row[6], 'description': row[15], 'remark': row[21], 'trans_charge': row[24] and float(row[24]) or 0, 'labor_charge': row[17] and float(row[17]) or 0, 'subtotal_charge': row[22] and float(row[22]) or 0, 'state': self.get_state(cr, uid, ids, row[7]), 'is_cash': row[10], 'is_cheque': row[11], 'cheque_num': row[12], 'hide_remark': row[16],} if row[13]: vals_re.update({'date': self.get_date(row[13]),}) if row[8]: vals_re.update({'appointment_date': self.get_date_time(row[8])}) self.create(cr, uid, vals_re) # except: # print row[4], ' ', row[2], ' ', row[5], ' ', row[23] return 1 def create(self, cr, uid, vals, context={}): if vals.get('name', False) == '/': vals['name'] = self.default_name(cr, uid, context) return super(crea8s_repair, self).create(cr, uid, vals, context) def action_open(self, cr, uid, ids, context={}): self.write(cr, uid, ids, {'state': 'open'}) #print self.pool.get('res.partner.repair').search(cr, uid, []) return 1 def action_confirm(self, cr, uid, ids, context={}): self.write(cr, uid, ids, {'state': 'confirm'}) return 1 def action_cancel(self, cr, uid, ids, context={}): self.write(cr, uid, ids, {'state': 'draft'}) return 1 def button_dummy(self,cr, uid, ids, context={}): return 1
def onchange_amount(self, cr, uid, ids, amount, rate, partner_id, journal_id, currency_id, ttype, date, payment_rate_currency_id, company_id, context=None): res = super(account_voucher, self).onchange_amount(cr, uid, ids, amount, rate, partner_id, journal_id, currency_id, ttype, date, payment_rate_currency_id, company_id, context=context) res['value'].update({'cc_order_amt':amount, 'cc_refund_amt':amount}) return res _inherit = 'account.voucher' _columns = { 'cc_name':fields.char("Card Holder's Name", size=32,), 'cc_b_addr_1':fields.char('Billing Address1', size=32,), 'cc_b_addr_2':fields.char('Billing Address2', size=32,), 'cc_city': fields.char('City', size=32,), 'cc_state':fields.char('State', size=32,), 'cc_zip':fields.char('Postal/Zip', size=32,), 'cc_country':fields.char('Country', size=32,), 'cc_order_date':fields.date('Order Date',), <<<<<<< HEAD 'cc_order_amt':fields.float('Order Amt'), ======= 'cc_order_amt':fields.float('Order Amt',required=True), >>>>>>> c1979f64b3360c86d60e00c92be0271d89f97f2d 'cc_number':fields.char('Credit Card Number', size=256), 'cc_v':fields.char('Card Code Verification', size=3), 'cc_e_d_month':fields.char('Expiration Date MM', size=32), 'cc_e_d_year':fields.char('Expiration Date YY', size=32), 'cc_comment':fields.char('Comment', size=128,), 'cc_auth_code':fields.char('Authorization Code', size=32), 'cc_save_card_details':fields.boolean('Save Credit Card details'), 'cc_ecommerce_sale':fields.boolean('Ecommerce sale'), 'cc_p_authorize':fields.boolean('Pre-authorize'), 'cc_charge':fields.boolean('Charge'),
class wizard_confirm_payment(orm.TransientModel): _name = 'wizard.confirm.payment' _description = 'Wizard Confirm Payment' _columns = { 'period_id': fields.many2one('account.period', 'Period'), 'operation_date': fields.date('Operation Date', required=True), 'document_date': fields.date('Document Date', required=True, states={'draft': [('readonly', False)]}, select=True), 'currency_date': fields.date('Currency Date'), 'partner_id': fields.many2one('res.partner', 'Supplier'), 'maturity': fields.date('Maturity Maximum'), 'journal_id': fields.many2one('account.journal', 'Journal'), 'line_ids': fields.one2many('wizard.confirm.payment.line', 'confirm_payment_id'), 'bank_id': fields.many2one('res.partner.bank', 'bank'), 'all_supplier': fields.boolean('All suppliers'), 'it_supplier': fields.boolean('Italian suppliers'), 'ext_supplier': fields.boolean('Foreign suppliers') } def create_voucher(self, cr, uid, ids, context=None): account_voucher_obj = self.pool.get('account.voucher') t_res = account_voucher_obj.create_validate_voucher( cr, uid, ids, context) return t_res def set_confirm_values(self, cr, uid, ids, context=None): if context is None: context = {} mod_obj = self.pool.get('ir.model.data') result = mod_obj.get_object_reference(cr, uid, 'account_voucher_makeover', 'wizard_values_confirm_view') t_cp = self.browse(cr, uid, ids[0]) context.update({ 'default_partner_id': t_cp.partner_id.id, 'default_all_supplier': t_cp.all_supplier, 'default_it_supplier': t_cp.it_supplier, 'default_ext_supplier': t_cp.ext_supplier, 'default_maturity': t_cp.maturity, 'default_operation_date': t_cp.operation_date, 'default_currency_date': t_cp.currency_date, }) view_id = result and result[1] or False return { 'name': _("Conferma Impostazione Valori"), 'view_type': 'form', 'view_mode': 'form', 'res_model': 'wizard.values.confirm', 'type': 'ir.actions.act_window', 'view_id': view_id, 'context': context, 'target': 'new', } _defaults = { 'operation_date': fields.date.context_today, 'document_date': fields.date.context_today, 'currency_date': fields.date.context_today, }
class payroll_advice(osv.osv): ''' Bank Advice ''' _name = 'hr.payroll.advice' _description = 'Bank Advice' _columns = { 'name': fields.char( 'Name', readonly=True, required=True, states={'draft': [('readonly', False)]}, ), 'note': fields.text('Description'), 'date': fields.date('Date', readonly=True, required=True, states={'draft': [('readonly', False)]}, help="Advice Date is used to search Payslips"), 'state': fields.selection([ ('draft', 'Draft'), ('confirm', 'Confirmed'), ('cancel', 'Cancelled'), ], 'Status', select=True, readonly=True), 'number': fields.char('Reference', readonly=True), 'line_ids': fields.one2many('hr.payroll.advice.line', 'advice_id', 'Employee Salary', states={'draft': [('readonly', False)]}, readonly=True, copy=True), 'chaque_nos': fields.char('Cheque Numbers'), 'neft': fields.boolean( 'NEFT Transaction', help="Check this box if your company use online transfer for salary" ), 'company_id': fields.many2one('res.company', 'Company', required=True, readonly=True, states={'draft': [('readonly', False)]}), 'bank_id': fields.many2one( 'res.bank', 'Bank', readonly=True, states={'draft': [('readonly', False)] }, help="Select the Bank from which the salary is going to be paid"), 'batch_id': fields.many2one('hr.payslip.run', 'Batch', readonly=True) } _defaults = { 'date': lambda * a: time.strftime('%Y-%m-%d'), 'state': lambda * a: 'draft', 'company_id': lambda self, cr, uid, context: \ self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id.id, 'note': "Please make the payroll transfer from above account number to the below mentioned account numbers towards employee salaries:" } def compute_advice(self, cr, uid, ids, context=None): """ Advice - Create Advice lines in Payment Advice and compute Advice lines. @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @param ids: List of Advice’s IDs @return: Advice lines @param context: A standard dictionary for contextual values """ payslip_pool = self.pool.get('hr.payslip') advice_line_pool = self.pool.get('hr.payroll.advice.line') payslip_line_pool = self.pool.get('hr.payslip.line') for advice in self.browse(cr, uid, ids, context=context): old_line_ids = advice_line_pool.search( cr, uid, [('advice_id', '=', advice.id)], context=context) if old_line_ids: advice_line_pool.unlink(cr, uid, old_line_ids, context=context) slip_ids = payslip_pool.search(cr, uid, [('date_from', '<=', advice.date), ('date_to', '>=', advice.date), ('state', '=', 'done')], context=context) for slip in payslip_pool.browse(cr, uid, slip_ids, context=context): if not slip.employee_id.bank_account_id and not slip.employee_id.bank_account_id.acc_number: raise UserError( _('Please define bank account for the %s employee') % (slip.employee_id.name, )) line_ids = payslip_line_pool.search(cr, uid, [('slip_id', '=', slip.id), ('code', '=', 'NET')], context=context) if line_ids: line = payslip_line_pool.browse(cr, uid, line_ids, context=context)[0] advice_line = { 'advice_id': advice.id, 'name': slip.employee_id.bank_account_id.acc_number, 'employee_id': slip.employee_id.id, 'bysal': line.total } advice_line_pool.create(cr, uid, advice_line, context=context) payslip_pool.write(cr, uid, slip_ids, {'advice_id': advice.id}, context=context) return True def confirm_sheet(self, cr, uid, ids, context=None): """ confirm Advice - confirmed Advice after computing Advice Lines.. @param cr: the current row, from the database cursor, @param uid: the current user’s ID for security checks, @param ids: List of confirm Advice’s IDs @return: confirmed Advice lines and set sequence of Advice. @param context: A standard dictionary for contextual values """ seq_obj = self.pool.get('ir.sequence') for advice in self.browse(cr, uid, ids, context=context): if not advice.line_ids: raise UserError( _('You can not confirm Payment advice without advice lines.' )) advice_date = datetime.strptime(advice.date, DATETIME_FORMAT) advice_year = advice_date.strftime( '%m') + '-' + advice_date.strftime('%Y') number = seq_obj.next_by_code(cr, uid, 'payment.advice') sequence_num = 'PAY' + '/' + advice_year + '/' + number self.write(cr, uid, [advice.id], { 'number': sequence_num, 'state': 'confirm' }, context=context) return True def set_to_draft(self, cr, uid, ids, context=None): """Resets Advice as draft. """ return self.write(cr, uid, ids, {'state': 'draft'}, context=context) def cancel_sheet(self, cr, uid, ids, context=None): """Marks Advice as cancelled. """ return self.write(cr, uid, ids, {'state': 'cancel'}, context=context) def onchange_company_id(self, cr, uid, ids, company_id=False, context=None): res = {} if company_id: company = self.pool.get('res.company').browse(cr, uid, [company_id], context=context)[0] if company.partner_id.bank_ids: res.update({'bank_id': company.partner_id.bank_ids[0].bank.id}) return {'value': res}
class StockAccrualWizard(osv.osv_memory): _name = 'stock.accrual.wizard' _rec_name = 'type' def _get_default_company(self, cr, uid, context=None): company_id = self.pool.get('res.users')._get_company(cr, uid, context=context) if not company_id: raise osv.except_osv( _('Error!'), _('There is no default company for the current user!')) return company_id def _get_debit_credit(self, cr, uid, ids, field_names=None, arg=False, context=None): """ Finds Grand total on debits and credits on wizard. @return: Dictionary of values """ field_names = field_names or [] context = dict(context or {}) res = {} for idx in ids: res[idx] = {}.fromkeys(field_names, 0.0) for brw in self.browse(cr, uid, ids, context=context): for lbrw in brw.line_ids: for fn in field_names: res[brw.id][fn] += getattr(lbrw, fn) return res _columns = { 'type': fields.selection(SELECTION_TYPE, string='Type', required=True), 'report_format': fields.selection([('pdf', 'PDF'), ('xls', 'Spreadsheet')], 'Report Format', required=True), 'fy_start_id': fields.many2one( 'account.fiscalyear', 'From Fiscal Year', help='Fiscal Year', required=False, ), 'fy_stop_id': fields.many2one( 'account.fiscalyear', 'To Fiscal Year', help='Fiscal Year', required=False, ), 'period_start_id': fields.many2one( 'account.period', domain=("[('special','=',False)," "('fiscalyear_id','=',fy_start_id)," "('company_id','=',company_id)]"), string='From Period', required=False, ), 'period_stop_id': fields.many2one( 'account.period', domain=("[('special','=',False)," "('fiscalyear_id','=',fy_stop_id)," "('company_id','=',company_id)]"), string='To Period', required=False, ), 'date_start': fields.date( 'From Date', required=True, ), 'date_stop': fields.date( 'To Date', required=True, ), 'line_ids': fields.one2many( 'stock.accrual.wizard.line', 'wzd_id', 'Lines', ), 'company_id': fields.many2one( 'res.company', 'Company', required=True, ), 'user_id': fields.many2one('res.users', 'User'), 'debit': fields.function(_get_debit_credit, type='float', digits_compute=dp.get_precision('Account'), string='Debit', multi='debit_credit', help="Debit"), 'credit': fields.function(_get_debit_credit, type='float', digits_compute=dp.get_precision('Account'), string='Credit', multi='debit_credit', help="Credit"), 'filter': fields.selection( [ ('bydate', 'By Date'), ('byperiod', 'By Period'), ], string='Date/Period Filter', required=True, ), 'time_span': fields.selection( [ ('all_periods', 'All Periods'), ('this_period', 'This Period Only'), ], string='Lines on:', required=True, ), 'accrual_filter': fields.selection( [ ('all_lines', 'Bring All Order Lines'), ('with_accrual', 'Only with Accruals'), ], string='Accrual on Lines:', required=True, ), 'reconcile_filter': fields.selection( [ ('all_lines', 'Bring All Accruals'), ('fully_reconcile', 'Only Fully Reconciled Accruals'), ('unreconciled', 'Unreconciled & Partial Reconciled Accruals'), ], string='Reconciliation:', required=True, ), } _defaults = { 'report_format': lambda *args: 'pdf', 'time_span': lambda *args: 'this_period', 'accrual_filter': lambda *args: 'all_lines', 'reconcile_filter': lambda *args: 'all_lines', 'filter': lambda *args: 'byperiod', 'type': lambda *args: 'sale', 'company_id': _get_default_company, 'user_id': lambda s, c, u, cx: s.pool.get('res.users').browse(c, u, u, cx).id, 'fy_start_id': lambda s, c, u, cx: s.pool['account.fiscalyear'].find( c, u, exception=False), 'fy_stop_id': lambda s, c, u, cx: s.pool['account.fiscalyear'].find( c, u, exception=False), } def _check_duration(self, cr, uid, ids, context=None): ids = isinstance(ids, (int, long)) and [ids] or ids obj_fy = self.browse(cr, uid, ids[0], context=context) if obj_fy.date_stop < obj_fy.date_start: return False return True _constraints = [ (_check_duration, 'Error!\nBeginning and Ending Dates in report are not logical.', ['date_start', 'date_stop']) ] def onchange_period_id(self, cr, uid, ids, period_id=False, start=True, context=None): ap_obj = self.pool.get('account.period') res = {} if period_id: ap_brw = ap_obj.browse(cr, uid, period_id, context=context) res['value'] = { start and 'date_start' or 'date_stop': start and ap_brw.date_start or ap_brw.date_stop } return res def _get_accrual(self, cr, uid, wzd_brw, line_brw, context=None): context = context or {} res = {'debit': 0.0, 'credit': 0.0} for move in line_brw.move_ids: for aml_brw in move.aml_ids: # Account must be reciliable in order to bring it back if not aml_brw.account_id.reconcile: continue # Include a filter to retrieve only values from period if (wzd_brw.time_span == 'this_period' and not (aml_brw.date >= wzd_brw.date_start and aml_brw.date <= wzd_brw.date_stop)): continue if (wzd_brw.reconcile_filter == 'fully_reconcile' and not aml_brw.reconcile_id): continue if (wzd_brw.reconcile_filter == 'unreconciled' and aml_brw.reconcile_id): continue res['debit'] += aml_brw.debit res['credit'] += aml_brw.credit return res def _get_lines(self, cr, uid, wzd_brw, order_brw, line_brw, context=None): context = context or {} if 'sale' in order_brw._name: product_qty = line_brw.product_uom_qty if 'purchase' in order_brw._name: product_qty = line_brw.product_qty res = { 'wzd_id': wzd_brw.id, 'order_id': '%s,%s' % (order_brw._name, order_brw.id), 'line_id': '%s,%s' % (line_brw._name, line_brw.id), 'product_qty': product_qty, 'product_uom': line_brw.product_uom.id, 'qty_delivered': line_brw.qty_delivered, 'qty_invoiced': line_brw.qty_invoiced, } res.update( self._get_accrual(cr, uid, wzd_brw, line_brw, context=context)) return res def _get_lines_from_stock(self, cr, uid, ids, context=None): context = context or {} ids = isinstance(ids, (int, long)) and [ids] or ids res = [] wzd_brw = self.browse(cr, uid, ids[0], context=context) ttype = 'sale' if wzd_brw.type == 'sale' else 'purchase' query = QUERY_LINE_MOVE.format( ttype=ttype, company_id=wzd_brw.company_id.id, date_start=wzd_brw.date_start, date_stop=wzd_brw.date_stop, ) cr.execute(query) res = cr.fetchall() res = [val[0] for val in res] return set(res) def _get_lines_from_invoice(self, cr, uid, ids, context=None): context = context or {} ids = isinstance(ids, (int, long)) and [ids] or ids res = [] wzd_brw = self.browse(cr, uid, ids[0], context=context) ttype = 'sale' if wzd_brw.type == 'sale' else 'purchase' query = QUERY_LINE_INVOICE.format( ttype=ttype, company_id=wzd_brw.company_id.id, date_start=wzd_brw.date_start, date_stop=wzd_brw.date_stop, ) cr.execute(query) res = cr.fetchall() res = [val[0] for val in res] return set(res) def _get_orders_from_stock(self, cr, uid, ids, context=None): context = context or {} ids = isinstance(ids, (int, long)) and [ids] or ids res = [] wzd_brw = self.browse(cr, uid, ids[0], context=context) ttype = 'sale' if wzd_brw.type == 'sale' else 'purchase' query = QUERY_MOVE.format( ttype=ttype, company_id=wzd_brw.company_id.id, date_start=wzd_brw.date_start, date_stop=wzd_brw.date_stop, ) cr.execute(query) res = cr.fetchall() res = [val[0] for val in res] return set(res) def _get_orders_from_invoice(self, cr, uid, ids, context=None): context = context or {} ids = isinstance(ids, (int, long)) and [ids] or ids res = [] wzd_brw = self.browse(cr, uid, ids[0], context=context) ttype = 'sale' if wzd_brw.type == 'sale' else 'purchase' query = QUERY_INVOICE.format( ttype=ttype, company_id=wzd_brw.company_id.id, date_start=wzd_brw.date_start, date_stop=wzd_brw.date_stop, ) cr.execute(query) res = cr.fetchall() res = [val[0] for val in res] return set(res) def compute_order_lines(self, cr, uid, ids, context=None): context = dict(context or {}) ids = isinstance(ids, (int, long)) and [ids] or ids wzd_brw = self.browse(cr, uid, ids[0], context=context) res = [] if wzd_brw.time_span == 'all_periods': order_obj = self.pool.get('%s.order' % wzd_brw.type) record_ids = self._get_orders_from_stock(cr, uid, ids, context=context) record_idx = self._get_orders_from_invoice(cr, uid, ids, context=context) record_ids = record_ids | record_idx order_brws = [] if record_ids: record_ids = list(record_ids) order_brws = order_obj.browse(cr, uid, record_ids, context=context) for order_brw in order_brws: for line_brw in order_brw.order_line: res.append( self._get_lines(cr, uid, wzd_brw, order_brw, line_brw, context=context)) elif wzd_brw.time_span == 'this_period': context.update( dict( date_start=wzd_brw.date_start, date_stop=wzd_brw.date_stop, )) order_obj = self.pool.get('%s.order.line' % wzd_brw.type) record_ids = self._get_lines_from_stock(cr, uid, ids, context=context) record_idx = self._get_lines_from_invoice(cr, uid, ids, context=context) record_ids = record_ids | record_idx order_brws = [] if record_ids: record_ids = list(record_ids) order_brws = order_obj.browse(cr, uid, record_ids, context=context) for line_brw in order_brws: res.append( self._get_lines(cr, uid, wzd_brw, line_brw.order_id, line_brw, context=context)) return res def compute_lines(self, cr, uid, ids, context=None): context = context or {} ids = isinstance(ids, (int, long)) and [ids] or ids sawl_obj = self.pool.get('stock.accrual.wizard.line') wzd_brw = self.browse(cr, uid, ids[0], context=context) res = [] wzd_brw.line_ids.unlink() res = self.compute_order_lines(cr, uid, ids, context=context) for rex in res: if (wzd_brw.accrual_filter == 'with_accrual' and not any([rex['debit'], rex['credit']])): continue sawl_obj.create(cr, uid, rex, context=context) return True def show_lines(self, cr, uid, ids, context=None): context = dict(context or {}) ids = isinstance(ids, (int, long)) and [ids] or ids wzd_brw = self.browse(cr, uid, ids[0], context=context) self.compute_lines(cr, uid, ids, context=context) res = [line.id for line in wzd_brw.line_ids] if len(res) >= 1: res = "[('id','in', [%s])]" % ','.join([str(rex) for rex in res]) else: res = "[('id','in',[])]" return { 'domain': res, 'name': _('Stock Accrual Lines'), 'view_type': 'form', 'view_mode': 'tree', 'res_model': 'stock.accrual.wizard.line', 'view_id': False, 'type': 'ir.actions.act_window' } def print_report(self, cr, uid, ids, context=None): """To get the date and print the report @return : return report """ context = dict(context or {}) ids = isinstance(ids, (int, long)) and [ids] or ids wzd_brw = self.browse(cr, uid, ids[0], context=context) self.compute_lines(cr, uid, ids, context=context) datas = {'active_ids': ids} context['active_ids'] = ids context['active_model'] = 'stock.accrual.wizard' context['xls_report'] = wzd_brw.report_format == 'xls' name = 'stock_accrual_report.stock_accrual_report_name' return self.pool['report'].get_action(cr, uid, [], name, data=datas, context=context)
# These are the Fiscal Attributes which are checked at runtime on the invoice-line level. As a many2many you can # select a custom number out of the Fiscal Attributes Table. Typically you might want to constrain the choice to # an above set Fiscal Domain (optional). Typically when parametrizing you might filter by Attribute Use (eg. # 'partner' or 'product' cases for convenience. (planned partner specific roles: 'seller' 'invoiced partner' # 'shipped partner' 'fiscal_attributes_id': fields.many2many( 'account.fiscal.attribute', 'fiscal_attribute_rel', 'rule_id', 'attr_id', 'Fiscal Attributes', # TODO this probably might result in problems as templates do not have field company_id domain="[('company_id','=',company_id),('fiscal_domain_id','=',fiscal_domain_id)]"), 'use_sale': fields.boolean('Sales Order'), 'use_invoice': fields.boolean('Invoices'), 'use_purchase': fields.boolean('Purchases'), 'use_picking': fields.boolean('Picking'), 'date_start': fields.date( 'from', help="Starting date for this rule to be valid."), 'date_end': fields.date( 'until', help="Ending date for this rule to be valid."), 'vat_rule': fields.selection( [('with', 'With VAT number'), ('both', 'With or Without VAT number'), ('without', 'Without VAT number')], "VAT Rule", help=("Choose if the customer need to have the" " field VAT fill for using this fiscal position")), 'sequence': fields.integer( 'Priority', help='Unused, unless you use account replacement. Within a sequence, the rule with ' 'the highest sequence AND which has an account replacement defined, will apply ' 'across all fiscal domains will.'), # --- APPLICATION SECTION ---
class kite_departmentmaster(osv.osv): _name = "kite.departmentmaster" _description = "Kite departmentmaster" _order = "GRN_date desc" _columns = { 'supplier': fields.char('Number', size=128, select=True, required=True, readonly=True, states={'draft': [('readonly', False)]}), 'GRN_date': fields.date('GRN Date', readonly=True), 'GRN_No': fields.float('GRN No', size=128), 'state': fields.selection([('draft', 'Draft'), ('cancel', 'Cancelled'), ('confirm', 'Confirmed')], 'Status', readonly=False), 'line_id': fields.one2many('kite.departmentmaster.line', 'Item_Name', 'product line', readonly=True, states={'draft': [('readonly', False)]}), 'GRN_type': fields.selection([('direct', 'Direct'), ('fromcp', 'From Purchase Planning')], 'GRN Type', readonly=True, states={'draft': [('readonly', False)]}), 'DC_Date': fields.date('DC Date', readonly=True), 'creation_Date': fields.date('creation Date', readonly=True), 'Created_By': fields.char('Created By', size=128, select=True, required=True, readonly=True, states={'draft': [('readonly', False)]}), } _defaults = { 'GRN_date': fields.date.context_today, #~ 'status':'draft', } def create(self, cr, uid, vals, context=None): if vals.get('name', '/') == '/': vals['name'] = self.pool.get('ir.sequence').get( cr, uid, 'kite.departmentmaster') or '/' order = super(kite_departmentmaster, self).create(cr, uid, vals, context=context) return order def confirm_purchase(self, cr, uid, ids, context=None): #~ purchase_plan_obj = self.pool.get('kite.general.planning') rec = self.browse(cr, uid, ids[0]) rec.write({'state': 'confirm'})