def _check_selection(self, cr, uid, selection, context=None): try: selection_list = eval(selection) except Exception: _logger.warning("Invalid selection list definition for fields.selection", exc_info=True) raise except_orm( _("Error"), _( "The Selection Options expression is not a valid Pythonic expression." "Please provide an expression in the [('key','Label'), ...] format." ), ) check = True if not (isinstance(selection_list, list) and selection_list): check = False else: for item in selection_list: if not (isinstance(item, (tuple, list)) and len(item) == 2): check = False break if not check: raise except_orm( _("Error"), _("The Selection Options expression is must be in the [('key','Label'), ...] format!") ) return True
def execute_import(self): obj = self[0] if not obj.choices: raise except_orm('Error', 'You have to select a category!!!') if obj.file: data = base64.decodestring(obj.file) try: document = xlrd.open_workbook(file_contents=data) except: raise except_orm('Error', _('Wrong file!!!')) msg = getattr(obj, 'import_' + obj.choices)(document) msg = str(msg) + '\n' msg += _('Press cancel to close') if msg: obj.write({'result': msg}) else: obj.write({'result': _('Import successfully!!!!')}) return { 'name': 'Import Excels', 'type': 'ir.actions.act_window', 'view_type': 'form', 'view_mode': 'form', 'res_model': 'import.modules', 'res_id': obj.id, 'target': 'new', 'context': {}, } else: raise except_orm(_('Error!'), _('You must select a file.'))
def buy_in_approve(self): '''审核采购入库单,更新购货订单的状态和本单的付款状态,并生成源单''' if self.bank_account_id and self.payment == 0: raise except_orm(u'警告!', u'结算账户不为空时,需要输入付款额!') elif self.payment != 0 and not self.bank_account_id: raise except_orm(u'警告!', u'付款额不为空时,请选择结算账户!') order = self.env['buy.order'].search([('name', '=', self.origin)]) if order.quantity < self.line_in_ids.goods_qty: raise except_orm(u'警告!', u'入库数量不能超过购货订单数量!') elif order.quantity > self.line_in_ids.goods_qty: order.write({'state': 'part_in'}) else: order.write({'state': 'all_in'}) if self.payment > self.amount: raise except_orm(u'警告!', u'本次付款金额不能大于折后金额!') elif self.payment == 0: self.write({'state': 'confirmed'}) elif self.payment < self.amount: self.write({'state': 'part_paid'}) else: self.write({'state': 'paid'}) self.write({'approve_uid': self._uid}) return True
def _get_conversion_rate(self, from_currency, to_currency): pricelist_type = self._context.get('pricelist_type', False) or 'sale' # pricelist_type default to 'sale' and use buying rate to_currency_rate = 0.0 from_currency_rate = 0.0 # kittiu: Buying rate if pricelist_type == 'sale': if from_currency.rate == 0 or to_currency.rate == 0: date = self._context.get('date', time.strftime('%Y-%m-%d')) if from_currency.rate == 0: currency_symbol = from_currency.symbol else: currency_symbol = to_currency.symbol raise except_orm(_('Error'), _('No buying rate found \n for the currency: %s \n at the date: %s') % (currency_symbol, date)) to_currency_rate = to_currency.rate from_currency_rate = from_currency.rate # kittiu: Selling rate if pricelist_type == 'purchase': if from_currency.rate_sell == 0 or to_currency.rate_sell == 0: date = self._context.get('date', time.strftime('%Y-%m-%d')) if from_currency.rate == 0: currency_symbol = from_currency.symbol else: currency_symbol = to_currency.symbol raise except_orm(_('Error'), _('No selling rate found \n for the currency: %s \n at the date: %s') % (currency_symbol, date)) to_currency_rate = to_currency.rate_sell from_currency_rate = from_currency.rate_sell # kittiu: check Smaller/Bigger currency to_rate = to_currency.type_ref_base == 'bigger' and (1 / to_currency_rate) or to_currency_rate from_rate = from_currency.type_ref_base == 'bigger' and (1 / from_currency_rate) or from_currency_rate return to_rate / from_rate
def check_tax_lines(self, compute_taxes): account_invoice_tax_var = self.env['account.invoice.tax'] company_currency = self.company_id.currency_id if not self.tax_line: for tax in compute_taxes.values(): account_invoice_tax_var.create(tax) else: tax_key = [] for tax in self.tax_line: if tax.manual: continue # start custom change #~ key = (tax.tax_code_id.id, tax.base_code_id.id, tax.account_id.icd, tax.account_analytic_id.id) key = (tax.tax_id and tax.tax_id.id or False) # end custom change tax_key.append(key) if key not in compute_taxes: raise except_orm(_('Warning!'), _( 'Global taxes defined, but they are not in invoice lines !')) base = compute_taxes[key]['base'] if abs(base - tax.base) > company_currency.rounding: raise except_orm(_('Warning!'), _( 'Tax base different!\nClick on compute to update the tax base.')) for key in compute_taxes: if key not in tax_key: raise except_orm(_('Warning!'), _( 'Taxes are missing!\nClick on compute button.'))
def fetch_ntty_suppliers_prices(self, ntty_id, suppliers, quantities): ntty = self.env['ntty.config.settings'].get_default_ntty() if not ntty: return None ntty_service_address = ntty['ntty_service_address'] ntty_service_user_email = ntty['ntty_service_user_email'] ntty_service_token = ntty['ntty_service_token'] if not ntty_id: ntty_id = self.ntty_id req = urllib2.Request(str(ntty_service_address) + "entities/" + str(ntty_id) + "/calculate?suppliers=" + suppliers + "&quantities=" + quantities + "&return_type=short") req.add_header('X-User-Email', str(ntty_service_user_email)) req.add_header('X-User-Token', str(ntty_service_token)) try: resp = urllib2.urlopen(req) except StandardError: raise except_orm(_('Warning'), _("Error connecting to NTTY.")) return False if not resp.code == 200 and resp.msg == "OK": print "Did not manage to connect to NTTY" return {} content = resp.read() res = json.loads(content) if not res: raise except_orm(_('Warning'), _("NTTY did not return any information.")) return False return res
def _check_invoice_plan(self): if self.invoice_method == 'invoice_plan': if self.invoice_mode == 'change_price': for order_line in self.order_line: if order_line.product_qty != 1: raise UserError( _('For invoice plan mode "As 1 Job", ' 'all line quantity must equal to 1')) obj_precision = self.env['decimal.precision'] prec = obj_precision.precision_get('Account') for order_line in self.order_line: subtotal = order_line.price_subtotal invoice_lines = self.env['purchase.invoice.plan'].search( [('order_line_id', '=', order_line.id)]) total_amount = 0.0 for line in invoice_lines: total_amount += line.invoice_amount # Validate percent if round(line.invoice_percent/100 * subtotal, prec) != \ round(line.invoice_amount, prec): raise except_orm( _('Invoice Plan Percent Mismatch!'), _("%s on installment %s") % (order_line.name, line.installment)) if round(total_amount, prec) != round(subtotal, prec): raise except_orm( _('Invoice Plan Amount Mismatch!'), _("%s, plan amount %d not equal to line amount %d!") % (order_line.name, total_amount, subtotal)) return True
def money_invoice_done(self): res = super(money_invoice, self).money_invoice_done() vals = {} vouch_obj = self.env['voucher'].create({'date': self.date}) self.write({'voucher_id': vouch_obj.id}) if not self.category_id.account_id: raise except_orm(u'错误', u'请配置%s的会计科目' % (self.category_id.name)) if self.partner_id.c_category_id: partner_account_id = self.partner_id.c_category_id.account_id.id else: partner_account_id = self.partner_id.s_category_id.account_id.id if not partner_account_id: raise except_orm(u'错误', u'请配置%s的会计科目' % (self.category_id.name)) if self.category_id.type == 'income': vals.update({'vouch_obj_id': vouch_obj.id, 'partner_credit': self.partner_id.id, 'name': self.name, 'string': u'源单', 'amount': self.amount, 'credit_account_id': self.category_id.account_id.id, 'partner_debit': '', 'debit_account_id': partner_account_id }) else: vals.update({'vouch_obj_id': vouch_obj.id, 'name': self.name, 'string': u'源单', 'amount': abs(self.amount), 'credit_account_id': partner_account_id, 'debit_account_id': self.category_id.account_id.id, 'partner_credit': "", 'partner_debit': self.partner_id.id }) self.create_voucher_line(vals) return res
def check_in(self): flag = False if self.client_ids: for client in self.client_ids: if client.check: if client.guest_state == 'confirmed': flag = self.validate_traveler_data(client.partner_id) if flag: raise except_orm(_('Advertencia!'), _("Debe llenar completamente los datos del registro del Huésped... Puede hacerlo en la pestaña Datos de Registro en Clientes")) traveler_values = { 'doc_number': client.partner_id.doc_number, 'doc_type': client.partner_id.doc_type, 'last_name1': client.partner_id.last_name1, 'last_name2': client.partner_id.last_name2, 'first_name': client.partner_id.first_name, 'gender': client.partner_id.gender, 'birth_date': client.partner_id.birth_date, 'birth_country': client.partner_id.birth_place.id, 'reservation_id': self.id } self.env['traveler.register'].create(traveler_values) client.arrival_date = datetime.today() client.guest_state = 'check_in' client.register_state = 'filled' elif client.guest_state == 'check_in': client.check = False raise except_orm(_('Advertencia!'), _("Ya el huesped se encuentra en estatus Check In")) else: client.check = False raise except_orm(_('Advertencia!'), _("El huesped debe estar confirmado antes de realizar Check In")) client.check = False
def other_money_done(self): res = super(other_money_order, self).other_money_done() vals = {} vouch_obj = self.env['voucher'].create({'date': self.date}) self.write({'voucher_id': vouch_obj.id}) if not self.bank_id.account_id: raise except_orm(u'错误', u'请配置%s的会计科目' % (self.bank_id.name)) if self.type == 'other_get': for line in self.line_ids: if not line.category_id.account_id: raise except_orm(u'错误', u'请配置%s的会计科目' % (line.category_id.name)) vals.update({'vouch_obj_id': vouch_obj.id, 'name': self.name, 'string': u'其他收入单', 'credit_auxiliary_id':line.auxiliary_id, 'amount': abs(line.amount), 'credit_account_id': line.category_id.account_id.id, 'debit_account_id': self.bank_id.account_id.id, 'partner_credit': self.partner_id.id, 'partner_debit': '' }) self.env['money.invoice'].create_voucher_line(vals) else: for line in self.line_ids: if not line.category_id.account_id: raise except_orm(u'错误', u'请配置%s的会计科目' % (line.category_id.name)) vals.update({'vouch_obj_id': vouch_obj.id, 'name': self.name, 'string': u'其他支出单', 'debit_auxiliary_id':line.auxiliary_id, 'amount': abs(line.amount), 'credit_account_id': self.bank_id.account_id.id, 'debit_account_id': line.category_id.account_id.id, 'partner_credit': '', 'partner_debit': self.partner_id.id }) self.env['money.invoice'].create_voucher_line(vals) return res
def buy_in_approve(self): '''审核采购入库单,更新购货订单的状态和本单的付款状态,并生成源单''' order = self.env['buy.order'].search([('name', '=', self.origin)]) for line in order.line_ids: if line.goods_id.id == self.line_in_ids.goods_id.id: if line.quantity < self.line_in_ids.goods_qty: raise except_orm(u'警告!', u'入库数量不能超过购货订单数量!') elif line.quantity > self.line_in_ids.goods_qty: order.write({'state': 'part_in'}) else: order.write({'state': 'all_in'}) if self.payment > self.amount: raise except_orm(u'警告!', u'本次付款金额不能大于折后金额!') elif self.payment == 0: self.write({'state': 'confirmed'}) elif self.payment < self.amount: self.write({'state': 'part_paid'}) else: self.write({'state': 'paid'}) self.write({'approve_uid': self._uid}) # 生成源单 self.env['money.invoice'].create({ 'name': self.name, 'partner_id': self.partner_id.id, 'business_type': u'普通采购', 'date': fields.Date.context_today(self), 'amount': self.debt, 'reconciled': 0.0, 'to_reconcile': self.debt, 'date_due': self.date_due, # 'state': 'done', }) return True
def action_date_ret(self): """ Undated records will be assigned the current date """ values = {} period = self.env['account.period'] for wh in self: if wh.type in ['in_invoice']: values['date_ret'] = wh.company_id.allow_vat_wh_outdated \ and wh.date or time.strftime('%Y-%m-%d') values['date'] = values['date_ret'] if not ((wh.period_id.id, wh.fortnight) == period.find_fortnight(values['date_ret'])): raise exceptions.except_orm( _("Invalid action !"), _("You have introduced non-valid accounting date. The" "date needs to be in the same withholding period and" " fortnigh.")) elif wh.type in ['out_invoice']: values['date_ret'] = wh.date_ret or time.strftime('%Y-%m-%d') if not wh.company_id.allow_vat_wh_outdated and \ values['date_ret'] > time.strftime('%Y-%m-%d'): error_msg = _( 'You have introduced a non valid withholding date (a date \ in the future). The withholding date needs to be at least \ today or a previous date.') raise exceptions.except_orm( _("Invalid action !"), _(error_msg)) wh.write(values) return True
def cancel_file(self): if not self.journal_id.update_posted: raise osv.except_osv(_('Error!'), _('You cannot modify a posted entry of this journal.\nFirst you should set the journal to allow cancelling entries.')) #for withholding in self.withholding: # withholding.write({'state': 'cancel', 'move_id': False}) moves = self.env['account.move'] for inv in self: if inv.payment_ids: for move_line in inv.payment_ids: if move_line.reconcile_partial_id.line_partial_ids: raise except_orm(_('Error!'), _('You cannot cancel an invoice which is partially paid or paid. You need to unreconcile related payment entries first.')) for inv in self.invoices: if inv.payment_ids: for move_line in inv.payment_ids: if move_line.reconcile_partial_id.line_partial_ids or move_line.reconcile_ref: raise except_orm(_('Error!'), _('You cannot cancel an invoice which is partially paid or paid. You need to unreconcile related payment entries first.')) move_id = self.move_id for line in self.move_id.line_id: self._cr.execute("DELETE FROM account_move_line where id = %s", (line.id,)) for invoice_related in self.invoices: invoice_related.write({'state': 'cancel', 'move_id': False}) self.write({'state': 'cancel', 'move_id': False}) self._cr.execute("DELETE FROM account_move where id = %s", (move_id.id,)) self._log_event(-1.0, 'Cancel Invoice') return True
def check_tax_lines(self, compute_taxes): account_invoice_tax = self.env['account.invoice.tax'] company_currency = self.company_id.currency_id if not self.tax_line: for tax in compute_taxes.values(): account_invoice_tax.create(tax) else: tax_key = [] precision = self.env['decimal.precision'].precision_get('Account') for tax in self.tax_line: if tax.manual: continue key = self.get_tax_key(tax.id) tax_key.append(key) if key not in compute_taxes: raise except_orm(_('Warning!'), _('Global taxes defined,\ but they are not in invoice lines !')) base = compute_taxes[key]['base'] if float_compare(abs(base - tax.base), company_currency.rounding, precision_digits=precision) == 1: raise except_orm(_('Warning!'), _('Tax base different!\nClick\ on compute to update the tax base.')) for key in compute_taxes: if self.check_missing_tax(): if key not in tax_key: raise except_orm(_('Warning!'), _('Taxes are missing!\nClick\ on compute button.'))
def check_wh_taxes(self): """ Check that are valid and that amount retention is not greater than amount """ note = _('Taxes in the following invoices have been miscalculated\n\n') error_msg = '' for record in self: wh_line_ids = [] for wh_line in record.wh_lines: for tax in wh_line.tax_line: if not record._get_valid_wh( tax.amount_ret, tax.amount, tax.wh_vat_line_id.wh_iva_rate): if wh_line.id not in wh_line_ids: note += _('\tInvoice: %s, %s, %s\n') % ( wh_line.invoice_id.name, wh_line.invoice_id.number, wh_line.invoice_id.supplier_invoice_number or '/') wh_line_ids.append(wh_line.id) note += '\t\t%s\n' % tax.name if tax.amount_ret > tax.amount: porcent = '%' error_msg += _( "The withheld amount: %s(%s%s), must be less than" " tax amount %s(%s%s).") % ( tax.amount_ret, wh_line.wh_iva_rate, porcent, tax.amount, tax.amount * 100, porcent) if wh_line_ids and record.type == 'in_invoice': raise exceptions.except_orm( _('Miscalculated Withheld Taxes'), note) if error_msg: raise exceptions.except_orm(_('Invalid action !'), error_msg) return True
def check_vat_wh(self): """ Check whether the invoice will need to be withheld taxes """ res = {} for obj in self: if obj.type == 'out_invoice' and \ (not obj.date or not obj.date_ret): raise exceptions.except_orm( _('Error!'), _('Must indicate: Accounting date and (or) Voucher Date')) for wh_line in obj.wh_lines: if not wh_line.tax_line: res[wh_line.id] = ( wh_line.invoice_id.name, wh_line.invoice_id.number, wh_line.invoice_id.supplier_invoice_number) if res: note = _( 'The Following Invoices Have not already been withheld:\n\n') for i in res: note += '* %s, %s, %s\n' % res[i] note += _('\nPlease, Load the Taxes to be withheld and Try Again') raise exceptions.except_orm( _('Invoices with Missing Withheld Taxes!'), note) return True
def onchange_goods_id(self): if self.goods_id: partner_id = self.env.context.get('default_partner') partner = self.env['partner'].search([('id', '=', partner_id)]) is_return = self.env.context.get('default_is_return') if self.type == 'in': if not self.goods_id.cost: raise except_orm(u'错误', u'请先设置商品的成本!') self.tax_rate = self.env.user.company_id.import_tax_rate self.price = self.goods_id.cost # 如果是销售退货单行 if is_return: self.tax_rate = self.env.user.company_id.output_tax_rate self.price = self.goods_id.price elif self.type == 'out': self.tax_rate = self.env.user.company_id.output_tax_rate self.price = self.goods_id.price # 如果是采购退货单行 if is_return: if not self.goods_id.cost: raise except_orm(u'错误', u'请先设置商品的成本!') self.tax_rate = self.env.user.company_id.import_tax_rate self.price = self.goods_id.cost return super(wh_move_line,self).onchange_goods_id()
def _check_invoice_plan(self): if self.use_invoice_plan: obj_precision = self.env['decimal.precision'] prec = obj_precision.precision_get('Account') for order_line in self.order_line: subtotal = self.price_include and \ order_line.product_uom_qty * order_line.price_unit or \ order_line.price_subtotal invoice_lines = self.env['sale.invoice.plan'].search( [('order_line_id', '=', order_line.id)]) total_amount = 0.0 for line in invoice_lines: total_amount += line.invoice_amount # Validate percent if round(line.invoice_percent/100 * subtotal, prec) != \ round(line.invoice_amount, prec): raise except_orm( _('Invoice Plan Percent Mismatch!'), _("%s on installment %s") % (order_line.name, line.installment)) if round(total_amount, prec) != round(subtotal, prec): raise except_orm( _('Invoice Plan Amount Mismatch!'), _("%s, plan amount %d not equal to line amount %d!") % (order_line.name, total_amount, subtotal)) return True
def create(self, data): workcenter_obj = self.env['mrp.routing.workcenter'] find_test = False if 'required_test' in data: required_test = data.get('required_test') if required_test: if 'qtemplate_id' not in data: raise except_orm(_('Error!'), _("You must define the test template")) else: qtemplate_id = data.get('required_test') if not qtemplate_id: raise except_orm(_('Error!'), _("You must define template test")) else: find_test = True data.update({'qtemplate_id': False}) else: data.update({'qtemplate_id': False}) find_test = True if find_test: if 'routing_wc_line' in data: routing_wc_line_id = data.get('routing_wc_line') work = workcenter_obj.browse(routing_wc_line_id) data.update({'required_test': work.operation.required_test}) if work.operation.qtemplate_id: data.update({'qtemplate_id': work.operation.qtemplate_id.id}) return super(MrpProductionWorkcenterLine, self).create(data)
def table_reserved(self): """ when CONFIRM BUTTON is clicked this method is called for table reservation @param self: The object pointer @return: change a state depending on the condition """ for reservation in self: self._cr.execute("select count(*) from " "hotel_restaurant_reservation as hrr " "inner join reservation_table as rt on \ rt.reservation_table_id = hrr.id " "where (start_date,end_date)overlaps\ ( timestamp %s , timestamp %s ) " "and hrr.id<> %s and state != 'done'" "and rt.name in (select rt.name from \ hotel_restaurant_reservation as hrr " "inner join reservation_table as rt on \ rt.reservation_table_id = hrr.id " "where hrr.id= %s) ", (reservation.start_date, reservation.end_date, reservation.id, reservation.id)) res = self._cr.fetchone() roomcount = res and res[0] or 0.0 if len(reservation.tableno.ids) == 0: raise except_orm(_('Warning'), _('Please Select Tables For Reservation')) if roomcount: raise except_orm(_('Warning'), _('You tried to confirm \ reservation with table those already reserved in this \ reservation period')) else: self.write({'state': 'confirm'}) return True
def money_order_done(self): '''对收支单的审核按钮''' if self.advance_payment < 0: raise except_orm(u'错误', u'核销金额不能大于付款金额') self.to_reconcile = self.advance_payment self.reconciled = self.amount - self.advance_payment total = 0 for line in self.line_ids: if self.type == 'pay': # 付款账号余额减少, 退款账号余额增加 if line.bank_id.balance < line.amount: raise except_orm(u'错误', u'账户余额不足') line.bank_id.balance -= line.amount else: # 收款账号余额增加, 退款账号余额减少 line.bank_id.balance += line.amount total += line.amount if self.type == 'pay': self.partner_id.payable -= total else: self.partner_id.receivable -= total # 更新源单的未核销金额、已核销金额 for source in self.source_ids: if abs(source.to_reconcile) < source.this_reconcile: raise except_orm(u'错误', u'本次核销金额不能大于未核销金额') source.name.to_reconcile = source.to_reconcile - source.this_reconcile source.name.reconciled = source.reconciled + source.this_reconcile self.state = 'done' return True
def reconcile_order_done(self): '''核销单的审核按钮''' # 核销金额不能大于未核销金额 for order in self: if order.state == 'done': continue order_reconcile, invoice_reconcile = 0, 0 if self.business_type in ['get_to_get', 'pay_to_pay'] and order.partner_id.id == order.to_partner_id.id: raise except_orm(u'错误', u'转出客户和转入客户不能相同') # 核销预收预付 for line in order.advance_payment_ids: order_reconcile += line.this_reconcile if line.this_reconcile > line.to_reconcile: raise except_orm(u'错误', u'核销金额不能大于未核销金额') # 更新每一行的已核销余额、未核销余额 line.name.to_reconcile -= line.this_reconcile line.name.reconciled += line.this_reconcile for line in order.receivable_source_ids: invoice_reconcile += line.this_reconcile self._get_or_pay(line, order.business_type, order.partner_id, order.to_partner_id, order.name) for line in order.payable_source_ids: order_reconcile += line.this_reconcile self._get_or_pay(line, order.business_type, order.partner_id, order.to_partner_id, order.name) # 核销金额必须相同 if self.business_type in ['adv_pay_to_get', 'adv_get_to_pay', 'get_to_pay']: if order_reconcile != invoice_reconcile: raise except_orm(u'错误', u'核销金额必须相同') order.state = 'done' return True
def change_product_rfid(self): context = self._context product = self.env['product.product'].browse(context['active_ids'])[0] res = {} move_pool = self.env['stock.move'] move_search_ids = move_pool.search([('product_id','=',product.id),('state','=','done')],order='id desc',limit=1) if not move_search_ids: raise except_orm(_('No Location Found!'), _("Product %s must have location '!") % (product.name)) usage = move_search_ids[0].location_dest_id.usage if usage=='supplier' or usage=='customer': raise except_orm(_('Wrong Location!'), _("Product %s must have on internal or inventory location '!") % (product.name)) if usage == 'internal' or usage == 'inventory': if move_search_ids and self.product_rfid and self.product_rfid.id : newmove = move_search_ids.copy() vals = { 'product_rfid': self.product_rfid.id, 'date' : datetime.now(), 'name' : "RFID Assigned", 'state' : "done", } newmove[0].write(vals) return res
def wcfmc_upload(self): """ Send quotation to WCFMC """ if self.can_upload(): wcfmc_id = self.wcfmc_id # construct message get quote total quote = self.amount_total message = self.env["ir.config_parameter"].get_param("cm.wcfmc.quote_message") if not message: raise odoo_exceptions.except_orm(_("Quote Message Missing"),\ _("Please set a WCFMC quote message in Settings > Configuration > WCFMC Settings")) message = message.replace('{price}', '%.2f' % round(quote, 2)) message = message.replace('{name}', self.partner_id.name) message = message.replace('{wcfmc_id}', str(self.wcfmc_id)) message = message.replace('{vehicle_registration}', self.vehicle_registration) message = message.replace('{make_model}', self.make_model) message = message.replace('{registration_year}', str(self.registration_year)) message = message.replace('{city}', self.city) message = message.replace('{postcode}', self.postcode) try: wcfmc = self.env['cm.cron'].get_wcfmc_instance() phone = wcfmc.apply_for_job(wcfmc_id, message, quote, self.branch_id.wcfmc_account_id.wcfmc_id) self.partner_id.phone = phone except wcfmc_exceptions.LoginError as e: raise odoo_exceptions.except_orm(_("WhoCanFixMyCar login information missing"), \ _("The log in information for WhoCanFixMyCar is missing. Please enter it in Settings > Configuration > WCFMC Settings")) self.message_post(_("Uploaded to WhoCanFixMyCar"))
def action_create_agreement_po_requisition(self, cr, uid, ids, context=None): """ Implement buttons that create PO from selected source lines""" act_obj = self.pool['ir.actions.act_window'] source_ids = self._get_source_ids(cr, uid, context=context) if not source_ids: raise except_orm(_('No sourcing line Found'), _('No sourcing line were found, ' 'please create one.')) form = self.browse(cr, uid, ids, context=context)[0] pricelist = form.pricelist_id available_curr = [ x.currency_id for x in form.framework_currency_ids] if available_curr and pricelist.currency_id not in available_curr: raise except_orm(_('User Error'), _( 'You must chose a pricelist that is in the same currency ' 'than one of the available in the framework agreement.')) po_id = self._make_purchase_order(cr, uid, pricelist, source_ids, context=context) # TODO : update LRS price from PO depending on the chosen currency res = act_obj.for_xml_id(cr, uid, 'purchase', 'purchase_rfq', context=context) res.update({'domain': [('id', '=', po_id)], 'res_id': po_id, 'context': '{}', 'search_view_id': False, }) return res
def create_voucher_line(self, vals): debit = credit = vals.get('amount') # 把税从金额中减去 if vals.get('buy_tax_amount'): debit = vals.get('amount') - vals.get('buy_tax_amount') if vals.get('sell_tax_amount'): credit = vals.get('amount') - vals.get('sell_tax_amount') # 借方行 self.env['voucher.line'].create({ 'name': u"%s %s " % (vals.get('string'), vals.get('name')), 'account_id': vals.get('debit_account_id'), 'debit': debit, 'voucher_id': vals.get('vouch_obj_id'), 'partner_id': vals.get('partner_debit', ''), }) # 进项税行 if vals.get('buy_tax_amount'): if not self.env.user.company_id.import_tax_account: raise except_orm(u'错误', u'请通过"配置-->高级配置-->系统参数"菜单来设置进项税科目') self.env['voucher.line'].create({ 'name': u"%s %s" % (vals.get('string'), vals.get('name')), 'account_id': self.env.user.company_id.import_tax_account.id, 'debit': vals.get('buy_tax_amount'), 'voucher_id': vals.get('vouch_obj_id'), }) # 贷方行 self.env['voucher.line'].create({ 'name': u"%s %s" % (vals.get('string'), vals.get('name')), 'partner_id': vals.get('partner_credit', ''), 'account_id': vals.get('credit_account_id'), 'credit': credit, 'voucher_id': vals.get('vouch_obj_id'), }) # 销项税行 if vals.get('sell_tax_amount'): if not self.env.user.company_id.output_tax_account: raise except_orm(u'错误', u'请通过"配置-->高级配置-->系统参数"菜单来设置销项税科目' ) self.env['voucher.line'].create({ 'name': u"%s %s" % (vals.get('string'), vals.get('name')), 'account_id': self.env.user.company_id.output_tax_account.id, 'credit': vals.get('sell_tax_amount'), 'voucher_id': vals.get('vouch_obj_id'), }) return True
def vehicle_transfer(self): stu_prt_obj = self.env['transport.participant'] vehi_obj = self.env['transport.vehicle'] for new_data in self.browse(self.id): vehi_data = vehi_obj.browse(new_data.old_vehicle_id.id) vehi_new_data = vehi_obj.browse(new_data.new_vehicle_id.id) #check for transfer in same vehicle if new_data.old_vehicle_id.id == new_data.new_vehicle_id.id: raise except_orm(_('Error !'),_('Sorry you can not transfer in same vehicle.')) # First Check Is there vacancy or not person = int(vehi_data.participant) + 1 if vehi_data.capacity < person: raise except_orm(_('Error !'),_('There is No More vacancy on this vehicle.')) #remove entry of participant in old vehicle. participants = [prt_id.id for prt_id in vehi_data.vehi_participants_ids] if new_data.participation_id.id in participants: participants.remove(new_data.participation_id.id) # vehi_obj.write(cr, uid, new_data.old_vehicle_id.id, {'vehi_participants_ids':[(6,0,participants)]}, context=context) old_veh_id = vehi_obj.browse(new_data.old_vehicle_id.id) old_veh_id.write({'vehi_participants_ids':[(6,0,participants)]}) #entry of participant in new vehicle. participants = [prt_id.id for prt_id in vehi_new_data.vehi_participants_ids] participants.append(new_data.participation_id.id) # vehi_obj.write(cr, uid, new_data.new_vehicle_id.id, {'vehi_participants_ids':[(6,0,participants)]}, context=context) new_veh_id = vehi_obj.browse(new_data.new_vehicle_id.id) new_veh_id.write({'vehi_participants_ids':[(6,0,participants)]}) # stu_prt_obj.write(cr, uid, new_data.participation_id.id, {'vehicle_id': new_data.new_vehicle_id.id,}, context=context) stu_prt_id = stu_prt_obj.browse(new_data.participation_id.id) stu_prt_id.write({'vehicle_id': new_data.new_vehicle_id.id,}) return {}
def get_updated_currency(self, currency_array, main_currency, max_delta_days): """implementation of abstract method of Curreny_getter_interface""" # as of Jan 2014 BOC is publishing noon rates for about 60 currencies url = ('http://www.bankofcanada.ca/stats/assets/' 'rates_rss/noon/en_%s.xml') # closing rates are available as well (please note there are only 12 # currencies reported): # http://www.bankofcanada.ca/stats/assets/rates_rss/closing/en_%s.xml # We do not want to update the main currency if main_currency in currency_array: currency_array.remove(main_currency) import feedparser import pytz from dateutil import parser for curr in currency_array: _logger.debug("BOC currency rate service : connecting...") dom = feedparser.parse(url % curr) self.validate_cur(curr) # check if BOC service is running if dom.bozo and dom.status != 404: _logger.error("Bank of Canada - service is down - try again\ later...") # check if BOC sent a valid response for this currency if dom.status != 200: _logger.error("Exchange data for %s is not reported by Bank\ of Canada." % curr) raise except_orm(_('Error !'), _('Exchange data for %s is not\ reported by Bank of Canada.' % str(curr))) _logger.debug("BOC sent a valid RSS file for: " + curr) # check for valid exchange data if (dom.entries[0].cb_basecurrency == main_currency) and \ (dom.entries[0].cb_targetcurrency == curr): rate = dom.entries[0].cb_exchangerate.split('\n', 1)[0] rate_date_datetime = parser.parse(dom.entries[0].updated)\ .astimezone(pytz.utc).replace(tzinfo=None) self.check_rate_date(rate_date_datetime, max_delta_days) self.updated_currency[curr] = rate _logger.debug("BOC Rate retrieved : %s = %s %s" % (main_currency, rate, curr)) else: _logger.error( "Exchange data format error for Bank of Canada -" "%s. Please check provider data format " "and/or source code." % curr) raise except_orm(_('Error !'), _('Exchange data format error for\ Bank of Canada - %s !' % str(curr))) return self.updated_currency, self.log_info
def money_invoice_done(self): res = super(money_invoice, self).money_invoice_done() vals = {} vouch_obj = self.env['voucher'].create({'date': self.date}) self.write({'voucher_id': vouch_obj.id}) if not self.category_id.account_id: raise except_orm(u'错误', u'请配置%s的会计科目' % (self.category_id.name)) partner_cat = self.category_id.type == 'income' and self.partner_id.c_category_id or self.partner_id.s_category_id partner_account_id = partner_cat.account_id.id if not partner_account_id: raise except_orm(u'错误', u'请配置%s的会计科目' % (partner_cat.name)) if self.category_id.type == 'income': vals.update({'vouch_obj_id': vouch_obj.id, 'partner_credit': self.partner_id.id, 'name': self.name, 'string': u'源单', 'amount': self.amount, 'credit_account_id': self.category_id.account_id.id, 'partner_debit': self.partner_id.id, 'debit_account_id': partner_account_id, 'sell_tax_amount': self.tax_amount or 0, 'credit_auxiliary_id':self.auxiliary_id.id,'currency_id':self.currency_id.id or '','rate_silent':self.currency_id.rate_silent or 0, }) else: vals.update({'vouch_obj_id': vouch_obj.id, 'name': self.name, 'string': u'源单', 'amount': self.amount, 'credit_account_id': partner_account_id, 'debit_account_id': self.category_id.account_id.id, 'partner_debit': self.partner_id.id, 'partner_credit':self.partner_id.id, 'buy_tax_amount': self.tax_amount or 0, 'debit_auxiliary_id':self.auxiliary_id.id,'currency_id':self.currency_id.id or '','rate_silent':self.currency_id.rate_silent or 0, }) self.create_voucher_line(vals) return res
def action_wh_iva_create(self): """ Create withholding objects """ for inv in self: if inv.wh_iva_id: if inv.wh_iva_id.state == 'draft': inv.wh_iva_id.compute_amount_wh() else: raise exceptions.except_orm( _('Warning !'), _('You have already a withholding doc associate to' ' your invoice, but this withholding doc is not in' ' cancel state.')) else: # Create Lines Data ret_id = False ret_line_id = inv.wh_iva_line_create() fortnight_wh_id = inv.get_fortnight_wh_id() # Add line to a WH DOC if inv.company_id.consolidate_vat_wh and fortnight_wh_id: # Add to an exist WH Doc ret_id = fortnight_wh_id if not ret_id: raise exceptions.except_orm( _('Error!'), _('Can\'t find withholding doc')) wh_iva = self.env['account.wh.iva'].browse(ret_id) wh_iva.write({'wh_lines': [(4, ret_line_id)]}) else: # Create a New WH Doc and add line ret_id = inv.create_new_wh_iva(ret_line_id) if ret_id: inv.write({'wh_iva_id': ret_id}) inv.wh_iva_id.compute_amount_wh() return True
def buy_receipt_done(self): '''审核采购入库单/退货单,更新本单的付款状态/退款状态,并生成源单和付款单''' if self.state == 'done': raise except_orm(u'错误', u'请不要重复审核!') if self.bank_account_id and not self.payment: raise except_orm(u'警告!', u'结算账户不为空时,需要输入付款额!') if not self.bank_account_id and self.payment: raise except_orm(u'警告!', u'付款额不为空时,请选择结算账户!') if self.payment > self.amount: raise except_orm(u'警告!', u'本次付款金额不能大于折后金额!') if (sum(cost_line.amount for cost_line in self.cost_line_ids) != sum(line.share_cost for line in self.line_in_ids)): raise except_orm(u'警告!', u'采购费用还未分摊或分摊不正确!') if self.order_id: if not self.is_return: line_ids = self.line_in_ids else: line_ids = self.line_out_ids for line in line_ids: line.buy_line_id.quantity_in += line.goods_qty # 入库单/退货单 生成源单 if not self.is_return: amount = self.amount this_reconcile = self.payment else: amount = -self.amount this_reconcile = -self.payment categ = self.env.ref('money.core_category_purchase') source_id = self.env['money.invoice'].create({ 'move_id': self.buy_move_id.id, 'name': self.name, 'partner_id': self.partner_id.id, 'category_id': categ.id, 'date': fields.Date.context_today(self), 'amount': amount, 'reconciled': 0, 'to_reconcile': amount, 'date_due': self.date_due, 'state': 'draft', }) self.invoice_id = source_id.id # 采购费用产生源单 if sum(cost_line.amount for cost_line in self.cost_line_ids) > 0: for line in self.cost_line_ids: cost_id = self.env['money.invoice'].create({ 'move_id': self.buy_move_id.id, 'name': self.name, 'partner_id': line.partner_id.id, 'category_id': line.category_id.id, 'date': fields.Date.context_today(self), 'amount': line.amount, 'reconciled': 0.0, 'to_reconcile': line.amount, 'date_due': self.date_due, 'state': 'draft', }) # 生成付款单 if self.payment: money_lines = [] source_lines = [] money_lines.append({ 'bank_id': self.bank_account_id.id, 'amount': this_reconcile, }) source_lines.append({ 'name': source_id.id, 'category_id': categ.id, 'date': source_id.date, 'amount': amount, 'reconciled': 0.0, 'to_reconcile': amount, 'this_reconcile': this_reconcile, }) rec = self.with_context(type='pay') money_order = rec.env['money.order'].create({ 'partner_id': self.partner_id.id, 'date': fields.Date.context_today(self), 'line_ids': [(0, 0, line) for line in money_lines], 'source_ids': [(0, 0, line) for line in source_lines], 'type': 'pay', 'amount': amount, 'reconciled': this_reconcile, 'to_reconcile': amount, 'state': 'draft', }) money_order.money_order_done() # 调用wh.move中审核方法,更新审核人和审核状态 self.buy_move_id.approve_order() # 生成分拆单 FIXME:无法跳转到新生成的分单 if self.order_id: return self.order_id.buy_generate_receipt()
def unlink(self): for order in self: if order.state == 'done': raise except_orm(u'错误', u'不能删除已审核的单据') return super(buy_order, self).unlink()
def button_ok(self): res = [] if self.date_end < self.date_start: raise except_orm(u'错误', u'开始日期不能大于结束日期!') domain = [ ('move_id.date', '>=', self.date_start), ('move_id.date', '<=', self.date_end), ('move_id.origin', 'like', 'sell.delivery'), ('state', '=', 'done'), ] if self.goods_id: domain.append(('goods_id', '=', self.goods_id.id)) if self.partner_id: domain.append(('move_id.partner_id', '=', self.partner_id.id)) order_type = '' total_qty = total_price = total_amount = total_tax_amount = total_subtotal = 0 for line in self.env['wh.move.line'].search(domain, order='move_id'): if line.move_id.origin and 'return' in line.move_id.origin: order_type = u'退货' else: order_type = u'销货' sell_delivery = self.env['sell.delivery'].search([ ('sell_move_id', '=', line.move_id.id) ]) if sell_delivery: staff_id = sell_delivery.staff_id and sell_delivery.staff_id.id or '' detail = self.env['sell.order.detail'].create({ 'date': line.move_id.date, 'order_name': line.move_id.name, 'type': order_type, 'staff_id': staff_id, 'partner_id': line.move_id.partner_id.id, 'goods_code': line.goods_id.code, 'goods_id': line.goods_id.id, 'attribute': line.attribute_id.name, 'uom': line.uom_id.name, 'warehouse_dest': line.warehouse_dest_id.name, 'qty': line.goods_qty, 'price': line.price, 'amount': line.amount, 'tax_amount': line.tax_amount, 'subtotal': line.subtotal, 'note': line.note, }) res.append(detail.id) total_qty += line.goods_qty total_price += line.price total_amount += line.amount total_tax_amount += line.tax_amount total_subtotal += line.subtotal sum_detail = self.env['sell.order.detail'].create({ 'warehouse_dest': u'合计', 'qty': total_qty, 'price': total_price, 'amount': total_amount, 'tax_amount': total_tax_amount, 'subtotal': total_subtotal, }) res.append(sum_detail.id) view = self.env.ref('sell.sell_order_detail_tree') cond = [('id', 'in', res)] if self.staff_id: cond.append(('staff_id', '=', self.staff_id.id)) return { 'name': u'销售明细表', 'view_type': 'form', 'view_mode': 'tree', 'view_id': False, 'views': [(view.id, 'tree')], 'res_model': 'sell.order.detail', 'type': 'ir.actions.act_window', 'domain': cond, 'limit': 300, }
def _action_compute_lines(self, product_id, product_qty, pick_results=None, properties=None, initial_run=0): self = self.with_context(to_date=self.date_planned) if properties is None: properties = [] results = [] bom = self.env['mrp.bom'] uom = self.env['product.uom'] prod = self.env['product.product'] route = self.env['stock.location.route'] bom_id = bom._bom_find(product_id=product_id, properties=properties) if bom_id: bom_point = bom.browse(bom_id) else: raise exceptions.except_orm(_('Error!'), _("Cannot find a bill of materials for this product.")) pick_results = pick_results or OrderedDict() for p in prod.browse(product_id): factor = uom._compute_qty(p.uom_id.id, product_qty, bom_point.product_uom.id) results, results2 = bom._bom_explode(bom_point, product_id, factor / bom_point.product_qty, properties) if initial_run: diff = p.virtual_available-self.product_qty new_pick = { 'product_id': p.id, 'name': p.product_tmpl_id.name, 'default_code': p.default_code, 'product_uom': p.product_tmpl_id.uom_id.id, 'categ_id': p.product_tmpl_id.categ_id.id, 'route_name': route.browse(p.product_tmpl_id.route_ids.id).name, 'product_qty': self.product_qty, 'on_hand_before': p.virtual_available, 'on_hand_after': diff, 'short': -(diff) if diff < 0 else 0, } pick_results[new_pick['product_id']] = new_pick for line in results: p = prod.browse(line['product_id']) # product previously collected in pick_results, update qty if line['product_id'] in pick_results and line['product_id'] == pick_results[line['product_id']]['product_id']: pick_results[line['product_id']]['product_qty'] += line['product_qty'] diff = p.virtual_available-pick_results[line['product_id']]['product_qty'] pick_results[line['product_id']]['on_hand_after'] = diff pick_results[line['product_id']]['short'] = -(diff) if diff < 0 else 0 # not yet collected, prep and collect in pick_results else: diff = p.virtual_available-line['product_qty'] line['default_code'] = p.default_code line['categ_id'] = p.product_tmpl_id.categ_id.id line['route_name'] = route.browse(p.product_tmpl_id.route_ids.id).name line['on_hand_before'] = p.virtual_available line['on_hand_after'] = diff line['short'] = -(diff) if diff < 0 else 0 pick_results[line['product_id']] = line bom_id = bom._bom_find(product_id=line['product_id']) if bom_id: self._action_compute_lines(line['product_id'], line['product_qty'], pick_results, properties) return pick_results
def compute_early_payment_lines(self): """creates early payment lines""" early_payments = {} inv_lines_out_vat = [] for invoice_line in self.invoice_line: if invoice_line.invoice_line_tax_id: line_tax_ids = [x.id for x in invoice_line.invoice_line_tax_id] found = False for key in early_payments: if intersect([int(x) for x in key.split(",")], line_tax_ids): early_payments[key].append(invoice_line.id) found = True break if not found: tax_str = ",".join([str(x) for x in line_tax_ids]) early_payments[tax_str] = [invoice_line.id] else: #lines without vat defined inv_lines_out_vat.append(invoice_line.id) prod_early_payment = self.env['product.product'].search([ ('default_code', '=', 'DPP') ]) prod_early_payment = prod_early_payment and prod_early_payment[ 0] or False if prod_early_payment: analytic_id = False rec = self.env['account.analytic.default'].account_get( prod_early_payment.id, self.partner_id.id, self._uid, time.strftime('%Y-%m-%d'), company_id=self.company_id.id) if rec: analytic_id = rec.analytic_id.id group_account_line = {} for early_payment_line in early_payments: group_account_line[early_payment_line] = {} for invoice_line in self.env['account.invoice.line'].browse( early_payments[early_payment_line]): if invoice_line.product_id.categ_id and invoice_line.product_id.categ_id.property_account_sale_early_payment_disc and str( invoice_line.product_id.categ_id. property_account_sale_early_payment_disc.id ) not in group_account_line[early_payment_line]: group_account_line[early_payment_line][str( invoice_line.product_id.categ_id. property_account_sale_early_payment_disc.id)] = [ invoice_line.id ] elif invoice_line.product_id.categ_id and invoice_line.product_id.categ_id.property_account_sale_early_payment_disc and str( invoice_line.product_id.categ_id. property_account_sale_early_payment_disc.id ) in group_account_line[early_payment_line]: group_account_line[early_payment_line][str( invoice_line.product_id.categ_id. property_account_sale_early_payment_disc.id )].append(invoice_line.id) elif prod_early_payment.property_stock_account_output and str( prod_early_payment.property_stock_account_output.id ) not in group_account_line[early_payment_line]: group_account_line[early_payment_line][str( prod_early_payment.property_stock_account_output.id )] = [invoice_line.id] elif prod_early_payment.property_stock_account_output and str( prod_early_payment.property_stock_account_output.id ) in group_account_line[ early_payment_line] or prod_early_payment.categ_id.property_account_sale_early_payment_disc.id and str( prod_early_payment.categ_id. property_account_sale_early_payment_disc.id ) in group_account_line[early_payment_line]: group_account_line[early_payment_line][str( prod_early_payment.property_stock_account_output.id )].append(invoice_line.id) else: raise exceptions.except_orm( _('Warning'), _('Cannot set early payment discount because now is impossible find the early payment account. Review invoice products categories have defined early payment account by default or early payment discount product have defined an output account.' )) partner_id = self.partner_id and self.partner_id.id or False for early_payment_line in group_account_line: for account_id in group_account_line[early_payment_line]: self.env['account.invoice.line'].with_context( partner_id=partner_id).create({ 'name': _("Early payment discount") + " " + str(self.early_payment_discount) + "%", 'invoice_id': self.id, 'product_id': prod_early_payment.id, 'account_id': int(account_id), 'price_unit': 0.0 - (self.compute_early_payment_discount( group_account_line[early_payment_line] [account_id], self.early_payment_discount)), 'quantity': 1, 'invoice_line_tax_id': [(6, 0, [int(x) for x in early_payment_line.split(',')])], 'account_analytic_id': analytic_id }) if inv_lines_out_vat: self.env['account.invoice.line'].with_context( partner_id=partner_id).create({ 'name': _("Early payment discount") + " " + str(self.early_payment_discount) + "%", 'invoice_id': self.id, 'product_id': prod_early_payment.id, 'account_id': prod_early_payment.categ_id and prod_early_payment. categ_id.property_account_sale_early_payment_disc.id or prod_early_payment.property_stock_account_output.id, 'price_unit': 0.0 - (self.compute_early_payment_discount( inv_lines_out_vat, self.early_payment_discount)), 'quantity': 1, 'account_analytic_id': analytic_id }) #recompute taxes self.button_compute(set_total=(type in ('in_invoice', 'in_refund'))) return True
def event_open(self): if self.part_ids and self.part_ids[0].id: self.write({'state': 'open'}) else: raise except_orm(_('No Participants !'), _('No Participants to \ open the Event.'))
def sell_delivery_done(self): '''审核销售发货单/退货单,更新本单的收款状态/退款状态,并生成源单和收款单''' if self.state == 'done': raise except_orm(u'错误', u'请不要重复审核!') if self.bank_account_id and not self.receipt: raise except_orm(u'警告!', u'结算账户不为空时,需要输入付款额!') if not self.bank_account_id and self.receipt: raise except_orm(u'警告!', u'付款额不为空时,请选择结算账户!') if self.receipt > self.amount: raise except_orm(u'警告!', u'本次收款金额不能大于优惠后金额!') if self.order_id: for line in self.line_out_ids: line.sell_line_id.quantity_out += line.goods_qty # 发库单/退货单 生成源单 if not self.is_return: amount = self.amount + self.partner_cost this_reconcile = self.receipt else: amount = -(self.amount + self.partner_cost) this_reconcile = -self.receipt categ = self.env.ref('money.core_category_sale') source_id = self.env['money.invoice'].create({ 'move_id': self.sell_move_id.id, 'name': self.name, 'partner_id': self.partner_id.id, 'category_id': categ.id, 'date': fields.Date.context_today(self), 'amount': amount, 'reconciled': 0, 'to_reconcile': amount, 'date_due': self.date_due, 'state': 'draft', }) self.invoice_id = source_id.id # 销售费用产生源单 if sum(cost_line.amount for cost_line in self.cost_line_ids) > 0: for line in self.cost_line_ids: cost_id = self.env['money.invoice'].create({ 'move_id': self.sell_move_id.id, 'name': self.name, 'partner_id': line.partner_id.id, 'category_id': line.category_id.id, 'date': fields.Date.context_today(self), 'amount': line.amount, 'reconciled': 0.0, 'to_reconcile': line.amount, 'date_due': self.date_due, 'state': 'draft', }) # 生成收款单 if self.receipt: money_lines = [] source_lines = [] money_lines.append({ 'bank_id': self.bank_account_id.id, 'amount': this_reconcile, }) source_lines.append({ 'name': source_id.id, 'category_id': categ.id, 'date': source_id.date, 'amount': amount, 'reconciled': 0.0, 'to_reconcile': amount, 'this_reconcile': this_reconcile, }) rec = self.with_context(type='get') money_order = rec.env['money.order'].create({ 'partner_id': self.partner_id.id, 'date': fields.Date.context_today(self), 'line_ids': [(0, 0, line) for line in money_lines], 'source_ids': [(0, 0, line) for line in source_lines], 'type': 'get', 'amount': amount, 'reconciled': this_reconcile, 'to_reconcile': amount, 'state': 'draft', }) money_order.money_order_done() # 调用wh.move中审核方法,更新审核人和审核状态 self.sell_move_id.approve_order() # 生成分拆单 FIXME:无法跳转到新生成的分单 if self.order_id: return self.order_id.sell_generate_delivery() return True
def set_context(self, objects, data, ids, report_type=None): """Populate a ledger_lines attribute on each browse record that will be used by mako template""" lang = self.localcontext.get('lang') lang_ctx = lang and {'lang': lang} or {} new_ids = data['form']['chart_account_id'] # Account initial balance memoizer init_balance_memoizer = {} # Reading form main_filter = self._get_form_param('filter', data, default='filter_no') target_move = self._get_form_param('target_move', data, default='all') start_date = self._get_form_param('date_from', data) stop_date = self._get_form_param('date_to', data) start_period = self.get_start_period_br(data) stop_period = self.get_end_period_br(data) fiscalyear = self.get_fiscalyear_br(data) partner_ids = self._get_form_param('partner_ids', data) result_selection = self._get_form_param('result_selection', data) date_until = self._get_form_param('until_date', data) chart_account = self._get_chart_account_id_br(data) group_by_currency = self._get_form_param('group_by_currency', data) if main_filter == 'filter_no' and fiscalyear: start_period = self.get_first_fiscalyear_period(fiscalyear) stop_period = self.get_last_fiscalyear_period(fiscalyear) # Retrieving accounts filter_type = ('payable', 'receivable') if result_selection == 'customer': filter_type = ('receivable',) if result_selection == 'supplier': filter_type = ('payable',) account_ids = self.get_all_accounts( new_ids, exclude_type=['view'], only_type=filter_type) if not account_ids: raise except_orm(_('Error'), _('No accounts to print.')) # computation of ledeger lines if main_filter == 'filter_date': start = start_date stop = stop_date else: start = start_period stop = stop_period ledger_lines_memoizer = self._compute_open_transactions_lines( account_ids, main_filter, target_move, start, stop, date_until, partner_filter=partner_ids) objects = self.pool.get('account.account').browse(self.cursor, self.uid, account_ids, context=lang_ctx) ledger_lines = {} init_balance = {} partners_order = {} for account in objects: ledger_lines[account.id] = ledger_lines_memoizer.get(account.id, {}) init_balance[account.id] = init_balance_memoizer.get(account.id, {}) # we have to compute partner order based on inital balance # and ledger line as we may have partner with init bal # that are not in ledger line and vice versa ledg_lines_pids = ledger_lines_memoizer.get(account.id, {}).keys() non_null_init_balances = dict([ (ib, amounts) for ib, amounts in init_balance[account.id].iteritems() if amounts['init_balance'] or amounts['init_balance_currency']]) init_bal_lines_pids = non_null_init_balances.keys() partners_order[account.id] = self._order_partners( ledg_lines_pids, init_bal_lines_pids) ledger_lines[account.id] = ledger_lines_memoizer.get(account.id, {}) if group_by_currency: self._group_lines_by_currency( account, ledger_lines[account.id]) self.localcontext.update({ 'fiscalyear': fiscalyear, 'start_date': start_date, 'stop_date': stop_date, 'start_period': start_period, 'stop_period': stop_period, 'date_until': date_until, 'partner_ids': partner_ids, 'chart_account': chart_account, 'ledger_lines': ledger_lines, 'init_balance': init_balance, 'partners_order': partners_order }) return super(PartnersOpenInvoicesWebkit, self).set_context( objects, data, new_ids, report_type=report_type)
def afip_validation(self): """ Check basic AFIP request to generate invoices. """ for invoice in self: # If parter is not in Argentina, ignore it. if invoice.company_id.partner_id.country_id.name != 'Argentina': continue # Check if you choose the right journal. if invoice.type == 'out_invoice' and \ invoice.journal_id.journal_class_id.afip_code not in\ [1, 6, 11, 51, 19, 2, 7, 12, 52, 20]: raise except_orm( _('Wrong Journal'), _('Out invoice journal must have a valid journal class.')) if invoice.type == 'out_refund' and \ invoice.journal_id.journal_class_id.afip_code not in\ [3, 8, 13, 53, 21]: raise except_orm( _('Wrong Journal'), _('Out invoice journal must have a valid journal class.')) # Partner responsability ? partner = invoice.partner_id if not partner.responsability_id: raise except_orm( _('No responsability'), _('Your partner have not afip responsability assigned.' ' Assign one please.')) # Take responsability classes for this journal invoice_class = \ invoice.journal_id.journal_class_id.document_class_id company = invoice.journal_id.company_id.partner_id resp_class = \ self.env['afip.responsability_relation'].search( [('document_class_id', '=', invoice_class.id), ('issuer_id.code', '=', company.responsability_id.code)]) # You can emmit this document? if not resp_class: raise except_orm( _('Invalid emisor'), _('Your responsability with AFIP dont let you generate' ' this kind of document.')) # Partner can receive this document? resp_class = \ self.env['afip.responsability_relation'].search([ ('document_class_id', '=', invoice_class.id), ('receptor_id.code', '=', partner.responsability_id.code) ]) if not resp_class: raise except_orm( _('Invalid receptor'), _('Your partner cant receive this document.' ' Check AFIP responsability of the partner,' ' or Journal Account of the invoice.')) # If Final Consumer have pay more than 1000$, # you need more information to generate document. if partner.responsability_id.code == 'CF' \ and invoice.amount_total > 1000 and \ (partner.document_type.code in [None, 'Sigd'] or invoice.partner_id.document_number is None): raise except_orm( _('Partner without Identification for total' ' invoices > $1000.-'), _('You must define valid document type and' ' number for this Final Consumer.')) return True
def action_paid_amount(self): context = self._context can_close = False loan_obj = self.env['hr.loan'] period_obj = self.env['account.period'] move_obj = self.env['account.move'] move_line_obj = self.env['account.move.line'] currency_obj = self.env['res.currency'] created_move_ids = [] loan_ids = [] for line in self: if line.loan_id.state != 'approve': raise except_orm('Warning', "Loan Request must be approved") paid_date = line.paid_date period_ids =period_obj.with_context().find(paid_date).id company_currency = line.employee_id.company_id.currency_id.id current_currency = self.env.user.company_id.currency_id.id amount = line.paid_amount loan_name = line.employee_id.name reference = line.loan_id.name journal_id = line.loan_id.journal_id.id move_vals = { 'name': loan_name, 'date': paid_date, 'ref': reference, 'period_id': period_ids or False, 'journal_id': journal_id, 'state': 'posted', } move_id = move_obj.create(move_vals) move_line_vals = { 'name': loan_name, 'ref': reference, 'move_id': move_id.id, 'account_id': line.loan_id.emp_account_id.id, 'debit': 0.0, 'credit': amount, 'period_id': period_ids or False, 'journal_id': journal_id, 'currency_id': company_currency != current_currency and current_currency or False, 'amount_currency': 0.0, 'date': paid_date, 'loan_id':line.loan_id.id, } move_line_obj.create(move_line_vals) move_line_vals2 = { 'name': loan_name, 'ref': reference, 'move_id': move_id.id, 'account_id': line.loan_id.treasury_account_id.id, 'credit': 0.0, 'debit': amount, 'period_id': period_ids or False, 'journal_id': journal_id, 'currency_id': company_currency != current_currency and current_currency or False, 'amount_currency': 0.0, 'date': paid_date, 'loan_id':line.loan_id.id, } move_line_obj.create(move_line_vals2) self.write({'paid': True}) return True
def import_products(self): '''Import product data from CSV/XLS''' product_model = self.env['product.product'] supplierinfo_model = self.env['product.supplierinfo'] currency_mapping_model = self.env['product_import_vendor_cart.currency_mapping'] uom_mapping_model = self.env['product_import_vendor_cart.uom_mapping'] file_format = self.vendor_settings_id.file_format # Read in the CSV or XLS file contents csv_rows = False sheet = False if file_format == 'csv': delimiter = str(self.vendor_settings_id.delimiter) reader, range_start, range_stop, csv_rows = self.get_csv_reader(delimiter) else: reader, range_start, range_stop, sheet = self.get_xls_reader() ''' Iterate content rows from the header+1 row onwards ''' for row_number in range(range_start, range_stop): # Stop iteration at the first encountered empty row (=empty first cell) if self.get_cell_value(file_format, row_number, 0, excel_data=sheet, csv_data=csv_rows, strip_nonnumeric=False) == '': break # Placeholder dictionaries for storing product and supplierinfo row values product_vals = {} supplierinfo_vals = {} # Value of the field specified in vendor settings, e.g. manufacturer code # If found, is used to update existing product identifying_field_value = False # Go through all mapping rows that have product or supplierinfo counterpart fields defined for mapping in self.vendor_settings_id.field_mapping_ids: if mapping.product_field_ids: for product_field_id in mapping.product_field_ids: if product_field_id.ttype == 'many2one': # Rudimentary handling for m2o fields pointing to res.partner (other types are not currently allowed): # Search case-insensitively for records that are named with the cell contents, e.g. "NEUTRIK" target_model = self.env[product_field_id.relation] search_term = self.get_cell_value(file_format, row_number, mapping.column_number - 1, excel_data=sheet, csv_data=csv_rows, strip_nonnumeric=False) # If there are duplicates found, ignore them and just use the first result matching_target = target_model.search(args=[('name', '=ilike', search_term)], limit=1) if matching_target: # Link the product to the m2o target model product_vals[product_field_id.name] = matching_target[0].id else: # Create a new object if there was no match, and link the product to it target_res = target_model.create({ 'name': search_term }) product_vals[product_field_id.name] = target_res.id else: # Strip nonnumeric characters if the target field is numeric, in case the field contains e.g. currency with the value, e.g. "34.72 EUR" if product_field_id.ttype in ['integer', 'float']: strip_nonnumeric = True else: strip_nonnumeric = False product_vals[product_field_id.name] = self.get_cell_value(file_format, row_number, mapping.column_number - 1, excel_data=sheet, csv_data=csv_rows, strip_nonnumeric=strip_nonnumeric) # Also store the value of the identifying product field (e.g. manufacturer code), so that # we can search later if such product already exists. if product_field_id.id == self.vendor_settings_id.identifying_field_id.id: identifying_field_value = self.get_cell_value(file_format, row_number, mapping.column_number - 1, excel_data=sheet, csv_data=csv_rows, strip_nonnumeric=False) if mapping.supplierinfo_field_ids: for supplierinfo_field_id in mapping.supplierinfo_field_ids: if supplierinfo_field_id.ttype == 'many2one' and supplierinfo_field_id.relation == 'res.currency': search_term = self.get_cell_value(file_format, row_number, mapping.column_number - 1, excel_data=sheet, csv_data=csv_rows, strip_nonnumeric=False) matching_currency_mappings = currency_mapping_model.search(args=[('value_in_file', '=', search_term)], limit=1) if matching_currency_mappings: supplierinfo_vals[supplierinfo_field_id.name] = matching_currency_mappings[0].currency_id.id else: raise exceptions.except_orm('Error', 'Currency "{}" has not been mapped to any Odoo currency.'.format(search_term)) elif supplierinfo_field_id.ttype == 'many2one' and supplierinfo_field_id.relation == 'product.uom': search_term = self.get_cell_value(file_format, row_number, mapping.column_number - 1, excel_data=sheet, csv_data=csv_rows, strip_nonnumeric=False) matching_uom_mappings = uom_mapping_model.search(args=[('value_in_file', '=', search_term)], limit=1) if matching_uom_mappings: supplierinfo_vals[supplierinfo_field_id.name] = matching_uom_mappings[0].uom_id.id else: raise exceptions.except_orm('Error', 'UoM "{}" has not been mapped to any Odoo Unit of Measure.'.format(search_term)) else: if supplierinfo_field_id.ttype in ['integer', 'float']: strip_nonnumeric = True else: strip_nonnumeric = False supplierinfo_vals[supplierinfo_field_id.name] = self.get_cell_value(file_format, row_number, mapping.column_number - 1, excel_data=sheet, csv_data=csv_rows, strip_nonnumeric=strip_nonnumeric) # Check if we should create a new product or update an existing one if identifying_field_value and identifying_field_value.strip() != '': existing_products = product_model.search([(self.vendor_settings_id.identifying_field_id.name, '=', identifying_field_value)]) else: existing_products = False if not existing_products: # Create a new product and a new supplierinfo row for it res = product_model.create(product_vals) supplierinfo_vals['product_tmpl_id'] = res.product_tmpl_id.id supplierinfo_vals['name'] = self.vendor_settings_id.partner_id.id supplierinfo_model.create(supplierinfo_vals) else: # Update the products existing_products.write(product_vals) # Check all products individually if their supplierinfo should be updated as well for existing_product in existing_products: # Check for existing supplierinfo row for the product and vendor existing_supplierinfo = supplierinfo_model.search(args=[('product_tmpl_id', '=', existing_product.product_tmpl_id.id), ('name', '=', self.vendor_settings_id.partner_id.id)]) if existing_supplierinfo: existing_supplierinfo.write(supplierinfo_vals) else: supplierinfo_vals['product_tmpl_id'] = existing_product.product_tmpl_id.id supplierinfo_vals['name'] = self.vendor_settings_id.partner_id.id supplierinfo_model.create(supplierinfo_vals)
def action_retention_create(self): """ Este método genera el documento de retencion en varios escenarios considera casos de: * Generar retencion automaticamente * Generar retencion de reemplazo * Cancelar retencion generada """ TYPES_TO_VALIDATE = ['in_invoice', 'liq_purchase'] for inv in self: if not (inv.retention_ir or inv.retention_vat): continue if inv.create_retention_type == 'no_retention': continue wd_number = False if inv.create_retention_type == 'auto': sequence = inv.journal_id.auth_ret_id.sequence_id wd_number = self.env['ir.sequence'].get(sequence.code) else: if inv.withdrawing_number <= 0: raise except_orm(_('Error!'), u'El número de retención es incorrecto.') wd_number = inv.withdrawing_number # TODO: validate number if inv.retention_id: inv.retention_id.action_validate(wd_number) continue if inv.type in ['in_invoice', 'liq_purchase' ] and not inv.journal_id.auth_ret_id: # noqa raise except_orm( 'Error', 'No ha configurado la autorización de retenciones en el diario.' # noqa ) withdrawing_data = { 'partner_id': inv.partner_id.id, 'name': wd_number, 'invoice_id': inv.id, 'auth_id': inv.journal_id.auth_ret_id.id, 'type': inv.type, 'in_type': 'ret_%s' % inv.type, 'date': inv.date_invoice, 'num_document': self.invoice_number, } withdrawing = self.env['account.retention'].create( withdrawing_data) # noqa tids = [ l.id for l in inv.tax_line_ids if l.tax_group in ['ret_vat_b', 'ret_vat_srv', 'ret_ir'] ] # noqa account_invoice_tax = self.env['account.invoice.tax'].browse(tids) account_invoice_tax.write({ 'retention_id': withdrawing.id, 'num_document': inv.supplier_invoice_number }) # noqa if inv.type in TYPES_TO_VALIDATE: withdrawing.action_validate(wd_number) inv.write({'retention_id': withdrawing.id}) return True
def run(self): """ Executed by workflow """ result = False # Loop on actions to run action = self logger.debug('Action : %s' % action.name) ctx = self.env.context.copy() # Check if there is an active_id (this situation should not appear) if not self.env.context.get('active_id', False): logger.warning('active_id not found in context') return False # Retrieve the model related object action_model_obj = self.env[action.model_id.model] action_model = action_model_obj.browse(self.env.context['active_id']) # Check the action condition values = { 'context': self.env.context, 'object': action_model, 'time': time, 'cr': self.env.cr, 'pool': self.pool, 'uid': self.env.uid, } expression = eval(str(action.condition), values) if not expression: logger.debug('This action doesn\'t match with this object : %s' % action.condition) return False # If state is 'printing', execute the action if action.state == 'printing': # Get the printer id user = self.env.user values = { 'c': self.env.context, 'o': action_model, 'time': time, 'u': user, } try: # Retrieve the printer id printer_id = eval(str(action.printing_source), values) # Check if the printer was found if not printer_id: raise except_orm(_('Error'), _('Printer not found !')) except Exception: logger.error(traceback.format_exc()) raise except_orm(_('Error'), _('Printer not found !')) try: jobname = eval(str(action.printing_jobname), values) if jobname: ctx['jobname'] = jobname except Exception: logger.error(traceback.format_exc()) raise except_orm(_('Error'), _('Job Name expression error !')) # Get the report id # TODO : Check for a specific function, on action_model, which will return False or a report id. If False is returned, use the report put in the printing_report_id. # Prototype of the function : def get_printing_report_id(self, cr, uid, ids, context=None) # report_id = False # if getattr(action_model, 'get_printing_report_id', None) and callable(action_model.get_printing_report_id): # report_id = action_model.get_printing_report_id()[action_model.id] # # if not report_id: report_id = action.printing_report_id.id # Log the printer and report id logger.debug('ID of the printer : %s' % str(printer_id)) logger.debug('ID of the report : %s' % str(report_id)) # Print the requested ir.actions.report.xml if report_id: self.env['printers.list'].browse(printer_id).with_context( ctx).send_printer(report_id, [action_model.id]) else: raise except_orm(_('Error'), _('Report to print not found !')) # If the state is not 'printing', let the server action run itself else: result = super(ir_actions_server, action).run() return result
def unlink(self): for checkbook in self: if len(checkbook.issued_check_ids): raise except_orm(_('Error'), _('You cannot delete this checkbook because it has Issued Checks')) super(account_checkbook, checkbook).unlink() return True
def validate(self): move_obj = self.env['stock.move'] wo_resource_obj = self.env['mrp.wo.resource'] location_obj = self.env['stock.location'] for wiz in self: if wiz.qty <= 0: raise except_orm(_('Error'), _('Quantity must be higher than 0')) wo_resource_rcs = wo_resource_obj.search( [('wo_id', '=', wiz.wo_id.id)], order='sequence asc', limit=1) if wo_resource_rcs: location_in = wo_resource_rcs.resource_id.location_id else: location_in = location_obj.search([('usage', '=', 'internal')], limit=1) if not location_in: raise except_orm(_('Error'), _('There is not location internal.')) location_out = location_obj.search([('usage', '=', 'production')], limit=1) if not location_out: raise except_orm(_('Error'), _('There is not location production.')) new_move_rm = self.env['stock.move'] for line_rm in wiz.line_rm_ids: if line_rm.move_id: move_qty_uom = line_rm.qty uom_qty = line_rm.move_id.uom_qty or 1.0 move_qty_sec_uom = line_rm.move_id.sec_uom_qty * line_rm.qty / uom_qty move_qty_uoi = line_rm.move_id.uoi_qty * line_rm.qty / uom_qty history_rm_id = line_rm.move_id.history_id and line_rm.move_id.history_id.id or False new_move_rm += line_rm.move_id.copy({ 'uom_qty': move_qty_uom, 'sec_uom_qty': move_qty_sec_uom, 'uoi_qty': move_qty_uoi, 'procurement_id': False, 'history_id': history_rm_id }) else: efficient_unit_qty = line_rm.qty / wiz.qty new_move_rm += move_obj.create_move( line_rm.product_id, location_in.id, location_out.id, qty=line_rm.qty, uom=line_rm.uom_id, other_data={ 'wo_incoming_id': wiz.wo_id.id, 'efficient_unit_qty': efficient_unit_qty, 'origin': wiz.wo_id.name_get()[0][1], 'is_forecast': wiz.wo_id.is_forecast }) new_move_fp = self.env['stock.move'] for line_fp in wiz.line_fp_ids: if line_fp.move_id: move_qty_uom = line_fp.qty uom_qty = line_fp.move_id.uom_qty or 1.0 move_qty_sec_uom = line_fp.move_id.sec_uom_qty * line_fp.qty / uom_qty move_qty_uoi = line_fp.move_id.uoi_qty * line_fp.qty / uom_qty history_fp_id = line_fp.move_id.history_id and line_fp.move_id.history_id.id or False new_move_fp += line_fp.move_id.copy({ 'uom_qty': move_qty_uom, 'sec_uom_qty': move_qty_sec_uom, 'uoi_qty': move_qty_uoi, 'procurement_id': False, 'history_id': history_fp_id }) else: efficient_unit_qty = line_fp.qty / wiz.qty new_move_fp += move_obj.create_move( line_fp.product_id, location_out.id, location_in.id, qty=line_fp.qty, uom=line_fp.uom_id, other_data={ 'wo_outgoing_id': wiz.wo_id.id, 'efficient_unit_qty': efficient_unit_qty, 'origin': wiz.wo_id.name_get()[0][1], 'is_forecast': wiz.wo_id.is_forecast }) if new_move_rm: wiz.wo_id.aggregate_move(new_move_rm, type='rm', waiting_state=True) if new_move_fp: wiz.wo_id.aggregate_move(new_move_fp, type='fp', waiting_state=True) quantity = wiz.wo_id.quantity + wiz.qty wiz.wo_id.write({'quantity': quantity}) return True
def assigned_datetime(self, cr, uid, values, context=None): if context is None: context = {} res = {} if values.get('date_invoice', False) and\ not values.get('invoice_datetime', False): user_hour = self._get_time_zone(cr, uid, [], context=context) time_invoice = datetime.time(abs(user_hour), 0, 0) date_invoice = datetime.datetime.strptime(values['date_invoice'], '%Y-%m-%d').date() dt_invoice = datetime.datetime.combine( date_invoice, time_invoice).strftime('%Y-%m-%d %H:%M:%S') #res['invoice_datetime'] = dt_invoice res['invoice_datetime'] = datetime.datetime.now() res['date_invoice'] = values['date_invoice'] if values.get('invoice_datetime', False) and not\ values.get('date_invoice', False): date_invoice = fields.datetime.context_timestamp( cr, uid, datetime.datetime.strptime( values['invoice_datetime'], tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context) res['date_invoice'] = date_invoice res['invoice_datetime'] = values['invoice_datetime'] if 'invoice_datetime' in values and 'date_invoice' in values: if values['invoice_datetime'] and values['date_invoice']: date_invoice = datetime.datetime.strptime( values['invoice_datetime'], '%Y-%m-%d %H:%M:%S').date().strftime('%Y-%m-%d') if date_invoice != values['date_invoice']: groups_obj = self.pool.get('res.groups') group_datetime = self.pool.get( 'ir.model.data').get_object_reference( cr, uid, 'l10n_mx_invoice_datetime', 'group_datetime_invoice_l10n_mx_facturae') group_date = self.pool.get( 'ir.model.data').get_object_reference( cr, uid, 'l10n_mx_invoice_datetime', 'group_date_invoice_l10n_mx_facturae') if group_datetime and group_date: users_datetime = [] users_date = [] for user in groups_obj.browse( cr, uid, [group_datetime[1]], context=context)[0].users: users_datetime.append(user.id) for user in groups_obj.browse( cr, uid, [group_date[1]], context=context)[0].users: users_date.append(user.id) if uid in users_datetime: date_invoice = fields.datetime.context_timestamp( cr, uid, datetime.datetime.strptime( values['invoice_datetime'], tools.DEFAULT_SERVER_DATETIME_FORMAT), context=context) res['date_invoice'] = date_invoice res['invoice_datetime'] = values[ 'invoice_datetime'] elif uid in users_date: user_hour = self._get_time_zone(cr, uid, [], context=context) time_invoice = datetime.time(abs(user_hour), 0, 0) date_invoice = datetime.datetime.strptime( values['date_invoice'], '%Y-%m-%d').date() dt_invoice = datetime.datetime.combine( date_invoice, time_invoice).strftime('%Y-%m-%d %H:%M:%S') res['invoice_datetime'] = dt_invoice res['date_invoice'] = values['date_invoice'] else: raise except_orm( _('Warning!'), _('Invoice dates should be equal')) else: raise except_orm(_('Warning!'), _('Invoice dates should be equal')) if not values.get('invoice_datetime', False) and\ not values.get('date_invoice', False): res['date_invoice'] = fields.date.context_today(self, cr, uid, context=context) res['invoice_datetime'] = fields.datetime.now() return res
def _create_returns(self, cr, uid, ids, context=None): if context is None: context = {} record_id = context and context.get('active_id', False) or False sale_line_obj = self.pool.get('sale.order.line') move_obj = self.pool.get('stock.move') pick_obj = self.pool.get('stock.picking') uom_obj = self.pool.get('product.uom') data_obj = self.pool.get('stock.return.picking.line') pick = pick_obj.browse(cr, uid, record_id, context=context) data = self.read(cr, uid, ids[0], context=context) returned_lines = 0 # Cancel assignment of existing chained assigned moves moves_to_unreserve = [] for move in pick.move_lines: to_check_moves = [move.move_dest_id] while to_check_moves: current_move = to_check_moves.pop() if current_move.state not in ('done', 'cancel') and \ current_move.reserved_quant_ids: moves_to_unreserve.append(current_move.id) split_move_ids = move_obj.search(cr, uid, [('split_from', '=', current_move.id)], context=context) if split_move_ids: to_check_moves += move_obj.browse(cr, uid, split_move_ids, context=context) if moves_to_unreserve: move_obj.do_unreserve(cr, uid, moves_to_unreserve, context=context) # break the link between moves in order to be able to fix them # later if needed move_obj.write(cr, uid, moves_to_unreserve, {'move_orig_ids': False}, context=context) # Create new picking for returned products pick_type_id = pick.picking_type_id.return_picking_type_id and \ pick.picking_type_id.return_picking_type_id.id or \ pick.picking_type_id.id new_picking = pick_obj.copy(cr, uid, pick.id, { 'move_lines': [], 'picking_type_id': pick_type_id, 'state': 'draft', 'origin': pick.name, }, context=context) for data_get in data_obj.browse(cr, uid, data['product_return_moves'], context=context): move = data_get.move_id if not move: raise exceptions.except_orm(_('Warning !'), _("You have manually created " "product lines, please delete " "them to proceed")) new_qty = data_get.quantity if new_qty: # si es una reposición se controla que la cantidad no pase # del total que falta por reponer. if move.picking_id and move.picking_id.sale_id and \ move.picking_id.sale_id.replacement: used_sale_line = None for line in move.picking_id.sale_id.order_line: if line.product_id.id == data_get.product_id.id and \ new_qty <= (line.product_uom_qty - line.qty_replacement): used_sale_line = line if not used_sale_line: raise exceptions.except_orm(_('Replacement Error !'), _("Error in the quantity" "of replacement.")) qty_replacement = used_sale_line.qty_replacement + new_qty sale_line_obj.write(cr, uid, [used_sale_line.id], {'qty_replacement': qty_replacement}, context) returned_lines += 1 move_obj.copy(cr, uid, move.id, { 'product_id': data_get.product_id.id, 'product_uom_qty': new_qty, 'product_uos_qty': uom_obj._compute_qty(cr, uid, move.product_uom.id, new_qty, move.product_uos.id), 'picking_id': new_picking, 'state': 'draft', 'location_id': move.location_dest_id.id, 'location_dest_id': move.location_id.id, 'origin_returned_move_id': move.id, 'procure_method': 'make_to_stock', 'restrict_lot_id': data_get.lot_id.id, }) if not returned_lines: raise exceptions.except_orm(_('Warning!'), _("Please specify at least one" "non-zero quantity.")) pick_obj.action_confirm(cr, uid, [new_picking], context=context) pick_obj.action_assign(cr, uid, [new_picking], context) return new_picking, pick_type_id
def create_trial_balance(self): """ \ 生成科目余额表 \ 1.如果所选区间已经关闭则直接调出已有的科目余额表记录 2.判断如果所选的区间的 前一个期间没有关闭则报错 3.如果上一个区间不存在则报错 """ trial_balance_objs = self.env['trial.balance'].search([('period_id', '=', self.period_id.id)]) trial_balance_ids = [balance.id for balance in trial_balance_objs] if not self.period_id.is_closed: trial_balance_objs.unlink() last_period = self.compute_last_period_id(self.period_id) if last_period: last_period_id = last_period.id if not last_period.is_closed: raise except_orm(u'错误', u'前一期间未结账,无法取到期初余额') else: last_period_id = False period_id = self.period_id.id current_occurrence_dic_list = self.get_period_balance(period_id) trial_balance_dict = {} """把本期发生额的数量填写到 准备好的dict 中 """ for current_occurrence in current_occurrence_dic_list: account = self.env['finance.account'].browse(current_occurrence.get('account_id')) ending_balance_result = self.compute_ending_balance(current_occurrence.get('credit', 0) or 0, current_occurrence.get('debit', 0) or 0) account_dict = {'period_id': period_id, 'current_occurrence_debit': current_occurrence.get('debit', 0) or 0, 'current_occurrence_credit': current_occurrence.get('credit') or 0, 'subject_code': account.code, 'initial_balance_credit': 0, 'initial_balance_debit': 0, 'ending_balance_credit': ending_balance_result[0], 'ending_balance_debit': ending_balance_result[1], 'cumulative_occurrence_credit': current_occurrence.get('credit', 0) or 0, 'cumulative_occurrence_debit': current_occurrence.get('debit', 0) or 0, 'subject_name_id': current_occurrence.get('account_id')} trial_balance_dict[current_occurrence.get('account_id')] = account_dict """ 结合上一期间的 数据 填写 trial_balance_dict(余额表 记录生成dict) """ for trial_balance in self.env['trial.balance'].search([('period_id', '=', last_period_id)]): initial_balance_credit = trial_balance.ending_balance_credit or 0 initial_balance_debit = trial_balance.ending_balance_debit or 0 subject_name_id = trial_balance.subject_name_id.id if subject_name_id in trial_balance_dict: ending_balance_credit = trial_balance_dict[subject_name_id].get('current_occurrence_credit', 0) + initial_balance_credit ending_balance_debit = trial_balance_dict[subject_name_id].get('current_occurrence_debit', 0) + initial_balance_debit cumulative_occurrence_credit = trial_balance_dict[subject_name_id].get('current_occurrence_credit', 0) + trial_balance.cumulative_occurrence_credit cumulative_occurrence_debit = trial_balance_dict[subject_name_id].get('current_occurrence_debit', 0) + trial_balance.cumulative_occurrence_debit else: ending_balance_credit = initial_balance_credit ending_balance_debit = initial_balance_debit cumulative_occurrence_credit = trial_balance.cumulative_occurrence_credit or 0 cumulative_occurrence_debit = trial_balance.cumulative_occurrence_debit or 0 ending_balance_result = self.compute_ending_balance(ending_balance_credit, ending_balance_debit) subject_code = trial_balance.subject_code trial_balance_dict[subject_name_id] = { 'initial_balance_credit': initial_balance_credit, 'initial_balance_debit': initial_balance_debit, 'ending_balance_credit': ending_balance_result[0], 'ending_balance_debit': ending_balance_result[1], 'cumulative_occurrence_credit': cumulative_occurrence_credit, 'cumulative_occurrence_debit': cumulative_occurrence_debit, 'subject_code': subject_code, 'period_id': period_id, 'subject_name_id': subject_name_id } trial_balance_ids = [self.env['trial.balance'].create(vals).id for (key, vals) in trial_balance_dict.items()] view_id = self.env.ref('finance.trial_balance_tree').id return { 'type': 'ir.actions.act_window', 'name': u'期末余额表', 'view_type': 'form', 'view_mode': 'tree', 'res_model': 'trial.balance', 'target': 'current', 'view_id': False, 'views': [(view_id, 'tree')], 'domain': [('id', 'in', trial_balance_ids)] }
class ExportXlsxTemplate(models.TransientModel): """ This wizard is used with the template (ir.attachment) to export xlsx template filled with data form the active record """ _name = 'export.xlsx.template' name = fields.Char( string='File Name', readonly=True, ) data = fields.Binary( string='File', readonly=True, ) template_id = fields.Many2one( 'ir.attachment', string='Template', required=True, ondelete='cascade', domain="[('res_model', '=', res_model)]", ) res_id = fields.Integer( string='Resource ID', readonly=True, required=True, ) res_model = fields.Char( string='Resource Model', readonly=True, required=True, ) state = fields.Selection( [('choose', 'choose'), ('get', 'get')], default='choose', ) @api.model def default_get(self, fields): res_model = self._context.get('active_model', False) res_id = self._context.get('active_id', False) template_dom = [('res_model', '=', res_model), ('parent_id', '!=', False)] templates = self.env['ir.attachment'].search(template_dom) template_fname = self._context.get('template_fname', False) if template_fname: # Specific template template_dom.append(('datas_fname', '=', template_fname)) if not templates: raise ValidationError(_('No template found!')) defaults = super(ExportXlsxTemplate, self).default_get(fields) for template in templates: if not template.datas: raise ValidationError(_('No file in %s') % (template.name, )) defaults['template_id'] = len(templates) == 1 and templates.id or False defaults['res_id'] = res_id defaults['res_model'] = res_model return defaults @api.model def _get_line_vals(self, record, line_field, fields): """ Get values of this field from record set """ line_field, max_row = get_line_max(line_field) lines = record[line_field] if max_row > 0 and len(lines) > max_row: raise Exception( _('Records in %s exceed max record allowed!') % line_field) vals = dict([(field, []) for field in fields]) # Get field condition & aggre function field_cond_dict = {} aggre_func_dict = {} field_format_dict = {} pair_fields = [] # I.e., ('debit${value and . or .}@{sum}', 'debit') for field in fields: temp_field, eval_cond = get_field_condition(field) temp_field, field_format = get_field_format(temp_field) raw_field, aggre_func = get_field_aggregation(temp_field) # Dict of all special conditions field_cond_dict.update({field: eval_cond}) aggre_func_dict.update({field: aggre_func}) field_format_dict.update({field: field_format}) # -- pair_fields.append((field, raw_field)) # -- for line in lines: for field in pair_fields: # (field, raw_field) value = self._get_field_data(field[1], line) # Case Eval eval_cond = field_cond_dict[field[0]] if eval_cond: # Get eval_cond of a raw field eval_context = { 'float_compare': float_compare, 'time': time, 'datetime': dt, 'date': date, 'value': value, 'object': line, 'model': self.env[record._name], 'env': self.env, 'context': self._context, } # value = str(eval(eval_cond, eval_context)) # Test removing str(), coz some case, need resulting number value = eval(eval_cond, eval_context) # -- vals[field[0]].append(value) return (vals, aggre_func_dict, field_format_dict) @api.model def _fill_workbook_data(self, workbook, record, data_dict): """ Fill data from record with format in data_dict to workbook """ if not record or not data_dict: return try: # variable to store data range of each worksheet worksheet_range = {} for sheet_name in data_dict: ws = data_dict[sheet_name] st = False if isinstance(sheet_name, str): st = get_sheet_by_name(workbook, sheet_name) elif isinstance(sheet_name, int): st = workbook.worksheets[sheet_name - 1] if not st: raise ValidationError( _('Sheet %s not found!') % sheet_name) # ================ HEAD ================ self._fill_head(ws, st, record) # ============= Line Items ============= all_rc, max_row, tail_fields = self._fill_lines(ws, st, record) # ================ TAIL ================ self._fill_tail(ws, st, record, tail_fields) # prepare worksheet data range, to be used in BI funtions if all_rc: begin_rc = min(all_rc) col, row = split_row_col(max(all_rc)) end_rc = '%s%s' % (col, max_row) worksheet_range[sheet_name] = '%s:%s' % (begin_rc, end_rc) # ================ BI Function ================ self._fill_bi(workbook, data_dict, worksheet_range) except KeyError, e: raise except_orm(_('Key Error!'), e) except IllegalCharacterError, e: raise except_orm( _('IllegalCharacterError!\n' 'Some exporting data may contain special character'), e)
def calculate_interest(self, cr, uid, ids, date_from, date_to, exclude_debit_note=True, company_id=False, context=None): if context is None: context = {} limit_value = 0 invoice_obj = self.pool.get('account.invoice') invoice_line_obj = self.pool.get('account.invoice.line') account_move_line_obj = self.pool.get('account.move.line') account_account_obj = self.pool.get('account.account') user = self.pool.get('res.users').browse(cr, uid, uid, context) # If not company defined we use the user company if not company_id: company_id = user.company_id.id # for partner in self.browse(cr, uid, [73], context=context): for partner in self.browse(cr, uid, ids, context=context): journal_domain = [ ('type', '=', 'sale'), ('company_id', '=', company_id), ] # Ahora el debit se elije en la invoice # ('afip_document_class_id.document_type', '=', 'debit_note') journal_ids = self.pool.get('account.journal').search( cr, uid, journal_domain, limit=1) if not journal_ids: raise except_orm( _('Error!'), _('Please define sales journal for this company id = %d.') % (company_id)) # TODO si se quiere mejorar, habria que poder setear algun diarion en algun lugar que se quiera usar pore defecto, y tal vez un document type (si el diario usa doucments) journal_id = journal_ids[0] values = {} interest = 0 move_line_domain = [ ('partner_id', '=', partner.id), ('journal_id.type', 'in', ['sale']), ('account_id.type', '=', 'receivable'), ('company_id', '=', company_id), # No se puede buscar por amoun_residual porque es una funcion # ('amount_residual', '>', 0), # We add this line for filtering thos moves that reconciled ('reconcile_id', '=', False), ('account_id.account_account_interest_ids', '!=', False), ('date_maturity', '<', date_to) ] if exclude_debit_note: move_line_domain.extend([ '|', ('invoice.afip_document_class_id', '=', False), ('invoice.afip_document_class_id.document_type', '!=', 'debit_note') ]) move_line_ids = account_move_line_obj.search(cr, uid, move_line_domain, order='date_maturity') # We generate a list of partial reconcile ids partial_reconcile_ids = [] for line in account_move_line_obj.browse(cr, uid, move_line_ids): if line.date_maturity < date_from: date_start = date_from else: date_start = line.date_maturity balance = line.amount_residual if balance <= 0: continue interest_data = account_account_obj.get_active_interest_data( cr, uid, [line.account_id.id], date_from, date_to, context=context) if line.account_id.id in interest_data: interest_rate = interest_data[ line.account_id.id].interest_rate account_id = interest_data[ line.account_id.id].interest_account_id.id analytic_id = interest_data[ line.account_id.id].analytic_account_id.id or False if line.reconcile_partial_id: # we check if we have already make the appointemnt for this # account move if line.id in partial_reconcile_ids: for partial_reconcile_id in line.reconcile_partial_id.line_partial_ids: partial_reconcile_ids.append( partial_reconcile_id.id) continue for partial_reconcile_id in line.reconcile_partial_id.line_partial_ids: partial_reconcile_ids.append( partial_reconcile_id.id) interest_res = self.calc_interests(cr, uid, date_start, date_to, balance, interest_rate) comment = self._prepare_description( cr, uid, line, date_start, date_to, balance, interest_rate) values[len(values)] = [ comment, round(interest_res, 2), line.move_id.id ] interest += interest_res # if values: if values and round(interest, 2) > limit_value: # if True: invoice_vals = self._prepare_invoice(cr, uid, partner, journal_id, context=context) tmp_date_from = datetime.strptime(date_from, '%Y-%m-%d') tmp_date_from = tmp_date_from.strftime('%d-%m-%y') tmp_date_to = datetime.strptime(date_to, '%Y-%m-%d') tmp_date_to = tmp_date_to.strftime('%d-%m-%y') invoice_vals['name'] = '' invoice_vals['comment'] = _( 'Punitive Interests ') + tmp_date_from + '/' + tmp_date_to invoice_vals['origin'] = invoice_vals['reference'] = _( 'Interests ') + tmp_date_from + '/' + tmp_date_to inv_id = invoice_obj.create(cr, uid, invoice_vals) for pos in values: if values[pos][1] > 0: invoice_line_obj.create( cr, uid, { 'name': values[pos][0], 'origin': '', 'invoice_id': inv_id, 'account_id': account_id, 'account_analytic_id': analytic_id, 'price_unit': values[pos][1], 'quantity': 1 }) return True
def approve_loan(self, cr, uid, ids, context=None): move_pool = self.pool.get('account.move') period_pool = self.pool.get('account.period') timenow = time.strftime('%Y-%m-%d') loan_slip = self.browse(cr, uid, ids)[0] line_ids = [] # get period ctx = dict(context or {}, account_period_prefer_normal=True) search_periods = period_pool.find(cr, uid, loan_slip.start_date, context=ctx) period_id = search_periods[0] # prepare account move data name = _('Loan for ') + (loan_slip.employee_id.name) move = { 'narration': name, 'date': timenow, 'loan_id': loan_slip.id, 'journal_id': loan_slip.payment_method.journal_id.id, 'period_id': period_id, } amount = loan_slip.amount debit_account_id = loan_slip.payment_method.debit_account_id.id or False credit_account_id = loan_slip.payment_method.credit_account_id.id or False analytic_account_id = loan_slip.payment_method.analytic_account_id.id or False if not loan_slip.payment_method: raise except_orm(_('Error!'), _('Please Set payment method')) if amount <= 0: raise except_orm(_('Error!'), _('Please Set Amount')) if not loan_slip.payment_method.journal_id: raise except_orm(_('Error!'), _('Please Set Journal For payment method')) if not credit_account_id or not debit_account_id: raise except_orm(_('Error!'), _('Please Set credit/debit account ')) if debit_account_id: debit_line = (0, 0, { 'name': 'Loan', 'date': timenow, 'partner_id': False, 'account_id': debit_account_id, 'journal_id': loan_slip.payment_method.journal_id.id, 'period_id': period_id, 'debit': amount, 'credit': 0.0, 'analytic_account_id': analytic_account_id, }) line_ids.append(debit_line) if credit_account_id: credit_line = (0, 0, { 'name': 'Loan', 'date': timenow, 'partner_id': False, 'account_id': credit_account_id, 'journal_id': loan_slip.payment_method.journal_id.id, 'period_id': period_id, 'debit': 0.0, 'credit': amount, 'analytic_account_id': False, }) line_ids.append(credit_line) move.update({'line_id': line_ids}) move_id = move_pool.create(cr, uid, move, context=context) move_ids = [] move_ids.append(move_id) for move_rec in loan_slip.move_ids: move_ids.append(move_rec.id) loan_name = loan_slip.name if not loan_slip.name: loan_name = self.pool.get('ir.sequence').get( cr, uid, 'hr.loan') self.write(cr, uid, [loan_slip.id], { 'move_id': move_id, 'period_id': period_id, 'move_ids': [(6, 0, move_ids)], 'state': 'approved', 'name': loan_name }, context=context) move_pool.post(cr, uid, [move_id], context=context) return True
begin_rc = min(all_rc) col, row = split_row_col(max(all_rc)) end_rc = '%s%s' % (col, max_row) worksheet_range[sheet_name] = '%s:%s' % (begin_rc, end_rc) # ================ BI Function ================ self._fill_bi(workbook, data_dict, worksheet_range) except KeyError, e: raise except_orm(_('Key Error!'), e) except IllegalCharacterError, e: raise except_orm( _('IllegalCharacterError!\n' 'Some exporting data may contain special character'), e) except Exception, e: raise except_orm(_('Error filling data into excel sheets!'), e) @api.model def _get_field_data(self, _field, _line): """ Get field data, and convert data type if needed """ if not _field: return None line_copy = _line for f in _field.split('.'): data_type = line_copy._fields[f].type line_copy = line_copy[f] if data_type == 'date': if line_copy: line_copy = dt.strptime(line_copy, '%Y-%m-%d') elif data_type == 'datetime': if line_copy:
def button_ok(self): res = [] if self.date_end < self.date_start: raise except_orm(u'错误', u'开始日期不能大于结束日期!') domain = [ ('move_id.date', '>=', self.date_start), ('move_id.date', '<=', self.date_end), ('move_id.origin', 'like', 'buy'), ('state', '=', 'done'), ] if self.goods_id: domain.append(('goods_id', '=', self.goods_id.id)) if self.partner_id: domain.append(('move_id.partner_id', '=', self.partner_id.id)) if self.order_id: buy_receipt = self.env['buy.receipt'].search([('id', '=', self.order_id.id)]) domain.append(('move_id.id', '=', buy_receipt.buy_move_id.id)) order_type = '' for line in self.env['wh.move.line'].search(domain, order='move_id'): if line.move_id.origin and 'return' in line.move_id.origin: order_type = '退货' else: order_type = '购货' detail = self.env['buy.order.detail'].create({ 'date': line.move_id.date, 'order_name': line.move_id.name, 'type': order_type, 'partner_id': line.move_id.partner_id.id, 'goods_code': line.goods_id.code, 'goods_id': line.goods_id.id, 'attribute': line.attribute_id.name, 'uom': line.uom_id.name, 'warehouse_dest': line.warehouse_dest_id.name, 'qty': line.goods_qty, 'price': line.price, 'amount': line.amount, 'tax_amount': line.tax_amount, 'subtotal': line.subtotal, 'note': line.note, }) res.append(detail.id) view = self.env.ref('buy.buy_order_detail_tree') return { 'name': u'采购明细表', 'view_type': 'form', 'view_mode': 'tree', 'view_id': False, 'views': [(view.id, 'tree')], 'res_model': 'buy.order.detail', 'type': 'ir.actions.act_window', 'domain': [('id', 'in', res)], 'limit': 300, }
def _merge(self, cr, uid, partner_ids, dst_partner=None, context=None): proxy = self.pool.get('res.partner') partner_ids = proxy.exists(cr, uid, list(partner_ids), context=context) if len(partner_ids) < 2: return if len(partner_ids) > 3: raise except_orm( _('Error'), _("For safety reasons, you cannot merge more than 3 contacts " "together. You can re-open the wizard several times if " "needed.")) if (openerp.SUPERUSER_ID != uid and len( set(partner.email for partner in proxy.browse( cr, uid, partner_ids, context=context))) > 1): raise except_orm( _('Error'), _("All contacts must have the same email. Only the " "Administrator can merge contacts with different emails.")) if dst_partner and dst_partner.id in partner_ids: src_partners = proxy.browse( cr, uid, [id for id in partner_ids if id != dst_partner.id], context=context) else: ordered_partners = self._get_ordered_partner( cr, uid, partner_ids, context) dst_partner = ordered_partners[-1] src_partners = ordered_partners[:-1] _logger.info("dst_partner: %s", dst_partner.id) if (openerp.SUPERUSER_ID != uid and self._model_is_installed( cr, uid, 'account.move.line', context=context) and self.pool['account.move.line'].search( cr, openerp.SUPERUSER_ID, [('partner_id', 'in', [partner.id for partner in src_partners])], context=context)): raise except_orm( _('Error'), _("Only the destination contact may be linked to existing " "Journal Items. Please ask the Administrator if you need to" " merge several contacts linked to existing Journal " "Items.")) self._update_foreign_keys(cr, uid, src_partners, dst_partner, context=context) self._update_reference_fields(cr, uid, src_partners, dst_partner, context=context) self._update_values(cr, uid, src_partners, dst_partner, context=context) _logger.info('(uid = %s) merged the partners %r with %s', uid, list(map(operator.attrgetter('id'), src_partners)), dst_partner.id) dst_partner.message_post(body='%s %s' % (_("Merged with the following partners:"), ", ".join('%s<%s>(ID %s)' % (p.name, p.email or 'n/a', p.id) for p in src_partners))) for partner in src_partners: partner.unlink()
def _compute_open_transactions_lines(self, accounts_ids, main_filter, target_move, start, stop, date_until=False, partner_filter=False): res = defaultdict(dict) # we check if until date and date stop have the same value if main_filter in ('filter_period', 'filter_no'): date_stop = stop.date_stop date_until_match = (date_stop == date_until) elif main_filter == 'filter_date': date_stop = stop date_until_match = (stop == date_until) else: raise except_orm( _('Unsuported filter'), _('Filter has to be in filter date, period, or none')) initial_move_lines_per_account = {} if main_filter in ('filter_period', 'filter_no'): initial_move_lines_per_account = self._tree_move_line_ids( self._partners_initial_balance_line_ids(accounts_ids, start, partner_filter, exclude_reconcile=True, force_period_ids=False, date_stop=date_stop), key='id') for account_id in accounts_ids: initial_move_lines_ids_per_partner = \ initial_move_lines_per_account.get(account_id, {}) # We get the move line ids of the account move_line_ids_per_partner = self.get_partners_move_lines_ids( account_id, main_filter, start, stop, target_move, exclude_reconcile=True, partner_filter=partner_filter) if not initial_move_lines_ids_per_partner \ and not move_line_ids_per_partner: continue for partner_id in list( set(initial_move_lines_ids_per_partner.keys() + move_line_ids_per_partner.keys())): partner_line_ids = ( move_line_ids_per_partner.get(partner_id, []) + initial_move_lines_ids_per_partner.get(partner_id, [])) clearance_line_ids = [] if date_until and not date_until_match and partner_line_ids: clearance_line_ids = self._get_clearance_move_line_ids( partner_line_ids, date_stop, date_until) partner_line_ids += clearance_line_ids lines = self._get_move_line_datas(list(set(partner_line_ids))) for line in lines: if line['id'] in initial_move_lines_ids_per_partner.\ get(partner_id, []): line['is_from_previous_periods'] = True if line['id'] in clearance_line_ids: line['is_clearance_line'] = True res[account_id][partner_id] = lines return res
def compute_difference(self): form = self[0] move_obj = self.env['account.move'] account_obj = self.env['account.account'] journal_obj = self.env['account.journal'] move_line_obj = self.env['account.move.line'] period_obj = self.env['account.period'] curr_obj = self.env['res.currency'] # get current period from company company = form.company_id period = form.period_id journal = form.journal_id company_currency = company.currency_id reevaluation_date = period.date_stop account_ids = [ account.id for account in account_obj.search([( 'currency_reevaluation', '=', True), ('company_id', '=', company.id)]) ] date1 = datetime.strptime(reevaluation_date, "%Y-%m-%d") + relativedelta(day=1, months=+1) ctx = dict(self._context) ctx1 = dict(self._context) ctx.update({'date': date1}) #get account move lines with foreign currency posted before reevaluation date (end of period) #balance and foreign balance are not taking in consideration newwer reconciliations query = """ SELECT DISTINCT sub.id, sub.date, sub.account_id, sub.journal_id, sub.partner_id, sub.currency_id, COALESCE(SUM(sub.balance),0) + COALESCE(SUM(sub.pay_amount),0) as balance, COALESCE(SUM(sub.foreign_balance),0) + COALESCE(SUM(sub.foreign_pay_amount),0) as foreign_balance FROM (SELECT l.id as id, l.date as date, COALESCE(partner.id,0) AS partner_id, account.id as account_id, l.journal_id as journal_id, COALESCE(SUM(l.debit - l.credit),0) / (CASE WHEN EXISTS(select lrec.id from account_move_line lrec WHERE l.reconcile_partial_id = lrec.reconcile_partial_id and l.id != lrec.id AND lrec.date <= %(reevaluation_date)s::date) THEN COUNT(lrec.id) ELSE 1 END) as balance, COALESCE(SUM(l.amount_currency),0) / (CASE WHEN EXISTS(select lrec.id from account_move_line lrec WHERE l.reconcile_partial_id = lrec.reconcile_partial_id and l.id != lrec.id AND lrec.date <= %(reevaluation_date)s::date) THEN COUNT(lrec.id) ELSE 1 END) as foreign_balance, COALESCE(SUM(lrec.debit - lrec.credit),0) as pay_amount, COALESCE(SUM(lrec.amount_currency),0) as foreign_pay_amount, l.currency_id as currency_id FROM account_move_line l LEFT JOIN account_move am ON am.id = l.move_id LEFT JOIN account_account account ON account.id = l.account_id LEFT JOIN account_journal journal ON journal.id = l.journal_id LEFT JOIN res_partner partner ON partner.id = l.partner_id LEFT JOIN account_move_line lrec ON l.reconcile_partial_id = lrec.reconcile_partial_id and l.id != lrec.id AND lrec.date <= %(reevaluation_date)s::date WHERE (journal.type::text != 'bank'::character varying::text AND journal.type::text != 'cash'::character varying::text) AND account.company_id = %(company_id)s AND am.state::text = 'posted'::character varying::text AND account.id = ANY(%(account_ids)s) AND l.date <= %(reevaluation_date)s AND l.currency_id IS NOT NULL GROUP BY l.id, account.id, partner.id, l.journal_id, l.currency_id ORDER BY account_id, journal_id, partner_id, l.id) AS sub WHERE sub.foreign_balance <> 0.00 AND sub.currency_id IS NOT NULL GROUP BY partner_id, account_id, journal_id, date, sub.currency_id, sub.id ORDER BY account_id, journal_id, partner_id, sub.id """ params = { 'reevaluation_date': reevaluation_date, 'account_ids': account_ids, 'company_id': company.id } self._cr.execute(query, params) lines = self._cr.dictfetchall() created_ids = [] vals = { 'name': 'Currency update ' + period.code, 'journal_id': journal.id, 'period_id': period.id, 'date': period.date_stop } move_id = move_obj.create(vals) move = move_id[0] expense_acc = company.expense_currency_exchange_account_id.id income_acc = company.income_currency_exchange_account_id.id for line in lines: aml = move_line_obj.browse(line['id']) currency = curr_obj.browse(line['currency_id']) account = account_obj.browse(line['account_id']) new_amount = currency.with_context(ctx).compute( line['foreign_balance'], company_currency, round=True) rec_ids = [] if datetime.strptime(line['date'], "%Y-%m-%d").month == datetime.strptime( reevaluation_date, "%Y-%m-%d").month: #get current currency rate date1 = datetime.strptime(line['date'], "%Y-%m-%d") ctx1.update({'date': date1}) else: date1 = datetime.strptime(period.date_start, "%Y-%m-%d") ctx1.update({'date': date1}) old_amount = currency.with_context(ctx1).compute( line['foreign_balance'], company_currency, round=True) amount = new_amount - old_amount if amount <> 0.00: if amount > 0: eval_account = income_acc debit = abs(amount) credit = 0.00 if account.user_type.code in ['payable', 'liability']: partner_id = line['partner_id'] <> 0 and line[ 'partner_id'] else: partner_id = False else: eval_account = expense_acc debit = 0.00 credit = abs(amount) if account.user_type.code in ['payable', 'liability']: partner_id = False else: partner_id = line['partner_id'] <> 0 and line[ 'partner_id'] valsm = { 'name': 'Update ' + str(line['foreign_balance']), 'ref': 'Update ' + str(line['foreign_balance']), 'move_id': move.id, 'journal_id': journal.id, 'account_id': account.id, 'partner_id': line['partner_id'], 'period_id': period.id, 'debit': debit, 'credit': credit, 'amount_currency': 0.00, 'currency_id': currency.id, 'date': period.date_stop, } part_move = move_line_obj.create(valsm) valsm = { 'name': 'Update ' + str(line['foreign_balance']), 'ref': 'Update ' + str(line['foreign_balance']), 'move_id': move.id, 'journal_id': journal.id, 'account_id': eval_account, 'partner_id': False, 'period_id': period.id, 'debit': credit, 'credit': debit, 'amount_currency': 0.00, 'currency_id': currency.id, 'date': period.date_stop, } move_line_obj.create(valsm) move_lines = [ move_line.id for move_line in aml.reconcile_partial_id.line_partial_ids ] move_lines.append(part_move[0].id) move_line_obj.browse(move_lines).reconcile_partial('auto') created_ids.append(move_id) lines = [] query = """ SELECT DISTINCT ON (journal_id) j.id as journal_id, s.date AS date, s.balance_end_real as balance, c.id as currency_id FROM account_bank_statement s INNER JOIN account_journal j on s.journal_id = j.id INNER JOIN res_company com on s.company_id = com.id INNER JOIN res_currency c on ((j.currency is not null and j.currency = c.id)) INNER JOIN (SELECT journal_id, max(date) as max_date FROM account_bank_statement WHERE date <= %(reevaluation_date)s::date AND state = 'confirm' GROUP BY journal_id) d ON (s.journal_id = d.journal_id AND s.date = d.max_date) WHERE j.company_id = %(company_id)s ORDER BY journal_id, date""" params = { 'reevaluation_date': reevaluation_date, 'company_id': company.id } self._cr.execute(query, params) lines = self._cr.dictfetchall() for line in lines: currency = curr_obj.browse(line['currency_id']) journal = journal_obj.browse(line['journal_id']) new_amount = currency.with_context(ctx).compute(line['balance'], company_currency, round=True) rec_ids = [] if datetime.strptime(line['date'], "%Y-%m-%d").month == datetime.strptime( reevaluation_date, "%Y-%m-%d").month: #get current currency rate date1 = datetime.strptime(line['date'], "%Y-%m-%d") ctx1.update({'date': date1}) else: date1 = datetime.strptime(period.date_start, "%Y-%m-%d") ctx1.update({'date': date1}) old_amount = currency.with_context(ctx1).compute(line['balance'], company_currency, round=True) amount = new_amount - old_amount if amount <> 0.00: vals = { 'name': 'Currency update ' + period.code, 'journal_id': journal.id, 'period_id': period.id, 'date': period.date_stop } move_id = move_obj.create(vals) move = move_id[0] if amount > 0: eval_account = income_acc journal_account = journal.default_debit_account_id debit = abs(amount) credit = 0.00 else: eval_account = expense_acc journal_account = journal.default_credit_account_id debit = 0.00 credit = abs(amount) valsm = { 'name': 'Update ' + str(line['balance']), 'ref': 'Update ' + str(line['balance']), 'move_id': move.id, 'journal_id': journal.id, 'account_id': journal_account.id, 'partner_id': False, 'period_id': period.id, 'debit': debit, 'credit': credit, 'amount_currency': 0.00, 'currency_id': currency.id, 'date': period.date_stop, } move_line_obj.create(valsm) valsm = { 'name': 'Update ' + str(line['balance']), 'ref': 'Update ' + str(line['balance']), 'move_id': move.id, 'journal_id': journal.id, 'account_id': eval_account, 'partner_id': False, 'period_id': period.id, 'debit': credit, 'credit': debit, 'amount_currency': 0.00, 'currency_id': currency.id, 'date': period.date_stop, } move_line_obj.create(valsm) created_ids.append(move_id) if created_ids: return { 'domain': "[('id','in', %s)]" % (created_ids, ), 'name': _("Created reevaluation lines"), 'view_type': 'form', 'view_mode': 'tree,form', 'auto_search': True, 'res_model': 'account.move', 'view_id': False, 'search_view_id': False, 'type': 'ir.actions.act_window' } else: raise except_orm(_("Warning"), _("No accounting entry have been posted."))
'%s://%s' % (proto, self.instance_id.main_hostname), db=self.name, user='******', password=self.instance_id.admin_pass) # then try to connect using database pass except: try: proto = 'https' if self.instance_id.type == u'secure' else 'http' return Client( '%s://%s' % (proto, self.instance_id.main_hostname), db=self.name, user='******', password=self.admin_password) except Exception, e: raise except_orm( _("Unable to Connect to Database."), _('Error: %s') % e ) # Backups management # @api.one # def update_backups_data(self): # client = self.get_client() # modules = ['database_tools'] # for module in modules: # if client.modules(name=module, installed=True) is None: # raise Warning( # _("You can not Update Backups Data if module '%s' is not installed in the database") % (module)) # self_db_id = client.model('ir.model.data').xmlid_to_res_id( # 'database_tools.db_self_database') # backups_data = client.read(
def show_passwd(self): raise except_orm( _("Password:"******"%s") % self.admin_password )
def action_approve(self): self.state = 'approve' if not self.emp_account_id or not self.treasury_account_id or not self.journal_id: raise except_orm('Warning', "You must enter employee account & Treasury account and journal to approve ") if not self.loan_line_ids: raise except_orm('Warning', 'You must compute Loan Request before Approved') can_close = False loan_obj = self.env['hr.loan'] period_obj = self.env['account.period'] move_obj = self.env['account.move'] move_line_obj = self.env['account.move.line'] currency_obj = self.env['res.currency'] created_move_ids = [] loan_ids = [] for loan in self: loan_request_date = loan.date period_ids =period_obj.with_context().find(loan_request_date).id company_currency = loan.employee_id.company_id.currency_id.id current_currency = self.env.user.company_id.currency_id.id amount = loan.loan_amount loan_name = loan.employee_id.name reference = loan.name journal_id = loan.journal_id.id move_vals = { 'name': loan_name, 'date': loan_request_date, 'ref': reference, 'period_id': period_ids or False, 'journal_id': journal_id, 'state': 'posted', } move_id = move_obj.create(move_vals) move_line_vals = { 'name': loan_name, 'ref': reference, 'move_id': move_id.id, 'account_id': loan.treasury_account_id.id, 'debit': 0.0, 'credit': amount, 'period_id': period_ids or False, 'journal_id': journal_id, 'currency_id': company_currency != current_currency and current_currency or False, 'amount_currency': 0.0, 'date': loan_request_date, } move_line_obj.create(move_line_vals) move_line_vals2 = { 'name': loan_name, 'ref': reference, 'move_id': move_id.id, 'account_id': loan.emp_account_id.id, 'credit': 0.0, 'debit': amount, 'period_id': period_ids or False, 'journal_id': journal_id, 'currency_id': company_currency != current_currency and current_currency or False, 'amount_currency': 0.0, 'date': loan_request_date, } move_line_obj.create(move_line_vals2) self.write({'move_id': move_id.id}) return True
def write(self, vals): if not self.env['res.users'].has_group( 'streamline_ame_modules.group_ame_edit_product'): raise except_orm(_('Invalid Action!'), _('User is not in "Editing Product" group.')) return super(product_template, self).write(vals)