[ADD]: Multi Branch : Sale, Account.
This commit is contained in:
parent
dbdbad7ab1
commit
5993da4d2a
@ -45,6 +45,7 @@ class AccountAccountTag(models.Model):
|
||||
class AccountAccount(models.Model):
|
||||
_name = "account.account"
|
||||
_description = "Account"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_order = "code"
|
||||
|
||||
@api.multi
|
||||
@ -84,6 +85,17 @@ class AccountAccount(models.Model):
|
||||
('code_company_uniq', 'unique (code,company_id)', 'The code of the account must be unique per company !')
|
||||
]
|
||||
|
||||
@api.multi
|
||||
@api.constrains('branch_id', 'company_id')
|
||||
def _check_company_branch(self):
|
||||
for record in self:
|
||||
if record.branch_id and record.company_id != record.branch_id.company_id:
|
||||
raise ValidationError(_(
|
||||
'Configuration Error of Company:\n'
|
||||
'The Account Company (%s) and the Company (%s) of '
|
||||
'Branch must be the same!') % (
|
||||
record.company_id.name, record.branch_id.company_id.name))
|
||||
|
||||
def _compute_opening_debit_credit(self):
|
||||
for record in self:
|
||||
opening_debit = opening_credit = 0.0
|
||||
@ -305,6 +317,7 @@ class AccountGroup(models.Model):
|
||||
|
||||
class AccountJournal(models.Model):
|
||||
_name = "account.journal"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = "Journal"
|
||||
_order = 'sequence, type, code'
|
||||
|
||||
@ -387,6 +400,17 @@ class AccountJournal(models.Model):
|
||||
('code_company_uniq', 'unique (code, name, company_id)', 'The code and name of the journal must be unique per company !'),
|
||||
]
|
||||
|
||||
@api.multi
|
||||
@api.constrains('branch_id', 'company_id')
|
||||
def _check_company_branch(self):
|
||||
for record in self:
|
||||
if record.branch_id and record.company_id != record.branch_id.company_id:
|
||||
raise ValidationError(_(
|
||||
'Configuration Error of Company:\n'
|
||||
'The Account Company (%s) and the Company (%s) of '
|
||||
'Branch must be the same!') % (
|
||||
record.company_id.name, record.branch_id.company_id.name))
|
||||
|
||||
@api.multi
|
||||
# do not depend on 'sequence_id.date_range_ids', because
|
||||
# sequence_id._get_current_sequence() may invalidate it!
|
||||
@ -720,6 +744,7 @@ class AccountTaxGroup(models.Model):
|
||||
|
||||
class AccountTax(models.Model):
|
||||
_name = 'account.tax'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = 'Tax'
|
||||
_order = 'sequence,id'
|
||||
|
||||
@ -1008,6 +1033,7 @@ class AccountTax(models.Model):
|
||||
|
||||
class AccountReconcileModel(models.Model):
|
||||
_name = "account.reconcile.model"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = "Preset to create journal entries during a invoices and payments matching"
|
||||
|
||||
name = fields.Char(string='Button Label', required=True)
|
||||
|
@ -144,6 +144,8 @@ class AccountBankStatement(models.Model):
|
||||
journal_type = fields.Selection(related='journal_id.type', help="Technical field used for usability purposes")
|
||||
company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', store=True, readonly=True,
|
||||
default=lambda self: self.env['res.company']._company_default_get('account.bank.statement'))
|
||||
branch_id = fields.Many2one(related='journal_id.branch_id',
|
||||
string='Branch', store=True, readonly=True)
|
||||
|
||||
total_entry_encoding = fields.Monetary('Transactions Subtotal', compute='_end_balance', store=True, help="Total of transaction lines.")
|
||||
balance_end = fields.Monetary('Computed Balance', compute='_end_balance', store=True, help='Balance as calculated based on Opening Balance and transaction lines')
|
||||
@ -366,6 +368,8 @@ class AccountBankStatementLine(models.Model):
|
||||
note = fields.Text(string='Notes')
|
||||
sequence = fields.Integer(index=True, help="Gives the sequence order when displaying a list of bank statement lines.", default=1)
|
||||
company_id = fields.Many2one('res.company', related='statement_id.company_id', string='Company', store=True, readonly=True)
|
||||
branch_id = fields.Many2one(related='statement_id.branch_id',
|
||||
string='Company', store=True, readonly=True)
|
||||
journal_entry_ids = fields.One2many('account.move.line', 'statement_line_id', 'Journal Items', copy=False, readonly=True)
|
||||
amount_currency = fields.Monetary(help="The amount expressed in an optional other currency if it is a multi-currency entry.")
|
||||
currency_id = fields.Many2one('res.currency', string='Currency', help="The optional other currency if it is a multi-currency entry.")
|
||||
|
@ -41,7 +41,8 @@ MAGIC_COLUMNS = ('id', 'create_uid', 'create_date', 'write_uid', 'write_date')
|
||||
|
||||
class AccountInvoice(models.Model):
|
||||
_name = "account.invoice"
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin', 'portal.mixin']
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin', 'portal.mixin',
|
||||
'ir.branch.company.mixin']
|
||||
_description = "Invoice"
|
||||
_order = "date_invoice desc, number desc, id desc"
|
||||
|
||||
@ -383,6 +384,18 @@ class AccountInvoice(models.Model):
|
||||
domain += [('journal_id', '=', self.journal_id.id), ('state', 'not in', ['draft', 'cancel'])]
|
||||
return journal_sequence, domain
|
||||
|
||||
@api.constrains('company_id', 'branch_id')
|
||||
def _check_company(self):
|
||||
for order in self:
|
||||
if order.branch_id and order.company_id != order.branch_id.company_id:
|
||||
raise ValidationError(
|
||||
_('Configuration Error of Company:\n'
|
||||
'The Invoice Company (%s) and '
|
||||
'the Company (%s) of Branch must '
|
||||
'be the same company!') % (order.company_id.name,
|
||||
order.branch_id.company_id.name)
|
||||
)
|
||||
|
||||
def _compute_portal_url(self):
|
||||
super(AccountInvoice, self)._compute_portal_url()
|
||||
for order in self:
|
||||
@ -1131,6 +1144,7 @@ class AccountInvoice(models.Model):
|
||||
date = inv.date or inv.date_invoice
|
||||
move_vals = {
|
||||
'ref': inv.reference,
|
||||
'branch_id': inv.branch_id and inv.branch_id.id,
|
||||
'line_ids': line,
|
||||
'journal_id': journal.id,
|
||||
'date': date,
|
||||
@ -1493,6 +1507,9 @@ class AccountInvoiceLine(models.Model):
|
||||
analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags')
|
||||
company_id = fields.Many2one('res.company', string='Company',
|
||||
related='invoice_id.company_id', store=True, readonly=True, related_sudo=False)
|
||||
branch_id = fields.Many2one(string='Company',
|
||||
related='invoice_id.branch_id', store=True,
|
||||
readonly=True, related_sudo=False)
|
||||
partner_id = fields.Many2one('res.partner', string='Partner',
|
||||
related='invoice_id.partner_id', store=True, readonly=True, related_sudo=False)
|
||||
currency_id = fields.Many2one('res.currency', related='invoice_id.currency_id', store=True, related_sudo=False)
|
||||
@ -1676,6 +1693,9 @@ class AccountInvoiceTax(models.Model):
|
||||
manual = fields.Boolean(default=True)
|
||||
sequence = fields.Integer(help="Gives the sequence order when displaying a list of invoice tax.")
|
||||
company_id = fields.Many2one('res.company', string='Company', related='account_id.company_id', store=True, readonly=True)
|
||||
branch_id = fields.Many2one(string='Branch',
|
||||
related='account_id.branch_id', store=True,
|
||||
readonly=True)
|
||||
currency_id = fields.Many2one('res.currency', related='invoice_id.currency_id', store=True, readonly=True)
|
||||
base = fields.Monetary(string='Base', compute='_compute_base_amount', store=True)
|
||||
|
||||
@ -1687,6 +1707,7 @@ class AccountInvoiceTax(models.Model):
|
||||
|
||||
class AccountPaymentTerm(models.Model):
|
||||
_name = "account.payment.term"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = "Payment Terms"
|
||||
_order = "sequence, id"
|
||||
|
||||
|
@ -19,6 +19,7 @@ class AccountMove(models.Model):
|
||||
_name = "account.move"
|
||||
_description = "Account Entry"
|
||||
_order = 'date desc, id desc'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
|
||||
@api.multi
|
||||
@api.depends('name', 'state')
|
||||
@ -445,6 +446,8 @@ class AccountMoveLine(models.Model):
|
||||
analytic_account_id = fields.Many2one('account.analytic.account', string='Analytic Account')
|
||||
analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic tags')
|
||||
company_id = fields.Many2one('res.company', related='account_id.company_id', string='Company', store=True)
|
||||
branch_id = fields.Many2one(related='move_id.branch_id', string='Branch',
|
||||
store=True)
|
||||
counterpart = fields.Char("Counterpart", compute='_get_counterpart', help="Compute the counter part accounts of this journal item for this journal entry. This can be needed in reports.")
|
||||
|
||||
# TODO: put the invoice link and partner_id on the account_move
|
||||
@ -463,6 +466,31 @@ class AccountMoveLine(models.Model):
|
||||
('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in accounting entry !'),
|
||||
]
|
||||
|
||||
@api.constrains('move_id', 'branch_id')
|
||||
def _check_branch(self):
|
||||
for order in self:
|
||||
move_branch_id = order.move_id.branch_id
|
||||
if order.branch_id and move_branch_id != order.branch_id:
|
||||
raise ValidationError(
|
||||
_('Configuration Error of Branch:\n'
|
||||
'The Move Line Branch (%s) and '
|
||||
'the Branch (%s) of Journal Entry must '
|
||||
'be the same branch!') % (order.branch_id.name,
|
||||
move_branch_id.name)
|
||||
)
|
||||
|
||||
@api.constrains('company_id', 'branch_id')
|
||||
def _check_company(self):
|
||||
for order in self:
|
||||
if order.branch_id and order.company_id != order.branch_id.company_id:
|
||||
raise ValidationError(
|
||||
_('Configuration Error of Company:\n'
|
||||
'The Move Line Company (%s) and '
|
||||
'the Company (%s) of Branch must '
|
||||
'be the same company!') % (order.company_id.name,
|
||||
order.branch_id.company_id.name)
|
||||
)
|
||||
|
||||
@api.model
|
||||
def default_get(self, fields):
|
||||
rec = super(AccountMoveLine, self).default_get(fields)
|
||||
@ -1446,6 +1474,7 @@ class AccountMoveLine(models.Model):
|
||||
return {
|
||||
'name': self.name,
|
||||
'date': self.date,
|
||||
'branch_id': self.branch_id and self.branch_id.id,
|
||||
'account_id': self.analytic_account_id.id,
|
||||
'tag_ids': [(6, 0, self.analytic_tag_ids.ids)],
|
||||
'unit_amount': self.quantity,
|
||||
@ -1538,6 +1567,8 @@ class AccountPartialReconcile(models.Model):
|
||||
company_currency_id = fields.Many2one('res.currency', related='company_id.currency_id', readonly=True,
|
||||
help='Utility field to express amount currency')
|
||||
company_id = fields.Many2one('res.company', related='debit_move_id.company_id', store=True, string='Currency')
|
||||
branch_id = fields.Many2one(related='debit_move_id.branch_id', store=True,
|
||||
string='Branch')
|
||||
full_reconcile_id = fields.Many2one('account.full.reconcile', string="Full Reconcile", copy=False)
|
||||
max_date = fields.Date(string='Max Date of Matched Lines', compute='_compute_max_date',
|
||||
readonly=True, copy=False, store=True,
|
||||
|
@ -49,6 +49,8 @@ class account_abstract_payment(models.AbstractModel):
|
||||
communication = fields.Char(string='Memo')
|
||||
journal_id = fields.Many2one('account.journal', string='Payment Journal', required=True, domain=[('type', 'in', ('bank', 'cash'))])
|
||||
company_id = fields.Many2one('res.company', related='journal_id.company_id', string='Company', readonly=True)
|
||||
branch_id = fields.Many2one(related='journal_id.branch_id',
|
||||
string='Branch', readonly=True)
|
||||
|
||||
hide_payment_method = fields.Boolean(compute='_compute_hide_payment_method',
|
||||
help="Technical field used to hide the payment method if the selected journal has only one available which is 'manual'")
|
||||
@ -238,7 +240,7 @@ class account_register_payments(models.TransientModel):
|
||||
|
||||
class account_payment(models.Model):
|
||||
_name = "account.payment"
|
||||
_inherit = ['mail.thread', 'account.abstract.payment']
|
||||
_inherit = ['mail.thread', 'account.abstract.payment', 'ir.branch.company.mixin']
|
||||
_description = "Payments"
|
||||
_order = "payment_date desc, name desc"
|
||||
|
||||
|
@ -57,6 +57,7 @@ def preserve_existing_tags_on_taxes(cr, registry, module):
|
||||
class AccountAccountTemplate(models.Model):
|
||||
_name = "account.account.template"
|
||||
_description = 'Templates for Accounts'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_order = "code"
|
||||
|
||||
name = fields.Char(required=True, index=True)
|
||||
@ -498,6 +499,7 @@ class AccountChartTemplate(models.Model):
|
||||
|
||||
class AccountTaxTemplate(models.Model):
|
||||
_name = 'account.tax.template'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = 'Templates for Taxes'
|
||||
_order = 'id'
|
||||
|
||||
@ -621,6 +623,7 @@ class AccountTaxTemplate(models.Model):
|
||||
|
||||
class AccountFiscalPositionTemplate(models.Model):
|
||||
_name = 'account.fiscal.position.template'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = 'Template for Fiscal Position'
|
||||
|
||||
sequence = fields.Integer()
|
||||
@ -642,6 +645,7 @@ class AccountFiscalPositionTemplate(models.Model):
|
||||
|
||||
class AccountFiscalPositionTaxTemplate(models.Model):
|
||||
_name = 'account.fiscal.position.tax.template'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = 'Template Tax Fiscal Position'
|
||||
_rec_name = 'position_id'
|
||||
|
||||
@ -653,6 +657,7 @@ class AccountFiscalPositionTaxTemplate(models.Model):
|
||||
class AccountFiscalPositionAccountTemplate(models.Model):
|
||||
_name = 'account.fiscal.position.account.template'
|
||||
_description = 'Template Account Fiscal Mapping'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_rec_name = 'position_id'
|
||||
|
||||
position_id = fields.Many2one('account.fiscal.position.template', string='Fiscal Mapping', required=True, ondelete='cascade')
|
||||
@ -961,6 +966,7 @@ class AccountBankAccountsWizard(models.TransientModel):
|
||||
|
||||
class AccountReconcileModelTemplate(models.Model):
|
||||
_name = "account.reconcile.model.template"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
|
||||
chart_template_id = fields.Many2one('account.chart.template', string='Chart Template', required=True)
|
||||
name = fields.Char(string='Button Label', required=True)
|
||||
|
@ -11,6 +11,7 @@ from flectra.addons.base.res.res_partner import WARNING_MESSAGE, WARNING_HELP
|
||||
|
||||
class AccountFiscalPosition(models.Model):
|
||||
_name = 'account.fiscal.position'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = 'Fiscal Position'
|
||||
_order = 'sequence'
|
||||
|
||||
@ -164,6 +165,7 @@ class AccountFiscalPosition(models.Model):
|
||||
|
||||
class AccountFiscalPositionTax(models.Model):
|
||||
_name = 'account.fiscal.position.tax'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = 'Taxes Fiscal Position'
|
||||
_rec_name = 'position_id'
|
||||
|
||||
@ -182,6 +184,7 @@ class AccountFiscalPositionTax(models.Model):
|
||||
class AccountFiscalPositionAccount(models.Model):
|
||||
_name = 'account.fiscal.position.account'
|
||||
_description = 'Accounts Fiscal Position'
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_rec_name = 'position_id'
|
||||
|
||||
position_id = fields.Many2one('account.fiscal.position', string='Fiscal Position',
|
||||
|
@ -29,6 +29,10 @@ class ReportAgedPartnerBalance(models.AbstractModel):
|
||||
cr = self.env.cr
|
||||
user_company = self.env.user.company_id.id
|
||||
move_state = ['draft', 'posted']
|
||||
branch_id = data['form'].get('branch_id', False)
|
||||
branch = ''
|
||||
if branch_id:
|
||||
branch = 'AND (l.branch_id =' + str(branch_id[0]) + ')'
|
||||
if target_move == 'posted':
|
||||
move_state = ['posted']
|
||||
arg_list = (tuple(move_state), tuple(account_type))
|
||||
@ -49,7 +53,7 @@ class ReportAgedPartnerBalance(models.AbstractModel):
|
||||
AND (l.move_id = am.id)
|
||||
AND (am.state IN %s)
|
||||
AND (account_account.internal_type IN %s)
|
||||
AND ''' + reconciliation_clause + '''
|
||||
AND ''' + reconciliation_clause + branch +'''
|
||||
AND (l.date <= %s)
|
||||
AND l.company_id = %s
|
||||
ORDER BY UPPER(res_partner.name)'''
|
||||
@ -75,7 +79,7 @@ class ReportAgedPartnerBalance(models.AbstractModel):
|
||||
AND (account_account.internal_type IN %s)
|
||||
AND (COALESCE(l.date_maturity,l.date) > %s)\
|
||||
AND ((l.partner_id IN %s) OR (l.partner_id IS NULL))
|
||||
AND (l.date <= %s)
|
||||
AND (l.date <= %s) ''' + branch + '''
|
||||
AND l.company_id = %s'''
|
||||
cr.execute(query, (tuple(move_state), tuple(account_type), date_from, tuple(partner_ids), date_from, user_company))
|
||||
aml_ids = cr.fetchall()
|
||||
@ -125,7 +129,7 @@ class ReportAgedPartnerBalance(models.AbstractModel):
|
||||
AND (am.state IN %s)
|
||||
AND (account_account.internal_type IN %s)
|
||||
AND ((l.partner_id IN %s) OR (l.partner_id IS NULL))
|
||||
AND ''' + dates_query + '''
|
||||
AND ''' + dates_query + branch +'''
|
||||
AND (l.date <= %s)
|
||||
AND l.company_id = %s'''
|
||||
cr.execute(query, args_list)
|
||||
|
@ -6,6 +6,7 @@ from flectra import models, fields, api
|
||||
|
||||
class AccountInvoiceReport(models.Model):
|
||||
_name = "account.invoice.report"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = "Invoices Statistics"
|
||||
_auto = False
|
||||
_rec_name = 'date'
|
||||
@ -72,7 +73,7 @@ class AccountInvoiceReport(models.Model):
|
||||
|
||||
_depends = {
|
||||
'account.invoice': [
|
||||
'account_id', 'amount_total_company_signed', 'commercial_partner_id', 'company_id',
|
||||
'account_id', 'amount_total_company_signed', 'commercial_partner_id', 'company_id', 'branch_id',
|
||||
'currency_id', 'date_due', 'date_invoice', 'fiscal_position_id',
|
||||
'journal_id', 'partner_bank_id', 'partner_id', 'payment_term_id',
|
||||
'residual', 'state', 'type', 'user_id',
|
||||
@ -92,7 +93,7 @@ class AccountInvoiceReport(models.Model):
|
||||
select_str = """
|
||||
SELECT sub.id, sub.date, sub.product_id, sub.partner_id, sub.country_id, sub.account_analytic_id,
|
||||
sub.payment_term_id, sub.uom_name, sub.currency_id, sub.journal_id,
|
||||
sub.fiscal_position_id, sub.user_id, sub.company_id, sub.nbr, sub.type, sub.state,
|
||||
sub.fiscal_position_id, sub.user_id, sub.company_id, sub.branch_id, sub.nbr, sub.type, sub.state,
|
||||
sub.categ_id, sub.date_due, sub.account_id, sub.account_line_id, sub.partner_bank_id,
|
||||
sub.product_qty, sub.price_total as price_total, sub.price_average as price_average,
|
||||
COALESCE(cr.rate, 1) as currency_rate, sub.residual as residual, sub.commercial_partner_id as commercial_partner_id
|
||||
@ -105,7 +106,7 @@ class AccountInvoiceReport(models.Model):
|
||||
ai.date_invoice AS date,
|
||||
ail.product_id, ai.partner_id, ai.payment_term_id, ail.account_analytic_id,
|
||||
u2.name AS uom_name,
|
||||
ai.currency_id, ai.journal_id, ai.fiscal_position_id, ai.user_id, ai.company_id,
|
||||
ai.currency_id, ai.journal_id, ai.fiscal_position_id, ai.user_id, ai.company_id, ai.branch_id,
|
||||
1 AS nbr,
|
||||
ai.type, ai.state, pt.categ_id, ai.date_due, ai.account_id, ail.account_id AS account_line_id,
|
||||
ai.partner_bank_id,
|
||||
@ -148,7 +149,7 @@ class AccountInvoiceReport(models.Model):
|
||||
group_by_str = """
|
||||
GROUP BY ail.id, ail.product_id, ail.account_analytic_id, ai.date_invoice, ai.id,
|
||||
ai.partner_id, ai.payment_term_id, u2.name, u2.id, ai.currency_id, ai.journal_id,
|
||||
ai.fiscal_position_id, ai.user_id, ai.company_id, ai.type, invoice_type.sign, ai.state, pt.categ_id,
|
||||
ai.fiscal_position_id, ai.user_id, ai.company_id, ai.branch_id, ai.type, invoice_type.sign, ai.state, pt.categ_id,
|
||||
ai.date_due, ai.account_id, ail.account_id, ai.partner_bank_id, ai.residual_company_signed,
|
||||
ai.amount_total_company_signed, ai.commercial_partner_id, partner.country_id
|
||||
"""
|
||||
|
@ -44,6 +44,73 @@
|
||||
<field name="groups_id" eval="[(4,ref('account.group_account_manager'))]"/>
|
||||
</record>
|
||||
|
||||
<!-- Multi Branch -->
|
||||
|
||||
<record id="account_move_multi_branch_rule" model="ir.rule">
|
||||
<field name="name">Account Entry Multi Branch</field>
|
||||
<field name="model_id" ref="model_account_move"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_move_line_multi_branch_rule" model="ir.rule">
|
||||
<field name="name">Entry lines Multi Branch</field>
|
||||
<field name="model_id" ref="model_account_move_line"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record id="invoice_multi_branch_rule" model="ir.rule">
|
||||
<field name="name">Invoice multi-branch</field>
|
||||
<field name="model_id" ref="model_account_invoice"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record id="invoice_analysis_multi_branch_rule" model="ir.rule">
|
||||
<field name="name">Invoice Analysis multi-branch</field>
|
||||
<field name="model_id" ref="model_account_invoice_report"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="account_invoice_line_multi_branch_rule">
|
||||
<field name="name">Invoice Line branch rule</field>
|
||||
<field name="model_id" ref="model_account_invoice_line"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="account_bank_statement_multi_branch_rule">
|
||||
<field name="name">Account bank statement branch rule</field>
|
||||
<field name="model_id" ref="model_account_bank_statement"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="account_bank_statement_line_multi_branch_rule">
|
||||
<field name="name">Account bank statement line branch rule</field>
|
||||
<field name="model_id" ref="model_account_bank_statement_line"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="account_reconcile_model_templatemulti_branch_rule">
|
||||
<field name="name">Account reconcile model template company rule</field>
|
||||
<field name="model_id" ref="model_account_reconcile_model"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="account_payment_multi_branch_rule">
|
||||
<field name="name">Account payment company rule</field>
|
||||
<field name="model_id" ref="model_account_payment"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<!-- Multi Company -->
|
||||
|
||||
<record id="account_move_comp_rule" model="ir.rule">
|
||||
<field name="name">Account Entry</field>
|
||||
<field name="model_id" ref="model_account_move"/>
|
||||
|
@ -18,3 +18,8 @@ from . import test_search
|
||||
from . import test_setup_bar
|
||||
from . import test_tax
|
||||
from . import test_templates_consistency
|
||||
from . import test_account_branch
|
||||
from . import test_invoice_branch
|
||||
from . import test_journal_entries_branch
|
||||
from . import test_branch_moves
|
||||
from . import test_payment_branch
|
||||
|
91
addons/account/tests/test_account_branch.py
Normal file
91
addons/account/tests/test_account_branch.py
Normal file
@ -0,0 +1,91 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from flectra.addons.account.tests.account_test_classes import AccountingTestCase
|
||||
|
||||
|
||||
class TestAccountBranch(AccountingTestCase):
|
||||
def setUp(self):
|
||||
super(TestAccountBranch, self).setUp()
|
||||
self.apple_product = self.env.ref('product.product_product_7')
|
||||
self.keyboard_product = self.env.ref('product.product_product_9')
|
||||
self.ipod_product = self.env.ref('product.product_product_11')
|
||||
self.asset_account = self.env.ref('l10n_generic_coa.conf_stk')
|
||||
self.model_account_journal = self.env['account.journal']
|
||||
self.model_account = self.env['account.account']
|
||||
self.main_company = self.env.ref('base.main_company')
|
||||
self.manager_group = self.env.ref('account.group_account_manager')
|
||||
self.model_user = self.env['res.users']
|
||||
self.model_account_invoice = self.env['account.invoice']
|
||||
self.account_partner = self.env.ref('base.res_partner_1')
|
||||
self.branch_1 = self.env.ref('base_branch_company.data_branch_1')
|
||||
self.branch_2 = self.env.ref('base_branch_company.data_branch_2')
|
||||
self.branch_3 = self.env.ref('base_branch_company.data_branch_3')
|
||||
user_type = self.env.ref('account.data_account_type_liquidity')
|
||||
self.account_type = self.env.ref('account.data_account_type_expenses')
|
||||
|
||||
self.user_id = self.model_user.with_context(
|
||||
{'no_reset_password': True}).create({
|
||||
'company_id': self.main_company.id,
|
||||
'branch_ids': [(4, self.branch_2.id), (4, self.branch_3.id)],
|
||||
'company_ids': [(4, self.main_company.id)],
|
||||
'groups_id': [(6, 0, [self.manager_group.id])],
|
||||
'name': 'Test User 1',
|
||||
'email': 'demo@yourcompany.com',
|
||||
'password': '123',
|
||||
'login': 'tes_user_1',
|
||||
})
|
||||
|
||||
self.user_2 = self.model_user.with_context({
|
||||
'no_reset_password': True}).create({
|
||||
'company_id': self.main_company.id,
|
||||
'branch_ids': [(4, self.branch_3.id)],
|
||||
'company_ids': [(4, self.main_company.id)],
|
||||
'groups_id': [(6, 0, [self.manager_group.id])],
|
||||
'name': 'Test User',
|
||||
'email': 'demo@yourcompany.com',
|
||||
'password': '123',
|
||||
'login': 'test_user_2',
|
||||
})
|
||||
|
||||
self.cash_account = self.model_account.create({
|
||||
'company_id': self.main_company.id,
|
||||
'user_type_id': user_type.id,
|
||||
'code': 'cash_test',
|
||||
'name': 'Test Cash Account',
|
||||
})
|
||||
|
||||
self.cash_journal = self.model_account_journal.create({
|
||||
'company_id': self.main_company.id,
|
||||
'branch_id': self.branch_1.id,
|
||||
'name': 'Cash Journal - Branch 1',
|
||||
'default_credit_account_id': self.cash_account.id,
|
||||
'default_debit_account_id': self.cash_account.id,
|
||||
'type': 'cash',
|
||||
'code': 'cash_branch_1',
|
||||
})
|
||||
|
||||
def invoice_values(self, branch_id):
|
||||
products = [(self.apple_product, 1000),
|
||||
(self.keyboard_product, 500),
|
||||
(self.ipod_product, 800)]
|
||||
lines_data = []
|
||||
account_id = self.model_account.search([
|
||||
('user_type_id', '=', self.account_type.id)], limit=1).id
|
||||
for product_id, quantity in products:
|
||||
values = {
|
||||
'product_id': product_id.id,
|
||||
'name': product_id.name,
|
||||
'price_unit': 120,
|
||||
'quantity': quantity,
|
||||
'account_id': account_id
|
||||
}
|
||||
lines_data.append((0, 0, values))
|
||||
vals = {
|
||||
'partner_id': self.account_partner.id,
|
||||
'type': 'in_invoice',
|
||||
'name': "Supplier Invoice",
|
||||
# 'reference_type': "none",
|
||||
'account_id': self.account_partner.property_account_payable_id.id,
|
||||
'invoice_line_ids': lines_data,
|
||||
'branch_id': branch_id,
|
||||
}
|
||||
return vals
|
11
addons/account/tests/test_branch_moves.py
Normal file
11
addons/account/tests/test_branch_moves.py
Normal file
@ -0,0 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import test_account_branch
|
||||
|
||||
|
||||
class TestBranchJournalEntries(test_account_branch.TestAccountBranch):
|
||||
|
||||
def test_branch_security_move_line(self):
|
||||
move_ids = self.env['account.move.line'].sudo(self.user_2.id).\
|
||||
search([('branch_id', '=', self.branch_2.id)])
|
||||
self.assertFalse(move_ids, 'USer 2 should not have access to move lines with Branch %s'
|
||||
% self.branch_2.name)
|
18
addons/account/tests/test_invoice_branch.py
Normal file
18
addons/account/tests/test_invoice_branch.py
Normal file
@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import test_account_branch
|
||||
|
||||
|
||||
class TestInvoiceBranch(test_account_branch.TestAccountBranch):
|
||||
|
||||
def test_invoice_create(self):
|
||||
self.invoice_id = self.model_account_invoice.sudo(self.user_id.id).create(self.invoice_values(self.branch_2.id))
|
||||
|
||||
invoices = self.model_account_invoice.sudo(self.user_2.id).search([('branch_id', '=', self.branch_2.id)])
|
||||
|
||||
self.assertFalse(invoices, 'USer 2 should not have access to Invoice with Branch %s'
|
||||
% self.branch_2.name)
|
||||
|
||||
self.invoice_id.sudo(self.user_id.id).action_invoice_open()
|
||||
all_branch = all(move_line_id.branch_id.id == self.branch_2.id for
|
||||
move_line_id in self.invoice_id.move_id.line_ids)
|
||||
self.assertNotEqual(all_branch, False, 'Journal Entries have different Branch.')
|
63
addons/account/tests/test_journal_entries_branch.py
Normal file
63
addons/account/tests/test_journal_entries_branch.py
Normal file
@ -0,0 +1,63 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import test_account_branch
|
||||
|
||||
|
||||
class TestJournalEntryBranch(test_account_branch.TestAccountBranch):
|
||||
|
||||
def test_journal_entries_branch(self):
|
||||
journal_ids = self.model_account_journal.search([('code', '=', 'MISC')],
|
||||
limit=1)
|
||||
move_vals = self.env['account.move'].default_get([])
|
||||
lines = [
|
||||
(0, 0, {
|
||||
'name': 'Test',
|
||||
'account_id': self.asset_account.id,
|
||||
'debit': 0,
|
||||
'credit': 100,
|
||||
'branch_id': self.branch_1.id,
|
||||
}),
|
||||
(0, 0, {
|
||||
'name': 'Test',
|
||||
'account_id': self.asset_account.id,
|
||||
'debit': 100,
|
||||
'credit': 0,
|
||||
'branch_id': self.branch_1.id,
|
||||
})
|
||||
]
|
||||
move_vals.update({
|
||||
'journal_id': journal_ids and journal_ids.id,
|
||||
'line_ids': lines,
|
||||
})
|
||||
move = self.env['account.move'].sudo(self.user_id.id).create(move_vals)
|
||||
move.post()
|
||||
|
||||
def _check_balance(self, account_id, acc_type='clearing'):
|
||||
domain = [('account_id', '=', account_id)]
|
||||
balance = self._get_balance(domain)
|
||||
self.assertEqual(balance, 0.0, 'Balance is 0 for all Branch.')
|
||||
domain = [('account_id', '=', account_id),
|
||||
('branch_id', '=', self.branch_2.id)]
|
||||
balance = self._get_balance(domain)
|
||||
if acc_type == 'other':
|
||||
self.assertEqual(balance, -100,
|
||||
'Balance is -100 for Branch.')
|
||||
else:
|
||||
self.assertEqual(balance, 100,
|
||||
'Balance is 100 for Branch.')
|
||||
domain = [('account_id', '=', account_id),
|
||||
('branch_id', '=', self.branch_3.id)]
|
||||
balance = self._get_balance(domain)
|
||||
if acc_type == 'other':
|
||||
self.assertEqual(balance, 100.0,
|
||||
'Balance is 100 for Branch')
|
||||
else:
|
||||
self.assertEqual(balance, -100.0,
|
||||
'Balance is -100 for Branch')
|
||||
|
||||
def _get_balance(self, domain):
|
||||
|
||||
aml_rec = self.env['account.move.line'].sudo(self.user_id.id).read_group(domain,['debit', 'credit', 'account_id'], ['account_id'])
|
||||
if aml_rec:
|
||||
aml_rec = aml_rec[0]
|
||||
a = aml_rec.get('debit', 0) - aml_rec.get('credit', 0)
|
||||
return a
|
23
addons/account/tests/test_payment_branch.py
Normal file
23
addons/account/tests/test_payment_branch.py
Normal file
@ -0,0 +1,23 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from flectra.addons.account.tests import test_account_branch
|
||||
import time
|
||||
|
||||
|
||||
class TestPaymentsBranch(test_account_branch.TestAccountBranch):
|
||||
|
||||
def test_payment_branch(self):
|
||||
self.invoice_id = self.model_account_invoice.sudo(self.user_id.id).create(
|
||||
self.invoice_values(self.branch_2.id))
|
||||
self.invoice_id.sudo(self.user_id.id).action_invoice_open()
|
||||
|
||||
context = {'active_ids': [self.invoice_id.id], 'active_model': 'account.invoice'}
|
||||
create_payments = self.env['account.register.payments'].sudo(self.user_id.id).with_context(context).create({
|
||||
'payment_method_id': self.env.ref("account.account_payment_method_manual_in").id,
|
||||
'journal_id': self.cash_journal.id,
|
||||
'payment_date': time.strftime('%Y') + '-12-17',
|
||||
|
||||
})
|
||||
create_payments.create_payments()
|
||||
payment = self.env['account.payment'].sudo(self.user_2.id).search([('branch_id', '=', self.branch_2.id)])
|
||||
self.assertFalse(payment, 'USer 2 should not have access to Payments with Branch %s'
|
||||
% self.branch_2.name)
|
@ -330,6 +330,7 @@
|
||||
</group>
|
||||
<group>
|
||||
<field name="fiscal_position_id" options="{'no_create': True}" placeholder="Auto-detect"/>
|
||||
<field name="branch_id" options="{'no_create': True, 'no_open': True}"/>
|
||||
<field name="move_id" groups="account.group_account_user" attrs="{'invisible': [('move_id', '=', False)]}"/>
|
||||
<field name="date" domain="[('state', '=', 'draft'), ('company_id', '=', company_id)]" groups="account.group_account_user"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
@ -477,6 +478,7 @@
|
||||
<field domain="[('company_id', '=', company_id),('internal_type','=', 'receivable'), ('deprecated', '=', False)]"
|
||||
name="account_id" groups="account.group_account_user"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<field name="branch_id" options="{'no_create': True}"/>
|
||||
<field domain="[('partner_id.ref_company_ids', 'in', [company_id])]" name="partner_bank_id" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
|
@ -1155,6 +1155,7 @@
|
||||
<field name="move_id" attrs="{'readonly':[('parent_state','=','posted')]}"/>
|
||||
<field name="statement_id" readonly="True" attrs="{'invisible': [('statement_id','=',False)]}"/>
|
||||
<field name="invoice_id" attrs="{'invisible': [('invoice_id','=',False)]}"/>
|
||||
<field name="branch_id"/>
|
||||
</group>
|
||||
<group string="Dates">
|
||||
<field name="date_maturity"/>
|
||||
@ -1227,6 +1228,7 @@
|
||||
<field name="partner_id"/>
|
||||
<field name="account_id" options='{"no_open":True}' domain="[('company_id', '=', company_id)]" groups="account.group_account_user"/>
|
||||
<field name="analytic_account_id" groups="account.group_account_user"/>
|
||||
<field name="branch_id"/>
|
||||
<field name="reconciled" invisible="1"/>
|
||||
<field name="full_reconcile_id"/>
|
||||
<field name="debit" sum="Total Debit"/>
|
||||
@ -1304,6 +1306,7 @@
|
||||
<field name="move_id" string="Number (Move)"/>
|
||||
<field name="tax_line_id"/>
|
||||
<field name="tax_ids" />
|
||||
<field name="branch_id"/>
|
||||
<group expand="0" string="Group By">
|
||||
<filter string="Partner" domain="[]" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Journal" domain="[]" context="{'group_by':'journal_id'}"/>
|
||||
@ -1371,6 +1374,7 @@
|
||||
<field name="partner_id"/>
|
||||
<field name="ref"/>
|
||||
<field name="journal_id"/>
|
||||
<field name="branch_id"/>
|
||||
<field name="amount" sum="Total Amount"/>
|
||||
<field name="state"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
@ -1452,6 +1456,7 @@
|
||||
<group>
|
||||
<field name="journal_id" options="{'no_open': True, 'no_create': True}"/>
|
||||
<field name="company_id" required="1" groups="base.group_multi_company"/>
|
||||
<field name="branch_id" options="{'no_create': True}"/>
|
||||
<field name="amount" invisible="1"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
</group>
|
||||
@ -1465,6 +1470,7 @@
|
||||
<field name="partner_id"
|
||||
domain="['|', ('parent_id', '=', False), ('is_company', '=', True)]"/>
|
||||
<field name="name"/>
|
||||
<field name="branch_id"/>
|
||||
<field name="analytic_account_id" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="analytic_tag_ids" groups="analytic.group_analytic_accounting"/>
|
||||
<field name="amount_currency" groups="base.group_multi_currency"/>
|
||||
|
@ -40,6 +40,10 @@
|
||||
<t t-if="data['date_from']"><strong>Date from :</strong> <span t-esc="data['date_from']"/><br/></t>
|
||||
<t t-if="data['date_to']"><strong>Date to :</strong> <span t-esc="data['date_to']"/></t>
|
||||
</div>
|
||||
<div class="col-xs-4">
|
||||
<strong>Branch:</strong>
|
||||
<p t-if="data['branch_id']"><span t-esc="data['branch_id'][1]"/></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-condensed">
|
||||
|
@ -48,6 +48,10 @@
|
||||
<strong>Reference:</strong>
|
||||
<p t-field="o.reference"/>
|
||||
</div>
|
||||
<div name="branch" class="col-xs-2" t-if="o.branch_id">
|
||||
<strong>Branch:</strong>
|
||||
<p t-field="o.branch_id.name"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Is there a discount on at least one line? -->
|
||||
|
@ -24,6 +24,10 @@
|
||||
<p t-if="data['form']['target_move'] == 'all'">All Entries</p>
|
||||
<p t-if="data['form']['target_move'] == 'posted'">All Posted Entries</p>
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
<strong>Branch:</strong>
|
||||
<p t-if="data['form']['branch_id']"><span t-esc="data['form']['branch_id'][1]"/></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-condensed">
|
||||
|
@ -12,6 +12,8 @@
|
||||
<field name="date_from"/>
|
||||
<field name="period_length"/>
|
||||
<newline/>
|
||||
<field name="branch_id"/>
|
||||
<newline/>
|
||||
<field name="result_selection" widget="radio"/>
|
||||
<field name="target_move" widget="radio"/>
|
||||
</group>
|
||||
|
@ -6,6 +6,7 @@ from flectra import api, fields, models, _
|
||||
class AccountCommonReport(models.TransientModel):
|
||||
_name = "account.common.report"
|
||||
_description = "Account Common Report"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
|
||||
company_id = fields.Many2one('res.company', string='Company', readonly=True, default=lambda self: self.env.user.company_id)
|
||||
journal_ids = fields.Many2many('account.journal', string='Journals', required=True, default=lambda self: self.env['account.journal'].search([]))
|
||||
@ -21,6 +22,7 @@ class AccountCommonReport(models.TransientModel):
|
||||
result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
|
||||
result['date_from'] = data['form']['date_from'] or False
|
||||
result['date_to'] = data['form']['date_to'] or False
|
||||
result['branch_id'] = data['form']['branch_id'] or False
|
||||
result['strict_range'] = True if result['date_from'] else False
|
||||
return result
|
||||
|
||||
@ -33,7 +35,7 @@ class AccountCommonReport(models.TransientModel):
|
||||
data = {}
|
||||
data['ids'] = self.env.context.get('active_ids', [])
|
||||
data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
|
||||
data['form'] = self.read(['date_from', 'date_to', 'journal_ids', 'target_move'])[0]
|
||||
data['form'] = self.read(['date_from', 'date_to', 'journal_ids', 'target_move', 'branch_id'])[0]
|
||||
used_context = self._build_contexts(data)
|
||||
data['form']['used_context'] = dict(used_context, lang=self.env.context.get('lang') or 'en_US')
|
||||
return self._print_report(data)
|
||||
|
@ -12,6 +12,12 @@
|
||||
<field name="date_from"/>
|
||||
<field name="date_to"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
<group>
|
||||
<field name="branch_id"/>
|
||||
</group>
|
||||
|
||||
</group>
|
||||
<group>
|
||||
<field name="journal_ids" widget="many2many_tags" options="{'no_create': True}"/>
|
||||
</group>
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
from flectra import fields, models, api, _
|
||||
from flectra.addons import decimal_precision as dp
|
||||
from flectra.exceptions import UserError
|
||||
from flectra.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class AccountVoucher(models.Model):
|
||||
@ -46,7 +46,7 @@ class AccountVoucher(models.Model):
|
||||
narration = fields.Text('Notes', readonly=True, states={'draft': [('readonly', False)]})
|
||||
currency_id = fields.Many2one('res.currency', compute='_get_journal_currency',
|
||||
string='Currency', readonly=True, required=True, default=lambda self: self._get_currency())
|
||||
company_id = fields.Many2one('res.company', 'Company',
|
||||
company_id = fields.Many2one('res.company', 'Company', store=True,
|
||||
required=True, readonly=True, states={'draft': [('readonly', False)]},
|
||||
related='journal_id.company_id', default=lambda self: self._get_company())
|
||||
state = fields.Selection([
|
||||
@ -74,6 +74,20 @@ class AccountVoucher(models.Model):
|
||||
('pay_later', 'Pay Later'),
|
||||
], 'Payment', index=True, readonly=True, states={'draft': [('readonly', False)]}, default='pay_later')
|
||||
date_due = fields.Date('Due Date', readonly=True, index=True, states={'draft': [('readonly', False)]})
|
||||
branch_id = fields.Many2one('res.branch', 'Branch', ondelete="restrict",
|
||||
default=lambda self: self.env['res.users']._get_default_branch())
|
||||
|
||||
@api.constrains('company_id', 'branch_id')
|
||||
def _check_company_branch(self):
|
||||
for record in self:
|
||||
if record.branch_id and record.company_id != record.branch_id.company_id:
|
||||
raise ValidationError(
|
||||
_('Configuration Error of Company:\n'
|
||||
'The Company (%s) in the voucher and '
|
||||
'the Company (%s) of Branch must '
|
||||
'be the same company!') % (record.company_id.name,
|
||||
record.branch_id.company_id.name)
|
||||
)
|
||||
|
||||
@api.one
|
||||
@api.depends('move_id.line_ids.reconciled', 'move_id.line_ids.account_id.internal_type')
|
||||
@ -186,6 +200,7 @@ class AccountVoucher(models.Model):
|
||||
'date': self.account_date,
|
||||
'date_maturity': self.date_due,
|
||||
'payment_id': self._context.get('payment_id'),
|
||||
'branch_id': self.branch_id.id,
|
||||
}
|
||||
return move_line
|
||||
|
||||
@ -199,13 +214,13 @@ class AccountVoucher(models.Model):
|
||||
name = self.journal_id.sequence_id.with_context(ir_sequence_date=self.date).next_by_id()
|
||||
else:
|
||||
raise UserError(_('Please define a sequence on the journal.'))
|
||||
|
||||
move = {
|
||||
'name': name,
|
||||
'journal_id': self.journal_id.id,
|
||||
'narration': self.narration,
|
||||
'date': self.account_date,
|
||||
'ref': self.reference,
|
||||
'branch_id': self.branch_id.id
|
||||
}
|
||||
return move
|
||||
|
||||
@ -361,6 +376,10 @@ class AccountVoucherLine(models.Model):
|
||||
company_id = fields.Many2one('res.company', related='voucher_id.company_id', string='Company', store=True, readonly=True)
|
||||
tax_ids = fields.Many2many('account.tax', string='Tax', help="Only for tax excluded from price")
|
||||
currency_id = fields.Many2one('res.currency', related='voucher_id.currency_id')
|
||||
branch_id = fields.Many2one('res.branch',
|
||||
related='voucher_id.branch_id',
|
||||
string='Branch',
|
||||
readonly=True, store=True)
|
||||
|
||||
@api.one
|
||||
@api.depends('price_unit', 'tax_ids', 'quantity', 'product_id', 'voucher_id.currency_id')
|
||||
|
@ -13,5 +13,20 @@
|
||||
<field eval="True" name="global"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
<record id="ir_rule_voucher_branch"
|
||||
model="ir.rule">
|
||||
<field name="model_id" ref="account_voucher.model_account_voucher"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
<field name="name">Vouchers Branch</field>
|
||||
<field name="global" eval="True"/>
|
||||
</record>
|
||||
<record id="ir_rule_voucher_line_branch"
|
||||
model="ir.rule">
|
||||
<field name="model_id"
|
||||
ref="account_voucher.model_account_voucher_line"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
<field name="name">Voucher lines branch</field>
|
||||
<field name="global" eval="True"/>
|
||||
</record>
|
||||
</data>
|
||||
</flectra>
|
||||
|
4
addons/account_voucher/tests/__init__.py
Normal file
4
addons/account_voucher/tests/__init__.py
Normal file
@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import test_account_voucher_branch
|
||||
from . import test_voucher_receipt_branch
|
103
addons/account_voucher/tests/test_account_voucher_branch.py
Normal file
103
addons/account_voucher/tests/test_account_voucher_branch.py
Normal file
@ -0,0 +1,103 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from datetime import date
|
||||
from flectra.tests import common
|
||||
from flectra.api import Environment
|
||||
|
||||
|
||||
|
||||
class TestAccountVoucherBranch(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAccountVoucherBranch, self).setUp()
|
||||
self.account_user = self.env.ref('account.group_account_manager')
|
||||
self.model_account = self.env['account.account']
|
||||
self.main_company = self.env.ref('base.main_company')
|
||||
self.model_journal = self.env['account.journal']
|
||||
self.partner = self.env.ref('base.res_partner_1')
|
||||
self.model_voucher = self.env['account.voucher']
|
||||
self.apple_product = self.env.ref('product.product_product_7')
|
||||
self.model_voucher_line = self.env['account.voucher.line']
|
||||
self.branch_1 = self.env.ref('base_branch_company.data_branch_1')
|
||||
self.model_users = self.env['res.users']
|
||||
self.branch_2 = self.env.ref('base_branch_company.data_branch_2')
|
||||
self.income_type = self.env['account.account.type'].search([('name', '=', 'Income')])
|
||||
account_obj = self.env.ref['account.account']
|
||||
self.account_receivable = account_obj.create(
|
||||
{'code': 'X1012', 'name': 'Account Receivable - Test',
|
||||
'user_type_id': self.env.ref('account.data_account_type_receivable').id,
|
||||
'reconcile': True})
|
||||
self.account_1 = self.account_create('acc_code_1', self.income_type.id, self.main_company.id)
|
||||
self.account_2 = self.account_create('acc_code_2', self.income_type.id, self.main_company.id)
|
||||
self.journal_1 = self.journal_create('journal_code_1', self.account_1, self.main_company.id)
|
||||
self.journal_2 = self.journal_create('journal_code_2', self.account_2, self.main_company.id)
|
||||
self.branch_user_1 = self.user_create(
|
||||
'branch_user_1', self.branch_1, self.main_company,
|
||||
[self.branch_1, self.branch_2], [self.account_user])
|
||||
self.branch_user_2 = self.user_create('branch_user_2', self.branch_2, self.main_company, [self.branch_2],
|
||||
[self.account_user])
|
||||
|
||||
self.account_voucher_1 = self.receipt_create(self.journal_1, self.branch_1)
|
||||
self.account_voucher_2 = self.receipt_create(self.journal_2, self.branch_2)
|
||||
|
||||
def account_create(self, code, type, company_id):
|
||||
data = {'code': code,
|
||||
'name': 'Test Sales Account ' + code,
|
||||
'company_id': company_id,
|
||||
'user_type_id': type,
|
||||
}
|
||||
account_obj = self.model_account.create(data)
|
||||
return account_obj.id
|
||||
|
||||
def journal_create(self, code, account_id, company_id):
|
||||
data ={
|
||||
'code': code,
|
||||
'name': 'Test Sales Account ' + code,
|
||||
'type': 'sale',
|
||||
'default_debit_account_id': account_id,
|
||||
'default_credit_account_id': account_id,
|
||||
'company_id': company_id
|
||||
}
|
||||
journal_obj = self.model_journal.create(data)
|
||||
return journal_obj.id
|
||||
|
||||
def user_create(self, user_name, branch_id, company_id, branch_ids, groups_ids ):
|
||||
group_ids = [group.id for group in groups_ids]
|
||||
data = {
|
||||
'login': user_name,
|
||||
'name': 'Test User ' + user_name,
|
||||
'email': 'demo@yourcompany.com',
|
||||
'branch_id':branch_id.id,
|
||||
'password': 'test@123',
|
||||
'company_id': company_id.id,
|
||||
'groups_id': [(6, 0, group_ids)],
|
||||
'company_ids': [(4, company_id.id)],
|
||||
'branch_ids': [(4, branch.id) for branch in branch_ids],
|
||||
}
|
||||
user_obj = self.model_users.with_context({'no_reset_password': True}).create(data)
|
||||
return user_obj.id
|
||||
|
||||
def receipt_create(self, journal_id, branch_id):
|
||||
print ("@@@@@@@@@@@@@@@@",self.receivable_account )
|
||||
vals = {
|
||||
'name': 'Test Voucher',
|
||||
'partner_id': self.partner.id,
|
||||
'journal_id': journal_id,
|
||||
'voucher_type': 'sale',
|
||||
'account_id': self.receivable_account.id,
|
||||
'branch_id': branch_id.id,
|
||||
'company_id': self.main_company.id,
|
||||
'date': date.today(),
|
||||
}
|
||||
voucher_obj = self.model_voucher.create(vals)
|
||||
line_vals = {
|
||||
'name': self.apple_product.name,
|
||||
'product_id': self.apple_product.id,
|
||||
'price_unit': 500,
|
||||
'quantity': 10,
|
||||
'account_id': self.receivable_account.id,
|
||||
'voucher_id': voucher_obj.id,
|
||||
}
|
||||
self.model_voucher_line.create(line_vals)
|
||||
return voucher_obj
|
||||
|
30
addons/account_voucher/tests/test_voucher_receipt_branch.py
Normal file
30
addons/account_voucher/tests/test_voucher_receipt_branch.py
Normal file
@ -0,0 +1,30 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import test_account_voucher_branch as test_branch
|
||||
|
||||
|
||||
class TestAccountVoucherReceiptBranch(test_branch.TestAccountVoucherBranch):
|
||||
|
||||
def test_account_receipt_voucher(self):
|
||||
|
||||
self.account_voucher_1.proforma_voucher()
|
||||
self.account_voucher_2.proforma_voucher()
|
||||
|
||||
branch_1_ids = all(line_id_1.branch_id.id == self.account_voucher_1.branch_id.id
|
||||
for line_id_1 in self.account_voucher_1.move_id.line_ids)
|
||||
branch_2_ids = all(line_id_2.branch_id.id == self.account_voucher_2.branch_id.id
|
||||
for line_id_2 in self.account_voucher_2.move_id.line_ids)
|
||||
self.assertNotEqual(branch_1_ids, False, 'Journal Entries of receipt has different branch id.')
|
||||
self.assertNotEqual(branch_2_ids, False, 'Journal Entries of receipt has different branch id.')
|
||||
|
||||
self.account_move = self.env['account.move']
|
||||
account_move_id_1 = self.account_voucher_1.move_id
|
||||
account_move_id_2 = self.account_voucher_2.move_id
|
||||
account_move_ids = self.account_move.sudo(self.branch_user_1).search(
|
||||
[('id', 'in', [account_move_id_1.id, account_move_id_2.id])])
|
||||
self.assertEqual(len(account_move_ids), 2)
|
||||
|
||||
account_move_ids = self.account_move.sudo(self.branch_user_2).search(
|
||||
[('id', 'in', [account_move_id_1.id, account_move_id_2.id]),
|
||||
('branch_id', '=', self.branch_2.id)])
|
||||
self.assertEqual(len(account_move_ids), 1)
|
@ -233,6 +233,7 @@
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<field name="partner_id" domain="[('customer','=',True)]" string="Customer" context="{'search_default_customer':1, 'show_address': 1}" options='{"always_reload": True}'/>
|
||||
<field name="pay_now" required="1"/>
|
||||
<field name="branch_id"/>
|
||||
<field name="account_id" groups="account.group_account_user"/>
|
||||
</group>
|
||||
<group>
|
||||
@ -346,6 +347,7 @@
|
||||
<field name="account_id" groups="account.group_account_user"/>
|
||||
<field name="name" colspan="2" attrs="{'invisible': [('pay_now', '=', 'pay_later')]}"/>
|
||||
<field name="reference"/>
|
||||
<field name="branch_id"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
</group>
|
||||
<group>
|
||||
|
@ -14,7 +14,7 @@ class AccountAnalyticTag(models.Model):
|
||||
|
||||
class AccountAnalyticAccount(models.Model):
|
||||
_name = 'account.analytic.account'
|
||||
_inherit = ['mail.thread']
|
||||
_inherit = ['mail.thread', 'ir.branch.company.mixin']
|
||||
_description = 'Analytic Account'
|
||||
_order = 'code, name asc'
|
||||
|
||||
@ -105,4 +105,6 @@ class AccountAnalyticLine(models.Model):
|
||||
tag_ids = fields.Many2many('account.analytic.tag', 'account_analytic_line_tag_rel', 'line_id', 'tag_id', string='Tags', copy=True)
|
||||
|
||||
company_id = fields.Many2one(related='account_id.company_id', string='Company', store=True, readonly=True)
|
||||
branch_id = fields.Many2one(related='account_id.branch_id',
|
||||
string='Branch', store=True, readonly=True)
|
||||
currency_id = fields.Many2one(related="company_id.currency_id", string="Currency", readonly=True)
|
||||
|
@ -15,6 +15,14 @@
|
||||
<field eval="True" name="global"/>
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
<record id="account_analytic_account_multi_branch_rule" model="ir.rule">
|
||||
<field name="name">Analytic Multi Branch</field>
|
||||
<field name="model_id" ref="model_account_analytic_account"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
<data noupdate="0">
|
||||
|
||||
|
@ -51,6 +51,7 @@
|
||||
<field name="account_id"/>
|
||||
<field name="currency_id" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="branch_id" />
|
||||
<field name="unit_amount" sum="Quantity"/>
|
||||
<field name="amount" sum="Total"/>
|
||||
</tree>
|
||||
@ -112,6 +113,7 @@
|
||||
</group>
|
||||
<group>
|
||||
<field name="tag_ids" widget="many2many_tags"/>
|
||||
<field name="branch_id" options="{'no_create': True}"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<field name="currency_id" options="{'no_create': True}" groups="base.group_multi_currency"/>
|
||||
</group>
|
||||
@ -136,6 +138,7 @@
|
||||
<field name="partner_id"/>
|
||||
<field name="active" invisible="1"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="branch_id"/>
|
||||
<field name="debit"/>
|
||||
<field name="credit"/>
|
||||
<field name="balance"/>
|
||||
@ -229,6 +232,7 @@
|
||||
<field name="tag_ids" widget="many2many_tags"/>
|
||||
<field name="date"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="branch_id" options="{'no_create': True}"/>
|
||||
</group>
|
||||
<group string="Amount">
|
||||
<field name="amount"/>
|
||||
|
@ -38,5 +38,10 @@
|
||||
<field name="branch_ids" eval="[(6,0,[ref('data_branch_1'),])]"/>
|
||||
<field name='default_branch_id' ref='data_branch_1'/>
|
||||
</record>
|
||||
|
||||
<record id="base.user_demo" model="res.users">
|
||||
<field name="branch_ids" eval="[(6,0,[ref('data_branch_1'),ref('data_branch_2'),ref('data_branch_3')])]"/>
|
||||
<field name='default_branch_id' ref='data_branch_1'/>
|
||||
</record>
|
||||
</data>
|
||||
</flectra>
|
||||
|
@ -328,6 +328,7 @@
|
||||
<field name="partner_id" ref="base.res_partner_3"/>
|
||||
<field name="partner_invoice_id" ref="base.res_partner_address_25"/>
|
||||
<field name="partner_shipping_id" ref="base.res_partner_address_25"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="pricelist_id" ref="product.list0"/>
|
||||
<field name="team_id" ref="sales_team.crm_team_1"/>
|
||||
@ -338,6 +339,7 @@
|
||||
<field name="order_id" ref="sale_order_11"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="product_uom_qty">3</field>
|
||||
<field name="product_uom" ref="product.product_uom_unit"/>
|
||||
<field name="price_unit">2450.00</field>
|
||||
@ -345,6 +347,7 @@
|
||||
|
||||
<record id="sale_order_line_27" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_11"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Mouse, Wireless</field>
|
||||
<field name="product_id" ref="product.product_product_12"/>
|
||||
<field name="product_uom_qty">3</field>
|
||||
@ -354,6 +357,7 @@
|
||||
|
||||
<record id="sale_order_12" model="sale.order">
|
||||
<field name="partner_id" ref="base.res_partner_3"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="partner_invoice_id" ref="base.res_partner_address_25"/>
|
||||
<field name="partner_shipping_id" ref="base.res_partner_address_25"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
@ -364,6 +368,7 @@
|
||||
|
||||
<record id="sale_order_line_28" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_12"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">1</field>
|
||||
@ -373,6 +378,7 @@
|
||||
|
||||
<record id="sale_order_line_29" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_12"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Mouse, Wireless</field>
|
||||
<field name="product_id" ref="product.product_product_12"/>
|
||||
<field name="product_uom_qty">2</field>
|
||||
@ -381,6 +387,7 @@
|
||||
</record>
|
||||
|
||||
<record id="sale_order_13" model="sale.order">
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="partner_id" ref="base.res_partner_3"/>
|
||||
<field name="partner_invoice_id" ref="base.res_partner_address_25"/>
|
||||
<field name="partner_shipping_id" ref="base.res_partner_address_25"/>
|
||||
@ -392,6 +399,7 @@
|
||||
|
||||
<record id="sale_order_line_30" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_13"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">1</field>
|
||||
@ -401,6 +409,7 @@
|
||||
|
||||
<record id="sale_order_line_31" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_13"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Mouse, Wireless</field>
|
||||
<field name="product_id" ref="product.product_product_12"/>
|
||||
<field name="product_uom_qty">1</field>
|
||||
@ -411,6 +420,7 @@
|
||||
<record id="sale_order_14" model="sale.order">
|
||||
<field name="partner_id" ref="base.res_partner_3"/>
|
||||
<field name="partner_invoice_id" ref="base.res_partner_address_25"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="partner_shipping_id" ref="base.res_partner_address_25"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
<field name="pricelist_id" ref="product.list0"/>
|
||||
@ -420,6 +430,7 @@
|
||||
|
||||
<record id="sale_order_line_32" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_14"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">4</field>
|
||||
@ -429,6 +440,7 @@
|
||||
|
||||
<record id="sale_order_line_33" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_14"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Mouse, Wireless</field>
|
||||
<field name="product_id" ref="product.product_product_12"/>
|
||||
<field name="product_uom_qty">4</field>
|
||||
@ -438,6 +450,7 @@
|
||||
|
||||
<record id="sale_order_15" model="sale.order">
|
||||
<field name="partner_id" ref="base.res_partner_3"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="partner_invoice_id" ref="base.res_partner_address_25"/>
|
||||
<field name="partner_shipping_id" ref="base.res_partner_address_25"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
@ -448,6 +461,7 @@
|
||||
|
||||
<record id="sale_order_line_34" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_15"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">4</field>
|
||||
@ -457,6 +471,7 @@
|
||||
|
||||
<record id="sale_order_line_35" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_15"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Mouse, Wireless</field>
|
||||
<field name="product_id" ref="product.product_product_12"/>
|
||||
<field name="product_uom_qty">3</field>
|
||||
@ -466,6 +481,7 @@
|
||||
|
||||
<record id="sale_order_16" model="sale.order">
|
||||
<field name="partner_id" ref="base.res_partner_3"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="partner_invoice_id" ref="base.res_partner_address_25"/>
|
||||
<field name="partner_shipping_id" ref="base.res_partner_address_25"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
@ -476,6 +492,7 @@
|
||||
|
||||
<record id="sale_order_line_36" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_16"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">3</field>
|
||||
@ -485,6 +502,7 @@
|
||||
|
||||
<record id="sale_order_line_37" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_16"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Mouse, Wireless</field>
|
||||
<field name="product_id" ref="product.product_product_12"/>
|
||||
<field name="product_uom_qty">3</field>
|
||||
@ -494,6 +512,7 @@
|
||||
|
||||
<record id="sale_order_17" model="sale.order">
|
||||
<field name="partner_id" ref="base.res_partner_3"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="partner_invoice_id" ref="base.res_partner_address_25"/>
|
||||
<field name="partner_shipping_id" ref="base.res_partner_address_25"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
@ -504,6 +523,7 @@
|
||||
|
||||
<record id="sale_order_line_38" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_17"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">2</field>
|
||||
@ -513,6 +533,7 @@
|
||||
|
||||
<record id="sale_order_line_39" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_17"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Mouse, Wireless</field>
|
||||
<field name="product_id" ref="product.product_product_12"/>
|
||||
<field name="product_uom_qty">2</field>
|
||||
@ -522,6 +543,7 @@
|
||||
|
||||
<record id="sale_order_18" model="sale.order">
|
||||
<field name="partner_id" ref="base.res_partner_3"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="partner_invoice_id" ref="base.res_partner_address_25"/>
|
||||
<field name="partner_shipping_id" ref="base.res_partner_address_25"/>
|
||||
<field name="user_id" ref="base.user_demo"/>
|
||||
@ -532,6 +554,7 @@
|
||||
|
||||
<record id="sale_order_line_40" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_18"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Laptop E5023</field>
|
||||
<field name="product_id" ref="product.product_product_25"/>
|
||||
<field name="product_uom_qty">2</field>
|
||||
@ -541,6 +564,7 @@
|
||||
|
||||
<record id="sale_order_line_41" model="sale.order.line">
|
||||
<field name="order_id" ref="sale_order_18"/>
|
||||
<field name="branch_id" ref="base_branch_company.data_branch_2"/>
|
||||
<field name="name">Mouse, Wireless</field>
|
||||
<field name="product_id" ref="product.product_product_12"/>
|
||||
<field name="product_uom_qty">2</field>
|
||||
|
@ -13,13 +13,14 @@ from flectra.osv import expression
|
||||
from flectra.tools import float_is_zero, float_compare, DEFAULT_SERVER_DATETIME_FORMAT
|
||||
|
||||
from flectra.tools.misc import formatLang
|
||||
|
||||
from flectra.exceptions import ValidationError
|
||||
from flectra.addons import decimal_precision as dp
|
||||
|
||||
|
||||
class SaleOrder(models.Model):
|
||||
_name = "sale.order"
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin', 'portal.mixin']
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin', 'portal.mixin',
|
||||
'ir.branch.company.mixin']
|
||||
_description = "Quotation"
|
||||
_order = 'date_order desc, id desc'
|
||||
|
||||
@ -164,6 +165,17 @@ class SaleOrder(models.Model):
|
||||
|
||||
product_id = fields.Many2one('product.product', related='order_line.product_id', string='Product')
|
||||
|
||||
@api.multi
|
||||
@api.constrains('branch_id', 'company_id')
|
||||
def _check_company_branch(self):
|
||||
for order in self:
|
||||
if order.branch_id and order.company_id != order.branch_id.company_id:
|
||||
raise ValidationError(_(
|
||||
'Configuration Error of Company:\n'
|
||||
'The Sales Order Company (%s) and the Company (%s) of '
|
||||
'Branch must be the same!') % (
|
||||
order.company_id.name, order.branch_id.company_id.name))
|
||||
|
||||
def _compute_portal_url(self):
|
||||
super(SaleOrder, self)._compute_portal_url()
|
||||
for order in self:
|
||||
@ -354,6 +366,7 @@ class SaleOrder(models.Model):
|
||||
invoice_vals = {
|
||||
'name': self.client_order_ref or '',
|
||||
'origin': self.name,
|
||||
'branch_id': self.branch_id and self.branch_id.id,
|
||||
'type': 'out_invoice',
|
||||
'account_id': self.partner_invoice_id.property_account_receivable_id.id,
|
||||
'partner_id': self.partner_invoice_id.id,
|
||||
@ -548,6 +561,7 @@ class SaleOrder(models.Model):
|
||||
analytic = self.env['account.analytic.account'].create({
|
||||
'name': name,
|
||||
'code': order.client_order_ref,
|
||||
'branch_id': order.branch_id and order.branch_id.id,
|
||||
'company_id': order.company_id.id,
|
||||
'partner_id': order.partner_id.id
|
||||
})
|
||||
@ -907,6 +921,8 @@ class SaleOrderLine(models.Model):
|
||||
salesman_id = fields.Many2one(related='order_id.user_id', store=True, string='Salesperson', readonly=True)
|
||||
currency_id = fields.Many2one(related='order_id.currency_id', store=True, string='Currency', readonly=True)
|
||||
company_id = fields.Many2one(related='order_id.company_id', string='Company', store=True, readonly=True)
|
||||
branch_id = fields.Many2one(related='order_id.branch_id',
|
||||
string='Branch', store=True, readonly=True)
|
||||
order_partner_id = fields.Many2one(related='order_id.partner_id', store=True, string='Customer')
|
||||
analytic_tag_ids = fields.Many2many('account.analytic.tag', string='Analytic Tags')
|
||||
is_downpayment = fields.Boolean(
|
||||
@ -953,6 +969,7 @@ class SaleOrderLine(models.Model):
|
||||
'name': self.name,
|
||||
'sequence': self.sequence,
|
||||
'origin': self.order_id.name,
|
||||
'branch_id': self.branch_id and self.branch_id.id,
|
||||
'account_id': account.id,
|
||||
'price_unit': self.price_unit,
|
||||
'quantity': qty,
|
||||
|
@ -6,6 +6,7 @@ from flectra import api, fields, models, tools
|
||||
|
||||
class PosSaleReport(models.Model):
|
||||
_name = "report.all.channels.sales"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = "All sales orders grouped by sales channels"
|
||||
_auto = False
|
||||
|
||||
@ -37,6 +38,7 @@ class PosSaleReport(models.Model):
|
||||
so.user_id AS user_id,
|
||||
pt.categ_id AS categ_id,
|
||||
so.company_id AS company_id,
|
||||
so.branch_id AS branch_id,
|
||||
sol.price_total / COALESCE(cr.rate, 1.0) AS price_total,
|
||||
so.pricelist_id AS pricelist_id,
|
||||
rp.country_id AS country_id,
|
||||
@ -75,6 +77,7 @@ class PosSaleReport(models.Model):
|
||||
user_id,
|
||||
categ_id,
|
||||
company_id,
|
||||
branch_id,
|
||||
price_total,
|
||||
pricelist_id,
|
||||
analytic_account_id,
|
||||
|
@ -7,6 +7,7 @@ from flectra import api, fields, models
|
||||
|
||||
class SaleReport(models.Model):
|
||||
_name = "sale.report"
|
||||
_inherit = ['ir.branch.company.mixin']
|
||||
_description = "Sales Orders Statistics"
|
||||
_auto = False
|
||||
_rec_name = 'date'
|
||||
@ -68,6 +69,7 @@ class SaleReport(models.Model):
|
||||
s.partner_id as partner_id,
|
||||
s.user_id as user_id,
|
||||
s.company_id as company_id,
|
||||
s.branch_id as branch_id,
|
||||
extract(epoch from avg(date_trunc('day',s.date_order)-date_trunc('day',s.create_date)))/(24*60*60)::decimal(16,2) as delay,
|
||||
t.categ_id as categ_id,
|
||||
s.pricelist_id as pricelist_id,
|
||||
@ -111,6 +113,7 @@ class SaleReport(models.Model):
|
||||
s.user_id,
|
||||
s.state,
|
||||
s.company_id,
|
||||
s.branch_id,
|
||||
s.pricelist_id,
|
||||
s.analytic_account_id,
|
||||
s.team_id,
|
||||
|
@ -60,6 +60,10 @@
|
||||
<strong>Payment Terms:</strong>
|
||||
<p t-field="doc.payment_term_id"/>
|
||||
</div>
|
||||
<div name="branch" t-if="doc.branch_id" class="col-xs-3">
|
||||
<strong>Branch:</strong>
|
||||
<p t-field="doc.branch_id"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Is there a discount on at least one line? -->
|
||||
|
@ -84,6 +84,30 @@
|
||||
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])]</field>
|
||||
</record>
|
||||
|
||||
|
||||
<!-- Multi - Branch Rules -->
|
||||
|
||||
<record model="ir.rule" id="sale_order_multi_branch_rule">
|
||||
<field name="name">Sales Order multi-branch</field>
|
||||
<field name="model_id" ref="model_sale_order"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="sale_order_line_multi_branch_rule">
|
||||
<field name="name">Sales Order Line multi-branch</field>
|
||||
<field name="model_id" ref="model_sale_order_line"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.rule" id="sale_order_report_multi_branch_rule">
|
||||
<field name="name">Sales Order Analysis multi-branch</field>
|
||||
<field name="model_id" ref="model_sale_report"/>
|
||||
<field name="global" eval="True"/>
|
||||
<field name="domain_force">['|',('branch_id','=', False),'|',('branch_id','=',user.default_branch_id.id), ('branch_id','in', [b.id for b in user.branch_ids])]</field>
|
||||
</record>
|
||||
|
||||
<!-- Portal Access Rules -->
|
||||
<record id="sale_order_rule_portal" model="ir.rule">
|
||||
<field name="name">Portal Personal Quotations/Sales Orders</field>
|
||||
|
@ -4,3 +4,4 @@ from . import test_sale_to_invoice
|
||||
from . import test_sale_order
|
||||
from . import test_product_id_change
|
||||
from . import test_sale_to_invoice_and_to_be_invoiced
|
||||
from . import test_sale_branch
|
||||
|
121
addons/sale/tests/test_sale_branch.py
Normal file
121
addons/sale/tests/test_sale_branch.py
Normal file
@ -0,0 +1,121 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from flectra.tests import common
|
||||
|
||||
|
||||
class TestSaleBranch(common.TransactionCase):
|
||||
def setUp(self):
|
||||
super(TestSaleBranch, self).setUp()
|
||||
|
||||
self.sale_obj = self.env['sale.order']
|
||||
|
||||
self.main_company = self.env.ref('base.main_company')
|
||||
|
||||
self.payment_model_obj = self.env['sale.advance.payment.inv']
|
||||
|
||||
self.sale_user_group = self.env.ref('sales_team.group_sale_manager')
|
||||
self.account_user_group = self.env.ref('account.group_account_invoice')
|
||||
self.branch_1 = self.env.ref('base_branch_company.data_branch_1')
|
||||
self.branch_2 = self.env.ref('base_branch_company.data_branch_2')
|
||||
self.branch_3 = self.env.ref('base_branch_company.data_branch_3')
|
||||
|
||||
self.sale_customer = self.env.ref('base.res_partner_2')
|
||||
self.sale_pricelist = self.env.ref('product.list0')
|
||||
|
||||
self.apple_product = self.env.ref('product.product_product_7')
|
||||
self.apple_product.write({'invoice_policy': 'order'})
|
||||
|
||||
self.user_1 = self.create_sale_user(
|
||||
self.main_company, 'user_1', self.branch_1,
|
||||
[self.branch_1, self.branch_3],
|
||||
[self.sale_user_group, self.account_user_group])
|
||||
self.user_2 = self.create_sale_user(
|
||||
self.main_company, 'user_2', self.branch_3,
|
||||
[self.branch_3], [self.sale_user_group, self.account_user_group])
|
||||
|
||||
self.so_1 = self.create_so(
|
||||
self.sale_customer, self.apple_product, self.user_1.id,
|
||||
self.branch_1, self.sale_pricelist)
|
||||
self.so_2 = self.create_so(
|
||||
self.sale_customer, self.apple_product, self.user_2.id,
|
||||
self.branch_3, self.sale_pricelist)
|
||||
|
||||
def create_sale_user(self, main_company, user_name,
|
||||
branch_id, branch_ids, groups):
|
||||
group_ids = [grp.id for grp in groups]
|
||||
data = {
|
||||
'company_ids': [(4, main_company.id)],
|
||||
'branch_ids': [(4, ou.id) for ou in branch_ids],
|
||||
'company_id': main_company.id,
|
||||
'groups_id': [(6, 0, group_ids)],
|
||||
'default_branch_id': branch_id.id,
|
||||
'login': user_name,
|
||||
'name': 'Ron Sales User',
|
||||
'password': '123',
|
||||
'email': 'ron@yourcompany.com',
|
||||
|
||||
}
|
||||
user_obj = self.env['res.users'].create(data)
|
||||
return user_obj
|
||||
|
||||
def create_so(self, customer_id, product_id,
|
||||
user_id, branch_id, pricelist_id):
|
||||
data = {
|
||||
'partner_id': customer_id.id,
|
||||
'branch_id': branch_id.id,
|
||||
'pricelist_id': pricelist_id.id,
|
||||
'partner_shipping_id': customer_id.id,
|
||||
'partner_invoice_id': customer_id.id,
|
||||
}
|
||||
sale_id = self.sale_obj.sudo(user_id).create(data)
|
||||
self.env['sale.order.line'].sudo(user_id).create({
|
||||
'order_id': sale_id.id,
|
||||
'product_id': product_id.id,
|
||||
'name': 'Order Line'
|
||||
})
|
||||
return sale_id
|
||||
|
||||
def sale_order_confirm(self, sale_obj):
|
||||
context = {
|
||||
'open_invoices': True,
|
||||
'active_id': sale_obj.id,
|
||||
'active_model': 'sale.order',
|
||||
'active_ids': sale_obj.ids,
|
||||
|
||||
}
|
||||
sale_obj.action_confirm()
|
||||
|
||||
invoice = self.payment_model_obj.create({
|
||||
'advance_payment_method': 'all',
|
||||
})
|
||||
|
||||
result = invoice.with_context(context).create_invoices()
|
||||
invoice = result['res_id']
|
||||
return invoice
|
||||
|
||||
def get_sale_order(self, sale_order_id, branch_id):
|
||||
sale = self.sale_obj.sudo(self.user_2.id).search(
|
||||
[('id', '=', sale_order_id),
|
||||
('branch_id', '=', branch_id)])
|
||||
return sale
|
||||
|
||||
def test_user_authentication(self):
|
||||
sale = self.get_sale_order(self.so_1.id, self.branch_1.id)
|
||||
self.assertEqual(sale.ids, [], 'Test User 2 should not have access to '
|
||||
'Branch %s' % self.branch_1.name)
|
||||
self.sale_order_confirm(self.so_1)
|
||||
branch_3_invoice_id = self.sale_order_confirm(self.so_2)
|
||||
branch_3 = self.env['account.invoice'].sudo(self.user_2.id).search(
|
||||
[('id', '=', branch_3_invoice_id),
|
||||
('branch_id', '=', self.branch_3.id)])
|
||||
self.assertNotEqual(branch_3.ids, [],
|
||||
'Invoice should have branch_3 Branch')
|
||||
|
||||
def test_user_authentication_2(self):
|
||||
sale = self.get_sale_order(self.so_1.id, self.branch_1.id)
|
||||
self.assertEqual(sale.ids, [], 'Test User 2 should '
|
||||
'not have access to Branch %s'
|
||||
% self.branch_1.name)
|
||||
sale = self.get_sale_order(self.so_2.id, self.branch_3.id)
|
||||
self.assertEqual(len(sale.ids), 1, 'Test User 1 should'
|
||||
' have access to Branch : %s'
|
||||
% self.branch_3.name)
|
@ -381,6 +381,7 @@
|
||||
<field name="team_id" options="{'no_create': True}"/>
|
||||
<field name="client_order_ref"/>
|
||||
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
|
||||
<field name="branch_id" options="{'no_create': True}"/>
|
||||
<field name="analytic_account_id" context="{'default_partner_id':partner_invoice_id, 'default_name':name}" attrs="{'readonly': ['|',('analytic_account_id','!=',False),('invoice_count','!=',0),('state','=','sale')]}" groups="analytic.group_analytic_accounting"/>
|
||||
</group>
|
||||
<group name="sale_pay" string="Invoicing">
|
||||
|
@ -84,7 +84,7 @@ class CrmTeam(models.Model):
|
||||
@api.constrains('company_id', 'branch_id')
|
||||
def _check_company_branch(self):
|
||||
for record in self:
|
||||
if record.company_id and record.company_id != record.branch_id.company_id:
|
||||
if record.branch_id and record.company_id and record.company_id != record.branch_id.company_id:
|
||||
raise ValidationError(
|
||||
_('Configuration Error of Company:\n'
|
||||
'The Company (%s) in the Team and '
|
||||
|
Loading…
Reference in New Issue
Block a user