develop
Andreas 2015-03-02 09:46:30 +01:00
commit d88239c363
39 changed files with 17177 additions and 454 deletions

View File

@ -8,7 +8,7 @@ db_port = 5436
db_user = False
db_password = False
addons_path = ext/odoo/addons,ext/custom-addons
addons_path = ext/odoo/addons,ext/custom-addons,dmi/run1
timezone = Europe/Brussels
#dbfilter_test = ['.*',]

View File

@ -8,7 +8,7 @@ db_port = 5433
db_user = False
db_password = False
addons_path = ext/odoo/addons,ext/custom-addons
addons_path = ext/odoo/addons,ext/custom-addons,dmi/run1
timezone = Europe/Brussels
#dbfilter_test = ['.*',]

4556
dmi/run1/Kundendaten.ktr Normal file

File diff suppressed because it is too large Load Diff

4887
dmi/run1/Produktdaten.ktr Normal file

File diff suppressed because it is too large Load Diff

2305
dmi/run1/VAT-Lookup.ktr Normal file

File diff suppressed because it is too large Load Diff

2875
dmi/run1/Validation.ktr Normal file

File diff suppressed because it is too large Load Diff

23
dmi/run1/cam_dmi/__init__.py Executable file
View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

38
dmi/run1/cam_dmi/__openerp__.py Executable file
View File

@ -0,0 +1,38 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Datenübernahme',
'category': 'Custom',
'version': '1.0',
'description': """Datenübernahme""",
'author': 'camadeus GmbH',
'website': 'http://www.camadeus.at',
'depends': ['mail','cam_reports'],
'data': [
'res.users.csv',
],
'installable': True,
'auto_install': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,2 @@
"id","name","login","password","email","groups_id/id","tz","mobile","phone","function"
"p_xxx","Max Mustermann","mustermann@max.at","x","mustermann@max.at","base.group_sale_salesman_all_leads,account.group_account_invoice,base.group_erp_manager,stock.group_stock_user,purchase.group_purchase_user","Europe/Vienna",,,
1 id name login password email groups_id/id tz mobile phone function
2 p_xxx Max Mustermann mustermann@max.at x mustermann@max.at base.group_sale_salesman_all_leads,account.group_account_invoice,base.group_erp_manager,stock.group_stock_user,purchase.group_purchase_user Europe/Vienna

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1 @@
place here csv-Files

View File

@ -1,5 +0,0 @@
/var/log/odoo/*.log {
copytruncate
missingok
notifempty
}

View File

@ -11,14 +11,15 @@ db_user = False
debug_mode = False
list_db = True
log_level = error
logfile = /var/log/odoo/odoo-server.log
#max_cron_threads = 1
#workers = 1
xmlrpc_interface = 127.0.0.1
# WILL BE OVERWRITTEN BY COMMAND LINE ARGS
xmlrpc_port = 8069
longpolling_port = 8072
logfile = /var/log/odoo/odoo-server.log
timezone = Europe/Brussels
@ -34,3 +35,7 @@ limit_time_real = 6000
# if DB > 150MB, otherwise "AccessDenied" error occurs
# 10 GB
limit_memory_hard = 10000000000
# Use a new worker for the next request if 400MB is reached
# The worker will be recycled after the current request
limit_memory_soft = 400000000

View File

@ -1,85 +0,0 @@
#!/bin/sh
### BEGIN INIT INFO
# Provides: odoo-server
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Enterprise Resource Management software
# Description: Open ERP is a complete ERP and CRM software.
### END INIT INFO
PATH=/bin:/sbin:/usr/bin:/usr/local/bin
DAEMON=/opt/odoo/odoo/openerp-server
NAME=odoo-server
DESC=odoo-server
#FILTER="^%d$"
# Specify the user name (Default: openerp).
USER=odoo
# Specify an alternate config file (Default: /etc/openerp-server.conf).
CONFIGFILE="/opt/odoo/ext/config/odoo-server.conf"
# pidfile
PIDFILE=/var/run/$NAME.pid
# Additional options that are passed to the Daemon.
DAEMON_OPTS="-c $CONFIGFILE"
[ -x $DAEMON ] || exit 0
[ -f $CONFIGFILE ] || exit 0
checkpid() {
[ -f $PIDFILE ] || return 1
pid=`cat $PIDFILE`
[ -d /proc/$pid ] && return 0
return 1
}
case "${1}" in
start)
echo -n "Starting ${DESC}: "
start-stop-daemon --start --quiet --pidfile ${PIDFILE} \
--chuid ${USER} --background --make-pidfile \
--exec ${DAEMON} -- ${DAEMON_OPTS}
echo "${NAME}."
;;
stop)
echo -n "Stopping ${DESC}: "
start-stop-daemon --stop --quiet --pidfile ${PIDFILE} \
--oknodo
echo "${NAME}."
;;
restart|force-reload)
echo -n "Restarting ${DESC}: "
start-stop-daemon --stop --quiet --pidfile ${PIDFILE} \
--oknodo
sleep 1
start-stop-daemon --start --quiet --pidfile ${PIDFILE} \
--chuid ${USER} --background --make-pidfile \
--exec ${DAEMON} -- ${DAEMON_OPTS}
echo "${NAME}."
;;
*)
N=/etc/init.d/${NAME}
echo "Usage: ${NAME} {start|stop|restart|force-reload}" >&2
exit 1
;;
esac
exit 0

View File

@ -27,7 +27,7 @@
'description': """Individuelle Anpassungen""",
'author': 'camadeus GmbH',
'website': 'http://www.camadeus.at',
'depends': ['crm','sale','mail','account'],
'depends': ['crm','sale','mail','product','account'],
'data': [
'cam_custom_view.xml',
'cam_custom_data.xml',

View File

@ -27,6 +27,33 @@ from openerp import SUPERUSER_ID
from openerp import tools
from lxml import etree
DISABLED_MENUS = [
]
class ir_ui_menu(osv.osv):
_inherit = 'ir.ui.menu'
@tools.ormcache(skiparg=2)
def get_disabled_menu_ids(self, cr, uid, context=None):
data_obj = self.pool.get('ir.model.data')
menu_ids = []
for menu in DISABLED_MENUS:
module,xml_id = menu.split('.')
menu = data_obj.get_object(cr, uid, module, xml_id)
if menu:
menu_ids.append(menu.id)
return menu_ids
def _filter_visible_menus(self, cr, uid, ids, context=None):
if uid != 1:
disabled_ids = self.get_disabled_menu_ids(cr, uid)
ids = [id for id in ids if id not in disabled_ids]
ids = super(ir_ui_menu, self)._filter_visible_menus(cr, uid, ids, context)
return ids
class res_partner(osv.osv):
_inherit = 'res.partner'
@ -34,7 +61,17 @@ class res_partner(osv.osv):
def fields_view_get_address(self, arch):
""" verhindert das Überschreiben von address_format """
return arch
class product_product(osv.osv):
_inherit = 'product.product'
def name_get(self, cr, user, ids, context=None):
if context is None:
context = {}
c = context.copy()
c.update({'display_default_code': False})
return super(product_product, self).name_get(cr, user, ids, context=c)
class mail_notification(osv.Model):
_inherit = 'mail.notification'
@ -78,4 +115,15 @@ class mail_notification(osv.Model):
# })
# footer = tools.append_content_to_html(footer, signature_company, plaintext=False, container_tag='div')
return footer
return footer
# class product_product(osv.osv):
# _inherit = 'product.product'
#
# def name_get(self, cr, user, ids, context=None):
# if context is None:
# context = {}
# c = context.copy()
# c.update({'display_default_code': False})
# return super(product_product, self).name_get(cr, user, ids, context=c)

View File

@ -55,7 +55,7 @@
<field name="name" position="after">
<field name="list_price"/>
</field>
<field name="state" position="replace"/>
<!-- <field name="state" position="replace"/> -->
</field>
</record>
@ -64,5 +64,16 @@
<field name="view_id"></field>
</record>
<record id="product_supplierinfo_form_view" model="ir.ui.view">
<field name="name">product.supplierinfo.form.view</field>
<field name="model">product.supplierinfo</field>
<field name="inherit_id" ref="product.product_supplierinfo_form_view"/>
<field name="arch" type="xml">
<field name="product_code" position="replace">
<field name="product_code" invisible="1"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,25 @@
# German translation for openobject-addons
# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012
# This file is distributed under the same license as the openobject-addons package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2012.
#
msgid ""
msgstr ""
"Project-Id-Version: camadeus\n"
"Report-Msgid-Bugs-To: Andreas Brueckl <andreas.brueckl@camadeus.at>\n"
"POT-Creation-Date: 2014-09-23 16:26+0000\n"
"PO-Revision-Date: 2014-08-14 16:14+0000\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: Abkhazian <ab@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2014-09-24 09:44+0000\n"
"X-Generator: Launchpad (build 17196)\n"
#. module: cam_custom
#: field:product.product,default_code:0
#: field:product.template,default_code:0
msgid "Internal Reference"
msgstr "Artikelnummer"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View File

@ -33,7 +33,7 @@
""",
'author': 'camadeus GmbH',
'website': 'http://www.camadeus.at',
'depends': ['account'],
'depends': ['account', 'sale'],
'data': [
'cam_invoice_skonto_view.xml',
'cam_invoice_skonto_data.xml',

View File

@ -26,6 +26,7 @@ from openerp.osv import fields, osv
from openerp import models, fields as f, api
import openerp.addons.decimal_precision as dp
from datetime import date, timedelta, datetime
from openerp.tools.translate import _
class account_payment_term(osv.osv):
_inherit = 'account.payment.term'
@ -81,5 +82,325 @@ class account_invoice(models.Model):
if inv.payment_term and inv.payment_term.skonto_tage:
inv.write({'skonto_faelligkeit': datetime.strptime(inv.date_invoice, '%Y-%m-%d') + timedelta(days=inv.payment_term.skonto_tage)})
return True
# Add context 'click_register_payment'
def invoice_pay_customer(self, cr, uid, ids, context=None):
if not ids: return []
dummy, view_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account_voucher', 'view_vendor_receipt_dialog_form')
inv = self.browse(cr, uid, ids[0], context=context)
return {
'name':_("Pay Invoice"),
'view_mode': 'form',
'view_id': view_id,
'view_type': 'form',
'res_model': 'account.voucher',
'type': 'ir.actions.act_window',
'nodestroy': True,
'target': 'new',
'domain': '[]',
'context': {
'payment_expected_currency': inv.currency_id.id,
'default_partner_id': self.pool.get('res.partner')._find_accounting_partner(inv.partner_id).id,
'default_amount': inv.type in ('out_refund', 'in_refund') and -inv.residual or inv.residual,
'default_reference': inv.name,
'close_after_process': True,
'invoice_type': inv.type,
'invoice_id': inv.id,
'default_type': inv.type in ('out_invoice','out_refund') and 'receipt' or 'payment',
'type': inv.type in ('out_invoice','out_refund') and 'receipt' or 'payment',
'click_register_payment':True,
}
}
class account_voucher(osv.osv):
_inherit = 'account.voucher'
#Workaround to send context in _compute_writeoff_amount()
def onchange_line_ids(self, cr, uid, ids, line_dr_ids, line_cr_ids, amount, voucher_currency, type, context=None):
context = context or {}
if not line_dr_ids and not line_cr_ids:
return {'value':{'writeoff_amount': 0.0}}
line_osv = self.pool.get("account.voucher.line")
line_dr_ids = resolve_o2m_operations(cr, uid, line_osv, line_dr_ids, ['amount'], context)
line_cr_ids = resolve_o2m_operations(cr, uid, line_osv, line_cr_ids, ['amount'], context)
#compute the field is_multi_currency that is used to hide/display options linked to secondary currency on the voucher
is_multi_currency = False
#loop on the voucher lines to see if one of these has a secondary currency. If yes, we need to see the options
for voucher_line in line_dr_ids+line_cr_ids:
line_id = voucher_line.get('id') and self.pool.get('account.voucher.line').browse(cr, uid, voucher_line['id'], context=context).move_line_id.id or voucher_line.get('move_line_id')
if line_id and self.pool.get('account.move.line').browse(cr, uid, line_id, context=context).currency_id:
is_multi_currency = True
break
return {'value': {'writeoff_amount': self._compute_writeoff_amount(cr, uid, line_dr_ids, line_cr_ids, amount, type, context=context), 'is_multi_currency': is_multi_currency}}
def get_default_acc_id(self, cr, uid, args):
konto = self.pool.get('account.account').search(cr,uid,[('code','=','99999999')],limit=1)
if konto:
return konto[0]
else:
raise osv.except_osv(_('Konfigurationsfehler!'),_("Es ist kein Konto für den Ausgleich der Rechnungen definiert (Skonto). Bitte wenden Sie sich an den Support."))
return False
_defaults = {
'comment': 'Skonto',
'writeoff_acc_id': get_default_acc_id,
}
def _get_writeoff_amount(self, cr, uid, ids, name, args, context={}):
if not ids: return {}
currency_obj = self.pool.get('res.currency')
res = {}; diff_amount = 0.0
debit = credit = total_inv_residual = 0.0
for voucher in self.browse(cr, uid, ids, context=context):
sign = voucher.type == 'payment' and -1 or 1
for l in voucher.line_dr_ids:
debit += l.amount
if context.has_key('click_register_payment'):
if voucher.payment_option == 'with_writeoff':
# There can be several open lines => we only want to reconcile the line related to the invoice
if l.move_line_id and l.move_line_id.invoice and l.move_line_id.invoice.id == context.get('invoice_id',-1):
l.write({'reconcile': True, 'amount': l.amount_unreconciled})
total_inv_residual += (l.amount > 0 and l.amount_unreconciled - l.amount)
for l in voucher.line_cr_ids:
credit += l.amount
if context.has_key('click_register_payment'):
if voucher.payment_option == 'with_writeoff':
# There can be several open lines => we only want to reconcile the line related to the invoice
if l.move_line_id and l.move_line_id.invoice and l.move_line_id.invoice.id == context.get('invoice_id',-1):
l.write({'reconcile': True, 'amount': l.amount_unreconciled})
total_inv_residual += (l.amount > 0 and l.amount_unreconciled - l.amount)
currency = voucher.currency_id or voucher.company_id.currency_id
write_off_amount = voucher.amount - sign * (credit - debit)
if context.has_key('click_register_payment'):
write_off_amount = total_inv_residual * sign
res[voucher.id] = currency_obj.round(cr, uid, currency, write_off_amount)
return res
_columns = {
'writeoff_amount': fields.function(_get_writeoff_amount, string='Difference Amount', type='float', readonly=True, help="Computed as the difference between the amount stated in the voucher and the sum of allocation on the voucher lines."),
}
#working on context to differentiate the button clicks without affecting the present code
#Workaround to send context in _compute_writeoff_amount()
def _compute_writeoff_amount(self, cr, uid, line_dr_ids, line_cr_ids, amount, type, context={}):
debit = credit = total_inv_residual = 0.0
sign = type == 'payment' and -1 or 1
for l in line_dr_ids:
debit += l['amount']
#total_inv_residual += (l['amount'] > 0 and l['amount_unreconciled'] - l['amount'])
total_inv_residual += l['amount_unreconciled']
for l in line_cr_ids:
credit += l['amount']
#total_inv_residual += (l['amount'] > 0 and l['amount_unreconciled'] - l['amount'])
total_inv_residual += l['amount_unreconciled']
writeoff_amount = amount - sign * (credit - debit)
if context.has_key('click_register_payment'):
writeoff_amount = amount - (total_inv_residual)
return writeoff_amount
#Workaround to send context in _compute_writeoff_amount()
def recompute_voucher_lines(self, cr, uid, ids, partner_id, journal_id, price, currency_id, ttype, date, context=None):
"""
Returns a dict that contains new values and context
@param partner_id: latest value from user input for field partner_id
@param args: other arguments
@param context: context arguments, like lang, time zone
@return: Returns a dict which contains new values, and context
"""
def _remove_noise_in_o2m():
"""if the line is partially reconciled, then we must pay attention to display it only once and
in the good o2m.
This function returns True if the line is considered as noise and should not be displayed
"""
if line.reconcile_partial_id:
if currency_id == line.currency_id.id:
if line.amount_residual_currency <= 0:
return True
else:
if line.amount_residual <= 0:
return True
return False
if context is None:
context = {}
context_multi_currency = context.copy()
currency_pool = self.pool.get('res.currency')
move_line_pool = self.pool.get('account.move.line')
partner_pool = self.pool.get('res.partner')
journal_pool = self.pool.get('account.journal')
line_pool = self.pool.get('account.voucher.line')
#set default values
default = {
'value': {'line_dr_ids': [], 'line_cr_ids': [], 'pre_line': False},
}
# drop existing lines
line_ids = ids and line_pool.search(cr, uid, [('voucher_id', '=', ids[0])])
for line in line_pool.browse(cr, uid, line_ids, context=context):
if line.type == 'cr':
default['value']['line_cr_ids'].append((2, line.id))
else:
default['value']['line_dr_ids'].append((2, line.id))
if not partner_id or not journal_id:
return default
journal = journal_pool.browse(cr, uid, journal_id, context=context)
partner = partner_pool.browse(cr, uid, partner_id, context=context)
currency_id = currency_id or journal.company_id.currency_id.id
total_credit = 0.0
total_debit = 0.0
account_type = None
if context.get('account_id'):
account_type = self.pool['account.account'].browse(cr, uid, context['account_id'], context=context).type
if ttype == 'payment':
if not account_type:
account_type = 'payable'
total_debit = price or 0.0
else:
total_credit = price or 0.0
if not account_type:
account_type = 'receivable'
if not context.get('move_line_ids', False):
if context.get('click_register_payment', False) and context.get('invoice_id', False):
ids = move_line_pool.search(cr, uid, [('state','=','valid'), ('account_id.type', '=', account_type), ('reconcile_id', '=', False), ('partner_id', '=', partner_id),('invoice','=',context.get('invoice_id'))], context=context)
else:
ids = move_line_pool.search(cr, uid, [('state','=','valid'), ('account_id.type', '=', account_type), ('reconcile_id', '=', False), ('partner_id', '=', partner_id)], context=context)
else:
ids = context['move_line_ids']
invoice_id = context.get('invoice_id', False)
company_currency = journal.company_id.currency_id.id
move_lines_found = []
#order the lines by most old first
ids.reverse()
account_move_lines = move_line_pool.browse(cr, uid, ids, context=context)
#compute the total debit/credit and look for a matching open amount or invoice
for line in account_move_lines:
if _remove_noise_in_o2m():
continue
if invoice_id:
if line.invoice.id == invoice_id:
#if the invoice linked to the voucher line is equal to the invoice_id in context
#then we assign the amount on that line, whatever the other voucher lines
move_lines_found.append(line.id)
elif currency_id == company_currency:
#otherwise treatments is the same but with other field names
if line.amount_residual == price:
#if the amount residual is equal the amount voucher, we assign it to that voucher
#line, whatever the other voucher lines
move_lines_found.append(line.id)
break
#otherwise we will split the voucher amount on each line (by most old first)
total_credit += line.credit or 0.0
total_debit += line.debit or 0.0
elif currency_id == line.currency_id.id:
if line.amount_residual_currency == price:
move_lines_found.append(line.id)
break
total_credit += line.credit and line.amount_currency or 0.0
total_debit += line.debit and line.amount_currency or 0.0
remaining_amount = price
#voucher line creation
for line in account_move_lines:
if _remove_noise_in_o2m():
continue
if line.currency_id and currency_id == line.currency_id.id:
amount_original = abs(line.amount_currency)
amount_unreconciled = abs(line.amount_residual_currency)
else:
#always use the amount booked in the company currency as the basis of the conversion into the voucher currency
amount_original = currency_pool.compute(cr, uid, company_currency, currency_id, line.credit or line.debit or 0.0, context=context_multi_currency)
amount_unreconciled = currency_pool.compute(cr, uid, company_currency, currency_id, abs(line.amount_residual), context=context_multi_currency)
line_currency_id = line.currency_id and line.currency_id.id or company_currency
rs = {
'name':line.move_id.name,
'type': line.credit and 'dr' or 'cr',
'move_line_id':line.id,
'account_id':line.account_id.id,
'amount_original': amount_original,
'amount': (line.id in move_lines_found) and min(abs(remaining_amount), amount_unreconciled) or 0.0,
'date_original':line.date,
'date_due':line.date_maturity,
'amount_unreconciled': amount_unreconciled,
'currency_id': line_currency_id,
}
remaining_amount -= rs['amount']
#in case a corresponding move_line hasn't been found, we now try to assign the voucher amount
#on existing invoices: we split voucher amount by most old first, but only for lines in the same currency
if not move_lines_found:
if currency_id == line_currency_id:
if line.credit:
amount = min(amount_unreconciled, abs(total_debit))
rs['amount'] = amount
total_debit -= amount
else:
amount = min(amount_unreconciled, abs(total_credit))
rs['amount'] = amount
total_credit -= amount
if rs['amount_unreconciled'] == rs['amount']:
rs['reconcile'] = True
if rs['type'] == 'cr':
default['value']['line_cr_ids'].append(rs)
else:
default['value']['line_dr_ids'].append(rs)
if len(default['value']['line_cr_ids']) > 0:
default['value']['pre_line'] = 1
elif len(default['value']['line_dr_ids']) > 0:
default['value']['pre_line'] = 1
default['value']['writeoff_amount'] = self._compute_writeoff_amount(cr, uid, default['value']['line_dr_ids'], default['value']['line_cr_ids'], price, ttype, context=context)
return default
def resolve_o2m_operations(cr, uid, target_osv, operations, fields, context):
results = []
for operation in operations:
result = None
if not isinstance(operation, (list, tuple)):
result = target_osv.read(cr, uid, operation, fields, context=context)
elif operation[0] == 0:
# may be necessary to check if all the fields are here and get the default values?
result = operation[2]
elif operation[0] == 1:
result = target_osv.read(cr, uid, operation[1], fields, context=context)
if not result: result = {}
result.update(operation[2])
elif operation[0] == 4:
result = target_osv.read(cr, uid, operation[1], fields, context=context)
if result != None:
results.append(result)
return results
class sale_order(osv.osv):
_inherit = 'sale.order'
def _skonto_betrag_inkl(self, cr, uid, ids, field_name, arg, context=None):
res = {}
sos = self.browse(cr, uid, ids, context=context)
for so in sos:
if so.payment_term and so.payment_term.skonto_prozent:
res[so.id] = so.amount_total * (1 - so.payment_term.skonto_prozent/100.0)
return res
_columns = {
'skonto_betrag_inkl': fields.function(_skonto_betrag_inkl, string='Betrag inkl. Skonto', type='float'),
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -34,5 +34,17 @@ action_number()
invoice_validate()
action_skonto_faelligkeit_assign()</field>
</record>
</data>
</data>
<data noupdate="1">
<record id="account_account_skonto" model="account.account">
<field name="name">Skonto</field>
<field name="code">99999999</field>
<field name="type">other</field>
<field name="user_type" search="[('code','=','other')]"/>
</record>
</data>
</openerp>

View File

@ -28,7 +28,6 @@
<openerp>
<data>
<!-- account.payment.term -->
<record id="view_payment_term_form" model="ir.ui.view">
<field name="name">cam_invoice_skonto.payment.term.form</field>
<field name="model">account.payment.term</field>
@ -40,13 +39,12 @@
<group col="4">
<field name="skonto_tage"/>
<field name="netto_tage"/>
<field name="skonto_prozent"/>
<field name="skonto_prozent"/>
</group>
</xpath>
</field>
</record>
<!-- account.invoice -->
<record id="invoice_form" model="ir.ui.view">
<field name="name">cam_invoice_skonto.invoice.form</field>
<field name="model">account.invoice</field>
@ -56,10 +54,34 @@
<field name="skonto_faelligkeit"/>
</field>
<field name="residual" position="before">
<field name="skonto_betrag_inkl"/>
<field name="skonto_betrag_inkl" attrs="{'invisible': [('skonto_betrag_inkl','=',0)]}"/>
</field>
</field>
</record>
<!-- account.voucher -->
<record id="account_voucher_form" model="ir.ui.view">
<field name="name">cam_invoice_skonto.account_voucher.form</field>
<field name="model">account.voucher</field>
<field name="inherit_id" ref="account_voucher.view_vendor_receipt_dialog_form"/>
<field name="arch" type="xml">
<field name="writeoff_acc_id" position="attributes">
<attribute name="invisible">1</attribute>
</field>
</field>
</record>
<record id="view_order_form" model="ir.ui.view">
<field name="name">sale.order.form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="amount_total" position="after">
<field name="skonto_betrag_inkl"/>
</field>
</field>
</record>
</data>
</openerp>

View File

@ -1,11 +1,6 @@
<?xml version="1.0"?>
<!--
<reports>
<report>account.report_invoice</report>
</reports>
-->
<document filename="Rechnung.pdf">
<template pageSize="(595.0,842.0)" title="Sale Order" author="Andreas Brückl" allowSplitting="20">
<template pageSize="(595.0,842.0)" title="Sale Order" author="Camadeus Consulting" allowSplitting="20">
<pageTemplate id="first">
<frame id="first" x1="15.0" y1="42.0" width="539" height="758"/>
</pageTemplate>
@ -18,87 +13,95 @@
</para>
<para>[[repeatIn(objects,'o')]] [[ setLang(o.partner_id.commercial_partner_id.lang)]]</para>
<para style="fett">[[ o.partner_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (o.partner_id.commercial_partner_id.id != o.partner_id.id and o.partner_id.name) or '' ]] </para>
<para style="normal">[[ (o.partner_id.street ) or '']]</para>
<para style="normal">[[ (o.partner_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (o.partner_id.zip) or '' ]] [[ (o.partner_id and o.partner_id.city) or '' ]]</para>
<para style="normal">[[ (o.partner_id.state_id and o.partner_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (o.partner_id.country_id and o.partner_id.country_id.name) or '' ]]</para>
<blockTable colWidths="90,110" style="Struktur" hAlign="RIGHT">
<tr>
<td>
<para style="normal">Kundennr.:</para>
</td>
<td>
<para style="normal">[[ o.partner_id.ref or removeParentNode('tr') ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Ihre Referenz:</para>
</td>
<td>
<para style="normal">[[ o.name ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Ansprechpartner:</para>
</td>
<td>
<para style="normal">[[ (o.user_id and o.user_id.name) or '' ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Ihre UID:</para>
</td>
<td>
<para style="normal">[[ o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.vat or '' ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Datum:</para>
</td>
<td>
<para style="normal">[[ formatLang(o.date_invoice,date = True) ]]</para>
</td>
</tr>
</blockTable>
<blockTable colWidths="270,85,145" style="Struktur">
<tr>
<td>
<section>
<para style="fett">[[ o.partner_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (o.partner_id.commercial_partner_id.id != o.partner_id.id and o.partner_id.name) or '' ]] </para>
<para style="normal">[[ (o.partner_id.street ) or '']]</para>
<para style="normal">[[ (o.partner_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (o.partner_id.zip) or '' ]] [[ (o.partner_id and o.partner_id.city) or '' ]]</para>
<para style="normal">[[ (o.partner_id.state_id and o.partner_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (o.partner_id.country_id and o.partner_id.country_id.name) or '' ]]</para>
<!-- Für Sichtfenster -->
<section>[[ not (o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.ref) or removeParentNode('section') ]]
<para style="normal">&#160;</para>
</section>
</section>
<para></para>
</td>
<td>
<para style="normal">Datum:</para>
<para style="normal">Quelldokument:</para>
<para style="normal">Kundenreferenz:</para>
<!--<para style="normal">Kundennummer:</para>-->
<para style="normal">Kunde UID Nr.:</para>
<para style="normal">Ansprechpartner:</para>
</td>
<td>
<para style="normal">[[ formatLang(o.date_invoice,date = True) ]]&#160;</para>
<para style="normal">[[ o.origin ]]&#160;</para>
<para style="normal">[[ o.name ]]&#160;</para>
<!--<para style="normal">[[ o.partner_id.commercial_partner_id.ref ]]&#160;</para>-->
<para style="normal">[[ o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.vat or '' ]]&#160;</para>
<para style="normal">[[ (o.user_id and o.user_id.name) or '' ]]&#160;</para>
</td>
</tr>
<!--
<tr>
<td>
<section>[[ (o.partner_shipping_id and o.partner_shipping_id.id != o.partner_id.id) or removeParentNode('section')]]
<spacer length="0.5cm"/>
<para style="normal">Lieferadresse:</para>
<para style="normal">[[ o.partner_shipping_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (o.partner_shipping_id.commercial_partner_id.id != o.partner_shipping_id.id and o.partner_shipping_id.name) or '' ]] </para>
<para style="normal">[[ (o.partner_shipping_id.street ) or '']]</para>
<para style="normal">[[ (o.partner_shipping_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (o.partner_shipping_id.zip) or '' ]] [[ (o.partner_shipping_id and o.partner_shipping_id.city) or '' ]]</para>
<para style="normal">[[ (o.partner_shipping_id.state_id and o.partner_shipping_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (o.partner_shipping_id.country_id and o.partner_shipping_id.country_id.name) or '' ]]</para>
</section>
<para style="normal">&#160;</para>
</td>
<td>
<para style="normal">&#160;</para>
</td>
<td>
<para style="normal">&#160;</para>
</td>
</tr>
-->
</blockTable>
<para style="ueberschrift"><b>Rechnung [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<para style="ueberschrift"><b>PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma2') or removeParentNode('para')) and '' ]]</b></para>
<para style="ueberschrift"><b>Rechnungsentwurf [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]]</b></para>
<para style="ueberschrift"><b>Stornierte Rechnung [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<para style="ueberschrift"><b>Stornorechnung [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<para style="ueberschrift"><b>Stornorechnung [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<para style="ueberschrift"><b>Rechnung [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<spacer length="1.0cm"/>
<para style="ueberschrift2"><b>Rechnung [[ ((o.type == 'out_invoice' and (o.state == 'open' or o.state == 'paid')) or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<para style="ueberschrift2"><b>PRO-FORMA [[ ((o.type == 'out_invoice' and o.state == 'proforma2') or removeParentNode('para')) and '' ]]</b></para>
<para style="ueberschrift2"><b>Rechnungsentwurf [[ ((o.type == 'out_invoice' and o.state == 'draft') or removeParentNode('para')) and '' ]]</b></para>
<para style="ueberschrift2"><b>Stornierte Rechnung [[ ((o.type == 'out_invoice' and o.state == 'cancel') or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<para style="ueberschrift2"><b>Stornorechnung [[ (o.type=='out_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<para style="ueberschrift2"><b>Stornorechnung [[ (o.type=='in_refund' or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<para style="ueberschrift2"><b>Rechnung [[ (o.type=='in_invoice' or removeParentNode('para')) and '' ]] [[ o.number ]]</b></para>
<spacer length="0.5cm"/>
<blockTable colWidths="30,57,203,45,60,40,75" repeatRows="1" style="TabelleHaupt" hAlign="LEFT">
<blockTable colWidths="30,57,170,75,63,40,75" repeatRows="1" style="TabelleHaupt" hAlign="LEFT">
<tr>
<td>
<para style="tabelle_header">Pos</para>
</td>
<td>
<para style="tabelle_header">Art-nr.</para>
<para style="tabelle_header">Art.nr.</para>
</td>
<td>
<para style="tabelle_header_links">Bezeichnung</para>
</td>
<td>
<para style="tabelle_header">Menge</para>
</td>
<para style="tabelle_header_links">Menge</para>
</td>
<td>
<para style="tabelle_header_rechts">E-Preis</para>
<para style="tabelle_header_rechts">Einzelpreis</para>
</td>
<td>
<para style="tabelle_header"></para>
@ -125,8 +128,8 @@
</section>
</td>
<td>
<para style="tabelle_daten_center">[[formatLang(line.quantity, digits=2)[-2:]=='00' and formatLang(line.quantity, digits=0) or formatLang(line.quantity, digits=2)]]</para>
</td>
<para style="tabelle_daten_links">[[formatLang(line.quantity, digits=2)[-2:]=='00' and formatLang(line.quantity, digits=0) or formatLang(line.quantity, digits=2)]] [[ line.uos_id.name ]]</para>
</td>
<td>
<para style="tabelle_daten_rechts">[[ formatLang(line.price_unit,digits=2) ]]</para>
</td>
@ -151,15 +154,15 @@
<para style="schlussrechnung">[[ formatLang(o.amount_untaxed,digits=2 )]]</para>
</td>
</tr>
<tr>
<tr>[[ repeatIn(o.tax_line,'tax') ]]
<td>
<para></para>
<para style="schlussrechnung"></para>
</td>
<td>
<para style="schlussrechnung">MwSt. in €</para>
<para style="schlussrechnung">MwSt. [[tax.name.split(" ")[0] or ""]] in €</para>
</td>
<td>
<para style="schlussrechnung">[[ formatLang(o.amount_tax,digits=2 ) ]]</para>
<para style="schlussrechnung">[[ formatLang(tax.tax_amount) ]]</para>
</td>
</tr>
<tr>
@ -173,7 +176,18 @@
<para style="schlussrechnung_fett">[[ formatLang(o.amount_total,digits=2 ) ]]</para>
</td>
</tr>
</blockTable>
<tr>
<td>
<para></para>
</td>
<td>
<para style="schlussrechnung">Rechnungsbetrag inkl. Skonto in €</para>
</td>
<td>
<para style="schlussrechnung">[[ (o.skonto_betrag_inkl and formatLang(o.skonto_betrag_inkl,digits=2)) or removeParentNode('tr') ]]</para>
</td>
</tr>
</blockTable>
<spacer length="0.5cm"/>
@ -184,8 +198,8 @@
</section>
<spacer length="0.5cm"/>
<blockTable colWidths="110,300" style="Struktur" hAlign="LEFT">
<blockTable colWidths="110,390" style="Struktur" hAlign="LEFT">
<tr>
<td>
<para style="normal">Zahlungsbedingungen:</para>
@ -196,13 +210,27 @@
</tr>
</blockTable>
<!--
<spacer length="0.5cm"/>
<para style="normal">Vielen Dank für Ihren Auftrag!</para>
<spacer length="0.5cm"/>
<para style="normal">
Bis zur Bezahlung aller Ansprüche aus den Geschäftsverbindungen behält sich der Verkäufer das Eigentum an seinen Warenlieferungen vor. Es gelten unsere Allgemeinen Geschäftsbedingungen.
</para>
<blockTable colWidths="500" style="Struktur" hAlign="LEFT">
<tr>
<td>
<para style="normal"></para>
</td>
</tr>
<tr>[[ o.date_due and o.payment_term and o.payment_term.skonto_prozent or removeParentNode('tr') ]]
<td>
<para style="normal">Zahlbar bis [[ formatLang(o.skonto_faelligkeit,date = True) ]] abzüglich [[ formatLang(o.payment_term.skonto_prozent,digits=2) ]]% beträgt [[ formatLang(o.skonto_betrag_inkl,digits=2) ]]€.</para>
</td>
</tr>
<tr>[[ o.date_due or removeParentNode('tr') ]]
<td>
<para style="normal">Zahlbar bis [[ formatLang(o.date_due,date = True) ]] ohne Abzug.</para>
</td>
</tr>
</blockTable>
-->
</story>
</document>

View File

@ -38,7 +38,7 @@
<blockTableStyle id="TabelleHaupt">
<blockAlignment value="LEFT"/>
<blockValign value="MIDDLE"/>
<blockValign value="TOP"/>
<lineStyle kind="LINEBELOW" colorName="#000000" thickness="0.5"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="0,0" stop="-1,0" thickness="1"/>
<lineStyle kind="LINEBELOW" colorName="#000000" start="0,-1" stop="-1,-1" thickness="1"/>
@ -48,54 +48,50 @@
<blockValign value="MIDDLE"/>
</blockTableStyle>
</stylesheet>
<pageGraphics>
<!-- Logo -->
<image x="13cm" y="26.75cm" height="46" width="180" preserveAspectRatio="1" >[[ company.logo]]</image>
<!-- Absenderkopf -->
<place x="1.5cm" y="24.5cm" height="1.5cm" width="14cm">
<para style="header"><u>[[ company.partner_id.name ]], [[ company.partner_id.street ]], [[ company.partner_id.zip ]] [[ company.partner_id.city ]]</u></para>
<!-- Logo Oben 1 -->
<place x="1.75cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">[[ company.partner_id.name ]]</para>
<para style="footer">[[ company.street ]]</para>
<para style="footer">[[ company.zip ]] [[ company.city ]]</para>
<para style="footer">[[ company.country_id.name ]]</para>
</place>
<!-- Seitenzahl -->
<setFont name="Helvetica" size="9"/>
<drawRightString x="18.9cm" y="3.5cm">Seite <pageNumber/> </drawRightString>
<!-- Logo Oben 2 -->
<place x="6.90cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">Telefon:</para>
<para style="footer">Telefax:</para>
<para style="footer">E-Mail:</para>
<para style="footer">Web:</para>
</place>
<place x="8.10cm" y="24.75cm" height="3cm" width="7cm">
<para style="footer">[[ company.phone ]]</para>
<para style="footer">[[ company.fax ]]</para>
<para style="footer">[[ company.partner_id.email ]]</para>
<para style="footer">[[ company.partner_id.website ]]</para>
</place>
<!-- Logo Oben -->
<image x="13.80cm" y="26.60cm" height="1.5cm" preserveAspectRatio="1">[[ company.logo]]</image>
<!-- Seperator -->
<fill color="#000000"/>
<rect x="1.4cm" y="3.1cm" width="17.5cm" height="0.01cm" fill="yes" stroke="no"/>
<rect x="1.70cm" y="26.40cm" width="18.00cm" height="0.01cm" fill="yes" stroke="no"/>
<!-- Seperator -->
<rect x="1.70cm" y="1.85cm" width="18.00cm" height="0.01cm" fill="yes" stroke="no"/>
<!-- Footer links -->
<place x="1.5cm" y="0cm" height="3cm" width="7cm">
<para style="footer">--</para>
<para style="footer">--</para>
<para style="footer">--</para>
<para style="footer"></para>
<para style="footer"></para>
<para style="footer"></para>
</place>
<!-- Footer Mitte -->
<place x="8cm" y="0cm" height="3cm" width="7cm">
<para style="footer">[[ company.partner_id.street ]]</para>
<para style="footer">[[ company.partner_id.zip ]] [[ company.partner_id.city ]]</para>
<para style="footer">UID: [[company.vat ]]</para>
<para style="footer"></para>
<para style="footer"></para>
<para style="footer"></para>
<place x="1.75cm" y="0cm" height="1.75cm" width="18cm">
<para style="footer">Bankverbindung: BANK, IBAN: AT000000000000000000, BIC: AAAAAAAA</para>
<para style="footer">UID: [[company.vat ]], FN: [[ company.company_registry ]]</para>
<para style="footer">Die Ware bleibt bis zur vollständigen Bezahlung unser Eigentum.</para>
</place>
<!-- Footer rechts -->
<place x="15cm" y="0cm" height="3cm" width="7cm">
<para style="footer"></para>
<para style="footer"></para>
<para style="footer"></para>
<para style="footer"></para>
<para style="footer"></para>
<para style="footer"></para>
<para style="footer"></para>
<para style="footer"></para>
</place>
<!-- Seitenzahl -->
<setFont name="Helvetica" size="8"/>
<drawRightString x="561" y="58">Seite <pageNumber/> </drawRightString>
</pageGraphics>

View File

@ -1,85 +1,90 @@
<?xml version="1.0"?>
<!--
<reports>
<report>sale.report_saleorder</report>
</reports>
-->
<document filename="Sales Order.pdf">
<template pageSize="(595.0,842.0)" title="Sale Order" author="Andreas Brückl" allowSplitting="20">
<document filename="Auftrag.pdf">
<template pageSize="(595.0,842.0)" title="Sale Order" author="Camadeus Consulting" allowSplitting="20">
<pageTemplate id="first">
<frame id="first" x1="15.0" y1="42.0" width="539" height="758"/>
</pageTemplate>
</template>
<story>
<para>
<seqReset id="L1"/>
</para>
<para>[[repeatIn(objects,'o')]] [[ setLang(o.partner_id.commercial_partner_id.lang)]]</para>
<para style="fett">[[ o.partner_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (o.partner_id.commercial_partner_id.id != o.partner_id.id and o.partner_id.name) or '' ]] </para>
<para style="normal">[[ (o.partner_id.street ) or '']]</para>
<para style="normal">[[ (o.partner_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (o.partner_id.zip) or '' ]] [[ (o.partner_id and o.partner_id.city) or '' ]]</para>
<para style="normal">[[ (o.partner_id.state_id and o.partner_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (o.partner_id.country_id and o.partner_id.country_id.name) or '' ]]</para>
<blockTable colWidths="100,110" style="Struktur" hAlign="RIGHT">
<tr>
<td>
<para style="normal">Ihre Referenz:</para>
</td>
<td>
<para style="normal">[[ o.client_order_ref ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Ansprechpartner:</para>
</td>
<td>
<para style="normal">[[ (o.user_id and o.user_id.name) or '' ]]</para>
</td>
</tr>
<tr> [[ o.user_id and o.user_id.phone or removeParentNode('tr') ]]
<td>
<para style="normal">Tel.:</para>
</td>
<td>
<para style="normal">[[ (o.user_id and o.user_id.phone) or '' ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Ihre UID:</para>
</td>
<td>
<para style="normal">[[ o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.vat or '' ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Angebotsdatum:[[ o.state not in ['draft','sent'] and removeParentNode('para') ]]</para>
<para style="normal">Bestelldatum:[[ o.state in ['draft','sent'] and removeParentNode('para') ]]</para>
</td>
<td>
<para style="normal">[[ formatLang(o.date_order,date = True) ]]</para>
</td>
</tr>
</blockTable>
<blockTable colWidths="270,85,145" style="Struktur">
<tr>
<td>
<section>
<para style="fett">[[ o.partner_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (o.partner_id.commercial_partner_id.id != o.partner_id.id and o.partner_id.name) or '' ]] </para>
<para style="normal">[[ (o.partner_id.street ) or '']]</para>
<para style="normal">[[ (o.partner_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (o.partner_id.zip) or '' ]] [[ (o.partner_id and o.partner_id.city) or '' ]]</para>
<para style="normal">[[ (o.partner_id.state_id and o.partner_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (o.partner_id.country_id and o.partner_id.country_id.name) or '' ]]</para>
<!-- Für Sichtfenster -->
<section>[[ not (o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.ref) or removeParentNode('section') ]]
<para style="normal">&#160;</para>
</section>
</section>
<para></para>
</td>
<td>
<para style="normal">Angebotsdatum:[[ o.state not in ['draft','sent'] and removeParentNode('para') ]]</para>
<para style="normal">Bestelldatum:[[ o.state in ['draft','sent'] and removeParentNode('para') ]]</para>
<para style="normal">Quelldokument:</para>
<para style="normal">Referenz:</para>
<!--<para style="normal">Kundennummer:</para>-->
<para style="normal">Kunde UID Nr.:</para>
<para style="normal">Ansprechpartner:</para>
</td>
<td>
<para style="normal">[[ formatLang(o.date_order,date = True) ]]&#160;</para>
<para style="normal">[[ o.origin ]]&#160;</para>
<para style="normal">[[ o.client_order_ref ]]&#160;</para>
<!--<para style="normal">[[ o.partner_id.commercial_partner_id.ref ]]&#160;</para>-->
<para style="normal">[[ o.partner_id.commercial_partner_id and o.partner_id.commercial_partner_id.vat or '' ]]&#160;</para>
<para style="normal">[[ (o.user_id and o.user_id.name) or '' ]]&#160;</para>
</td>
</tr>
<!--
<tr>
<td>
<section>[[ (o.partner_shipping_id and o.partner_shipping_id.id != o.partner_id.id) or removeParentNode('section')]]
<spacer length="0.5cm"/>
<para style="normal">Lieferadresse:</para>
<para style="normal">[[ o.partner_shipping_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (o.partner_shipping_id.commercial_partner_id.id != o.partner_shipping_id.id and o.partner_shipping_id.name) or '' ]] </para>
<para style="normal">[[ (o.partner_shipping_id.street ) or '']]</para>
<para style="normal">[[ (o.partner_shipping_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (o.partner_shipping_id.zip) or '' ]] [[ (o.partner_shipping_id and o.partner_shipping_id.city) or '' ]]</para>
<para style="normal">[[ (o.partner_shipping_id.state_id and o.partner_shipping_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (o.partner_shipping_id.country_id and o.partner_shipping_id.country_id.name) or '' ]]</para>
</section>
<para style="normal">&#160;</para>
</td>
<td>
<para style="normal">&#160;</para>
</td>
<td>
<para style="normal">&#160;</para>
</td>
</tr>
-->
</blockTable>
<spacer length="1.0cm"/>
<section>
<para style="ueberschrift"><b>[[ o.state not in ['draft','sent'] and removeParentNode('para') ]] Angebot [[ o.name ]]</b></para>
<para style="ueberschrift"><b>[[ o.state in ['draft','sent'] and removeParentNode('para') ]] Bestellbestätigung [[ o.name ]]</b></para>
<para style="ueberschrift2"><b>[[ o.state not in ['draft','sent'] and removeParentNode('para') ]] Angebot [[ o.name ]]</b></para>
<para style="ueberschrift2"><b>[[ o.state in ['draft','sent'] and removeParentNode('para') ]] Bestellbestätigung [[ o.name ]]</b></para>
</section>
<spacer length="0.5cm"/>
<blockTable colWidths="30,57,213,45,50,40,75" repeatRows="1" style="TabelleHaupt" hAlign="LEFT">
<blockTable colWidths="30,57,170,75,63,40,75" repeatRows="1" style="TabelleHaupt" hAlign="LEFT">
<tr>
<td>
<para style="tabelle_header">Pos</para>
@ -91,10 +96,10 @@
<para style="tabelle_header_links">Bezeichnung</para>
</td>
<td>
<para style="tabelle_header">Menge</para>
</td>
<para style="tabelle_header_links">Menge</para>
</td>
<td>
<para style="tabelle_header_rechts">E-Preis</para>
<para style="tabelle_header_rechts">Einzelpreis</para>
</td>
<td>
<para style="tabelle_header"></para>
@ -103,7 +108,7 @@
<para style="tabelle_header_rechts">Gesamtpreis</para>
</td>
</tr>
<tr>[[repeatIn(o.order_line,'line')]]
<td>
<para style="tabelle_daten_center" leftIndent="0" bulletIndent="0" size="8.0">
@ -118,12 +123,11 @@
<section>[[ repeatIn((line.name or '').split('\n\n')[1:],'paragraphs') ]]
<spacer length="0.4cm"/>
<para style="tabelle_daten_links">[[ paragraphs ]]</para>
</section>
</section>
</td>
<td>
<para style="tabelle_daten_center">[[ formatLang(line.product_uos and line.product_uos_qty or line.product_uom_qty, digits=0) ]]</para>
</td>
<para style="tabelle_daten_links">[[ formatLang(line.product_uos and line.product_uos_qty or line.product_uom_qty, digits=0) ]] [[ line.product_uom.name ]]</para>
</td>
<td>
<para style="tabelle_daten_rechts">[[ formatLang(line.price_unit,digits=2) ]]</para>
</td>
@ -135,7 +139,7 @@
</td>
</tr>
</blockTable>
<blockTable colWidths="210,200,100" style="TabelleSchlussrechnung">
<tr>
<td>
@ -170,6 +174,17 @@
<para style="schlussrechnung_fett">[[ formatLang(o.amount_total,digits=2 ) ]]</para>
</td>
</tr>
<tr>
<td>
<para></para>
</td>
<td>
<para style="schlussrechnung">Rechnungsbetrag inkl. Skonto in €</para>
</td>
<td>
<para style="schlussrechnung">[[ (o.skonto_betrag_inkl and formatLang(o.skonto_betrag_inkl,digits=2)) or removeParentNode('tr') ]]</para>
</td>
</tr>
</blockTable>
<spacer length="0.5cm"/>
@ -181,19 +196,39 @@
</section>
<spacer length="0.5cm"/>
<blockTable colWidths="110,300" style="Struktur" hAlign="LEFT">
<blockTable colWidths="110,390" style="Struktur" hAlign="LEFT">
<tr>
<td>
<para style="normal">Zahlungsziele:</para>
<para style="normal">Zahlungsbedingungen:</para>
</td>
<td>
<para style="normal">[[ (o.payment_term and o.payment_term.note) or removeParentNode('blockTable') ]]</para>
</td>
</tr>
</blockTable>
<!--
<spacer length="0.5cm"/>
<blockTable colWidths="500" style="Struktur" hAlign="LEFT">
<tr>
<td>
<para style="normal"></para>
</td>
</tr>
<tr>[[ o.date_due and o.payment_term and o.payment_term.skonto_prozent or removeParentNode('tr') ]]
<td>
<para style="normal">Zahlbar bis [[ formatLang(o.skonto_faelligkeit,date = True) ]] abzüglich [[ formatLang(o.payment_term.skonto_prozent,digits=2) ]]% beträgt [[ formatLang(o.skonto_betrag_inkl,digits=2) ]]€.</para>
</td>
</tr>
<tr>[[ o.date_due or removeParentNode('tr') ]]
<td>
<para style="normal">Zahlbar bis [[ formatLang(o.date_due,date = True) ]] ohne Abzug.</para>
</td>
</tr>
</blockTable>
-->
</story>
</document>

View File

@ -1,69 +1,53 @@
<?xml version="1.0"?>
<!--
<reports>
<report>stock.report_picking</report>
</reports>
-->
<document filename="test.pdf">
<template pageSize="(595.0,842.0)" title="Test" author="Martin Simon" allowSplitting="20">
<document filename="Lieferschein.pdf">
<template pageSize="(595.0,842.0)" title="Sale Order" author="Camadeus Consulting" allowSplitting="20">
<pageTemplate id="first">
<frame id="first" x1="34.0" y1="57.0" width="504" height="728"/>
<frame id="first" x1="15.0" y1="42.0" width="539" height="758"/>
</pageTemplate>
</template>
<story>
<para>
<seqReset id="L1"/>
</para>
<para>[[ repeatIn(objects,'picking') ]] [[ picking.partner_id and setLang(picking.partner_id.lang) ]]</para>
<para style="fett">[[ picking.partner_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (picking.partner_id.commercial_partner_id.id != picking.partner_id.id and picking.partner_id.name) or '' ]] </para>
<para style="normal">[[ (picking.partner_id and picking.partner_id.street ) or '']]</para>
<para style="normal">[[ (picking.partner_id and picking.partner_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (picking.partner_id and picking.partner_id.zip) or '' ]] [[ (picking.partner_id and picking.partner_id.city) or '' ]]</para>
<para style="normal">[[ (picking.partner_id and picking.partner_id.state_id and picking.partner_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (picking.partner_id and picking.partner_id.country_id and picking.partner_id.country_id.name) or '' ]]</para>
<blockTable colWidths="100,110" style="Struktur" hAlign="RIGHT">
<tr>
<td>
<para style="normal">Bestellung:</para>
</td>
<td>
<para style="normal">[[ picking.origin ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Datum:</para>
</td>
<td>
<para style="normal">[[ formatLang(picking.date_done, date=True) or formatLang(time.strftime('%Y-%m-%d'),date=True) ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Referenz:</para>
</td>
<td>
<para style="normal">[[ picking.sale_id and picking.sale_id.client_order_ref or '' ]]</para>
</td>
</tr>
<tr>
<td>
<para style="normal">Kundennr.:</para>
</td>
<td>
<para style="normal">[[ picking.partner_id and picking.partner_id.commercial_partner_id and picking.partner_id.commercial_partner_id.ref or '' ]]</para>
</td>
</tr>
</blockTable>
<blockTable colWidths="270,85,145" style="Struktur">
<tr>
<td>
<section>
<para style="fett">[[ picking.partner_id.commercial_partner_id.name ]]</para>
<para style="normal">[[ (picking.partner_id.commercial_partner_id.id != picking.partner_id.id and picking.partner_id.name) or '' ]] </para>
<para style="normal">[[ (picking.partner_id.street ) or '']]</para>
<para style="normal">[[ (picking.partner_id.street2) or removeParentNode('para') ]]</para>
<para style="normal">[[ (picking.partner_id.zip) or '' ]] [[ (picking.partner_id and picking.partner_id.city) or '' ]]</para>
<para style="normal">[[ (picking.partner_id.state_id and picking.partner_id.state_id.name) or removeParentNode('para')]]</para>
<para style="normal">[[ (picking.partner_id.country_id and picking.partner_id.country_id.name) or '' ]]</para>
<!-- Für Sichtfenster -->
<section>[[ not (picking.partner_id.commercial_partner_id and picking.partner_id.commercial_partner_id.ref) or removeParentNode('section') ]]
<para style="normal">&#160;</para>
</section>
</section>
<para></para>
</td>
<td>
<para style="normal">Datum:</para>
<para style="normal">Bestellung:</para>
<para style="normal">Kundenreferenz:</para>
<para style="normal">Kundennr.:</para>
</td>
<td>
<para style="normal">[[ formatLang(picking.date_done, date=True) or formatLang(time.strftime('%Y-%m-%d'),date=True) ]]&#160;</para>
<para style="normal">[[ picking.origin ]]&#160;</para>
<para style="normal">[[ picking.sale_id and picking.sale_id.client_order_ref or '' ]]&#160;</para>
<para style="normal">[[ picking.partner_id and picking.partner_id.commercial_partner_id and picking.partner_id.commercial_partner_id.ref or '' ]]&#160;</para>
</td>
</tr>
</blockTable>
<spacer length="1.0cm"/>
<para style="ueberschrift">Lieferschein [[ picking.name ]]</para>
<spacer length="0.5cm"/>

View File

@ -0,0 +1,27 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2013 ZestyBeanz Technologies Pvt. Ltd.
# (http://wwww.zbeanztech.com)
# contact@zbeanztech.com
# prajul@zbeanztech.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
import trml2pdf
import controllers
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,41 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2013 ZestyBeanz Technologies Pvt. Ltd.
# (http://wwww.zbeanztech.com)
# contact@zbeanztech.com
# prajul@zbeanztech.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': 'Web Printscreen ZB',
'version': '1.0',
'category': 'Web',
'description': """
Module to export current active tree view in to excel report
""",
'author': 'Zesty Beanz Technologies',
'website': 'http://www.zbeanztech.com',
'depends': ['web'],
'data': ['views/web_printscreen_zb.xml'],
'qweb': ['static/src/xml/web_printscreen_export.xml'],
'installable': True,
'auto_install': False,
'web_preload': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,185 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2013 ZestyBeanz Technologies Pvt. Ltd.
# (http://wwww.zbeanztech.com)
# contact@zbeanztech.com
# prajul@zbeanztech.com
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
try:
import json
except ImportError:
import simplejson as json
import openerp.addons.web.http as openerpweb
from openerp.addons.web.controllers.main import ExcelExport
from openerp.addons.web.controllers.main import Export
import re
from cStringIO import StringIO
from lxml import etree
import trml2pdf
import time, os
import locale
import openerp.tools as tools
try:
import xlwt
except ImportError:
xlwt = None
class ZbExcelExport(ExcelExport):
_cp_path = '/web/export/zb_excel_export'
def from_data(self, fields, rows):
workbook = xlwt.Workbook()
worksheet = workbook.add_sheet('Sheet 1')
style = xlwt.easyxf('align: wrap yes')
font = xlwt.Font()
font.bold = True
style.font = font
ignore_index = []
count = 0
for i, fieldname in enumerate(fields):
if fieldname.get('header_data_id', False):
field_name = fieldname.get('header_name', '')
worksheet.write(0, i-count, field_name, style)
worksheet.col(i).width = 8000
else:
count += 1
ignore_index.append(i)
style = xlwt.easyxf('align: wrap yes')
bold_style = xlwt.easyxf('align: wrap yes')
font = xlwt.Font()
font.bold = True
bold_style.font = font
for row_index, row in enumerate(rows):
count = 0
for cell_index, cell_value in enumerate(row):
if cell_index not in ignore_index:
cell_style = style
if cell_value.get('bold', False):
cell_style = bold_style
cellvalue = cell_value.get('data', '')
if isinstance(cellvalue, basestring):
cellvalue = re.sub("\r", " ", cellvalue)
if cell_value.get('number', False) and cellvalue:
cellvalue = float(cellvalue)
if cellvalue is False: cellvalue = None
worksheet.write(row_index + 1, cell_index - count, cellvalue, cell_style)
else:
count += 1
fp = StringIO()
workbook.save(fp)
fp.seek(0)
data = fp.read()
fp.close()
return data
@openerpweb.httprequest
def index(self, req, data, token):
data = json.loads(data)
return req.make_response(
self.from_data(data.get('headers', []), data.get('rows', [])),
headers=[
('Content-Disposition', 'attachment; filename="%s"'
% data.get('model', 'Export.xls')),
('Content-Type', self.content_type)
],
cookies={'fileToken': token}
)
class ExportPdf(Export):
_cp_path = '/web/export/zb_pdf'
fmt = {
'tag': 'pdf',
'label': 'PDF',
'error': None
}
@property
def content_type(self):
return 'application/pdf'
def filename(self, base):
return base + '.pdf'
def from_data(self, uid, fields, rows, company_name):
pageSize=[210.0,297.0]
new_doc = etree.Element("report")
config = etree.SubElement(new_doc, 'config')
def _append_node(name, text):
n = etree.SubElement(config, name)
n.text = text
_append_node('date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))))
_append_node('PageSize', '%.2fmm,%.2fmm' % tuple(pageSize))
_append_node('PageWidth', '%.2f' % (pageSize[0] * 2.8346,))
_append_node('PageHeight', '%.2f' %(pageSize[1] * 2.8346,))
_append_node('PageFormat', 'a4')
_append_node('header-date', time.strftime(str(locale.nl_langinfo(locale.D_FMT).replace('%y', '%Y'))))
_append_node('company', company_name)
l = []
t = 0
temp = []
tsum = []
skip_index = []
header = etree.SubElement(new_doc, 'header')
i = 0
for f in fields:
if f.get('header_data_id', False):
value = f.get('header_name', "")
field = etree.SubElement(header, 'field')
field.text = tools.ustr(value)
else:
skip_index.append(i)
i += 1
lines = etree.SubElement(new_doc, 'lines')
for row_lines in rows:
node_line = etree.SubElement(lines, 'row')
j = 0
for row in row_lines:
if not j in skip_index:
para = "yes"
tree = "no"
value = row.get('data', '')
if row.get('bold', False):
para = "group"
if row.get('number', False):
tree = "float"
col = etree.SubElement(node_line, 'col', para=para, tree=tree)
col.text = tools.ustr(value)
j += 1
transform = etree.XSLT(
etree.parse(os.path.join(tools.config['root_path'],
'addons/base/report/custom_new.xsl')))
rml = etree.tostring(transform(new_doc))
self.obj = trml2pdf.parseNode(rml, title='Printscreen')
return self.obj
class ZbPdfExport(ExportPdf):
_cp_path = '/web/export/zb_pdf_export'
@openerpweb.httprequest
def index(self, req, data, token):
data = json.loads(data)
uid = data.get('uid', False)
return req.make_response(self.from_data(uid, data.get('headers', []), data.get('rows', []),
data.get('company_name','')),
headers=[('Content-Disposition',
'attachment; filename=PDF Export'),
('Content-Type', self.content_type)])
# cookies={'fileToken': long(token)})
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,122 @@
openerp.web_printscreen_zb = function(instance, m) {
var _t = instance.web._t;
var QWeb = instance.web.qweb;
instance.web.ListView.include({
load_list: function () {
var self = this;
this._super.apply(this, arguments);
self.$pager.find(".oe_list_button_import_excel").unbind('click').click(function(event){self.export_to_excel("excel")})
self.$pager.find(".oe_list_button_import_pdf").unbind('click').click(function(event){self.export_to_excel("pdf")})
},
export_to_excel: function(export_type) {
var self = this
var export_type = export_type
view = this.getParent()
// Find Header Element
header_eles = self.$el.find('.oe_list_header_columns')
header_name_list = []
$.each(header_eles,function(){
$header_ele = $(this)
header_td_elements = $header_ele.find('th')
$.each(header_td_elements,function(){
$header_td = $(this)
text = $header_td.text().trim() || ""
data_id = $header_td.attr('data-id')
if (text && !data_id){
data_id = 'group_name'
}
header_name_list.push({'header_name': text.trim(), 'header_data_id': data_id})
// }
});
});
//Find Data Element
data_eles = self.$el.find('.oe_list_content > tbody > tr')
export_data = []
$.each(data_eles,function(){
data = []
$data_ele = $(this)
is_analysis = false
if ($data_ele.text().trim()){
//Find group name
group_th_eles = $data_ele.find('th')
$.each(group_th_eles,function(){
$group_th_ele = $(this)
text = $group_th_ele.text().trim() || ""
is_analysis = true
data.push({'data': text, 'bold': true})
});
data_td_eles = $data_ele.find('td')
$.each(data_td_eles,function(){
$data_td_ele = $(this)
text = $data_td_ele.text().trim() || ""
if ($data_td_ele && $data_td_ele[0].classList.contains('oe_number') && !$data_td_ele[0].classList.contains('oe_list_field_float_time')){
text = text.replace('%', '')
text = instance.web.parse_value(text, { type:"float" })
data.push({'data': text || "", 'number': true})
}
else{
data.push({'data': text})
}
});
export_data.push(data)
}
});
//Find Footer Element
footer_eles = self.$el.find('.oe_list_content > tfoot> tr')
$.each(footer_eles,function(){
data = []
$footer_ele = $(this)
footer_td_eles = $footer_ele.find('td')
$.each(footer_td_eles,function(){
$footer_td_ele = $(this)
text = $footer_td_ele.text().trim() || ""
if ($footer_td_ele && $footer_td_ele[0].classList.contains('oe_number')){
text = instance.web.parse_value(text, { type:"float" })
data.push({'data': text || "", 'bold': true, 'number': true})
}
else{
data.push({'data': text, 'bold': true})
}
});
export_data.push(data)
});
//Export to excel
$.blockUI();
if (export_type === 'excel'){
view.session.get_file({
url: '/web/export/zb_excel_export',
data: {data: JSON.stringify({
model : view.model,
headers : header_name_list,
rows : export_data,
})},
complete: $.unblockUI
});
}
else{
console.log(view)
new instance.web.Model("res.users").get_func("read")(this.session.uid, ["company_id"]).then(function(res) {
new instance.web.Model("res.company").get_func("read")(res['company_id'][0], ["name"]).then(function(result) {
view.session.get_file({
url: '/web/export/zb_pdf_export',
data: {data: JSON.stringify({
uid: view.session.uid,
model : view.model,
headers : header_name_list,
rows : export_data,
company_name: result['name']
})},
complete: $.unblockUI
});
});
});
}
},
});
};

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-extend="ViewPager">
<t t-jquery=".oe_pager_value" t-operation="prepend">
<a t-if="(widget.ViewManager &amp;&amp; widget.ViewManager.active_view) === 'list'"
class="oe_bold oe_list_button_import_pdf"
id="button_export_pdf"
href="#">PDF</a>
<label t-if="(widget.ViewManager &amp;&amp; widget.ViewManager.active_view) === 'list'">or</label>
<a t-if="(widget.ViewManager &amp;&amp; widget.ViewManager.active_view) === 'list'"
class="oe_bold oe_list_button_import_excel"
id="button_export_excel"
href="#">Excel</a>
</t>
</t>
</templates>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- vim:fdn=3:
-->
<openerp>
<data>
<template id="assets_backend" name="web_printscreen_zb assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript" src="/web_printscreen_zb/static/src/js/web_printscreen_export.js"></script>
</xpath>
</template>
</data>
</openerp>

View File

@ -1,33 +0,0 @@
#!/bin/sh
#dump the OpenERP DB (postgreSQL)
#author: Camadeus GmbH
hostname=`/bin/hostname`
dbnames=`psql -d postgres -c "SELECT datname FROM pg_database WHERE NOT datistemplate AND datname <> 'postgres'" --tuples-only`
# Dump DBs
for db in $dbnames
do
echo "creating backup for db: " $db
date=`date +"%Y%m%d_%H%M%N"`
filename="/var/pgdump/${hostname}_${db}_${date}.sql"
pg_dump -E UTF-8 -F p -b -f $filename $db
chmod 600 $filename
gzip $filename
done
##########################################
## Housekeeping
##########################################
for file in `find /var/pgdump/ -mtime +30 -type f -name '*.sql.gz'`
do
echo "deleting: " $file
rm $file
done
exit 0

View File

@ -13,7 +13,7 @@ def main():
argv = sys.argv[1:]
if not len(argv) == 2:
if len(argv) == 3 and argv[1] == 'update': # 'update' requires additional param 'module_name'
if len(argv) == 3 and argv[1] in ['update','install']: # 'update' requires additional param 'module_name'
pass
else:
_usage()
@ -41,7 +41,7 @@ def main():
'install_module_sale',
'setup_accounting',
'setup_accounting2',
'set_admin_rights',
'set_admin_rights',
]
if cmd == 'setup':
@ -52,51 +52,66 @@ def main():
'set_warehouse',
'base_config',
'sale_config',
'set_date_format',
'set_company',
'set_taxes',
'set_uom',
'set_steuerzuordnung',
'setup_journals',
'stock_config',
'set_incoterms',
'purchase_config',
'set_date_format',
'set_company',
'set_taxes',
'set_uom',
'set_steuerzuordnung',
'setup_journals',
'set_currencies',
'set_decimal_price',
]
if cmd == 'rollout':
methods = [
'login',
'set_dokumentennummern',
]
'set_dokumentennummern',
'set_dmi_noupdate',
'dmi_confirm_inventory',
'setup_mail_server',
]
if cmd == 'update':
instance.config.module_name = argv[2]
methods = [
'login',
'update_module',
]
'update_module',
]
if cmd == 'install':
instance.config.module_name = argv[2]
methods = [
'login',
'install_module',
]
if cmd == 'update_modules':
methods = [
'login',
'update_modules',
]
'update_modules',
]
if cmd == 'update_all':
methods = [
'login',
'update_all',
]
'update_all',
]
if not methods:
_usage()
print env
for method in methods:
for method in methods:
res = getattr(instance, method)()
print "%s: %s" % (res and "OK " or "ERROR ", getattr(instance, method).__doc__)
if not res:
return False
print "\nAbgeschlossen."
if __name__ == "__main__":
main()
main()

View File

@ -7,8 +7,10 @@ class Config():
self.chart_of_accounts = 'l10n_at'
self.sales_tax = '20% MwSt'
self.purchase_tax = '20% VSt'
self.chart_template_id = 2 # Austrian Chart of Account
self.chart_template_id = 2 # Austrian Chart of Account
self.price_decimals = 2 # Nachkommastellen Preis
self.uom_decimals = 3 # Nachkommastellen Mengeneinheiten
self.company_data = {
'name': 'Camadeus GmbH',
'street': 'Kriehubergasse 16',
@ -26,8 +28,17 @@ class Config():
'rml_header1': False,
'vat_check_vies': True,
'tax_calculation_rounding_method': 'round_globally',
#'rml_header' : './ext/addons/custom_reports/report/page.rml', # Report File
'logo': '../ext/custom-addons/cam_reports/logo.png',
'logo': '../ext/custom-addons/cam_custom/static/src/img/logo.png',
}
self.mail_server = {
'name': 'test',
'sequence': 0,
'smtp_host': 'smtp.1und1.de',
'smtp_port': '465',
'smtp_encryption': 'ssl',
'smtp_user': 'test',
'smtp_pass': 'test',
}
# Nur für Lager
@ -50,51 +61,78 @@ class Config():
'Kunde Ausland',
'Kunde EU (ohne USt-ID)',
'Kunde EU Unternehmen (mit USt-ID)',
]
]
# Aktive Währungen
self.valid_currencies = [
'EUR',
]
# Allgemeine Einstellungen
self.base_config = {
'module_portal': False, # Kundenportal
'alias_domain': False, # False: keine Domainbezogenen E-Mails (wie zB. Reply-To zur alias-Adresse)
}
# Einstellungen Verkauf
self.sale_config = {
'group_sale_delivery_address': True, # Verschiedene Adressen für Rechnung und Lieferung
'group_sale_pricelist': True, # Preislisten verwenden
'group_discount_per_so_line': True, # Rabatte verwenden
'group_invoice_deli_orders': True, # Erstelle Rechnungen durch Auslieferungen
'group_uom': True, # Verwende Mengeneinheiten
'group_sale_delivery_address': True, # Verschiedene Adressen für Rechnung und Lieferung
'group_sale_pricelist': True, # Preislisten verwenden
'group_discount_per_so_line': True, # Rabatte verwenden
'group_uom': True, # Verwende Mengeneinheiten
'group_invoice_deli_orders': True, # Erstelle Rechnungen durch Auslieferungen
}
# Einstellungen Einkauf
self.purchase_config = {
'group_purchase_pricelist': True, # Preislisten verwenden
'group_purchase_pricelist': True, # Preislisten verwenden
}
#Einstellungen Lager
self.stock_config = {
'group_stock_multiple_locations': True, # Verwalten Sie mehrere Läger und Lagerorte
'group_stock_tracking_lot': False, # Benutze Verpackungen: Paletten, Boxen, ...
'group_stock_packaging': False, # Ermöglicht die Auswahl einer Verpackung
}
# Wenn gesetzt, teilen sich Gutschriften und Rechnungen den selben Nummernkreis
self.refund_invoice_sequence = True
self.sequences = {
'sale.order': {
'number_next_actual': 2000,
'number_next_actual': 1,
'prefix': 'A-',
'padding': 5,
},
# 'work.order': {
# 'number_next_actual': 100,
# 'number_next_actual': 1,
# 'prefix': 'AS-',
# 'padding': 5,
# },
# 'picking.out': {
# 'number_next_actual': 2000,
# 'prefix': 'L-',
# 'padding': 5,
# },
# 'picking.out': {
# #'number_next_actual': 1,
# 'prefix': 'LS/',
# 'padding': 4,
# },
# 'picking.in': {
# #'number_next_actual': 1,
# 'prefix': 'LS/IN/',
# 'padding': 4,
# },
# 'picking.int': {
# #'number_next_actual': 1,
# 'prefix': 'LS/INT/',
# 'padding': 4,
# },
# 'purchase.order': {
# 'number_next_actual': 2000,
# 'prefix': 'PO-',
# 'number_next_actual': 1,
# 'prefix': 'B-',
# 'padding': 5,
# },
# 'account.invoice': {
# 'number_next_actual': 2000,
# 'prefix': '14-',
# 'prefix': '15-',
# 'padding': 4,
# },
}
@ -105,6 +143,13 @@ class Config():
#'product.product_uom_litre': 'l',
#'product.product_uom_hour': 'h',
}
#Lieferbedingungen
self.incoterms = {
('Ab Werk', 'ABW'),
('Botendienst', 'BOT'),
('Zustellung', 'ZUS'),
}
# Soll das Ändern einer Rechnung im Nachhinein erlaubt sein?
self.allow_cancel_invoice = True
@ -118,7 +163,8 @@ class Config():
'cam_custom',
'cam_reports',
'account_cancel',
'cam_invoice_skonto',
'cam_invoice_skonto',
'web_printscreen_zb',
#'crm',
#'sale',
#'cam_hr_overtime',

View File

@ -130,6 +130,7 @@ class CamadeusFunctions():
vals.update(self.config.purchase_config)
wizard_id = self._execute('purchase.config.settings', 'create', vals)
return self._execute('purchase.config.settings', 'execute', [wizard_id])
return True
def sale_config(self):
"""Basiskonfiguration für Verkauf laden"""
@ -137,7 +138,46 @@ class CamadeusFunctions():
vals = self._execute('sale.config.settings', 'default_get', [])
vals.update(self.config.sale_config)
wizard_id = self._execute('sale.config.settings', 'create', vals)
return self._execute('sale.config.settings', 'execute', [wizard_id])
return self._execute('sale.config.settings', 'execute', [wizard_id])
def stock_config(self):
"""Basiskonfiguration für Lager laden"""
if hasattr(self.config, 'stock_config'):
vals = self._execute('stock.config.settings', 'default_get', [])
vals.update(self.config.stock_config)
wizard_id = self._execute('stock.config.settings', 'create', vals)
return self._execute('stock.config.settings', 'execute', [wizard_id])
return True
def set_incoterms(self):
"""Lieferbedingungen setzen"""
if hasattr(self.config, 'incoterms'):
terms = self.config.incoterms
for name,code in terms:
existing_ids = self._execute('stock.incoterms', 'search', ['|',('active','=',True),('active','=',False),('code','=',code)])
if existing_ids:
vals = {
'active': True,
'name': name,
}
self._execute('stock.incoterms', 'write', existing_ids, vals)
else:
vals = {
'name': name,
'code': code,
}
self._execute('stock.incoterms', 'create', vals)
codes = [code for name,code in terms]
inactive_ids = self._execute('stock.incoterms', 'search', [('code','not in',codes)])
self._execute('stock.incoterms', 'write', inactive_ids, {'active': False})
return True
def base_config(self):
"""Allgemeine Konfiguration laden"""
@ -163,18 +203,33 @@ class CamadeusFunctions():
res = self._execute('base.module.upgrade', 'upgrade_module', modules_to_install)
return True
def _set_picking_sequence_prefix(self, code, value):
seq_dict = self.config.sequences
#Hauptsequenz des Picking Types mit diesem code anpassen
picking_type_id = self._execute('stock.picking.type', 'search', [('code','=',code)], 0, 1, 'id')[0]
picking_type = self._execute('stock.picking.type', 'read', picking_type_id, ['sequence_id'])
s_id = picking_type['sequence_id'][0]
if not self._execute('ir.sequence', 'write', s_id, seq_dict.get(value)):
return False
#Allen Picking Types mit diesem code die Haupsequenz geben
picking_type_ids = self._execute('stock.picking.type', 'search', [('code','=',code)])
if not self._execute('stock.picking.type', 'write', picking_type_ids, {'sequence_id': s_id}):
return False
def set_dokumentennummern(self):
"""Dokumentennummern setzen"""
seq_dict = self.config.sequences
# Lieferschein
if seq_dict.get('picking.out',False):
picking_type_ids = self._execute('stock.picking.type', 'search', [])
picking_types = self._execute('stock.picking.type', 'read', picking_type_ids, ['sequence_id'])
s_ids = [t['sequence_id'][0] for t in picking_types]
if not self._execute('ir.sequence', 'write', s_ids, seq_dict.get('picking.out')):
return False
# Lieferschein
if seq_dict.get('picking.out',False):
self._set_picking_sequence_prefix('outgoing', 'picking.out')
if seq_dict.get('picking.in',False):
self._set_picking_sequence_prefix('incoming', 'picking.in')
if seq_dict.get('picking.int',False):
self._set_picking_sequence_prefix('internal', 'picking.int')
# Angebot
if seq_dict.get('sale.order',False):
@ -206,10 +261,26 @@ class CamadeusFunctions():
if len(j_ids) != 1:
return False
journals = self._execute('account.journal', 'read', j_ids, ['sequence_id'])
s_ids = [t['sequence_id'][0] for t in journals]
if not self._execute('ir.sequence', 'write', s_ids, seq_dict.get('account.invoice')):
s_id = journals[0]['sequence_id'][0]
if not self._execute('ir.sequence', 'write', [s_id], seq_dict.get('account.invoice')):
return False
# Setzen Gutschriftenkreis
if self.config.refund_invoice_sequence:
j_ids = self._execute('account.journal', 'search', [('code','=','VK')])
if len(j_ids) != 1:
return False
journals = self._execute('account.journal', 'read', j_ids, ['sequence_id'])
s_id = journals[0]['sequence_id'][0]
gj_ids = self._execute('account.journal', 'search', [('code','=','GSV')])
if len(gj_ids) != 1:
return False
vals = {
'sequence_id': s_id,
}
self._execute('account.journal', 'write', gj_ids,vals)
return True
def set_admin_rights(self):
@ -264,6 +335,25 @@ class CamadeusFunctions():
wizard_id = self._execute('wizard.multi.charts.accounts', 'create', vals)
res = self._execute('wizard.multi.charts.accounts', 'action_next', [wizard_id])
return True
def set_currencies(self):
"""Währungen setzen"""
c = self.config
# Set all currencies to active
ids = self._execute('res.currency', 'search', ['|',('active','=',True),('active','=',False)])
res = self._execute('res.currency', 'write', ids, {'active': True})
if not res:
return False
# Set all other UOMs to inactive
inactive_ids = self._execute('res.currency', 'search', [('name','not in',c.valid_currencies)])
res = self._execute('res.currency', 'write', inactive_ids, {'active': False})
if not res:
return False
return True
def uninstall_chat(self):
"""Chat-Modul deinstallieren """
@ -285,7 +375,13 @@ class CamadeusFunctions():
for uom_xml_id in active_uoms:
uom_id = self._execute('ir.model.data', 'xmlid_to_res_id', uom_xml_id)
active_ids.append(uom_id)
# Set all UOMs to active
ids = self._execute('product.uom', 'search', ['|',('active','=',True),('active','=',False)])
res = self._execute('product.uom', 'write', ids, {'active': True})
if not res:
return False
# Set all other UOMs to inactive
inactive_ids = self._execute('product.uom', 'search', [('id','not in',active_ids)])
res = self._execute('product.uom', 'write', inactive_ids, {'active': False})
@ -328,6 +424,17 @@ class CamadeusFunctions():
res = self._execute('base.module.upgrade', 'upgrade_module', [])
return True
def install_module(self):
"""Installiere Modul"""
module_name = self.config.module_name
mod_ids = self._execute('ir.module.module', 'search', [('name','=',module_name),('state','=','uninstalled')])
if not len(mod_ids) == 1:
raise "Module '%s' not found or is not in state 'uninstalled'." % module_name
res = self._execute('ir.module.module', 'button_install', mod_ids)
res = self._execute('base.module.upgrade', 'upgrade_module', [])
return True
def update_modules(self):
"""Verfügbare Module updaten"""
@ -367,7 +474,64 @@ class CamadeusFunctions():
vals = {
'name': self.config.warehouse_name or self.config.company_data.get('name','Mein Unternehmen')
}
warehouse_ids = self._execute('stock.warehouse', 'search', [])
warehouse_ids = self._execute('stock.warehouse', 'search', [('id','=',1)])
return self._execute('stock.warehouse', 'write', warehouse_ids, vals)
else:
return True
def set_dmi_noupdate(self):
"""DMI: Einträge auf 'no update' setzen"""
domain = [('module','=','cam_dmi'),('noupdate','=',False)]
data_ids = self._execute('ir.model.data', 'search', domain)
vals = {'noupdate': True}
return self._execute('ir.model.data', 'write', data_ids, vals)
def dmi_confirm_inventory(self):
"""DMI: Lagerstand einbuchen"""
dummy,inventory_id = self._execute('ir.model.data', 'get_object_reference', 'cam_dmi','inv_init')
inventory = self._execute('stock.inventory', 'read', inventory_id, ['state'])
if inventory.get('state','') == 'confirm':
return self._execute('stock.inventory', 'action_done', [inventory_id])
return True
def set_decimal_price(self):
"""Dezimalstellen setzen"""
# UOM
decimal_id = self._execute('ir.model.data', 'xmlid_to_res_id', 'product.decimal_product_uom')
res = self._execute('decimal.precision', 'write', [decimal_id], {'digits': self.config.uom_decimals})
if not res:
return False
# Product Price
decimal_id = self._execute('ir.model.data', 'xmlid_to_res_id', 'product.decimal_price')
res = self._execute('decimal.precision', 'write', [decimal_id], {'digits': self.config.price_decimals})
if not res:
return False
# Product Price
ids = self._execute('decimal.precision', 'search', [('name','=','Product Price')])
res = self._execute('decimal.precision', 'write', ids, {'digits': self.config.price_decimals})
if not res:
return False
return True
def setup_mail_server(self):
"""Mailserver einrichten"""
if hasattr(self.config, 'mail_server'):
vals = self.config.mail_server
server_ids = self._execute('ir.mail_server', 'search', [('name','=',vals.get('name'))])
if server_ids:
return self._execute('ir.mail_server', 'write', server_ids, vals)
else:
return self._execute('ir.mail_server', 'create', vals)
return False