reconciliation: check_overlap_dates() in validate() verschoben + tests
This commit is contained in:
parent
91a34e216b
commit
0b3f82f6c7
2 changed files with 174 additions and 141 deletions
|
@ -117,35 +117,31 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
@classmethod
|
def check_overlap_dates(self):
|
||||||
def check_overlap_dates(cls, date_from, date_to, id_cashbook, record=None):
|
|
||||||
""" deny overlap of date_from/date_to between records of same cashbook
|
""" deny overlap of date_from/date_to between records of same cashbook
|
||||||
allow: date_to=date_from
|
allow: date_to=date_from
|
||||||
"""
|
"""
|
||||||
Recon = Pool().get('cashbook.recon')
|
Recon = Pool().get('cashbook.recon')
|
||||||
|
|
||||||
query = [
|
query = [
|
||||||
('cashbook.id', '=', id_cashbook),
|
('cashbook.id', '=', self.cashbook.id),
|
||||||
|
('id', '!=', self.id),
|
||||||
['OR',
|
['OR',
|
||||||
[ # 'start' is inside of other record
|
[ # 'start' is inside of other record
|
||||||
('date_from', '<=', date_from),
|
('date_from', '<=', self.date_from),
|
||||||
('date_to', '>', date_from),
|
('date_to', '>', self.date_from),
|
||||||
],
|
],
|
||||||
[ # 'end' is inside of other record
|
[ # 'end' is inside of other record
|
||||||
('date_from', '<', date_to),
|
('date_from', '<', self.date_to),
|
||||||
('date_to', '>=', date_to),
|
('date_to', '>=', self.date_to),
|
||||||
],
|
],
|
||||||
[ # enclose other record
|
[ # enclose other record
|
||||||
('date_from', '>=', date_from),
|
('date_from', '>=', self.date_from),
|
||||||
('date_to', '<=', date_to),
|
('date_to', '<=', self.date_to),
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
]
|
]
|
||||||
|
|
||||||
# avoid finding ourselves
|
|
||||||
if record:
|
|
||||||
query.append(('id', '!=', record.id))
|
|
||||||
|
|
||||||
if Recon.search_count(query) > 0:
|
if Recon.search_count(query) > 0:
|
||||||
raise UserError(gettext('cashbook.msg_recon_err_overlap'))
|
raise UserError(gettext('cashbook.msg_recon_err_overlap'))
|
||||||
|
|
||||||
|
@ -373,6 +369,15 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
|
||||||
if self.cashbook:
|
if self.cashbook:
|
||||||
return self.cashbook.state
|
return self.cashbook.state
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def validate(cls, reconciliations):
|
||||||
|
""" deny overlap of dates
|
||||||
|
"""
|
||||||
|
super(Reconciliation, cls).validate(reconciliations)
|
||||||
|
|
||||||
|
for reconciliation in reconciliations:
|
||||||
|
reconciliation.check_overlap_dates()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def create(cls, vlist):
|
def create(cls, vlist):
|
||||||
""" add debit/credit
|
""" add debit/credit
|
||||||
|
@ -403,10 +408,6 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
|
||||||
if len(lines) > 0:
|
if len(lines) > 0:
|
||||||
values['date_to'] = lines[0].date
|
values['date_to'] = lines[0].date
|
||||||
|
|
||||||
cls.check_overlap_dates(
|
|
||||||
values.get('date_from', None),
|
|
||||||
values.get('date_to', None),
|
|
||||||
values.get('cashbook', None))
|
|
||||||
return super(Reconciliation, cls).create(vlist)
|
return super(Reconciliation, cls).create(vlist)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -418,22 +419,12 @@ class Reconciliation(Workflow, ModelSQL, ModelView):
|
||||||
for reconciliations, values in zip(actions, actions):
|
for reconciliations, values in zip(actions, actions):
|
||||||
# deny write if chashbook is not open
|
# deny write if chashbook is not open
|
||||||
for reconciliation in reconciliations:
|
for reconciliation in reconciliations:
|
||||||
|
|
||||||
# deny overlap
|
|
||||||
if len(set({'date_from', 'date_to'}).intersection(set(values.keys()))) > 0:
|
|
||||||
cls.check_overlap_dates(
|
|
||||||
values.get('date_from', reconciliation.date_from),
|
|
||||||
values.get('date_to', reconciliation.date_to),
|
|
||||||
reconciliation.cashbook.id,
|
|
||||||
reconciliation)
|
|
||||||
|
|
||||||
if reconciliation.cashbook.state != 'open':
|
if reconciliation.cashbook.state != 'open':
|
||||||
raise UserError(gettext(
|
raise UserError(gettext(
|
||||||
'cashbook.msg_book_deny_write',
|
'cashbook.msg_book_deny_write',
|
||||||
bookname = reconciliation.cashbook.rec_name,
|
bookname = reconciliation.cashbook.rec_name,
|
||||||
state_txt = reconciliation.cashbook.state_string,
|
state_txt = reconciliation.cashbook.state_string,
|
||||||
))
|
))
|
||||||
|
|
||||||
super(Reconciliation, cls).write(*args)
|
super(Reconciliation, cls).write(*args)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -16,8 +16,8 @@ class ReconTestCase(ModuleTestCase):
|
||||||
module = 'cashbook'
|
module = 'cashbook'
|
||||||
|
|
||||||
@with_transaction()
|
@with_transaction()
|
||||||
def test_recon_check_overlap(self):
|
def test_recon_check_overlap_start(self):
|
||||||
""" create, check deny of overlap date
|
""" create, check deny of overlap date - date_from
|
||||||
"""
|
"""
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
Book = pool.get('cashbook.book')
|
Book = pool.get('cashbook.book')
|
||||||
|
@ -33,136 +33,178 @@ class ReconTestCase(ModuleTestCase):
|
||||||
'currency': company.currency.id,
|
'currency': company.currency.id,
|
||||||
'number_sequ': self.prep_sequence().id,
|
'number_sequ': self.prep_sequence().id,
|
||||||
'start_date': date(2022, 5, 1),
|
'start_date': date(2022, 5, 1),
|
||||||
|
'reconciliations': [('create', [{
|
||||||
|
'date': date(2022, 5, 1),
|
||||||
|
'date_from': date(2022, 5, 1),
|
||||||
|
'date_to': date(2022, 5, 31),
|
||||||
|
}])],
|
||||||
}])
|
}])
|
||||||
|
|
||||||
recon1, = Reconciliation.create([{
|
Book.write(*[
|
||||||
'date': date(2022, 5, 1),
|
[book],
|
||||||
'date_from': date(2022, 5, 1),
|
{
|
||||||
'date_to': date(2022, 5, 31),
|
'reconciliations': [('create', [{
|
||||||
'cashbook': book.id,
|
'date': date(2022, 6, 1),
|
||||||
|
'date_from': date(2022, 6, 1),
|
||||||
|
'date_to': date(2022, 6, 30),
|
||||||
|
}])],
|
||||||
}])
|
}])
|
||||||
self.assertEqual(recon1.rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]')
|
self.assertEqual(book.reconciliations[0].rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]')
|
||||||
|
self.assertEqual(book.reconciliations[1].rec_name, '05/31/2022 - 06/30/2022 | 0.00 usd - 0.00 usd [0]')
|
||||||
|
|
||||||
recon2, = Reconciliation.create([{
|
|
||||||
'date': date(2022, 6, 1),
|
|
||||||
'date_from': date(2022, 6, 1),
|
|
||||||
'date_to': date(2022, 6, 30),
|
|
||||||
'cashbook': book.id,
|
|
||||||
}])
|
|
||||||
# updated by create to date_to of predecessor
|
|
||||||
self.assertEqual(recon2.rec_name, '05/31/2022 - 06/30/2022 | 0.00 usd - 0.00 usd [0]')
|
|
||||||
|
|
||||||
# same day for end of '0' and start of '1'
|
|
||||||
self.assertEqual(recon1.rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]')
|
|
||||||
self.assertEqual(recon2.rec_name, '05/31/2022 - 06/30/2022 | 0.00 usd - 0.00 usd [0]')
|
|
||||||
|
|
||||||
# 'date_from' inside of other record
|
|
||||||
self.assertRaisesRegex(UserError,
|
self.assertRaisesRegex(UserError,
|
||||||
'The date range overlaps with another reconciliation.',
|
'The date range overlaps with another reconciliation.',
|
||||||
Reconciliation.write,
|
Reconciliation.write,
|
||||||
*[
|
*[
|
||||||
[recon2],
|
[book.reconciliations[1]],
|
||||||
|
{
|
||||||
|
'date_from': date(2022, 4, 15),
|
||||||
|
'date_to': date(2022, 5, 2),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
@with_transaction()
|
||||||
|
def test_recon_check_overlap_end(self):
|
||||||
|
""" create, check deny of overlap date - date_to
|
||||||
|
"""
|
||||||
|
pool = Pool()
|
||||||
|
Book = pool.get('cashbook.book')
|
||||||
|
Reconciliation = pool.get('cashbook.recon')
|
||||||
|
|
||||||
|
types = self.prep_type()
|
||||||
|
category = self.prep_category(cattype='in')
|
||||||
|
company = self.prep_company()
|
||||||
|
book, = Book.create([{
|
||||||
|
'name': 'Book 1',
|
||||||
|
'btype': types.id,
|
||||||
|
'company': company.id,
|
||||||
|
'currency': company.currency.id,
|
||||||
|
'number_sequ': self.prep_sequence().id,
|
||||||
|
'start_date': date(2022, 5, 1),
|
||||||
|
'reconciliations': [('create', [{
|
||||||
|
'date': date(2022, 5, 1),
|
||||||
|
'date_from': date(2022, 5, 1),
|
||||||
|
'date_to': date(2022, 5, 31),
|
||||||
|
}])],
|
||||||
|
}])
|
||||||
|
|
||||||
|
Book.write(*[
|
||||||
|
[book],
|
||||||
|
{
|
||||||
|
'reconciliations': [('create', [{
|
||||||
|
'date': date(2022, 6, 1),
|
||||||
|
'date_from': date(2022, 6, 1),
|
||||||
|
'date_to': date(2022, 6, 30),
|
||||||
|
}])],
|
||||||
|
}])
|
||||||
|
self.assertEqual(book.reconciliations[0].rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]')
|
||||||
|
self.assertEqual(book.reconciliations[1].rec_name, '05/31/2022 - 06/30/2022 | 0.00 usd - 0.00 usd [0]')
|
||||||
|
|
||||||
|
self.assertRaisesRegex(UserError,
|
||||||
|
'The date range overlaps with another reconciliation.',
|
||||||
|
Reconciliation.write,
|
||||||
|
*[
|
||||||
|
[book.reconciliations[1]],
|
||||||
{
|
{
|
||||||
'date_from': date(2022, 5, 30),
|
'date_from': date(2022, 5, 30),
|
||||||
},
|
},
|
||||||
])
|
])
|
||||||
|
|
||||||
# 'date_from' inside of other record
|
@with_transaction()
|
||||||
self.assertRaisesRegex(UserError,
|
def test_recon_check_overlap_inside(self):
|
||||||
'The date range overlaps with another reconciliation.',
|
""" create, check deny of overlap date - inside of period
|
||||||
Reconciliation.write,
|
"""
|
||||||
*[
|
pool = Pool()
|
||||||
[recon2],
|
Book = pool.get('cashbook.book')
|
||||||
{
|
Reconciliation = pool.get('cashbook.recon')
|
||||||
'date_from': date(2022, 5, 2),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
# 'date_from' same date_from like other record
|
types = self.prep_type()
|
||||||
self.assertRaisesRegex(UserError,
|
category = self.prep_category(cattype='in')
|
||||||
'The date range overlaps with another reconciliation.',
|
company = self.prep_company()
|
||||||
Reconciliation.write,
|
book, = Book.create([{
|
||||||
*[
|
'name': 'Book 1',
|
||||||
[recon2],
|
'btype': types.id,
|
||||||
{
|
'company': company.id,
|
||||||
'date_from': date(2022, 5, 1),
|
'currency': company.currency.id,
|
||||||
},
|
'number_sequ': self.prep_sequence().id,
|
||||||
])
|
'start_date': date(2022, 5, 1),
|
||||||
|
'reconciliations': [('create', [{
|
||||||
# enclose other record
|
|
||||||
self.assertRaisesRegex(UserError,
|
|
||||||
'The date range overlaps with another reconciliation.',
|
|
||||||
Reconciliation.write,
|
|
||||||
*[
|
|
||||||
[recon2],
|
|
||||||
{
|
|
||||||
'date_from': date(2022, 4, 30),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
# within other record
|
|
||||||
self.assertRaisesRegex(UserError,
|
|
||||||
'The date range overlaps with another reconciliation.',
|
|
||||||
Reconciliation.write,
|
|
||||||
*[
|
|
||||||
[recon2],
|
|
||||||
{
|
|
||||||
'date_from': date(2022, 5, 2),
|
|
||||||
'date_to': date(2022, 5, 12),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
# from after to
|
|
||||||
self.assertRaisesRegex(UserError,
|
|
||||||
'The value for field "Start Date" in "Cashbook Reconciliation" is not valid according to its domain.',
|
|
||||||
Reconciliation.write,
|
|
||||||
*[
|
|
||||||
[recon2],
|
|
||||||
{
|
|
||||||
'date_from': date(2022, 4, 15),
|
|
||||||
'date_to': date(2022, 4, 10),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
# 'date_to' at 'date_from' of other record - allowed
|
|
||||||
Reconciliation.write(*[
|
|
||||||
[recon2],
|
|
||||||
{
|
|
||||||
'date_from': date(2022, 4, 15),
|
|
||||||
'date_to': date(2022, 5, 1),
|
|
||||||
}])
|
|
||||||
|
|
||||||
# 'date_to' after other date_from
|
|
||||||
self.assertRaisesRegex(UserError,
|
|
||||||
'The date range overlaps with another reconciliation.',
|
|
||||||
Reconciliation.write,
|
|
||||||
*[
|
|
||||||
[recon2],
|
|
||||||
{
|
|
||||||
'date_to': date(2022, 5, 2),
|
|
||||||
},
|
|
||||||
])
|
|
||||||
|
|
||||||
# overlap at .create()
|
|
||||||
self.assertRaisesRegex(UserError,
|
|
||||||
'The date range overlaps with another reconciliation.',
|
|
||||||
Reconciliation.create,
|
|
||||||
[{
|
|
||||||
'date': date(2022, 5, 1),
|
'date': date(2022, 5, 1),
|
||||||
'date_from': date(2022, 4, 1),
|
'date_from': date(2022, 5, 1),
|
||||||
'date_to': date(2022, 4, 16),
|
'date_to': date(2022, 5, 31),
|
||||||
'cashbook': book.id,
|
}])],
|
||||||
}])
|
}])
|
||||||
|
|
||||||
recon3, = Reconciliation.create([{
|
Book.write(*[
|
||||||
'date': date(2022, 4, 17),
|
[book],
|
||||||
'date_from': date(2022, 6, 1),
|
{
|
||||||
'date_to': date(2022, 6, 15),
|
'reconciliations': [('create', [{
|
||||||
'cashbook': book.id,
|
'date': date(2022, 6, 1),
|
||||||
|
'date_from': date(2022, 6, 1),
|
||||||
|
'date_to': date(2022, 6, 30),
|
||||||
|
}])],
|
||||||
}])
|
}])
|
||||||
self.assertEqual(recon1.rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]')
|
self.assertEqual(book.reconciliations[0].rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]')
|
||||||
self.assertEqual(recon2.rec_name, '04/15/2022 - 05/01/2022 | 0.00 usd - 0.00 usd [0]')
|
self.assertEqual(book.reconciliations[1].rec_name, '05/31/2022 - 06/30/2022 | 0.00 usd - 0.00 usd [0]')
|
||||||
self.assertEqual(recon3.rec_name, '05/31/2022 - 06/15/2022 | 0.00 usd - 0.00 usd [0]')
|
|
||||||
|
self.assertRaisesRegex(UserError,
|
||||||
|
'The date range overlaps with another reconciliation.',
|
||||||
|
Reconciliation.write,
|
||||||
|
*[
|
||||||
|
[book.reconciliations[1]],
|
||||||
|
{
|
||||||
|
'date_from': date(2022, 5, 5),
|
||||||
|
'date_to': date(2022, 5, 15),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
|
@with_transaction()
|
||||||
|
def test_recon_check_overlap_enclose(self):
|
||||||
|
""" create, check deny of overlap date - enclose a period
|
||||||
|
"""
|
||||||
|
pool = Pool()
|
||||||
|
Book = pool.get('cashbook.book')
|
||||||
|
Reconciliation = pool.get('cashbook.recon')
|
||||||
|
|
||||||
|
types = self.prep_type()
|
||||||
|
category = self.prep_category(cattype='in')
|
||||||
|
company = self.prep_company()
|
||||||
|
book, = Book.create([{
|
||||||
|
'name': 'Book 1',
|
||||||
|
'btype': types.id,
|
||||||
|
'company': company.id,
|
||||||
|
'currency': company.currency.id,
|
||||||
|
'number_sequ': self.prep_sequence().id,
|
||||||
|
'start_date': date(2022, 5, 1),
|
||||||
|
'reconciliations': [('create', [{
|
||||||
|
'date': date(2022, 5, 1),
|
||||||
|
'date_from': date(2022, 5, 1),
|
||||||
|
'date_to': date(2022, 5, 31),
|
||||||
|
}])],
|
||||||
|
}])
|
||||||
|
|
||||||
|
Book.write(*[
|
||||||
|
[book],
|
||||||
|
{
|
||||||
|
'reconciliations': [('create', [{
|
||||||
|
'date': date(2022, 6, 1),
|
||||||
|
'date_from': date(2022, 6, 1),
|
||||||
|
'date_to': date(2022, 6, 30),
|
||||||
|
}])],
|
||||||
|
}])
|
||||||
|
self.assertEqual(book.reconciliations[0].rec_name, '05/01/2022 - 05/31/2022 | 0.00 usd - 0.00 usd [0]')
|
||||||
|
self.assertEqual(book.reconciliations[1].rec_name, '05/31/2022 - 06/30/2022 | 0.00 usd - 0.00 usd [0]')
|
||||||
|
|
||||||
|
self.assertRaisesRegex(UserError,
|
||||||
|
'The date range overlaps with another reconciliation.',
|
||||||
|
Reconciliation.write,
|
||||||
|
*[
|
||||||
|
[book.reconciliations[1]],
|
||||||
|
{
|
||||||
|
'date_from': date(2022, 4, 25),
|
||||||
|
'date_to': date(2022, 6, 10),
|
||||||
|
},
|
||||||
|
])
|
||||||
|
|
||||||
@with_transaction()
|
@with_transaction()
|
||||||
def test_recon_set_start_amount_by_cashbook(self):
|
def test_recon_set_start_amount_by_cashbook(self):
|
||||||
|
|
Loading…
Reference in a new issue