Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ccda3c7734 | |||
| 5b8f0397b1 | |||
| 7ee11f1aff | |||
| 6985a3aac1 | |||
| 068f3b0e28 |
@@ -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">
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
45
sale.py
45
sale.py
@@ -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
|
||||||
@@ -70,18 +71,30 @@ class Sale(metaclass=PoolMeta):
|
|||||||
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,12 +110,15 @@ 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(
|
||||||
|
gettext(
|
||||||
'sale_payment.not_customer_invoice',
|
'sale_payment.not_customer_invoice',
|
||||||
reference=sale.reference))
|
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:
|
||||||
|
with Transaction().set_context(_skip_warnings=True):
|
||||||
Invoice.post(to_post)
|
Invoice.post(to_post)
|
||||||
|
|
||||||
to_save = []
|
to_save = []
|
||||||
@@ -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
|
||||||
|
|||||||
4
sale.xml
4
sale.xml
@@ -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>
|
||||||
|
|||||||
14
statement.py
14
statement.py
@@ -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
|
||||||
|
|||||||
@@ -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"/>
|
||||||
|
|||||||
@@ -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::
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
[tryton]
|
[tryton]
|
||||||
version=6.8.0
|
version=7.6.0
|
||||||
depends:
|
depends:
|
||||||
account_statement
|
account_statement
|
||||||
sale_shop
|
sale_shop
|
||||||
|
|||||||
Reference in New Issue
Block a user