def check_fund_activity_spending(self, fund_rule_line_id, amount): res = {'budget_ok': True, 'message': False} rule_line = self.env['budget.fund.rule.line'].browse(fund_rule_line_id) if rule_line.fund_rule_id.state in ('draft'): res['budget_ok'] = False res['message'] = _('Rules of Fund %s / Project %s ' 'has been set, but still in draft state!') % \ (rule_line.fund_rule_id.fund_id.name, rule_line.fund_rule_id.project_id.code) return res max_percent = rule_line.max_spending_percent expense_group = rule_line.expense_group_id if not rule_line.amount or rule_line.amount <= 0: res['budget_ok'] = False res['message'] = _('No amount has been allocated for ' 'Expense Group %s!') % (expense_group.name, ) return res future_amount = rule_line.amount_consumed + amount spending_percent = 100.0 * future_amount / rule_line.amount if spending_percent > max_percent: res['budget_ok'] = False res['message'] = _('Amount exceeded maximum spending ' 'for Expense Group %s!\n' '(%s%% vs %s%%)') % \ (expense_group.name, round(spending_percent, 2), round(max_percent, 2)) return res return res
def check_fund_activity_spending(self, fund_rule_line_id, amount): res = {'budget_ok': True, 'message': False} rule_line = self.env['budget.fund.rule.line'].browse(fund_rule_line_id) if rule_line.fund_rule_id.state in ('draft'): res['budget_ok'] = False res['message'] = _('Rules of Fund %s / Project %s ' 'has been set, but still in draft state!') % \ (rule_line.fund_rule_id.fund_id.name, rule_line.fund_rule_id.project_id.code) return res max_percent = rule_line.max_spending_percent expense_group = rule_line.expense_group_id if not rule_line.amount or rule_line.amount <= 0: res['budget_ok'] = False res['message'] = _('No amount has been allocated for ' 'Expense Group %s!') % (expense_group.name,) return res future_amount = rule_line.amount_consumed + amount spending_percent = 100.0 * future_amount / rule_line.amount if spending_percent > max_percent: res['budget_ok'] = False res['message'] = _('Amount exceeded maximum spending ' 'for Expense Group %s!\n' '(%s%% vs %s%%)') % \ (expense_group.name, round(spending_percent, 2), round(max_percent, 2)) return res 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 _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 _compute_check_invoice_plan_warning(self, exception=False): for purchase in self: if exception and purchase.bypass_validate_amount: continue if not purchase.invoice_method == 'invoice_plan': continue prec = 1 warnings = [] for order_line in purchase.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 # kittiu: Moving this error to show as invoice plan warning if round(line.invoice_percent / 100 * subtotal, prec) != \ round(line.invoice_amount, prec): warnings.append( _("- Diff %s -- on installment %s") % (order_line.name, line.installment)) if invoice_lines and \ round(total_amount, prec) != round(subtotal, prec): warnings.append( _("%s, plan amount %s diff with line amount %s!") % (order_line.name, '{:,.2f}'.format(total_amount), '{:,.2f}'.format(subtotal))) purchase.invoice_plan_warning = '\n'.join(warnings) if exception and purchase.invoice_plan_warning: raise except_orm(_('Invoice Plan Percent Mismatch!'), purchase.invoice_plan_warning) return True
def generate_report(self): """ Creates the trial balance in XML format """ import tempfile from datetime import datetime from openerp.tools import float_round as round # Get decimal precision from configuration for SAT precision_obj = self.pool.get('decimal.precision') dp = precision_obj.precision_get(self.cursor, self.uid, 'SAT') period = self._get_info(self.datas, 'period_from', 'account.period') time_period = datetime.strptime(period.date_start, "%Y-%m-%d") Etree = ET.ElementTree() balanza = ET.Element('BCE:Balanza') #namespace balanza.set( "xsi:schemaLocation", "www.sat.gob.mx/esquemas/ContabilidadE/1_1/BalanzaComprobacion http://www.sat.gob.mx/esquemas/ContabilidadE/1_1/BalanzaComprobacion/BalanzaComprobacion_1_1.xsd" ) balanza.set("xmlns:xsi", "http://www.w3.org/2001/XMLSchema-instance") balanza.set( "xmlns:BCE", "www.sat.gob.mx/esquemas/ContabilidadE/1_1/BalanzaComprobacion") balanza.set('Version', '1.1') balanza.set('RFC', self.localcontext['company'].partner_id.vat_split) balanza.set('Mes', str(time_period.month).rjust(2, '0')) balanza.set('Anio', str(time_period.year)) balanza.set('TipoEnvio', self.datas['type_send']) # If type_send equals to "C" puts the value of the "stop_period" field # as last modification of trial balance if self.datas['type_send'] == "C": balanza.set('FechaModBal', self.datas['last_modification']) Etree._setroot(balanza) for account in self.objects: # Verify if account has a valid fields "to_display" # and "sat_group_id", if no skips the account # code migrate time condition = if not account.to_display and not account.sat_group_id: if not account.sat_group_id: continue cuenta = ET.SubElement(balanza, 'BCE:Ctas') cuenta.set("NumCta", account.code) #befor code migration uncommented below one line # cuenta.set("SaldoIni", str(round(account.init_balance,dp))) cuenta.set("Debe", str(round(account.debit, dp))) cuenta.set("Haber", str(round(account.credit, dp))) cuenta.set("SaldoFin", str(round(account.balance, dp))) # Write data into temporal file with tempfile.NamedTemporaryFile(delete=False) as report: Etree.write(report.name, encoding='UTF-8') fname = report.name return fname
def _onchange_amount(self): if not self.plan_id.by_fiscalyear or self.is_advance_installment\ or self.is_deposit_installment: return super(PurchaseCreateInvoicePlanInstallment, self)._onchange_amount() obj_precision = self.env['decimal.precision'] prec = obj_precision.precision_get('Account') line_by_fiscalyear = self.plan_id._get_total_by_fy() order_amount = line_by_fiscalyear[self.fiscalyear_id.id] if not order_amount: raise Warning(_('Order amount equal to 0.0!')) new_val = self.amount / order_amount * 100 if round(new_val, prec) != round(self.percent, prec): self.percent = new_val
def _onchange_percent(self): if not self.plan_id.by_fiscalyear or\ self.is_advance_installment or self.is_deposit_installment: return super(PurchaseCreateInvoicePlanInstallment, self).\ _onchange_percent() obj_precision = self.env['decimal.precision'] prec = obj_precision.precision_get('Account') line_by_fiscalyear = self.plan_id._get_total_by_fy() order_amount = line_by_fiscalyear[self.fiscalyear_id.id] self.amount = round(order_amount * self.percent / 100, prec)
def _prepare_order_line_invoice_line_hook(self, cr, uid, line, account_id=False, context=None): if not account_id: if line.product_id: account_id = line.product_id.property_account_income.id if not account_id: account_id = line.product_id.\ categ_id.property_account_income_categ.id if not account_id: raise osv.except_osv( _('Error!'), _('Please define income account ' 'for this product: "%s" (id:%d).') % (line.product_id.name, line.product_id.id,)) else: prop = self.pool.get('ir.property').get( cr, uid, 'property_account_income_categ', 'product.category', context=context) account_id = prop and prop.id or False uosqty = self._get_line_qty(cr, uid, line, context=context) uos_id = self._get_line_uom(cr, uid, line, context=context) pu = 0.0 if uosqty: pu = round(line.price_unit * line.product_uom_qty / uosqty, self.pool.get('decimal.precision').precision_get( cr, uid, 'Product Price')) fpos = line.order_id.fiscal_position or False account_id = self.pool.get('account.fiscal.position').\ map_account(cr, uid, fpos, account_id) if not account_id: raise osv.except_osv( _('Error!'), _('There is no Fiscal Position defined or ' 'Income category account defined for ' 'default properties of Product categories.')) res = { 'name': line.name, 'sequence': line.sequence, 'origin': line.order_id.name, 'account_id': account_id, 'price_unit': pu, 'quantity': uosqty, 'discount': line.discount, 'uos_id': uos_id, 'product_id': line.product_id.id or False, 'invoice_line_tax_id': [(6, 0, [x.id for x in line.tax_id])], 'account_analytic_id': (line.order_id.project_id and line.order_id.project_id.id or False), } return res
def _check_invoice_plan(self): self.ensure_one() 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 ValidationError( _('For invoice plan mode "As 1 Job", ' 'all line quantity must equal to 1')) # kittiu: problem with decimal, so we dicide to test with 0 # obj_precision = self.env['decimal.precision'] # prec = obj_precision.precision_get('Account') prec = 0 # -- 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 %s not equal to line amount %s!") % (order_line.name, '{:,.2f}'.format(total_amount), '{:,.2f}'.format(subtotal))) return True
def _compute_installment_details(self): obj_precision = self.env['decimal.precision'] prec = obj_precision.precision_get('Account') if not self.by_fiscalyear: return super(PurchaseCreateInvoicePlan, self).\ _compute_installment_details() # order = self.env['purchase.order'].browse(self._context['active_id']) # order._check_invoice_mode() fiscalyear_dict = {} for f in self.env['account.fiscalyear'].search_read([], ['name', 'id']): fiscalyear_dict[f['id']] = f['name'] line_by_fiscalyear = self._get_total_by_fy() # line_by_fiscalyear = dict(sorted(line_by_fiscalyear.iteritems())) line_by_fiscalyear = \ OrderedDict(sorted(line_by_fiscalyear.iteritems())) line_of_fy = {} count = 0 installment_date = datetime.strptime(self.installment_date, "%Y-%m-%d") installment_day = installment_date.day for i in self.installment_ids: if i.is_advance_installment or i.is_deposit_installment: i.date_invoice = self.installment_date continue interval = self.interval if count == 0: interval = 0 if self.interval_type == 'month': installment_date =\ installment_date + relativedelta(months=+interval) elif self.interval_type == 'year': installment_date =\ installment_date + relativedelta(years=+interval) period_obj = self.env['account.period'] period_ids = period_obj.find(dt=installment_date) fy_id = period_ids[0].fiscalyear_id i.fiscalyear_id = fy_id # Check Fiscal year in invoice plan must not over fiscal year in # purchase order line (By POD) if i.fiscalyear_id.id not in line_by_fiscalyear.keys(): raise ValidationError( _('The number of installment and interval \ that you must yield invoice plan that \ cover all fiscal years.')) # -- if i.fiscalyear_id.id not in line_of_fy: line_of_fy[i.fiscalyear_id.id] = 1 else: line_of_fy[i.fiscalyear_id.id] += 1 i.date_invoice = installment_date count += 1 new_line_dict = {} installment_no = 1 if line_of_fy: for l in line_by_fiscalyear: if len(line_by_fiscalyear) == self.num_installment: number_of_lines = 1 else: if l not in line_of_fy.keys(): raise ValidationError( _('The number of installment and interval \ that you must yield invoice plan that \ cover all fiscal years.')) number_of_lines = line_of_fy[l] remaining_amt = line_by_fiscalyear[l] line_cnt = number_of_lines while line_cnt > 0: if self.env.context.get('from_installment_amount', False): installment_amt = self.installment_amount else: if l in line_of_fy.keys(): installment_amt = (line_by_fiscalyear[l] / line_of_fy[l]) else: installment_amt = self.installment_amount if line_cnt == 1 or\ installment_no == self.num_installment or\ remaining_amt < self.installment_amount: installment_amt = remaining_amt if installment_amt < 0: installment_amt = 0 remaining_amt -= installment_amt new_line_dict[installment_no] =\ (fiscalyear_dict[l], installment_amt, l) installment_no += 1 line_cnt -= 1 for i in self.installment_ids: if i.is_advance_installment or i.is_deposit_installment: continue if i.installment in new_line_dict: f_amount = line_by_fiscalyear[new_line_dict[i.installment][2]] if i.fiscalyear_id.id != new_line_dict[i.installment][2]: i.fiscalyear_id = new_line_dict[i.installment][2] fy_start_date = datetime.strptime( i.fiscalyear_id.date_start, "%Y-%m-%d") date_str = str(fy_start_date.month) + '/' + \ str(installment_day) + '/' + str(fy_start_date.year) i.date_invoice = datetime.strptime(date_str, '%m/%d/%Y') i.amount = new_line_dict[i.installment][1] new_val = f_amount and (i.amount / f_amount * 100) or 0.0 if round(new_val, prec) != round(i.percent, prec): i.percent = new_val
def _prepare_order_line_invoice_line_hook(self, cr, uid, line, account_id=False, context=None): if not account_id: if line.product_id: account_id = line.product_id.property_account_income.id if not account_id: account_id = line.product_id.\ categ_id.property_account_income_categ.id if not account_id: raise osv.except_osv( _('Error!'), _('Please define income account ' 'for this product: "%s" (id:%d).') % ( line.product_id.name, line.product_id.id, )) else: prop = self.pool.get('ir.property').get( cr, uid, 'property_account_income_categ', 'product.category', context=context) account_id = prop and prop.id or False uosqty = self._get_line_qty(cr, uid, line, context=context) uos_id = self._get_line_uom(cr, uid, line, context=context) pu = 0.0 if uosqty: pu = round( line.price_unit * line.product_uom_qty / uosqty, self.pool.get('decimal.precision').precision_get( cr, uid, 'Product Price')) fpos = line.order_id.fiscal_position or False account_id = self.pool.get('account.fiscal.position').\ map_account(cr, uid, fpos, account_id) if not account_id: raise osv.except_osv( _('Error!'), _('There is no Fiscal Position defined or ' 'Income category account defined for ' 'default properties of Product categories.')) res = { 'name': line.name, 'sequence': line.sequence, 'origin': line.order_id.name, 'account_id': account_id, 'price_unit': pu, 'quantity': uosqty, 'discount': line.discount, 'uos_id': uos_id, 'product_id': line.product_id.id or False, 'invoice_line_tax_id': [(6, 0, [x.id for x in line.tax_id])], 'account_analytic_id': (line.order_id.project_id and line.order_id.project_id.id or False), } return res
def _compute_installment_details(self): obj_precision = self.env['decimal.precision'] prec = obj_precision.precision_get('Account') if not self.by_fiscalyear: return super(PurchaseCreateInvoicePlan, self).\ _compute_installment_details() order = self.env['purchase.order'].browse(self._context['active_id']) self._check_invoice_mode(order) fiscalyear_dict = {} for f in self.env['account.fiscalyear'].search_read([], ['name', 'id']): fiscalyear_dict[f['id']] = f['name'] line_by_fiscalyear = self._get_total_by_fy() line_by_fiscalyear = dict(sorted(line_by_fiscalyear.iteritems())) line_of_fy = {} count = 0 installment_date = datetime.strptime(self.installment_date, "%Y-%m-%d") installment_day = installment_date.day for i in self.installment_ids: if i.is_advance_installment or i.is_deposit_installment: i.date_invoice = self.installment_date continue interval = self.interval if count == 0: interval = 0 if self.interval_type == 'month': installment_date =\ installment_date + relativedelta(months=+interval) elif self.interval_type == 'year': installment_date =\ installment_date + relativedelta(years=+interval) period_obj = self.env['account.period'] period_ids = period_obj.find(dt=installment_date) fy_id = period_ids[0].fiscalyear_id i.fiscalyear_id = fy_id if i.fiscalyear_id.id not in line_of_fy: line_of_fy[i.fiscalyear_id.id] = 1 else: line_of_fy[i.fiscalyear_id.id] += 1 i.date_invoice = installment_date count += 1 new_line_dict = {} installment_no = 1 if line_of_fy: for l in line_by_fiscalyear: if len(line_by_fiscalyear) == self.num_installment: number_of_lines = 1 else: if l not in line_of_fy.keys(): raise ValidationError( _('Please enter valid installment \ number and installment date .')) number_of_lines = line_of_fy[l] remaining_amt = line_by_fiscalyear[l] line_cnt = number_of_lines while line_cnt > 0: if self.env.context.get('from_installment_amount', False): installment_amt = self.installment_amount else: if l in line_of_fy.keys(): installment_amt = (line_by_fiscalyear[l] / line_of_fy[l]) else: installment_amt = self.installment_amount if line_cnt == 1 or\ installment_no == self.num_installment or\ remaining_amt < self.installment_amount: installment_amt = remaining_amt if installment_amt < 0: installment_amt = 0 remaining_amt -= installment_amt new_line_dict[installment_no] =\ (fiscalyear_dict[l], installment_amt, l) installment_no += 1 line_cnt -= 1 for i in self.installment_ids: if i.is_advance_installment or i.is_deposit_installment: continue if i.installment in new_line_dict: f_amount = line_by_fiscalyear[new_line_dict[i.installment][2]] if i.fiscalyear_id.id != new_line_dict[i.installment][2]: i.fiscalyear_id = new_line_dict[i.installment][2] fy_start_date = datetime.strptime( i.fiscalyear_id.date_start, "%Y-%m-%d") date_str = str(fy_start_date.month) + '/' + \ str(installment_day) + '/' + str(fy_start_date.year) i.date_invoice = datetime.strptime(date_str, '%m/%d/%Y') i.amount = new_line_dict[i.installment][1] new_val = i.amount / f_amount * 100 if round(new_val, prec) != round(i.percent, prec): i.percent = new_val