first commit

This commit is contained in:
root
2026-03-14 09:42:12 +00:00
commit 0adbd20c2c
10991 changed files with 1646955 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

View File

@@ -0,0 +1,96 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from sql import Null
from sql.conditionals import Greatest
from sql.functions import CurrentTimestamp
from trytond import backend
from trytond.model import ModelView, Workflow, fields
from trytond.pool import Pool, PoolMeta
from trytond.tools import grouped_slice, reduce_ids, sqlite_apply_types
from trytond.transaction import Transaction
class Invoice(metaclass=PoolMeta):
__name__ = 'account.invoice'
numbered_at = fields.Timestamp("Numbered At")
history_datetime = fields.Function(
fields.Timestamp("History DateTime"),
'get_history_datetime')
@classmethod
def __setup__(cls):
super().__setup__()
cls._check_modify_exclude.add('numbered_at')
cls.party.datetime_field = 'history_datetime'
cls.party_tax_identifier.datetime_field = 'history_datetime'
cls.invoice_address.datetime_field = 'history_datetime'
cls.payment_term.datetime_field = 'history_datetime'
@classmethod
def get_history_datetime(cls, invoices, name):
pool = Pool()
Party = pool.get('party.party')
Address = pool.get('party.address')
Identifier = pool.get('party.identifier')
PaymentTerm = pool.get('account.invoice.payment_term')
table = cls.__table__()
party = Party.__table__()
address = Address.__table__()
identifier = Identifier.__table__()
payment_term = PaymentTerm.__table__()
cursor = Transaction().connection.cursor()
invoice_ids = [i.id for i in invoices]
datetimes = dict.fromkeys(invoice_ids)
for ids in grouped_slice(invoice_ids):
query = (table
.join(party, condition=table.party == party.id)
.join(address, condition=table.invoice_address == address.id)
.join(identifier, 'LEFT',
condition=table.party_tax_identifier == identifier.id)
.join(payment_term, 'LEFT',
condition=table.payment_term == payment_term.id)
.select(table.id,
Greatest(table.numbered_at, party.create_date,
address.create_date, identifier.create_date,
payment_term.create_date).as_('history_datetime'),
where=reduce_ids(table.id, ids)
& (table.numbered_at != Null)
& (table.state.in_(cls._history_states()))))
if backend.name == 'sqlite':
sqlite_apply_types(query, [None, 'DATETIME'])
cursor.execute(*query)
datetimes.update(cursor)
return datetimes
@classmethod
def _history_states(cls):
return ['posted', 'paid', 'cancelled']
@classmethod
def set_number(cls, invoices):
numbered = [i for i in invoices if not i.number or not i.numbered_at]
super().set_number(invoices)
if numbered:
cls.write(numbered, {
'numbered_at': CurrentTimestamp(),
})
@classmethod
@ModelView.button
@Workflow.transition('draft')
def draft(cls, invoices):
super().draft(invoices)
cls.write(invoices, {
'numbered_at': None,
})
@classmethod
def copy(cls, invoices, default=None):
if default is None:
default = {}
else:
default = default.copy()
default.setdefault('numbered_at', None)
return super().copy(invoices, default=default)

View File

@@ -0,0 +1,32 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from sql.functions import CurrentTimestamp
from trytond.pool import PoolMeta
class PaymentTerm(metaclass=PoolMeta):
__name__ = 'account.invoice.payment_term'
_history = True
class PaymentTermLine(metaclass=PoolMeta):
__name__ = 'account.invoice.payment_term.line'
_history = True
class PaymentTermLineRelativeDelta(metaclass=PoolMeta):
__name__ = 'account.invoice.payment_term.line.delta'
_history = True
class RefreshInvoiceReport(metaclass=PoolMeta):
__name__ = 'account.invoice.refresh_invoice_report'
def transition_archive(self):
if records := [r for r in self.records if r.numbered_at]:
self.model.write(records, {
'numbered_at': CurrentTimestamp(),
})
return super().transition_archive()

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr "Data i Hora del historial"
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Numerat el"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr "Historisierungszeitpunkt"
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Rechnungsnummer vergeben um"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr "Fecha y hora del historial"
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Numerado el"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr "Date Heure de l'historique"
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Numéroté le"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr "Cronologia date e ora"
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Numerato a"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Numeris"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr "Geschiedenis DatumTijd"
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Genummerd op"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Numerowane"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr "Istoric DataTimp"
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr "Numerotat la"

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,11 @@
#
msgid ""
msgstr "Content-Type: text/plain; charset=utf-8\n"
msgctxt "field:account.invoice,history_datetime:"
msgid "History DateTime"
msgstr ""
msgctxt "field:account.invoice,numbered_at:"
msgid "Numbered At"
msgstr ""

View File

@@ -0,0 +1,18 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.pool import PoolMeta
class Party(metaclass=PoolMeta):
__name__ = 'party.party'
_history = True
class Address(metaclass=PoolMeta):
__name__ = 'party.address'
_history = True
class Identifier(metaclass=PoolMeta):
__name__ = 'party.identifier'
_history = True

View File

@@ -0,0 +1,2 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

View File

@@ -0,0 +1,72 @@
================================
Invoice Report Revision Scenario
================================
Imports::
>>> import datetime as dt
>>> from decimal import Decimal
>>> from proteus import Model, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.account_invoice.tests.tools import (
... set_fiscalyear_invoice_sequences)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertNotEqual
>>> today = dt.date.today()
Activate modules::
>>> config = activate_modules(
... 'account_invoice_history', create_company, create_chart)
>>> Invoice = Model.get('account.invoice')
>>> Journal = Model.get('account.journal')
>>> Move = Model.get('account.move')
>>> Party = Model.get('party.party')
>>> PaymentMethod = Model.get('account.invoice.payment.method')
>>> ProductCategory = Model.get('product.category')
>>> ProductTemplate = Model.get('product.template')
>>> ProductUom = Model.get('product.uom')
>>> Sequence = Model.get('ir.sequence')
Create fiscal year::
>>> fiscalyear = set_fiscalyear_invoice_sequences(
... create_fiscalyear())
>>> fiscalyear.click('create_period')
>>> period = fiscalyear.periods[0]
Get accounts::
>>> accounts = get_accounts()
Create party::
>>> party = Party(name="Party")
>>> party.save()
Post an invoice::
>>> invoice = Invoice()
>>> invoice.type = 'out'
>>> invoice.party = party
>>> invoice.invoice_date = today
>>> line = invoice.lines.new()
>>> line.account = accounts['revenue']
>>> line.quantity = 5
>>> line.unit_price = Decimal('20')
>>> invoice.click('post')
>>> invoice.state
'posted'
>>> numbered_at = invoice.numbered_at
Execute update invoice report wizard::
>>> refresh_invoice_report = Wizard(
... 'account.invoice.refresh_invoice_report', [invoice])
>>> assertNotEqual(invoice.numbered_at, numbered_at)

View File

@@ -0,0 +1,12 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.tests.test_tryton import ModuleTestCase
class AccountInvoiceHistoryTestCase(ModuleTestCase):
'Test AccountInvoiceHistory module'
module = 'account_invoice_history'
del ModuleTestCase

View File

@@ -0,0 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.tests.test_tryton import load_doc_tests
def load_tests(*args, **kwargs):
return load_doc_tests(__name__, __file__, *args, **kwargs)

View File

@@ -0,0 +1,17 @@
[tryton]
version=7.8.1
depends:
account_invoice
party
[register]
model:
party.Party
party.Address
party.Identifier
account.Invoice
account_invoice.PaymentTerm
account_invoice.PaymentTermLine
account_invoice.PaymentTermLineRelativeDelta
wizard:
account_invoice.RefreshInvoiceReport