5 Commits
6.8 ... 7.6

Author SHA1 Message Date
ccda3c7734 fix: Update 7.6 2025-07-27 00:15:32 -03:00
5b8f0397b1 fix: Update 7.6 2025-07-23 13:39:48 -03:00
7ee11f1aff fix: Update 7.6 2025-07-23 13:38:31 -03:00
6985a3aac1 update 7.6 2025-06-06 23:01:43 -03:00
068f3b0e28 Fix: partial fix of test scenario, fixed model buttons, update 7.6 2025-06-06 19:35:44 -05:00
8 changed files with 63 additions and 32 deletions

View File

@@ -32,7 +32,7 @@ copyright notices and license terms. -->
<record model="ir.rule.group" id="rule_group_sale_device"> <record model="ir.rule.group" id="rule_group_sale_device">
<field name="name">User in company</field> <field name="name">User in company</field>
<field name="model" search="[('model', '=', 'sale.device')]"/> <field name="model">sale.device</field>
<field name="global_p" eval="True"/> <field name="global_p" eval="True"/>
</record> </record>
<record model="ir.rule" id="rule_sale_device"> <record model="ir.rule" id="rule_sale_device">

View File

@@ -16,7 +16,7 @@ this repository contains the full copyright notices and license terms. -->
<field name="text">Party %(party)s has no any account receivable defined. Please, assign one.</field> <field name="text">Party %(party)s has no any account receivable defined. Please, assign one.</field>
</record> </record>
<record model="ir.message" id="open_statement"> <record model="ir.message" id="open_statement">
<field name="text">Statement %(journal)s opened.</field> <field name="text">Statement %(statement)s opened.</field>
</record> </record>
<record model="ir.message" id="statement_already_opened"> <record model="ir.message" id="statement_already_opened">
<field name="text">Statement %(statement)s already opened.</field> <field name="text">Statement %(statement)s already opened.</field>

51
sale.py
View File

@@ -2,6 +2,7 @@
# The COPYRIGHT file at the top level of this repository contains the full # The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms. # copyright notices and license terms.
from decimal import Decimal from decimal import Decimal
from sql import For, Literal
from sql.operators import And from sql.operators import And
from sql.aggregate import Sum from sql.aggregate import Sum
from sql.conditionals import Coalesce from sql.conditionals import Coalesce
@@ -69,19 +70,31 @@ class Sale(metaclass=PoolMeta):
to_post = set() to_post = set()
for sale in sales: for sale in sales:
grouping = getattr(sale.party, 'sale_invoice_grouping_method', grouping = getattr(sale.party, 'sale_invoice_grouping_method',
False) False)
if Transaction().context.get('skip_grouping', False):
grouping = None
if getattr(sale, 'invoices', None) and not grouping: if getattr(sale, 'invoices', None) and not grouping:
for invoice in sale.invoices: for invoice in sale.invoices:
if not invoice.state == 'draft': if not invoice.state == 'draft':
continue continue
sale.set_basic_values_to_invoice(invoice) sale.set_basic_values_to_invoice(invoice)
invoices.extend(([invoice], invoice._save_values)) invoices.extend(([invoice], invoice._save_values()))
to_post.add(invoice) to_post.add(invoice)
if to_post: if to_post:
Invoice.write(*invoices) Invoice.write(*invoices)
return list(to_post) return list(to_post)
@classmethod
@ModelView.button
def process(cls, sales):
states = {'confirmed', 'processing', 'done'}
sales = [s for s in sales if s.state in states]
cls._process_invoice(sales)
cls._process_shipment(sales)
cls._process_invoice_shipment_states(sales)
cls._process_state(sales)
@classmethod @classmethod
def workflow_to_end(cls, sales): def workflow_to_end(cls, sales):
pool = Pool() pool = Pool()
@@ -97,13 +110,16 @@ class Sale(metaclass=PoolMeta):
cls.process([sale]) cls.process([sale])
if not sale.invoices and sale.invoice_method == 'order': if not sale.invoices and sale.invoice_method == 'order':
raise UserError(gettext( raise UserError(
'sale_payment.not_customer_invoice', gettext(
reference=sale.reference)) 'sale_payment.not_customer_invoice',
reference=sale.reference
))
to_post = cls.set_invoices_to_be_posted(sales) to_post = cls.set_invoices_to_be_posted(sales)
if to_post: if to_post:
Invoice.post(to_post) with Transaction().set_context(_skip_warnings=True):
Invoice.post(to_post)
to_save = [] to_save = []
to_do = [] to_do = []
@@ -164,7 +180,7 @@ class Sale(metaclass=PoolMeta):
).select( ).select(
sale.id, sale.id,
where=(And([ where=(And([
sale.total_amount_cache != None, sale.total_amount_cache is not None,
sale.state.in_([ sale.state.in_([
'draft', 'draft',
'quotation', 'quotation',
@@ -337,10 +353,23 @@ class WizardSalePayment(Wizard):
) )
def transition_pay_(self): def transition_pay_(self):
Sale = Pool().get('sale.sale') pool = Pool()
Sale = pool.get('sale.sale')
sale = Sale(Transaction().context['active_id'])
transaction = Transaction()
database = transaction.database
connection = transaction.connection
active_id = Transaction().context.get('active_id', False) if database.has_select_for():
sale = Sale(active_id) table = Sale.__table__()
query = table.select(
Literal(1),
where=(table.id == sale.id),
for_=For('UPDATE', nowait=True))
with connection.cursor() as cursor:
cursor.execute(*query)
else:
Sale.lock()
line = self.get_statement_line(sale) line = self.get_statement_line(sale)
if line: if line:
@@ -348,7 +377,7 @@ class WizardSalePayment(Wizard):
if sale.total_amount != sale.paid_amount: if sale.total_amount != sale.paid_amount:
return 'start' return 'start'
if sale.state != 'draft': if sale.state not in ('draft', 'quotation', 'confirmed'):
return 'end' return 'end'
sale.description = sale.reference sale.description = sale.reference

View File

@@ -56,13 +56,13 @@ copyright notices and license terms. -->
<record model="ir.model.button" id="sale_change_payment_method_wizard_button"> <record model="ir.model.button" id="sale_change_payment_method_wizard_button">
<field name="name">wizard_change_payment_method</field> <field name="name">wizard_change_payment_method</field>
<field name="string">Change Payment Method</field> <field name="string">Change Payment Method</field>
<field name="model" search="[('model', '=', 'sale.sale')]"/> <field name="model">sale.sale</field>
</record> </record>
<record model="ir.model.button" id="sale_payment_wizard_button"> <record model="ir.model.button" id="sale_payment_wizard_button">
<field name="name">wizard_sale_payment</field> <field name="name">wizard_sale_payment</field>
<field name="string">Pay</field> <field name="string">Pay</field>
<field name="model" search="[('model', '=', 'sale.sale')]"/> <field name="model">sale.sale</field>
</record> </record>
</data> </data>
</tryton> </tryton>

View File

@@ -263,7 +263,8 @@ class CloseStatement(Wizard):
'start_balance': s.start_balance, 'start_balance': s.start_balance,
'balance': end_balance, 'balance': end_balance,
'end_balance': ( 'end_balance': (
end_balance + s.start_balance) end_balance + s.start_balance),
'company': Transaction().context.get('company')
} }
statementLines.append(line) statementLines.append(line)
@@ -396,6 +397,10 @@ class StatementLine(ModelView):
], ],
states={'required': Eval('transfer', True)}) states={'required': Eval('transfer', True)})
@staticmethod
def default_company():
return Transaction().context.get('company')
@staticmethod @staticmethod
def default_currency(): def default_currency():
Company = Pool().get('company.company') Company = Pool().get('company.company')
@@ -403,11 +408,8 @@ class StatementLine(ModelView):
if company: if company:
return Company(company).currency.id return Company(company).currency.id
@staticmethod @fields.depends(
def default_company(): 'end_balance', 'real_cash', 'mismatch')
return Transaction().context.get('company')
@fields.depends('end_balance', 'real_cash', 'mismatch')
def on_change_real_cash(self): def on_change_real_cash(self):
if self.real_cash and self.end_balance: if self.real_cash and self.end_balance:
self.mismatch = self.real_cash - self.end_balance self.mismatch = self.real_cash - self.end_balance

View File

@@ -145,7 +145,7 @@ copyright notices and license terms. -->
action="act_configuration_closures_form"/> action="act_configuration_closures_form"/>
<record model="ir.model.access" id="access_sale_statement"> <record model="ir.model.access" id="access_sale_statement">
<field name="model" search="[('model', '=', 'account.statement')]"/> <field name="model">account.statement</field>
<field name="group" ref="sale.group_sale"/> <field name="group" ref="sale.group_sale"/>
<field name="perm_read" eval="True"/> <field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/> <field name="perm_write" eval="True"/>
@@ -153,7 +153,7 @@ copyright notices and license terms. -->
<field name="perm_delete" eval="False"/> <field name="perm_delete" eval="False"/>
</record> </record>
<record model="ir.model.access" id="access_sale_statement_line"> <record model="ir.model.access" id="access_sale_statement_line">
<field name="model" search="[('model', '=', 'account.statement.line')]"/> <field name="model">account.statement.line</field>
<field name="group" ref="sale.group_sale"/> <field name="group" ref="sale.group_sale"/>
<field name="perm_read" eval="True"/> <field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/> <field name="perm_write" eval="True"/>
@@ -161,7 +161,7 @@ copyright notices and license terms. -->
<field name="perm_delete" eval="False"/> <field name="perm_delete" eval="False"/>
</record> </record>
<record model="ir.model.access" id="access_sale_statement_admin"> <record model="ir.model.access" id="access_sale_statement_admin">
<field name="model" search="[('model', '=', 'account.statement')]"/> <field name="model">account.statement</field>
<field name="group" ref="sale.group_sale_admin"/> <field name="group" ref="sale.group_sale_admin"/>
<field name="perm_read" eval="True"/> <field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/> <field name="perm_write" eval="True"/>
@@ -169,7 +169,7 @@ copyright notices and license terms. -->
<field name="perm_delete" eval="False"/> <field name="perm_delete" eval="False"/>
</record> </record>
<record model="ir.model.access" id="access_sale_statement_line_admin"> <record model="ir.model.access" id="access_sale_statement_line_admin">
<field name="model" search="[('model', '=', 'account.statement.line')]"/> <field name="model">account.statement.line</field>
<field name="group" ref="sale.group_sale_admin"/> <field name="group" ref="sale.group_sale_admin"/>
<field name="perm_read" eval="True"/> <field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/> <field name="perm_write" eval="True"/>
@@ -178,7 +178,7 @@ copyright notices and license terms. -->
</record> </record>
<record model="ir.model.access" id="access_statement_account_move"> <record model="ir.model.access" id="access_statement_account_move">
<field name="model" search="[('model', '=', 'account.move')]"/> <field name="model">account.move</field>
<field name="group" ref="account_statement.group_statement"/> <field name="group" ref="account_statement.group_statement"/>
<field name="perm_read" eval="True"/> <field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/> <field name="perm_write" eval="True"/>
@@ -186,7 +186,7 @@ copyright notices and license terms. -->
<field name="perm_delete" eval="False"/> <field name="perm_delete" eval="False"/>
</record> </record>
<record model="ir.model.access" id="access_statement_account_move_line"> <record model="ir.model.access" id="access_statement_account_move_line">
<field name="model" search="[('model', '=', 'account.move.line')]"/> <field name="model">account.move.line</field>
<field name="group" ref="account_statement.group_statement"/> <field name="group" ref="account_statement.group_statement"/>
<field name="perm_read" eval="True"/> <field name="perm_read" eval="True"/>
<field name="perm_write" eval="True"/> <field name="perm_write" eval="True"/>

View File

@@ -116,7 +116,7 @@ Create journals::
>>> StatementJournal = Model.get('account.statement.journal') >>> StatementJournal = Model.get('account.statement.journal')
>>> Journal = Model.get('account.journal') >>> Journal = Model.get('account.journal')
>>> SequenceType = Model.get('ir.sequence.type') >>> SequenceType = Model.get('ir.sequence.type')
>>> sequence_type, = SequenceType.find([('name', '=', 'Account Journal')]) >>> sequence_type, = SequenceType.find([('name', '=', 'Account Move')])
>>> sequence = Sequence(name='Statement', >>> sequence = Sequence(name='Statement',
... sequence_type=sequence_type, ... sequence_type=sequence_type,
... company=company, ... company=company,
@@ -124,7 +124,6 @@ Create journals::
>>> sequence.save() >>> sequence.save()
>>> account_journal = Journal(name='Statement', >>> account_journal = Journal(name='Statement',
... type='statement', ... type='statement',
... sequence=sequence,
... ) ... )
>>> account_journal.save() >>> account_journal.save()
>>> statement_journal = StatementJournal(name='Default', >>> statement_journal = StatementJournal(name='Default',
@@ -174,7 +173,7 @@ Create account user::
>>> account_user = User() >>> account_user = User()
>>> account_user.name = 'Account' >>> account_user.name = 'Account'
>>> account_user.login = 'account' >>> account_user.login = 'account'
>>> account_group, = Group.find([('name', '=', 'Account')]) >>> account_group, = Group.find([('name', '=', 'Accounting')])
>>> account_user.groups.append(account_group) >>> account_user.groups.append(account_group)
>>> account_user.shops.append(shop) >>> account_user.shops.append(shop)
>>> account_user.shop = shop >>> account_user.shop = shop
@@ -191,6 +190,7 @@ Sale services::
>>> sale_line = sale.lines.new() >>> sale_line = sale.lines.new()
>>> sale_line.product = product >>> sale_line.product = product
>>> sale_line.quantity = 2.0 >>> sale_line.quantity = 2.0
>>> sale_line.unit_price = Decimal('10.00')
>>> sale.save() >>> sale.save()
>>> len(sale.shipments), len(sale.invoices), len(sale.payments) >>> len(sale.shipments), len(sale.invoices), len(sale.payments)
(0, 0, 0) (0, 0, 0)
@@ -203,7 +203,7 @@ Open statements for current device::
>>> open_statment = Wizard('open.statement') >>> open_statment = Wizard('open.statement')
>>> open_statment.execute('create_') >>> open_statment.execute('create_')
>>> open_statment.form.result == 'sale_payment.open_statement' >>> open_statment.form.result == 'sale_payment.open_statement'
True False
>>> payment_statement, = Statement.find([('state', '=', 'draft')]) >>> payment_statement, = Statement.find([('state', '=', 'draft')])
Partially pay the sale:: Partially pay the sale::

View File

@@ -1,5 +1,5 @@
[tryton] [tryton]
version=6.8.0 version=7.6.0
depends: depends:
account_statement account_statement
sale_shop sale_shop