Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ccda3c7734 | |||
| 5b8f0397b1 | |||
| 7ee11f1aff | |||
| 6985a3aac1 | |||
| 068f3b0e28 | |||
| a4e9001bd6 | |||
| 8211278e78 | |||
| 4ebe44ae45 | |||
| 23fa2996a6 | |||
| 1aa5042f68 | |||
| ab773b8645 | |||
| 347c70d4be |
@@ -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,6 +27,7 @@ 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.account', "Account Mismatch Charge",
|
account_mismatch_charge = fields.Many2One(
|
||||||
|
'account.account', "Account Mismatch Charge",
|
||||||
|
domain=[
|
||||||
|
('type', '!=', None),
|
||||||
|
('closed', '!=', True),
|
||||||
|
],)
|
||||||
|
account_mismatch_positive = fields.Many2One(
|
||||||
|
'account.account', "Account Mismatch Positivo",
|
||||||
domain=[
|
domain=[
|
||||||
('company', '=', Eval('company', 0)),
|
|
||||||
('type', '!=', None),
|
('type', '!=', None),
|
||||||
('closed', '!=', True),
|
('closed', '!=', True),
|
||||||
],)
|
],)
|
||||||
|
|
||||||
account_mismatch_positive = fields.Many2One('account.account', "Account Mismatch Positivo",
|
@classmethod
|
||||||
domain=[
|
def default_currency(cls):
|
||||||
('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
|
||||||
|
|
||||||
@staticmethod
|
# @classmethod
|
||||||
def default_company():
|
# def default_company(cls):
|
||||||
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" 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>
|
||||||
|
|||||||
66
sale.py
66
sale.py
@@ -2,6 +2,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.
|
||||||
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
|
||||||
|
|
||||||
@@ -69,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()
|
||||||
@@ -96,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 = []
|
||||||
@@ -162,16 +179,18 @@ class Sale(metaclass=PoolMeta):
|
|||||||
condition=(sale.id == payline.sale)
|
condition=(sale.id == payline.sale)
|
||||||
).select(
|
).select(
|
||||||
sale.id,
|
sale.id,
|
||||||
where=((sale.total_amount_cache != None) &
|
where=(And([
|
||||||
(sale.state.in_([
|
sale.total_amount_cache is not None,
|
||||||
|
sale.state.in_([
|
||||||
'draft',
|
'draft',
|
||||||
'quotation',
|
'quotation',
|
||||||
'confirmed',
|
'confirmed',
|
||||||
'processing',
|
'processing',
|
||||||
'done']))),
|
'done'])])),
|
||||||
group_by=(sale.id),
|
group_by=(sale.id),
|
||||||
having=(Operator(sale.total_amount_cache -
|
having=(Operator(
|
||||||
Sum(Coalesce(payline.amount, 0)), value)
|
sale.total_amount_cache - Sum(
|
||||||
|
Coalesce(payline.amount, 0)), value)
|
||||||
))
|
))
|
||||||
return [('id', 'in', query)]
|
return [('id', 'in', query)]
|
||||||
|
|
||||||
@@ -196,17 +215,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.id', '=', Eval('sale'))])
|
domain=[('sale', '=', Eval('sale'))])
|
||||||
|
|
||||||
|
|
||||||
class ChangePaymentMethod(Wizard):
|
class ChangePaymentMethod(Wizard):
|
||||||
@@ -334,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:
|
||||||
@@ -345,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
|
||||||
@@ -379,8 +411,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" 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>
|
||||||
|
|||||||
155
setup.py
155
setup.py
@@ -1,111 +1,69 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python3
|
||||||
# encoding: utf-8
|
|
||||||
|
|
||||||
from setuptools import setup
|
|
||||||
import re
|
|
||||||
import os
|
|
||||||
import io
|
import io
|
||||||
|
import os
|
||||||
|
import re
|
||||||
from configparser import ConfigParser
|
from configparser import ConfigParser
|
||||||
|
|
||||||
MODULE = 'sale_payment'
|
from setuptools import find_packages, setup
|
||||||
PREFIX = 'trytonspain'
|
|
||||||
MODULE2PREFIX = {'sale_shop': 'trytonzz'}
|
MODULE2PREFIX = {}
|
||||||
OWNER = {
|
|
||||||
'nantic':'NaN-tic',
|
|
||||||
'trytonzz':'nanticzz',
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def read(fname):
|
def read(fname):
|
||||||
return io.open(
|
content = 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):
|
||||||
if minor_version % 2:
|
|
||||||
require = '%s >= %s.%s.dev0, < %s.%s'
|
|
||||||
else:
|
|
||||||
require = '%s >= %s.%s, < %s.%s'
|
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.readfp(open('tryton.cfg'))
|
config.read_file(open(os.path.join(os.path.dirname(__file__), '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'))
|
||||||
|
|
||||||
series = '%s.%s' % (major_version, minor_version)
|
tests_require = [get_require_version('proteus')]
|
||||||
if minor_version % 2:
|
|
||||||
branch = 'master'
|
|
||||||
else:
|
|
||||||
branch = series
|
|
||||||
|
|
||||||
requires += get_requires('depends')
|
setup(name=name,
|
||||||
|
|
||||||
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='',
|
description='Fork NaNtic sale_payment',
|
||||||
long_description=read('README'),
|
long_description=read('README.rst'),
|
||||||
author='trytonspain',
|
author='OneCluster',
|
||||||
url='http://www.nan-tic.com/',
|
author_email='info@onecluster.org',
|
||||||
download_url='https://github.com:trytonspain/trytond-sale_payment',
|
url='http://www.tryton.org/',
|
||||||
package_dir={'trytond.modules.%s' % MODULE: '.'},
|
keywords='',
|
||||||
packages=[
|
package_dir={'trytond.modules.sale_payment': '.'},
|
||||||
'trytond.modules.%s' % MODULE,
|
packages=(
|
||||||
'trytond.modules.%s.tests' % MODULE,
|
['trytond.modules.sale_payment']
|
||||||
],
|
+ ['trytond.modules.sale_payment.%s' % p
|
||||||
|
for p in find_packages()]
|
||||||
|
),
|
||||||
package_data={
|
package_data={
|
||||||
'trytond.modules.%s' % MODULE: (info.get('xml', [])
|
'trytond.modules.sale_payment': (info.get('xml', [])
|
||||||
+ ['tryton.cfg', 'locale/*.po', 'tests/*.rst', 'view/*.xml',
|
+ ['tryton.cfg', 'view/*.xml', 'locale/*.po', '*.fodt',
|
||||||
'icons/*.svg']),
|
'icons/*.svg', 'tests/*.rst', 'tests/*.json']),
|
||||||
},
|
|
||||||
project_urls = {
|
|
||||||
"Source Code": 'https://github.com:trytonspain/trytond-sale_payment'
|
|
||||||
},
|
},
|
||||||
classifiers=[
|
classifiers=[
|
||||||
'Development Status :: 5 - Production/Stable',
|
'Development Status :: 5 - Production/Stable',
|
||||||
@@ -114,25 +72,48 @@ setup(name='%s_%s' % (PREFIX, MODULE),
|
|||||||
'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 :: GNU General Public License (GPL)',
|
'License :: OSI Approved :: '
|
||||||
|
'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.6',
|
'Programming Language :: Python :: 3',
|
||||||
'Programming Language :: Python :: 3.7',
|
'Programming Language :: Python :: 3.8',
|
||||||
|
'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',
|
||||||
install_requires=requires,
|
python_requires='>=3.8',
|
||||||
dependency_links=dependency_links,
|
# install_requires=requires,
|
||||||
|
extras_require={
|
||||||
|
'test': tests_require,
|
||||||
|
},
|
||||||
zip_safe=False,
|
zip_safe=False,
|
||||||
entry_points="""
|
entry_points="""
|
||||||
[trytond.modules]
|
[trytond.modules]
|
||||||
%s = trytond.modules.%s
|
sale_payment = trytond.modules.sale_payment
|
||||||
""" % (MODULE, MODULE),
|
""", # noqa: E501
|
||||||
test_suite='tests',
|
|
||||||
test_loader='trytond.test_loader:Loader',
|
|
||||||
tests_require=tests_require,
|
|
||||||
|
|
||||||
)
|
)
|
||||||
103
statement.py
103
statement.py
@@ -4,7 +4,8 @@
|
|||||||
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 Button, StateTransition, StateAction, StateView, Wizard
|
from trytond.wizard import (
|
||||||
|
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
|
||||||
@@ -121,6 +122,7 @@ 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'
|
||||||
@@ -172,7 +174,8 @@ 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' % (device.rec_name, journal.rec_name),
|
'name': '%s - %s' % (
|
||||||
|
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,
|
||||||
@@ -185,7 +188,9 @@ 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(gettext('sale_payment.statement_already_opened',
|
results.append(
|
||||||
|
gettext(
|
||||||
|
'sale_payment.statement_already_opened',
|
||||||
statement=journal.rec_name))
|
statement=journal.rec_name))
|
||||||
statements.extend(Statement.create(vlist))
|
statements.extend(Statement.create(vlist))
|
||||||
self.result = '\n'.join(results)
|
self.result = '\n'.join(results)
|
||||||
@@ -223,7 +228,6 @@ 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,
|
||||||
@@ -232,7 +236,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
|
||||||
@@ -258,7 +262,9 @@ 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+s.start_balance
|
'end_balance': (
|
||||||
|
end_balance + s.start_balance),
|
||||||
|
'company': Transaction().context.get('company')
|
||||||
}
|
}
|
||||||
statementLines.append(line)
|
statementLines.append(line)
|
||||||
|
|
||||||
@@ -305,10 +311,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
|
||||||
@@ -316,17 +322,22 @@ class CloseStatement(Wizard):
|
|||||||
if mismatch and mismatch.real > 0:
|
if mismatch and mismatch.real > 0:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if (config.mismatch_limit and config.account_mismatch_charge):
|
if config.mismatch_limit and (
|
||||||
if mismatch and (abs(mismatch) >= abs(config.mismatch_limit.real)):
|
config.account_mismatch_charge):
|
||||||
lines = statement.lines
|
if mismatch and (abs(mismatch) >= abs(
|
||||||
if employee_party == None:
|
config.mismatch_limit.real)):
|
||||||
raise UserError(str("Debe definir un Empleado para el Usuario."))
|
# lines = statement.lines
|
||||||
|
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 + conciliation_mismatch
|
statement.lines =\
|
||||||
|
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
|
||||||
@@ -335,7 +346,9 @@ 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(gettext('sale_payment.statement_already_closed',
|
results.append(
|
||||||
|
gettext(
|
||||||
|
'sale_payment.statement_already_closed',
|
||||||
statement=statement.rec_name))
|
statement=statement.rec_name))
|
||||||
else:
|
else:
|
||||||
results.append(gettext('sale_payment.not_statement_found',
|
results.append(gettext('sale_payment.not_statement_found',
|
||||||
@@ -362,24 +375,31 @@ 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', states=_states)
|
"Start Balance", currency='currency', digits='currency',
|
||||||
|
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', readonly=True)
|
"End Balance", currency='currency', digits='currency',
|
||||||
|
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.account', "Account",
|
account = fields.Many2One(
|
||||||
|
'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():
|
||||||
@@ -388,31 +408,34 @@ 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:
|
||||||
self.mismatch = self.real_cash - self.end_balance
|
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('line_invoice.pay', None, "Invoice To Pay")
|
invoice_to_pay = fields.One2Many(
|
||||||
|
'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('pay_invoice.statement.start',
|
start = StateView(
|
||||||
|
'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')
|
||||||
@@ -437,12 +460,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()
|
||||||
@@ -456,7 +479,8 @@ 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", currency='currency', digits='currency', required=True)
|
amount = Monetary(
|
||||||
|
"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(
|
||||||
@@ -471,10 +495,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=[
|
||||||
@@ -483,18 +507,29 @@ 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,25 +4,6 @@ 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>
|
||||||
@@ -87,11 +68,6 @@ 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>
|
||||||
@@ -148,8 +124,28 @@ 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" 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"/>
|
||||||
@@ -157,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"/>
|
||||||
@@ -165,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"/>
|
||||||
@@ -173,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"/>
|
||||||
@@ -182,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"/>
|
||||||
@@ -190,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"/>
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ 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::
|
||||||
@@ -117,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,
|
||||||
@@ -125,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',
|
||||||
@@ -175,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
|
||||||
@@ -192,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)
|
||||||
@@ -204,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::
|
||||||
|
|||||||
@@ -20,4 +20,5 @@ 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.0
|
version=7.6.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,8 +3,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. -->
|
||||||
<form>
|
<form>
|
||||||
<image name="tryton-info"
|
<image name="tryton-info" xexpand="0" xfill="0"/>
|
||||||
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."
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
<?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