Added modules sale_order_optional and sale_order_reminder
							parent
							
								
									e50abf97f9
								
							
						
					
					
						commit
						83121d3b61
					
				|  | @ -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 | ||||
|  | @ -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: | ||||
|  | @ -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 | ||||
|          | ||||
|  | @ -0,0 +1,6 @@ | |||
| <?xml version="1.0" encoding='UTF-8'?> | ||||
| <openerp> | ||||
|     <data> | ||||
| 
 | ||||
|     </data> | ||||
| </openerp> | ||||
|  | @ -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 | 
|  | @ -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 | ||||
|  | @ -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: | ||||
|  | @ -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> | ||||
|  | @ -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) | ||||
|  | @ -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> | ||||
|  | @ -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 | 
|  | @ -156,4 +156,6 @@ class Config(): | |||
|             #'sale', | ||||
|             #'cam_hr_overtime', | ||||
|             #'cam_hr', | ||||
|             #'sale_order_optiona', | ||||
|             #'sale_order_reminder', | ||||
|         ] | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue