Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0ea115365a |
@@ -8,9 +8,9 @@ from . import statement
|
|||||||
from . import user
|
from . import user
|
||||||
from . import configuration_statement
|
from . import configuration_statement
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
Pool.register(
|
Pool.register(
|
||||||
|
configuration_statement.Configuration,
|
||||||
statement.Journal,
|
statement.Journal,
|
||||||
statement.Statement,
|
statement.Statement,
|
||||||
statement.Line,
|
statement.Line,
|
||||||
@@ -27,7 +27,6 @@ def register():
|
|||||||
statement.CloseStatementStart,
|
statement.CloseStatementStart,
|
||||||
statement.CloseStatementDone,
|
statement.CloseStatementDone,
|
||||||
statement.PayInvoiceSupplierStart,
|
statement.PayInvoiceSupplierStart,
|
||||||
configuration_statement.Configuration,
|
|
||||||
module='sale_payment', type_='model')
|
module='sale_payment', type_='model')
|
||||||
Pool.register(
|
Pool.register(
|
||||||
sale.WizardSalePayment,
|
sale.WizardSalePayment,
|
||||||
|
|||||||
@@ -2,41 +2,41 @@
|
|||||||
# this repository contains the full copyright notices and license terms.
|
# this repository contains the full copyright notices and license terms.
|
||||||
from trytond.model import ModelView, ModelSQL, ModelSingleton, fields
|
from trytond.model import ModelView, ModelSQL, ModelSingleton, fields
|
||||||
from trytond.modules.currency.fields import Monetary
|
from trytond.modules.currency.fields import Monetary
|
||||||
# from trytond.pyson import Eval
|
from trytond.pyson import Eval
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
from trytond.pool import Pool
|
from trytond.pool import Pool
|
||||||
|
|
||||||
|
|
||||||
class Configuration(ModelSingleton, ModelView, ModelSQL):
|
class Configuration(ModelSingleton, ModelView, ModelSQL):
|
||||||
"Configuration Chas Closures"
|
"Configuration Chas Closures"
|
||||||
__name__ = 'sale.cash_closures'
|
__name__ = 'sale.cash_closures'
|
||||||
|
|
||||||
# company = fields.Many2One(
|
company = fields.Many2One(
|
||||||
# 'company.company', "Company", required=True)
|
'company.company', "Company", required=True)
|
||||||
currency = fields.Many2One(
|
currency = fields.Many2One(
|
||||||
'currency.currency', "Currency")
|
'currency.currency', "Currency")
|
||||||
|
|
||||||
mismatch_limit = Monetary(
|
mismatch_limit = Monetary(
|
||||||
"Mismatch Limit", currency='currency', digits='currency')
|
"Mismatch Limit", currency='currency', digits='currency')
|
||||||
account_mismatch_charge = fields.Many2One(
|
account_mismatch_charge = fields.Many2One('account.account', "Account Mismatch Charge",
|
||||||
'account.account', "Account Mismatch Charge",
|
domain=[
|
||||||
domain=[
|
('company', '=', Eval('company', 0)),
|
||||||
('type', '!=', None),
|
('type', '!=', None),
|
||||||
('closed', '!=', True),
|
('closed', '!=', True),
|
||||||
],)
|
],)
|
||||||
account_mismatch_positive = fields.Many2One(
|
|
||||||
'account.account', "Account Mismatch Positivo",
|
|
||||||
domain=[
|
|
||||||
('type', '!=', None),
|
|
||||||
('closed', '!=', True),
|
|
||||||
],)
|
|
||||||
|
|
||||||
@classmethod
|
account_mismatch_positive = fields.Many2One('account.account', "Account Mismatch Positivo",
|
||||||
def default_currency(cls):
|
domain=[
|
||||||
|
('company', '=', Eval('company', 0)),
|
||||||
|
('type', '!=', None),
|
||||||
|
('closed', '!=', True),
|
||||||
|
],)
|
||||||
|
@staticmethod
|
||||||
|
def default_currency():
|
||||||
Company = Pool().get('company.company')
|
Company = Pool().get('company.company')
|
||||||
company = Transaction().context.get('company')
|
company = Transaction().context.get('company')
|
||||||
if company:
|
if company:
|
||||||
return Company(company).currency.id
|
return Company(company).currency.id
|
||||||
|
|
||||||
# @classmethod
|
@staticmethod
|
||||||
# def default_company(cls):
|
def default_company():
|
||||||
# return Transaction().context.get('company')
|
return Transaction().context.get('company')
|
||||||
|
|||||||
@@ -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">sale.device</field>
|
<field name="model" search="[('model', '=', 'sale.device')]"/>
|
||||||
<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 %(statement)s opened.</field>
|
<field name="text">Statement %(journal)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>
|
||||||
|
|||||||
80
sale.py
80
sale.py
@@ -2,8 +2,6 @@
|
|||||||
# 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.aggregate import Sum
|
from sql.aggregate import Sum
|
||||||
from sql.conditionals import Coalesce
|
from sql.conditionals import Coalesce
|
||||||
|
|
||||||
@@ -70,31 +68,19 @@ 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()
|
||||||
@@ -110,16 +96,13 @@ 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(
|
raise UserError(gettext(
|
||||||
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 = []
|
||||||
to_do = []
|
to_do = []
|
||||||
@@ -179,18 +162,16 @@ class Sale(metaclass=PoolMeta):
|
|||||||
condition=(sale.id == payline.sale)
|
condition=(sale.id == payline.sale)
|
||||||
).select(
|
).select(
|
||||||
sale.id,
|
sale.id,
|
||||||
where=(And([
|
where=((sale.total_amount_cache != None) &
|
||||||
sale.total_amount_cache is not None,
|
(sale.state.in_([
|
||||||
sale.state.in_([
|
'draft',
|
||||||
'draft',
|
'quotation',
|
||||||
'quotation',
|
'confirmed',
|
||||||
'confirmed',
|
'processing',
|
||||||
'processing',
|
'done']))),
|
||||||
'done'])])),
|
|
||||||
group_by=(sale.id),
|
group_by=(sale.id),
|
||||||
having=(Operator(
|
having=(Operator(sale.total_amount_cache -
|
||||||
sale.total_amount_cache - Sum(
|
Sum(Coalesce(payline.amount, 0)), value)
|
||||||
Coalesce(payline.amount, 0)), value)
|
|
||||||
))
|
))
|
||||||
return [('id', 'in', query)]
|
return [('id', 'in', query)]
|
||||||
|
|
||||||
@@ -215,17 +196,17 @@ class Sale(metaclass=PoolMeta):
|
|||||||
class ChangePaymentMethodForm(ModelView):
|
class ChangePaymentMethodForm(ModelView):
|
||||||
'Change Payments Method form'
|
'Change Payments Method form'
|
||||||
__name__ = 'sale.change_payment_method.form'
|
__name__ = 'sale.change_payment_method.form'
|
||||||
|
|
||||||
sale = fields.Many2One('sale.sale', "Sale", required=True)
|
sale = fields.Many2One('sale.sale', "Sale", required=True)
|
||||||
statement = fields.Many2One('account.statement', 'Statement Journal',
|
statement = fields.Many2One('account.statement', 'Statement Journal',
|
||||||
domain=[
|
domain=[
|
||||||
('id', 'in', Eval('statements', [])),
|
('id', 'in', Eval('statements', [])),
|
||||||
], required=True)
|
],
|
||||||
|
depends=['journals'], required=True)
|
||||||
statements = fields.One2Many('account.statement', None,
|
statements = fields.One2Many('account.statement', None,
|
||||||
'Allowed Statement', readonly=True)
|
'Allowed Statement', readonly=True)
|
||||||
payment = fields.Many2One(
|
payment = fields.Many2One(
|
||||||
'account.statement.line', "Payment", required=True,
|
'account.statement.line', "Payment", required=True,
|
||||||
domain=[('sale', '=', Eval('sale'))])
|
domain=[('sale.id', '=', Eval('sale'))])
|
||||||
|
|
||||||
|
|
||||||
class ChangePaymentMethod(Wizard):
|
class ChangePaymentMethod(Wizard):
|
||||||
@@ -353,23 +334,10 @@ class WizardSalePayment(Wizard):
|
|||||||
)
|
)
|
||||||
|
|
||||||
def transition_pay_(self):
|
def transition_pay_(self):
|
||||||
pool = Pool()
|
Sale = Pool().get('sale.sale')
|
||||||
Sale = pool.get('sale.sale')
|
|
||||||
sale = Sale(Transaction().context['active_id'])
|
|
||||||
transaction = Transaction()
|
|
||||||
database = transaction.database
|
|
||||||
connection = transaction.connection
|
|
||||||
|
|
||||||
if database.has_select_for():
|
active_id = Transaction().context.get('active_id', False)
|
||||||
table = Sale.__table__()
|
sale = Sale(active_id)
|
||||||
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:
|
||||||
@@ -377,7 +345,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 not in ('draft', 'quotation', 'confirmed'):
|
if sale.state != 'draft':
|
||||||
return 'end'
|
return 'end'
|
||||||
|
|
||||||
sale.description = sale.reference
|
sale.description = sale.reference
|
||||||
@@ -411,8 +379,8 @@ class WizardSaleReconcile(Wizard):
|
|||||||
if not payment.move:
|
if not payment.move:
|
||||||
continue
|
continue
|
||||||
for line in payment.move.lines:
|
for line in payment.move.lines:
|
||||||
if (not line.reconciliation and (
|
if (not line.reconciliation and
|
||||||
line.account == account)):
|
line.account == account):
|
||||||
lines.append(line)
|
lines.append(line)
|
||||||
amount += line.debit - line.credit
|
amount += line.debit - line.credit
|
||||||
if lines and amount == Decimal('0.0'):
|
if lines and amount == Decimal('0.0'):
|
||||||
|
|||||||
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">sale.sale</field>
|
<field name="model" search="[('model', '=', 'sale.sale')]"/>
|
||||||
</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">sale.sale</field>
|
<field name="model" search="[('model', '=', 'sale.sale')]"/>
|
||||||
</record>
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</tryton>
|
</tryton>
|
||||||
|
|||||||
157
setup.py
157
setup.py
@@ -1,70 +1,112 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python
|
||||||
import io
|
# encoding: utf-8
|
||||||
import os
|
|
||||||
|
from setuptools import setup
|
||||||
import re
|
import re
|
||||||
|
import os
|
||||||
|
import io
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
|
|
||||||
from setuptools import find_packages, setup
|
MODULE = 'sale_payment'
|
||||||
|
PREFIX = 'trytonspain'
|
||||||
MODULE2PREFIX = {}
|
MODULE2PREFIX = {'sale_shop': 'trytonzz'}
|
||||||
|
OWNER = {
|
||||||
|
'nantic':'NaN-tic',
|
||||||
|
'trytonzz':'nanticzz',
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def read(fname):
|
def read(fname):
|
||||||
content = io.open(
|
return io.open(
|
||||||
os.path.join(os.path.dirname(__file__), fname),
|
os.path.join(os.path.dirname(__file__), fname),
|
||||||
'r', encoding='utf-8').read()
|
'r', encoding='utf-8').read()
|
||||||
content = re.sub(
|
|
||||||
r'(?m)^\.\. toctree::\r?\n((^$|^\s.*$)\r?\n)*', '', content)
|
|
||||||
return content
|
|
||||||
|
|
||||||
|
|
||||||
def get_require_version(name):
|
def get_require_version(name):
|
||||||
require = '%s >= %s.%s, < %s.%s'
|
if minor_version % 2:
|
||||||
|
require = '%s >= %s.%s.dev0, < %s.%s'
|
||||||
|
else:
|
||||||
|
require = '%s >= %s.%s, < %s.%s'
|
||||||
require %= (name, major_version, minor_version,
|
require %= (name, major_version, minor_version,
|
||||||
major_version, minor_version + 1)
|
major_version, minor_version + 1)
|
||||||
return require
|
return require
|
||||||
|
|
||||||
|
def get_requires(depends='depends'):
|
||||||
|
requires = []
|
||||||
|
for dep in info.get(depends, []):
|
||||||
|
if not re.match(r'(ir|res)(\W|$)', dep):
|
||||||
|
prefix = MODULE2PREFIX.get(dep, 'trytond')
|
||||||
|
owner = OWNER.get(prefix, prefix)
|
||||||
|
if prefix == 'trytond':
|
||||||
|
requires.append(get_require_version('%s_%s' % (prefix, dep)))
|
||||||
|
else:
|
||||||
|
requires.append(
|
||||||
|
'%(prefix)s-%(dep)s@git+https://github.com/%(owner)s/'
|
||||||
|
'trytond-%(dep)s.git@%(branch)s'
|
||||||
|
'#egg=%(prefix)s-%(dep)s-%(series)s'%{
|
||||||
|
'prefix': prefix,
|
||||||
|
'owner': owner,
|
||||||
|
'dep':dep,
|
||||||
|
'branch': branch,
|
||||||
|
'series': series,})
|
||||||
|
|
||||||
|
return requires
|
||||||
|
|
||||||
config = ConfigParser()
|
config = ConfigParser()
|
||||||
config.read_file(open(os.path.join(os.path.dirname(__file__), 'tryton.cfg')))
|
config.readfp(open('tryton.cfg'))
|
||||||
info = dict(config.items('tryton'))
|
info = dict(config.items('tryton'))
|
||||||
for key in ('depends', 'extras_depend', 'xml'):
|
for key in ('depends', 'extras_depend', 'xml'):
|
||||||
if key in info:
|
if key in info:
|
||||||
info[key] = info[key].strip().splitlines()
|
info[key] = info[key].strip().splitlines()
|
||||||
|
|
||||||
version = info.get('version', '0.0.1')
|
version = info.get('version', '0.0.1')
|
||||||
major_version, minor_version, _ = version.split('.', 2)
|
major_version, minor_version, _ = version.split('.', 2)
|
||||||
major_version = int(major_version)
|
major_version = int(major_version)
|
||||||
minor_version = int(minor_version)
|
minor_version = int(minor_version)
|
||||||
name = 'trytondo_sale_payment'
|
|
||||||
|
|
||||||
requires = []
|
requires = []
|
||||||
for dep in info.get('depends', []):
|
|
||||||
if not re.match(r'(ir|res)(\W|$)', dep):
|
|
||||||
prefix = MODULE2PREFIX.get(dep, 'trytond')
|
|
||||||
requires.append(get_require_version('%s_%s' % (prefix, dep)))
|
|
||||||
requires.append(get_require_version('trytond'))
|
|
||||||
|
|
||||||
tests_require = [get_require_version('proteus')]
|
series = '%s.%s' % (major_version, minor_version)
|
||||||
|
if minor_version % 2:
|
||||||
|
branch = 'master'
|
||||||
|
else:
|
||||||
|
branch = series
|
||||||
|
|
||||||
setup(name=name,
|
requires += get_requires('depends')
|
||||||
|
|
||||||
|
tests_require = [
|
||||||
|
get_require_version('proteus'),
|
||||||
|
|
||||||
|
]
|
||||||
|
tests_require += get_requires('extras_depend')
|
||||||
|
requires += [get_require_version('trytond_account_statement')]
|
||||||
|
|
||||||
|
dependency_links = []
|
||||||
|
|
||||||
|
if minor_version % 2:
|
||||||
|
# Add development index for testing with proteus
|
||||||
|
dependency_links.append('https://trydevpi.tryton.org/')
|
||||||
|
|
||||||
|
setup(name='%s_%s' % (PREFIX, MODULE),
|
||||||
version=version,
|
version=version,
|
||||||
description='Fork NaNtic sale_payment',
|
description='',
|
||||||
long_description=read('README.rst'),
|
long_description=read('README'),
|
||||||
author='OneCluster',
|
author='trytonspain',
|
||||||
author_email='info@onecluster.org',
|
url='http://www.nan-tic.com/',
|
||||||
url='http://www.tryton.org/',
|
download_url='https://github.com:trytonspain/trytond-sale_payment',
|
||||||
keywords='',
|
package_dir={'trytond.modules.%s' % MODULE: '.'},
|
||||||
package_dir={'trytond.modules.sale_payment': '.'},
|
packages=[
|
||||||
packages=(
|
'trytond.modules.%s' % MODULE,
|
||||||
['trytond.modules.sale_payment']
|
'trytond.modules.%s.tests' % MODULE,
|
||||||
+ ['trytond.modules.sale_payment.%s' % p
|
],
|
||||||
for p in find_packages()]
|
|
||||||
),
|
|
||||||
package_data={
|
package_data={
|
||||||
'trytond.modules.sale_payment': (info.get('xml', [])
|
'trytond.modules.%s' % MODULE: (info.get('xml', [])
|
||||||
+ ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
|
+ ['tryton.cfg', 'locale/*.po', 'tests/*.rst', 'view/*.xml',
|
||||||
'icons/*.svg', 'tests/*.rst', 'tests/*.json']),
|
'icons/*.svg']),
|
||||||
},
|
},
|
||||||
|
project_urls = {
|
||||||
|
"Source Code": 'https://github.com:trytonspain/trytond-sale_payment'
|
||||||
|
},
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 5 - Production/Stable',
|
'Development Status :: 5 - Production/Stable',
|
||||||
'Environment :: Plugins',
|
'Environment :: Plugins',
|
||||||
@@ -72,48 +114,25 @@ setup(name=name,
|
|||||||
'Intended Audience :: Developers',
|
'Intended Audience :: Developers',
|
||||||
'Intended Audience :: Financial and Insurance Industry',
|
'Intended Audience :: Financial and Insurance Industry',
|
||||||
'Intended Audience :: Legal Industry',
|
'Intended Audience :: Legal Industry',
|
||||||
'License :: OSI Approved :: '
|
'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||||
'GNU General Public License v3 or later (GPLv3+)',
|
|
||||||
'Natural Language :: Bulgarian',
|
|
||||||
'Natural Language :: Catalan',
|
'Natural Language :: Catalan',
|
||||||
'Natural Language :: Chinese (Simplified)',
|
|
||||||
'Natural Language :: Czech',
|
|
||||||
'Natural Language :: Dutch',
|
|
||||||
'Natural Language :: English',
|
'Natural Language :: English',
|
||||||
'Natural Language :: Finnish',
|
|
||||||
'Natural Language :: French',
|
|
||||||
'Natural Language :: German',
|
|
||||||
'Natural Language :: Hungarian',
|
|
||||||
'Natural Language :: Indonesian',
|
|
||||||
'Natural Language :: Italian',
|
|
||||||
'Natural Language :: Persian',
|
|
||||||
'Natural Language :: Polish',
|
|
||||||
'Natural Language :: Portuguese (Brazilian)',
|
|
||||||
'Natural Language :: Romanian',
|
|
||||||
'Natural Language :: Russian',
|
|
||||||
'Natural Language :: Slovenian',
|
|
||||||
'Natural Language :: Spanish',
|
'Natural Language :: Spanish',
|
||||||
'Natural Language :: Turkish',
|
|
||||||
'Natural Language :: Ukrainian',
|
|
||||||
'Operating System :: OS Independent',
|
'Operating System :: OS Independent',
|
||||||
'Programming Language :: Python :: 3',
|
'Programming Language :: Python :: 3.6',
|
||||||
'Programming Language :: Python :: 3.8',
|
'Programming Language :: Python :: 3.7',
|
||||||
'Programming Language :: Python :: 3.9',
|
|
||||||
'Programming Language :: Python :: 3.10',
|
|
||||||
'Programming Language :: Python :: 3.11',
|
|
||||||
'Programming Language :: Python :: 3.12',
|
|
||||||
'Programming Language :: Python :: Implementation :: CPython',
|
|
||||||
'Topic :: Office/Business',
|
'Topic :: Office/Business',
|
||||||
],
|
],
|
||||||
license='GPL-3',
|
license='GPL-3',
|
||||||
python_requires='>=3.8',
|
install_requires=requires,
|
||||||
# install_requires=requires,
|
dependency_links=dependency_links,
|
||||||
extras_require={
|
|
||||||
'test': tests_require,
|
|
||||||
},
|
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
entry_points="""
|
entry_points="""
|
||||||
[trytond.modules]
|
[trytond.modules]
|
||||||
sale_payment = trytond.modules.sale_payment
|
%s = trytond.modules.%s
|
||||||
""", # noqa: E501
|
""" % (MODULE, MODULE),
|
||||||
|
test_suite='tests',
|
||||||
|
test_loader='trytond.test_loader:Loader',
|
||||||
|
tests_require=tests_require,
|
||||||
|
|
||||||
)
|
)
|
||||||
129
statement.py
129
statement.py
@@ -4,8 +4,7 @@
|
|||||||
from trytond.model import fields, ModelView
|
from trytond.model import fields, ModelView
|
||||||
from trytond.pool import Pool, PoolMeta
|
from trytond.pool import Pool, PoolMeta
|
||||||
from trytond.transaction import Transaction
|
from trytond.transaction import Transaction
|
||||||
from trytond.wizard import (
|
from trytond.wizard import Button, StateTransition, StateAction, StateView, Wizard
|
||||||
Button, StateTransition, StateAction, StateView, Wizard)
|
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
from trytond.i18n import gettext
|
from trytond.i18n import gettext
|
||||||
from trytond.modules.currency.fields import Monetary
|
from trytond.modules.currency.fields import Monetary
|
||||||
@@ -53,7 +52,7 @@ class Statement(metaclass=PoolMeta):
|
|||||||
|
|
||||||
query = statement.join(
|
query = statement.join(
|
||||||
journal, condition=statement.journal == journal.id).join(
|
journal, condition=statement.journal == journal.id).join(
|
||||||
device_journal,
|
device_journal,
|
||||||
condition=journal.id == device_journal.journal).join(
|
condition=journal.id == device_journal.journal).join(
|
||||||
device, condition=device_journal.device == device.id).join(
|
device, condition=device_journal.device == device.id).join(
|
||||||
user, condition=device.id == user.sale_device).select(
|
user, condition=device.id == user.sale_device).select(
|
||||||
@@ -122,7 +121,6 @@ class OpenStatementStart(ModelView):
|
|||||||
'Open Statement'
|
'Open Statement'
|
||||||
__name__ = 'open.statement.start'
|
__name__ = 'open.statement.start'
|
||||||
|
|
||||||
|
|
||||||
class OpenStatementDone(ModelView):
|
class OpenStatementDone(ModelView):
|
||||||
'Open Statement'
|
'Open Statement'
|
||||||
__name__ = 'open.statement.done'
|
__name__ = 'open.statement.done'
|
||||||
@@ -174,8 +172,7 @@ class OpenStatement(Wizard):
|
|||||||
for journal in device.journals:
|
for journal in device.journals:
|
||||||
if journal not in journals_of_draft_statements:
|
if journal not in journals_of_draft_statements:
|
||||||
values = {
|
values = {
|
||||||
'name': '%s - %s' % (
|
'name': '%s - %s' % (device.rec_name, journal.rec_name),
|
||||||
device.rec_name, journal.rec_name),
|
|
||||||
'journal': journal.id,
|
'journal': journal.id,
|
||||||
'company': user.company.id,
|
'company': user.company.id,
|
||||||
'start_balance': start_balances.get(journal.id,
|
'start_balance': start_balances.get(journal.id,
|
||||||
@@ -188,10 +185,8 @@ class OpenStatement(Wizard):
|
|||||||
results.append(gettext('sale_payment.open_statement',
|
results.append(gettext('sale_payment.open_statement',
|
||||||
statement=journal.rec_name))
|
statement=journal.rec_name))
|
||||||
else:
|
else:
|
||||||
results.append(
|
results.append(gettext('sale_payment.statement_already_opened',
|
||||||
gettext(
|
statement=journal.rec_name))
|
||||||
'sale_payment.statement_already_opened',
|
|
||||||
statement=journal.rec_name))
|
|
||||||
statements.extend(Statement.create(vlist))
|
statements.extend(Statement.create(vlist))
|
||||||
self.result = '\n'.join(results)
|
self.result = '\n'.join(results)
|
||||||
else:
|
else:
|
||||||
@@ -228,6 +223,7 @@ class CloseStatement(Wizard):
|
|||||||
Button('Done', 'end', 'tryton-ok', default=True),
|
Button('Done', 'end', 'tryton-ok', default=True),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
def default_done(self, fields):
|
def default_done(self, fields):
|
||||||
return {
|
return {
|
||||||
'result': self.result,
|
'result': self.result,
|
||||||
@@ -236,7 +232,7 @@ class CloseStatement(Wizard):
|
|||||||
def default_start(self, fields):
|
def default_start(self, fields):
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
User = pool.get('res.user')
|
User = pool.get('res.user')
|
||||||
# StatementLine = pool.get('statement.line')
|
StatementLine = pool.get('statement.line')
|
||||||
Statement = pool.get('account.statement')
|
Statement = pool.get('account.statement')
|
||||||
statementLines = []
|
statementLines = []
|
||||||
user = Transaction().user
|
user = Transaction().user
|
||||||
@@ -262,9 +258,7 @@ class CloseStatement(Wizard):
|
|||||||
'journal': s.journal.id,
|
'journal': s.journal.id,
|
||||||
'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)
|
||||||
|
|
||||||
@@ -311,10 +305,10 @@ class CloseStatement(Wizard):
|
|||||||
if account and transfer:
|
if account and transfer:
|
||||||
end_balance = abs(end_balance) - abs(transfer)
|
end_balance = abs(end_balance) - abs(transfer)
|
||||||
statement.end_balance = end_balance
|
statement.end_balance = end_balance
|
||||||
# lines = statement.lines
|
lines = statement.lines
|
||||||
conciliation = tuple([StatementLine(
|
conciliation = tuple([StatementLine(
|
||||||
date=datetime.today().date(),
|
date=datetime.today().date(),
|
||||||
amount=abs(transfer) * -1,
|
amount= abs(transfer)*-1,
|
||||||
account=account.id)]
|
account=account.id)]
|
||||||
)
|
)
|
||||||
statement.lines = statement.lines + conciliation
|
statement.lines = statement.lines + conciliation
|
||||||
@@ -322,22 +316,17 @@ class CloseStatement(Wizard):
|
|||||||
if mismatch and mismatch.real > 0:
|
if mismatch and mismatch.real > 0:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if config.mismatch_limit and (
|
if (config.mismatch_limit and config.account_mismatch_charge):
|
||||||
config.account_mismatch_charge):
|
if mismatch and (abs(mismatch) >= abs(config.mismatch_limit.real)):
|
||||||
if mismatch and (abs(mismatch) >= abs(
|
lines = statement.lines
|
||||||
config.mismatch_limit.real)):
|
if employee_party == None:
|
||||||
# lines = statement.lines
|
raise UserError(str("Debe definir un Empleado para el Usuario."))
|
||||||
if employee_party is None:
|
|
||||||
raise UserError(str(
|
|
||||||
"Debe definir un Empleado para el Usuario."
|
|
||||||
))
|
|
||||||
conciliation_mismatch = tuple([StatementLine(
|
conciliation_mismatch = tuple([StatementLine(
|
||||||
date=datetime.today().date(),
|
date=datetime.today().date(),
|
||||||
amount=mismatch,
|
amount=mismatch,
|
||||||
account=config.account_mismatch_charge.id)]
|
account=config.account_mismatch_charge.id)]
|
||||||
)
|
)
|
||||||
statement.lines =\
|
statement.lines = statement.lines + conciliation_mismatch
|
||||||
statement.lines + conciliation_mismatch
|
|
||||||
end_balance = abs(end_balance) - abs(mismatch)
|
end_balance = abs(end_balance) - abs(mismatch)
|
||||||
|
|
||||||
statement.end_balance = end_balance
|
statement.end_balance = end_balance
|
||||||
@@ -346,10 +335,8 @@ class CloseStatement(Wizard):
|
|||||||
results.append(gettext('sale_payment.close_statement',
|
results.append(gettext('sale_payment.close_statement',
|
||||||
statement=statement.rec_name))
|
statement=statement.rec_name))
|
||||||
elif statement:
|
elif statement:
|
||||||
results.append(
|
results.append(gettext('sale_payment.statement_already_closed',
|
||||||
gettext(
|
statement=statement.rec_name))
|
||||||
'sale_payment.statement_already_closed',
|
|
||||||
statement=statement.rec_name))
|
|
||||||
else:
|
else:
|
||||||
results.append(gettext('sale_payment.not_statement_found',
|
results.append(gettext('sale_payment.not_statement_found',
|
||||||
journal=journal.rec_name))
|
journal=journal.rec_name))
|
||||||
@@ -375,31 +362,24 @@ class StatementLine(ModelView):
|
|||||||
currency = fields.Many2One(
|
currency = fields.Many2One(
|
||||||
'currency.currency', "Currency")
|
'currency.currency', "Currency")
|
||||||
start_balance = Monetary(
|
start_balance = Monetary(
|
||||||
"Start Balance", currency='currency', digits='currency',
|
"Start Balance", currency='currency', digits='currency', states=_states)
|
||||||
states=_states)
|
|
||||||
balance = Monetary(
|
balance = Monetary(
|
||||||
"Balance", currency='currency', digits='currency', states=_states)
|
"Balance", currency='currency', digits='currency', states=_states)
|
||||||
end_balance = Monetary(
|
end_balance = Monetary(
|
||||||
"End Balance", currency='currency', digits='currency',
|
"End Balance", currency='currency', digits='currency', readonly=True)
|
||||||
readonly=True)
|
|
||||||
transfer = Monetary(
|
transfer = Monetary(
|
||||||
"Transfer", currency='currency', digits='currency')
|
"Transfer", currency='currency', digits='currency')
|
||||||
real_cash = Monetary(
|
real_cash = Monetary(
|
||||||
"Real Cash", currency='currency', digits='currency')
|
"Real Cash", currency='currency', digits='currency')
|
||||||
mismatch = Monetary(
|
mismatch = Monetary(
|
||||||
"Mismatch", currency='currency', digits='currency', readonly=True)
|
"Mismatch", currency='currency', digits='currency', readonly=True)
|
||||||
account = fields.Many2One(
|
account = fields.Many2One('account.account', "Account",
|
||||||
'account.account', "Account",
|
domain=[
|
||||||
domain=[
|
('company', '=', Eval('company', 0)),
|
||||||
('company', '=', Eval('company', 0)),
|
('type', '!=', None),
|
||||||
('type', '!=', None),
|
('closed', '!=', True),
|
||||||
('closed', '!=', True),
|
],
|
||||||
],
|
states={'required': If(Eval('transfer', True), True)})
|
||||||
states={'required': Eval('transfer', True)})
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def default_company():
|
|
||||||
return Transaction().context.get('company')
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def default_currency():
|
def default_currency():
|
||||||
@@ -408,34 +388,31 @@ class StatementLine(ModelView):
|
|||||||
if company:
|
if company:
|
||||||
return Company(company).currency.id
|
return Company(company).currency.id
|
||||||
|
|
||||||
@fields.depends(
|
@staticmethod
|
||||||
'end_balance', 'real_cash', 'mismatch')
|
def default_company():
|
||||||
def on_change_real_cash(self):
|
return Transaction().context.get('company')
|
||||||
if self.real_cash and self.end_balance:
|
|
||||||
self.mismatch = self.real_cash - self.end_balance
|
|
||||||
|
|
||||||
|
@fields.depends('end_balance', 'real_cash', 'mismatch')
|
||||||
|
def on_change_real_cash(self):
|
||||||
|
self.mismatch = self.real_cash - self.end_balance
|
||||||
|
|
||||||
class PayInvoiceSupplierStart(ModelView):
|
class PayInvoiceSupplierStart(ModelView):
|
||||||
'Payment Invoice To Supplier'
|
'Payment Invoice To Supplier'
|
||||||
__name__ = 'pay_invoice.statement.start'
|
__name__ = 'pay_invoice.statement.start'
|
||||||
|
|
||||||
invoice_to_pay = fields.One2Many(
|
invoice_to_pay = fields.One2Many('line_invoice.pay', None, "Invoice To Pay")
|
||||||
'line_invoice.pay', None, "Invoice To Pay")
|
|
||||||
|
|
||||||
|
|
||||||
class PayInvoiceSupplier(Wizard):
|
class PayInvoiceSupplier(Wizard):
|
||||||
'Payment Invoice To Supplier'
|
'Payment Invoice To Supplier'
|
||||||
__name__ = 'pay_invoice.statement'
|
__name__ = 'pay_invoice.statement'
|
||||||
|
|
||||||
start = StateView(
|
start = StateView('pay_invoice.statement.start',
|
||||||
'pay_invoice.statement.start',
|
'sale_payment.pay_invoice_statement_start', [
|
||||||
'sale_payment.pay_invoice_statement_start', [
|
Button('Cancel', 'end', 'tryton-cancel'),
|
||||||
Button('Cancel', 'end', 'tryton-cancel'),
|
Button('Pay', 'pay', 'tryton-ok', default=True),
|
||||||
Button('Pay', 'pay', 'tryton-ok', default=True),
|
])
|
||||||
])
|
|
||||||
|
|
||||||
pay = StateAction('account_statement.act_statement_form')
|
pay = StateAction('account_statement.act_statement_form')
|
||||||
|
|
||||||
def do_pay(self, action):
|
def do_pay(self, action):
|
||||||
pool = Pool()
|
pool = Pool()
|
||||||
User = pool.get('res.user')
|
User = pool.get('res.user')
|
||||||
@@ -460,12 +437,12 @@ class PayInvoiceSupplier(Wizard):
|
|||||||
party = pay.party
|
party = pay.party
|
||||||
amount = pay.amount
|
amount = pay.amount
|
||||||
statement = draft_statements.get(journal)
|
statement = draft_statements.get(journal)
|
||||||
# lines = statement.lines
|
lines = statement.lines
|
||||||
pay_to_add = tuple([StatementLine(
|
pay_to_add = tuple([StatementLine(
|
||||||
date=datetime.today().date(),
|
date=datetime.today().date(),
|
||||||
party=party,
|
party=party,
|
||||||
related_to=invoice,
|
related_to=invoice,
|
||||||
amount=abs(amount) * -1,
|
amount= abs(amount)*-1,
|
||||||
account=account.id)])
|
account=account.id)])
|
||||||
statement.lines = statement.lines + pay_to_add
|
statement.lines = statement.lines + pay_to_add
|
||||||
statement.save()
|
statement.save()
|
||||||
@@ -479,8 +456,7 @@ class LinesInvoiceToPay(ModelView):
|
|||||||
'company.company', "Company", required=True)
|
'company.company', "Company", required=True)
|
||||||
journal = fields.Many2One('account.statement.journal', 'Journal',
|
journal = fields.Many2One('account.statement.journal', 'Journal',
|
||||||
required=True)
|
required=True)
|
||||||
amount = Monetary(
|
amount = Monetary("Amount", currency='currency', digits='currency', required=True)
|
||||||
"Amount", currency='currency', digits='currency', required=True)
|
|
||||||
party = fields.Many2One('party.party', "Party", required=True,
|
party = fields.Many2One('party.party', "Party", required=True,
|
||||||
context={'company': Eval('company', -1)},)
|
context={'company': Eval('company', -1)},)
|
||||||
invoice = fields.Reference(
|
invoice = fields.Reference(
|
||||||
@@ -495,10 +471,10 @@ class LinesInvoiceToPay(ModelView):
|
|||||||
If(Bool(Eval('account')),
|
If(Bool(Eval('account')),
|
||||||
('account', '=', Eval('account')),
|
('account', '=', Eval('account')),
|
||||||
()),
|
()),
|
||||||
# If(Eval('statement_state') == 'draft',
|
If(Eval('statement_state') == 'draft',
|
||||||
# ('state', '=', 'posted'),
|
('state', '=', 'posted'),
|
||||||
# ('state', '!=', '')),
|
('state', '!=', '')),
|
||||||
]},
|
],},
|
||||||
context={'with_payment': False})
|
context={'with_payment': False})
|
||||||
account = fields.Many2One('account.account', "Account",
|
account = fields.Many2One('account.account', "Account",
|
||||||
domain=[
|
domain=[
|
||||||
@@ -507,29 +483,18 @@ class LinesInvoiceToPay(ModelView):
|
|||||||
('closed', '!=', True),
|
('closed', '!=', True),
|
||||||
],)
|
],)
|
||||||
description = fields.Char("Description")
|
description = fields.Char("Description")
|
||||||
currency = fields.Many2One(
|
|
||||||
'currency.currency', 'Currency', required=True)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def default_company():
|
def default_company():
|
||||||
return Transaction().context.get('company')
|
return Transaction().context.get('company')
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def default_currency(cls, **pattern):
|
|
||||||
pool = Pool()
|
|
||||||
Company = pool.get('company.company')
|
|
||||||
company = pattern.get('company')
|
|
||||||
if not company:
|
|
||||||
company = cls.default_company()
|
|
||||||
if company:
|
|
||||||
return Company(company).currency.id
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def _get_relations(cls):
|
def _get_relations(cls):
|
||||||
"Return a list of Model names for related_to Reference"
|
"Return a list of Model names for related_to Reference"
|
||||||
|
|
||||||
return ['account.invoice']
|
return ['account.invoice']
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_relations(cls):
|
def get_relations(cls):
|
||||||
Model = Pool().get('ir.model')
|
Model = Pool().get('ir.model')
|
||||||
|
|||||||
@@ -4,6 +4,25 @@ The COPYRIGHT file at the top level of this repository contains the full
|
|||||||
copyright notices and license terms. -->
|
copyright notices and license terms. -->
|
||||||
<tryton>
|
<tryton>
|
||||||
<data>
|
<data>
|
||||||
|
<record model="ir.action.act_window" id="act_configuration_closures_form">
|
||||||
|
<field name="name">Configuration Closures</field>
|
||||||
|
<field name="res_model">sale.cash_closures</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.ui.view" id="configuration_closures_view_form">
|
||||||
|
<field name="model">sale.cash_closures</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">configuration_closures_form</field>
|
||||||
|
</record>
|
||||||
|
<record model="ir.action.act_window.view" id="act_prospect_form_view1">
|
||||||
|
<field name="sequence" eval="10"/>
|
||||||
|
<field name="view" ref="configuration_closures_view_form"/>
|
||||||
|
<field name="act_window" ref="act_configuration_closures_form"/>
|
||||||
|
</record>
|
||||||
|
<menuitem
|
||||||
|
parent="sale.menu_configuration"
|
||||||
|
sequence="10"
|
||||||
|
id="menu_configuration_closure"
|
||||||
|
action="act_configuration_closures_form"/>
|
||||||
<record model="ir.action.act_window" id="act_sale_statement_form">
|
<record model="ir.action.act_window" id="act_sale_statement_form">
|
||||||
<field name="name">Statements</field>
|
<field name="name">Statements</field>
|
||||||
<field name="res_model">account.statement</field>
|
<field name="res_model">account.statement</field>
|
||||||
@@ -68,6 +87,11 @@ copyright notices and license terms. -->
|
|||||||
<field name="name">Open Statements</field>
|
<field name="name">Open Statements</field>
|
||||||
<field name="wiz_name">open.statement</field>
|
<field name="wiz_name">open.statement</field>
|
||||||
</record>
|
</record>
|
||||||
|
<record model="ir.ui.view" id="statement_line_view_form">
|
||||||
|
<field name="model">statement.line</field>
|
||||||
|
<field name="type">form</field>
|
||||||
|
<field name="name">statement_line_form</field>
|
||||||
|
</record>
|
||||||
<record model="ir.ui.view" id="statement_line_view_tree_sequence">
|
<record model="ir.ui.view" id="statement_line_view_tree_sequence">
|
||||||
<field name="model">statement.line</field>
|
<field name="model">statement.line</field>
|
||||||
<field name="type">tree</field>
|
<field name="type">tree</field>
|
||||||
@@ -124,28 +148,8 @@ copyright notices and license terms. -->
|
|||||||
<field name="group" ref="account_statement.group_statement"/>
|
<field name="group" ref="account_statement.group_statement"/>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
<record model="ir.action.act_window" id="act_configuration_closures_form">
|
|
||||||
<field name="name">Configuration Closures</field>
|
|
||||||
<field name="res_model">sale.cash_closures</field>
|
|
||||||
</record>
|
|
||||||
<record model="ir.ui.view" id="configuration_closures_view_form">
|
|
||||||
<field name="model">sale.cash_closures</field>
|
|
||||||
<field name="type">form</field>
|
|
||||||
<field name="name">configuration_closures_form</field>
|
|
||||||
</record>
|
|
||||||
<record model="ir.action.act_window.view" id="act_prospect_form_view1">
|
|
||||||
<field name="sequence" eval="10"/>
|
|
||||||
<field name="view" ref="configuration_closures_view_form"/>
|
|
||||||
<field name="act_window" ref="act_configuration_closures_form"/>
|
|
||||||
</record>
|
|
||||||
<menuitem
|
|
||||||
parent="sale.menu_configuration"
|
|
||||||
sequence="10"
|
|
||||||
id="menu_configuration_closure"
|
|
||||||
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">account.statement</field>
|
<field name="model" search="[('model', '=', 'account.statement')]"/>
|
||||||
<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 +157,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">account.statement.line</field>
|
<field name="model" search="[('model', '=', 'account.statement.line')]"/>
|
||||||
<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 +165,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">account.statement</field>
|
<field name="model" search="[('model', '=', 'account.statement')]"/>
|
||||||
<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 +173,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">account.statement.line</field>
|
<field name="model" search="[('model', '=', 'account.statement.line')]"/>
|
||||||
<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 +182,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">account.move</field>
|
<field name="model" search="[('model', '=', 'account.move')]"/>
|
||||||
<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 +190,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">account.move.line</field>
|
<field name="model" search="[('model', '=', 'account.move.line')]"/>
|
||||||
<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"/>
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ Imports::
|
|||||||
>>> today = datetime.date.today()
|
>>> today = datetime.date.today()
|
||||||
|
|
||||||
Install sale::
|
Install sale::
|
||||||
|
|
||||||
>>> config = activate_modules(['party', 'sale_payment'])
|
>>> config = activate_modules(['party', 'sale_payment'])
|
||||||
|
|
||||||
Create company::
|
Create company::
|
||||||
@@ -116,7 +117,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 Move')])
|
>>> sequence_type, = SequenceType.find([('name', '=', 'Account Journal')])
|
||||||
>>> sequence = Sequence(name='Statement',
|
>>> sequence = Sequence(name='Statement',
|
||||||
... sequence_type=sequence_type,
|
... sequence_type=sequence_type,
|
||||||
... company=company,
|
... company=company,
|
||||||
@@ -124,6 +125,7 @@ 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',
|
||||||
@@ -173,7 +175,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', '=', 'Accounting')])
|
>>> account_group, = Group.find([('name', '=', 'Account')])
|
||||||
>>> 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
|
||||||
@@ -190,7 +192,6 @@ 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 +204,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'
|
||||||
False
|
True
|
||||||
>>> payment_statement, = Statement.find([('state', '=', 'draft')])
|
>>> payment_statement, = Statement.find([('state', '=', 'draft')])
|
||||||
|
|
||||||
Partially pay the sale::
|
Partially pay the sale::
|
||||||
|
|||||||
@@ -20,5 +20,4 @@ def load_tests(loader, tests, pattern):
|
|||||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||||
finally:
|
finally:
|
||||||
os.chdir(cwd)
|
os.chdir(cwd)
|
||||||
|
|
||||||
return tests
|
return tests
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
[tryton]
|
[tryton]
|
||||||
version=7.6.0
|
version=7.0
|
||||||
depends:
|
depends:
|
||||||
account_statement
|
account_statement
|
||||||
sale_shop
|
sale_shop
|
||||||
xml:
|
xml:
|
||||||
statement.xml
|
|
||||||
device.xml
|
device.xml
|
||||||
sale.xml
|
sale.xml
|
||||||
|
statement.xml
|
||||||
user.xml
|
user.xml
|
||||||
message.xml
|
message.xml
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
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. -->
|
||||||
<form>
|
<form>
|
||||||
<image name="tryton-info" xexpand="0" xfill="0"/>
|
<image name="tryton-info"
|
||||||
|
xalign="1" yalign="0.0" xexpand="0" xfill="0"/>
|
||||||
<newline/>
|
<newline/>
|
||||||
<label
|
<label
|
||||||
string="You are going to close statements of your device."
|
string="You are going to close statements of your device."
|
||||||
|
|||||||
9
view/statement_line_tree.xml
Normal file
9
view/statement_line_tree.xml
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!-- This file is part sale_pos module for Tryton. The COPYRIGHT file at the top level of
|
||||||
|
this repository contains the full copyright notices and license terms. -->
|
||||||
|
<tree editable="1">
|
||||||
|
<field name="journal"/>
|
||||||
|
<field name="start_balance"/>
|
||||||
|
<field name="current_balance"/>
|
||||||
|
<field name="account"/>
|
||||||
|
</tree>
|
||||||
Reference in New Issue
Block a user