Merge branch 'master' of git:~/gitrepos/cam-template

develop
Andreas Brückl 2015-05-20 17:37:26 +02:00
commit 2e5e5328ff
15 changed files with 450 additions and 0 deletions

View File

@ -127,3 +127,14 @@ class mail_notification(osv.Model):
# c.update({'display_default_code': False})
# return super(product_product, self).name_get(cr, user, ids, context=c)
class sale_order_line(models.Model):
_inherit = 'sale.order.line'
@api.onchange('name')
def onchange_name(self):
if self.name != False and self.product_id.id == False:
ir_values = self.pool.get('ir.values')
company = self.env['res.company'].search([], limit=1)
taxes_id = ir_values.get_default(self._cr, self._uid, 'product.template', 'taxes_id', company_id=company.id)
at = self.env['account.tax'].search([('id','=',isinstance(taxes_id, list) and taxes_id[0] or taxes_id)])
self.tax_id = at

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# 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/>.
#
##############################################################################
import sale_order_optional

View File

@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# 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': "Optional Lines for Sale Orders",
'version': "1.0",
'category': "Sales",
'description': """
This addon adds optional sale order lines.
""",
'author': "Camadeus GmbH",
'website': "http://www.camadeus.at",
'css': [],
'images': [],
'depends': ['sale'],
'data': ['sale_order_optional_view.xml',
'sale_order_optional_data.xml',
],
'installable': True,
'auto_install': False,
'application': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,135 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# 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/>.
#
##############################################################################
from openerp.osv import fields, osv
import openerp.addons.decimal_precision as dp
class sale_order(osv.osv):
_inherit = "sale.order"
def _amount_line_tax(self, cr, uid, line, context=None):
val = 0.0
if not line.optional:
for c in self.pool.get('account.tax').compute_all(cr, uid, line.tax_id, line.price_unit * (1-(line.discount or 0.0)/100.0), line.product_uom_qty, line.product_id, line.order_id.partner_id)['taxes']:
val += c.get('amount', 0.0)
return val
def _amount_all(self, cr, uid, ids, field_name, arg, context=None):
cur_obj = self.pool.get('res.currency')
res = {}
for order in self.browse(cr, uid, ids, context=context):
res[order.id] = {
'amount_untaxed': 0.0,
'amount_tax': 0.0,
'amount_total': 0.0,
}
val = val1 = 0.0
cur = order.pricelist_id.currency_id
for line in order.order_line:
val1 += line.price_subtotal
val += self._amount_line_tax(cr, uid, line, context=context)
res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val)
res[order.id]['amount_untaxed'] = cur_obj.round(cr, uid, cur, val1)
res[order.id]['amount_total'] = res[order.id]['amount_untaxed'] + res[order.id]['amount_tax']
return res
def _amount_all_wrapper(self, cr, uid, ids, field_name, arg, context=None):
""" Wrapper because of direct method passing as parameter for function fields """
return self._amount_all(cr, uid, ids, field_name, arg, context=context)
def _get_order(self, cr, uid, ids, context=None):
result = {}
for line in self.pool.get('sale.order.line').browse(cr, uid, ids, context=context):
result[line.order_id.id] = True
return result.keys()
_columns = {
'amount_untaxed': fields.function(_amount_all_wrapper, digits_compute=dp.get_precision('Account'), string='Untaxed Amount',
store={
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
},
multi='sums', help="The amount without tax.", track_visibility='always'),
'amount_tax': fields.function(_amount_all_wrapper, digits_compute=dp.get_precision('Account'), string='Taxes',
store={
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
},
multi='sums', help="The tax amount."),
'amount_total': fields.function(_amount_all_wrapper, digits_compute=dp.get_precision('Account'), string='Total',
store={
'sale.order': (lambda self, cr, uid, ids, c={}: ids, ['order_line'], 10),
'sale.order.line': (_get_order, ['price_unit', 'tax_id', 'discount', 'product_uom_qty'], 10),
},
multi='sums', help="The total amount."),
}
class sale_order_line(osv.osv):
_inherit = 'sale.order.line'
def _fnct_line_invoiced(self, cr, uid, ids, field_name, args, context=None):
res = dict.fromkeys(ids, False)
for this in self.browse(cr, uid, ids, context=context):
res[this.id] = this.invoice_lines and \
all(iline.invoice_id.state != 'cancel' for iline in this.invoice_lines) or \
this.optional
return res
def _order_lines_from_invoice(self, cr, uid, ids, context=None):
# direct access to the m2m table is the less convoluted way to achieve this (and is ok ACL-wise)
cr.execute("""SELECT DISTINCT sol.id FROM sale_order_invoice_rel rel JOIN
sale_order_line sol ON (sol.order_id = rel.order_id)
WHERE rel.invoice_id = ANY(%s)""", (list(ids),))
return [i[0] for i in cr.fetchall()]
def _amount_line(self, cr, uid, ids, field_name, arg, context=None):
tax_obj = self.pool.get('account.tax')
cur_obj = self.pool.get('res.currency')
res = {}
if context is None:
context = {}
for line in self.browse(cr, uid, ids, context=context):
if not line.optional:
price = line.price_unit * (1 - (line.discount or 0.0) / 100.0)
taxes = tax_obj.compute_all(cr, uid, line.tax_id, price, line.product_uom_qty, line.product_id, line.order_id.partner_id)
cur = line.order_id.pricelist_id.currency_id
res[line.id] = cur_obj.round(cr, uid, cur, taxes['total'])
else:
res[line.id] = 0
return res
_columns = {
'invoiced': fields.function(_fnct_line_invoiced, string='Invoiced', type='boolean',
store={
'account.invoice': (_order_lines_from_invoice, ['state'], 10),
'sale.order.line': (lambda self,cr,uid,ids,ctx=None: ids, ['invoice_lines'], 10)
}),
'price_subtotal': fields.function(_amount_line, string='Subtotal', digits_compute= dp.get_precision('Account')),
'optional': fields.boolean('Optional'),
}
def _prepare_order_line_invoice_line(self, cr, uid, line, account_id=False, context=None):
if not line.optional:
return super(sale_order_line, self)._prepare_order_line_invoice_line(cr, uid, line, account_id, context=context)
else:
return False

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding='UTF-8'?>
<openerp>
<data>
</data>
</openerp>

View File

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="view_order_form_optional" model="ir.ui.view">
<field name="name">sale.order.form.optional</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<xpath expr="//tree/field[@name='price_subtotal']" position="after">
<field name="optional"/>
</xpath>
</field>
</record>
</data>
</openerp>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# 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/>.
#
##############################################################################
import sale_order_reminder

View File

@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# 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': "Reminder for Sale Orders",
'version': "1.0",
'category': "Sales",
'description': """
This addon adds the field 'offer_valid_until' in the sale order. If this date is passed and the order is still in state 'draft' or 'sent', then
a reminder email is sent to the sales person every day.
""",
'author': "Camadeus GmbH",
'website': "http://www.camadeus.at",
'css': [],
'images': [],
'depends': ['sale'],
'data': ['sale_order_reminder_view.xml',
'sale_order_reminder_data.xml',
'email_template.xml',
],
'installable': True,
'auto_install': False,
'application': False,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -0,0 +1,46 @@
<?xml version="1.0" ?>
<openerp>
<!-- Mail template is done in a NOUPDATE block
so users can freely customize/delete them -->
<data noupdate="1">
<!--Email template -->
<record id="email_template_sale_reminder" model="email.template">
<field name="name">Erinnerung: Angebot</field>
<field name="email_from">${(object.user_id and object.user_id.email or '')|safe}</field>
<field name="subject">Erinnerung: Angebot ${object.name}</field>
<field name="partner_to">${object.user_id and object.user_id.partner_id.id}</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="auto_delete" eval="True"/>
<field name="body_html"><![CDATA[
<div style="color:#007434; font-size:10.0pt; font-family:Arial Unicode MS sans-serif;">
<p>Erinnerung für folgendes offenes Angebot:</p>
<p>
<table style="color:#007434; font-size:10.0pt; font-family:Arial Unicode MS sans-serif;">
<tr>
<td style='width: 200px;'>Name:</td>
<td><b>${object.name}</b></td>
</tr>
<tr>
<td>Datum:</td>
<td> ${object.date_order}</td>
</tr>
<tr>
<td>Kunde:</td>
<td> ${object.partner_id.display_name}</td>
</tr>
<tr>
<td>Auftragsvolumen (netto):</td>
<td> ${object.amount_untaxed}</td>
</tr>
</table>
</p>
<br>
</div>
]]></field>
</record>
</data>
</openerp>

View File

@ -0,0 +1,68 @@
# -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). All Rights Reserved
# $Id$
#
# 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/>.
#
##############################################################################
from openerp import models, fields, api, _
from datetime import datetime, timedelta
from openerp.tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT
class res_company(models.Model):
_inherit = 'res.company'
sale_offer_days = fields.Integer(string='Tage Gültigkeit Angebot', default=14)
class sale_order(models.Model):
_inherit = 'sale.order'
@api.model
def _offer_valid_until(self):
user = self.env['res.users'].browse(self._uid)
now = datetime.now()
res = now + timedelta(days=user.company_id.sale_offer_days)
return res.strftime(DATE_FORMAT)
offer_valid_until = fields.Date(string='Angebot gültig bis', index=True,
readonly=True, states={'draft': [('readonly', False)], 'sent': [('readonly', False)]},
default=_offer_valid_until)
@api.model
def order_reminder_job(self):
today = fields.Date.today()
orders = self.search([('offer_valid_until','<',today),('state','in',('draft','sent')),('user_id','!=',False)])
template_id = self.env['ir.model.data'].xmlid_to_res_id('sale_order_reminder.email_template_sale_reminder')
context = {'append_link': True}
for order in orders:
res = self.pool.get('email.template').send_mail(self._cr, self._uid, template_id, order.id, True, context=context)
return True
class mail_mail(models.Model):
_inherit = 'mail.mail'
def create(self, cr, uid, vals, context=None):
# notification field: set if it comes from order reminder job
if context is None:
context = {}
if context.get('append_link'):
vals['notification'] = True
return super(mail_mail, self).create(cr, uid, vals, context=context)

View File

@ -0,0 +1,16 @@
<?xml version="1.0" encoding='UTF-8'?>
<openerp>
<data>
<record model="ir.cron" id="cron_sale_offer_reminder">
<field name="name">Reminder for Sale Orders</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="model" eval="'sale.order'"/>
<field name="function" eval="'order_reminder_job'"/>
<field name="args" eval="'()'" />
</record>
</data>
</openerp>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="sale_order_valid_until_form" model="ir.ui.view">
<field name="name">sale_order_valid_until_form</field>
<field name="model">sale.order</field>
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<field name="date_order" position="after">
<field name="offer_valid_until"/>
</field>
</field>
<field name="priority">20</field>
</record> #
<record id="res_company_order_days_form" model="ir.ui.view">
<field name="name">"res_company_order_days_form"</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name="arch" type="xml">
<field name="sale_note" position="after">
<group>
<field name="sale_offer_days"/>
</group>
</field>
</field>
</record>
</data>
</openerp>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@ -185,6 +185,8 @@ class Config():
'sale',
#'cam_hr_overtime',
#'cam_hr',
#'sale_order_optiona',
#'sale_order_reminder',
]
self.users_file = "res.users.csv"