From 64ec79520368a9fc73b37060685701730f4d0014 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 7 Aug 2013 11:47:34 +0200 Subject: [PATCH 01/77] [IMP] website_event: managment of tickets for an event to defined price and max number registration bzr revid: chm@openerp.com-20130807094734-4uwlezgr50m4lwwu --- addons/website_event/event.py | 49 ++++++++++--- .../security/ir.model.access.csv | 2 +- .../website_event/security/website_event.xml | 6 +- addons/website_event/views/website_event.xml | 72 ++++++++++--------- 4 files changed, 83 insertions(+), 46 deletions(-) diff --git a/addons/website_event/event.py b/addons/website_event/event.py index 65a8034951f..58741dfe9d5 100644 --- a/addons/website_event/event.py +++ b/addons/website_event/event.py @@ -2,35 +2,64 @@ from openerp.osv import osv, fields +# defined for access rules +class product(osv.osv): + _inherit = 'product.product' + _columns = { + 'event_ticket_ids': fields.one2many('event.event.ticket', 'product_id', 'Event Tickets'), + } + class event(osv.osv): _inherit = 'event.event' + + def _get_register_max(self, cr, uid, ids, field_name, arg, context=None): + result = dict.fromkeys(ids, 0) + for rec in self.browse(cr, uid, ids, context=context): + result[rec.id] = sum([ep.register_max for ep in rec.event_ticket_ids]) + return result + _columns = { 'website_published': fields.boolean('Available in the website'), 'description_website': fields.html('Description for the website'), - 'event_product_ids': fields.one2many('event.event.product', "event_id", "Event"), + 'event_ticket_ids': fields.one2many('event.event.ticket', "event_id", "Event Ticket"), 'organizer_id': fields.many2one('res.partner', "Orgonizer"), 'phone': fields.related('orgonizer_id', 'phone', type='char', string='Phone'), 'email': fields.related('orgonizer_id', 'email', type='char', string='Email'), + 'register_max': fields.function(_get_register_max, + string='Maximum Registrations', + help="The maximum registration level is equal to the sum of the maximum registration of event ticket." + + "If you have too much registrations you are not able to confirm your event. (0 to ignore this rule )", + type='integer', store=True) } -class event_product(osv.osv): - _name = 'event.event.product' +class event_ticket(osv.osv): + _name = 'event.event.ticket' + + def _get_register_current(self, cr, uid, ids, field_name, arg, context=None): + result = dict.fromkeys(ids, 0) + for rec in self.browse(cr, uid, ids, context=context): + result[rec.id] = sum([ep.nb_register for ep in rec.registration_ids]) + return result + _columns = { + 'event_id': fields.many2one('event.event', "Event", required=True), + 'product_id': fields.many2one('product.product', 'Product', required=True, domain=[("event_type_id", "!=", False)]), + 'registration_ids': fields.one2many('event.registration', 'event_ticket_id', 'Registrations'), 'deadline': fields.date("Sales End"), - 'event_id': fields.many2one('event.event', "Event"), - 'product_id': fields.many2one('product.product', 'Product', domain=[("event_type_id", "!=", False)]), 'price': fields.float('Price'), - 'qty': fields.integer('Current Registrations', readonly=True), - 'max_qty': fields.integer('Maximum Registrations'), + 'register_max': fields.integer('Maximum Registrations'), + 'register_current': fields.function(_get_register_current, string='Current Registrations', type='integer', store=True), } + def onchange_product_id(self, cr, uid, ids, product_id=False, context=None): return {'value': {'price': self.pool.get("product.product").browse(cr, uid, product_id).list_price or 0}} -class product(osv.osv): - _inherit = 'product.product' +class event_registration(osv.osv): + """Event Registration""" + _inherit= 'event.registration' _columns = { - 'event_product_ids': fields.one2many('event.event.product', 'product_id', 'Linked event product'), + 'event_ticket_id': fields.many2one('event.event.ticket', 'Event Ticket'), } diff --git a/addons/website_event/security/ir.model.access.csv b/addons/website_event/security/ir.model.access.csv index 430fced34b5..409ca162c66 100644 --- a/addons/website_event/security/ir.model.access.csv +++ b/addons/website_event/security/ir.model.access.csv @@ -1,4 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0 -access_event_event_product_public,event.event.product.public,website_event.model_event_event_product,base.group_public,1,0,0,0 +access_event_event_ticket_public,event.event.ticket.public,website_event.model_event_event_ticket,base.group_public,1,0,0,0 access_event_product_product_public,event.product.product.public,product.model_product_product,base.group_public,1,0,0,0 \ No newline at end of file diff --git a/addons/website_event/security/website_event.xml b/addons/website_event/security/website_event.xml index 6c571eb4875..e1d3ea4ae6a 100644 --- a/addons/website_event/security/website_event.xml +++ b/addons/website_event/security/website_event.xml @@ -11,9 +11,9 @@ - - event product: Public - + + event ticket: Public + [('event_id.website_published', '=', True)] diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index 65ff07fa9dd..2b511e25c7e 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -10,12 +10,12 @@ - + - + @@ -93,9 +93,11 @@
  • - - No ticket available. - + No tickets needed. + + Tickets availables. + No ticket available. + Only tickets @@ -153,9 +155,11 @@
    - - No ticket available. - + No tickets needed. + + Tickets availables. + No ticket available. + Only tickets @@ -164,36 +168,40 @@

    + + Click to Unpublish + Click to Publish +


    - - Click to Unpublish - Click to Publish - -

    Ticket Information

    -
    +

    Ticket Information

    + - - - - - - - - - - - + + + + + + + + + + + + + + +
    Ticket typeSales EndPriceSeatsQuantity
    - - - / - -
    Ticket typeSales EndPriceSeatsQuantity
    + + + / + +
    From 95e8504d5cb4163e5082bf6eb0e221e058aabbae Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 7 Aug 2013 13:28:12 +0200 Subject: [PATCH 02/77] [IMP] website_event: add function fields register on ticket model. Add onchange on sale.order.line for event tickets bzr revid: chm@openerp.com-20130807112812-23l0b8pjdzutyixy --- addons/event_sale/event_sale.py | 111 +++++++++++++++++- addons/event_sale/event_sale_view.xml | 32 ++++- addons/website_event/event.py | 54 --------- .../security/ir.model.access.csv | 2 +- .../website_event/security/website_event.xml | 2 +- addons/website_event/views/website_event.xml | 25 ---- 6 files changed, 139 insertions(+), 87 deletions(-) diff --git a/addons/event_sale/event_sale.py b/addons/event_sale/event_sale.py index 8bacd37fc15..6d6e2ca1624 100644 --- a/addons/event_sale/event_sale.py +++ b/addons/event_sale/event_sale.py @@ -29,14 +29,17 @@ class product(osv.osv): 'event_type_id': fields.many2one('event.type', 'Type of Event', help='Select event types so when we use this product in sales order lines, it will filter events of this type only.'), } - def onchange_event_ok(self, cr, uid, ids, event_ok, context=None): - return {'value': {'type': event_ok and 'service' or False}} + def onchange_event_ok(self, cr, uid, ids, type, event_ok, context=None): + return {'value': {'type': event_ok and 'service' or type != 'service' and type or False}} class sale_order_line(osv.osv): _inherit = 'sale.order.line' _columns = { - 'event_id': fields.many2one('event.event', 'Event', help="Choose an event and it will automatically create a registration for this event."), + 'event_id': fields.many2one('event.event', 'Event', + help="Choose an event and it will automatically create a registration for this event."), + 'event_ticket_id': fields.many2one('event.event.ticket', 'Event Ticket', + help="Choose an event ticket and it will automatically create a registration for this event ticket."), #those 2 fields are used for dynamic domains and filled by onchange 'event_type_id': fields.related('product_id','event_type_id', type='many2one', relation="event.type", string="Event Type"), 'event_ok': fields.related('product_id', 'event_ok', string='event_ok', type='boolean'), @@ -73,7 +76,6 @@ class sale_order_line(osv.osv): if context is None: context = {} registration_obj = self.pool.get('event.registration') - sale_obj = self.pool.get('sale.order') for order_line in self.browse(cr, uid, ids, context=context): if order_line.event_id.id: dic = { @@ -84,9 +86,108 @@ class sale_order_line(osv.osv): 'phone': order_line.order_id.partner_id.phone, 'origin': order_line.order_id.name, 'event_id': order_line.event_id.id, + 'event_ticket_id': order_line.event_ticket_id and order_line.event_ticket_id.id or None, } - message = _("The registration has been created for event %s from the Sale Order %s. ") % (order_line.event_id.name, order_line.order_id.name) + print dic + + if order_line.event_ticket_id: + if order_line.event_ticket_id.register_avail != 9999 and dic['nb_register'] < order_line.event_ticket_id.register_avail: + raise osv.except_osv(_('Error!'), _('There are not enough tickets available (%s).' % order_line.event_ticket_id.register_avail)) + message = _("The registration has been created for event %s with the ticket %s from the Sale Order %s. ") % (order_line.event_id.name, order_line.event_ticket_id.name, order_line.order_id.name) + else: + message = _("The registration has been created for event %s from the Sale Order %s. ") % (order_line.event_id.name, order_line.order_id.name) + context.update({'mail_create_nolog': True}) registration_id = registration_obj.create(cr, uid, dic, context=context) registration_obj.message_post(cr, uid, [registration_id], body=message, context=context) return super(sale_order_line, self).button_confirm(cr, uid, ids, context=context) + + def onchange_event_ticket_id(self, cr, uid, ids, event_ticket_id=False, context=None): + price = event_ticket_id and self.pool.get("event.event.ticket").browse(cr, uid, event_ticket_id, context=context).price or False + return {'value': {'price_unit': price}} + + +class event(osv.osv): + _inherit = 'event.event' + + def _get_register_max(self, cr, uid, ids, field_name, arg, context=None): + result = dict.fromkeys(ids, 0) + for rec in self.browse(cr, uid, ids, context=context): + result[rec.id] = sum([ep.register_max for ep in rec.event_ticket_ids]) + return result + + _columns = { + 'website_published': fields.boolean('Available in the website'), + 'description_website': fields.html('Description for the website'), + 'event_ticket_ids': fields.one2many('event.event.ticket', "event_id", "Event Ticket"), + 'organizer_id': fields.many2one('res.partner', "Orgonizer"), + 'phone': fields.related('orgonizer_id', 'phone', type='char', string='Phone'), + 'email': fields.related('orgonizer_id', 'email', type='char', string='Email'), + 'register_max': fields.function(_get_register_max, + string='Maximum Registrations', + help="The maximum registration level is equal to the sum of the maximum registration of event ticket." + + "If you have too much registrations you are not able to confirm your event. (0 to ignore this rule )", + type='integer', store=True) + } + + +class event_ticket(osv.osv): + _name = 'event.event.ticket' + + def _get_register(self, cr, uid, ids, fields, args, context=None): + """Get Confirm or uncofirm register value. + @param ids: List of Event Ticket registration type's id + @param fields: List of function fields(register_current and register_prospect). + @param context: A standard dictionary for contextual values + @return: Dictionary of function fields value. + """ + res = {} + for event in self.browse(cr, uid, ids, context=context): + res[event.id] = {} + reg_open = reg_done = reg_draft =0 + for registration in event.registration_ids: + if registration.state == 'open': + reg_open += registration.nb_register + elif registration.state == 'done': + reg_done += registration.nb_register + elif registration.state == 'draft': + reg_draft += registration.nb_register + for field in fields: + number = 0 + if field == 'register_current': + number = reg_open + elif field == 'register_attended': + number = reg_done + elif field == 'register_prospect': + number = reg_draft + elif field == 'register_avail': + #the number of ticket is unlimited if the event.register_max field is not set. + #In that cas we arbitrary set it to 9999, it is used in the kanban view to special case the display of the 'subscribe' button + number = event.register_max - reg_open if event.register_max != 0 else 9999 + res[event.id][field] = number + return res + + _columns = { + 'name': fields.char('Name', size=64, required=True), + 'event_id': fields.many2one('event.event', "Event", required=True), + 'product_id': fields.many2one('product.product', 'Product', required=True, domain=[("event_type_id", "!=", False)]), + 'registration_ids': fields.one2many('event.registration', 'event_ticket_id', 'Registrations'), + 'deadline': fields.date("Sales End"), + 'price': fields.float('Price'), + 'register_max': fields.integer('Maximum Registrations'), + 'register_current': fields.function(_get_register, string='Current Registrations', type='integer', multi='register_numbers'), + 'register_avail': fields.function(_get_register, string='Available Registrations', type='integer', multi='register_numbers'), + 'register_prospect': fields.function(_get_register, string='Unconfirmed Registrations', type='integer', multi='register_numbers'), + 'register_attended': fields.function(_get_register, string='# of Participations', type='integer', multi='register_numbers'), + } + + def onchange_product_id(self, cr, uid, ids, product_id=False, context=None): + return {'value': {'price': self.pool.get("product.product").browse(cr, uid, product_id).list_price or 0}} + + +class event_registration(osv.osv): + """Event Registration""" + _inherit= 'event.registration' + _columns = { + 'event_ticket_id': fields.many2one('event.event.ticket', 'Event Ticket'), + } diff --git a/addons/event_sale/event_sale_view.xml b/addons/event_sale/event_sale_view.xml index cc00365c980..43d2fcde495 100644 --- a/addons/event_sale/event_sale_view.xml +++ b/addons/event_sale/event_sale_view.xml @@ -7,7 +7,7 @@
    - +
    @@ -23,6 +23,8 @@ + @@ -34,5 +36,33 @@ + + view_event_form + event.event + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/addons/website_event/event.py b/addons/website_event/event.py index 58741dfe9d5..da80f86fc5b 100644 --- a/addons/website_event/event.py +++ b/addons/website_event/event.py @@ -9,57 +9,3 @@ class product(osv.osv): 'event_ticket_ids': fields.one2many('event.event.ticket', 'product_id', 'Event Tickets'), } - -class event(osv.osv): - _inherit = 'event.event' - - def _get_register_max(self, cr, uid, ids, field_name, arg, context=None): - result = dict.fromkeys(ids, 0) - for rec in self.browse(cr, uid, ids, context=context): - result[rec.id] = sum([ep.register_max for ep in rec.event_ticket_ids]) - return result - - _columns = { - 'website_published': fields.boolean('Available in the website'), - 'description_website': fields.html('Description for the website'), - 'event_ticket_ids': fields.one2many('event.event.ticket', "event_id", "Event Ticket"), - 'organizer_id': fields.many2one('res.partner', "Orgonizer"), - 'phone': fields.related('orgonizer_id', 'phone', type='char', string='Phone'), - 'email': fields.related('orgonizer_id', 'email', type='char', string='Email'), - 'register_max': fields.function(_get_register_max, - string='Maximum Registrations', - help="The maximum registration level is equal to the sum of the maximum registration of event ticket." + - "If you have too much registrations you are not able to confirm your event. (0 to ignore this rule )", - type='integer', store=True) - } - - -class event_ticket(osv.osv): - _name = 'event.event.ticket' - - def _get_register_current(self, cr, uid, ids, field_name, arg, context=None): - result = dict.fromkeys(ids, 0) - for rec in self.browse(cr, uid, ids, context=context): - result[rec.id] = sum([ep.nb_register for ep in rec.registration_ids]) - return result - - _columns = { - 'event_id': fields.many2one('event.event', "Event", required=True), - 'product_id': fields.many2one('product.product', 'Product', required=True, domain=[("event_type_id", "!=", False)]), - 'registration_ids': fields.one2many('event.registration', 'event_ticket_id', 'Registrations'), - 'deadline': fields.date("Sales End"), - 'price': fields.float('Price'), - 'register_max': fields.integer('Maximum Registrations'), - 'register_current': fields.function(_get_register_current, string='Current Registrations', type='integer', store=True), - } - - def onchange_product_id(self, cr, uid, ids, product_id=False, context=None): - return {'value': {'price': self.pool.get("product.product").browse(cr, uid, product_id).list_price or 0}} - - -class event_registration(osv.osv): - """Event Registration""" - _inherit= 'event.registration' - _columns = { - 'event_ticket_id': fields.many2one('event.event.ticket', 'Event Ticket'), - } diff --git a/addons/website_event/security/ir.model.access.csv b/addons/website_event/security/ir.model.access.csv index 409ca162c66..1c35f9ea5e9 100644 --- a/addons/website_event/security/ir.model.access.csv +++ b/addons/website_event/security/ir.model.access.csv @@ -1,4 +1,4 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_event_event_public,event.event.public,event.model_event_event,base.group_public,1,0,0,0 -access_event_event_ticket_public,event.event.ticket.public,website_event.model_event_event_ticket,base.group_public,1,0,0,0 +access_event_event_ticket_public,event.event.ticket.public,event_sale.model_event_event_ticket,base.group_public,1,0,0,0 access_event_product_product_public,event.product.product.public,product.model_product_product,base.group_public,1,0,0,0 \ No newline at end of file diff --git a/addons/website_event/security/website_event.xml b/addons/website_event/security/website_event.xml index e1d3ea4ae6a..0bf2f29a733 100644 --- a/addons/website_event/security/website_event.xml +++ b/addons/website_event/security/website_event.xml @@ -13,7 +13,7 @@ event ticket: Public - + [('event_id.website_published', '=', True)] diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index 2b511e25c7e..9bbd8225690 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -2,31 +2,6 @@ - - view_event_form - event.event - - - - - - - - - - - - - - - - - - - - - - From c012e3bdc603cb0be83721d5a6e4a3e5ad148d0a Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 7 Aug 2013 15:45:47 +0200 Subject: [PATCH 03/77] [IMP] website_event: create order_line and check registration_limits bzr revid: chm@openerp.com-20130807134547-rbsrcswsozmna03w --- addons/event_sale/event_sale.py | 31 +++++++++++++-- addons/website_event/controllers/main.py | 42 +++++++++++++++++++- addons/website_event/views/website_event.xml | 5 ++- addons/website_sale/controllers/main.py | 7 +++- addons/website_sale/views/ecommerce.xml | 2 +- 5 files changed, 76 insertions(+), 11 deletions(-) diff --git a/addons/event_sale/event_sale.py b/addons/event_sale/event_sale.py index 6d6e2ca1624..a8f73a3055f 100644 --- a/addons/event_sale/event_sale.py +++ b/addons/event_sale/event_sale.py @@ -77,7 +77,7 @@ class sale_order_line(osv.osv): context = {} registration_obj = self.pool.get('event.registration') for order_line in self.browse(cr, uid, ids, context=context): - if order_line.event_id.id: + if order_line.event_id: dic = { 'name': order_line.order_id.partner_invoice_id.name, 'partner_id': order_line.order_id.partner_id.id, @@ -91,8 +91,8 @@ class sale_order_line(osv.osv): print dic if order_line.event_ticket_id: - if order_line.event_ticket_id.register_avail != 9999 and dic['nb_register'] < order_line.event_ticket_id.register_avail: - raise osv.except_osv(_('Error!'), _('There are not enough tickets available (%s).' % order_line.event_ticket_id.register_avail)) + if order_line.event_ticket_id.register_avail != 9999 and dic['nb_register'] > order_line.event_ticket_id.register_avail: + raise osv.except_osv(_('Error!'), _('There are not enough tickets available (%s) for %s' % (order_line.event_ticket_id.register_avail, order_line.event_ticket_id.name))) message = _("The registration has been created for event %s with the ticket %s from the Sale Order %s. ") % (order_line.event_id.name, order_line.event_ticket_id.name, order_line.order_id.name) else: message = _("The registration has been created for event %s from the Sale Order %s. ") % (order_line.event_id.name, order_line.order_id.name) @@ -107,7 +107,7 @@ class sale_order_line(osv.osv): return {'value': {'price_unit': price}} -class event(osv.osv): +class event_event(osv.osv): _inherit = 'event.event' def _get_register_max(self, cr, uid, ids, field_name, arg, context=None): @@ -130,6 +130,12 @@ class event(osv.osv): type='integer', store=True) } + def check_registration_limits(self, cr, uid, ids, context=None): + for event in self.browse(cr, uid, ids, context=context): + if event.event_ticket_ids: + event.event_ticket_ids.check_registration_limits_before(0) + return super(event_event, self).check_registration_limits(cr, uid, ids, context=context) + class event_ticket(osv.osv): _name = 'event.event.ticket' @@ -181,6 +187,15 @@ class event_ticket(osv.osv): 'register_attended': fields.function(_get_register, string='# of Participations', type='integer', multi='register_numbers'), } + def check_registration_limits_before(self, cr, uid, ids, number, context=None): + for ticket in self.browse(cr, uid, ids, context=context): + if ticket.register_max: + if not ticket.register_avail: + raise osv.except_osv(_('Warning!'),_('No Tickets Available for "%s"' % ticket.name)) + elif number + ticket.register_current > ticket.register_max: + raise osv.except_osv(_('Warning!'), _('There only %d tickets available for "%s"' % (ticket.register_avail, ticket.name))) + return True + def onchange_product_id(self, cr, uid, ids, product_id=False, context=None): return {'value': {'price': self.pool.get("product.product").browse(cr, uid, product_id).list_price or 0}} @@ -191,3 +206,11 @@ class event_registration(osv.osv): _columns = { 'event_ticket_id': fields.many2one('event.event.ticket', 'Event Ticket'), } + + def registration_open(self, cr, uid, ids, context=None): + """ Open Registration + """ + for registration in self.browse(cr, uid, ids, context=context): + if registration.event_ticket_id: + registration.event_ticket_id.check_registration_limits_before(1) + return super(event_registration, self).registration_open(cr, uid, ids, context=context) diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index adc4342b7d5..6afb1adbca5 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -10,6 +10,7 @@ from dateutil.relativedelta import relativedelta from openerp import tools import urllib import werkzeug +from openerp.osv import osv class website_event(http.Controller): @@ -105,9 +106,45 @@ class website_event(http.Controller): @http.route(['/event//add_cart'], type='http', auth="public") def add_cart(self, event_id=None, **post): - if not post: - return werkzeug.utils.redirect("/event/%s/" % event_id) + order_line_obj = request.registry.get('sale.order.line') + ticket_obj = request.registry.get('event.event.ticket') + order = request.registry['website'].get_rendering_context()['order'] + partner_id = request.registry.get('res.users').browse(request.cr, SUPERUSER_ID, request.uid).partner_id.id + + context = {} + + fields = [k for k, v in order_line_obj._columns.items()] + values = order_line_obj.default_get(request.cr, SUPERUSER_ID, fields, context=context) + + _values = None + for key, value in post.items(): + quantity = int(value) + ticket_id = key.split("-")[0] == 'ticket' and int(key.split("-")[1]) or None + if not ticket_id or not quantity: + continue + ticket = ticket_obj.browse(request.cr, request.uid, ticket_id) + + values['product_id'] = ticket.product_id.id + values['event_id'] = ticket.event_id.id + values['event_ticket_id'] = ticket.id + values['product_uom_qty'] = quantity + values['price_unit'] = ticket.price + values['order_id'] = order.id + values['name'] = "%s: %s" % (ticket.event_id.name, ticket.name) + + ticket.check_registration_limits_before(quantity) + + # change and record value + pricelist_id = order.pricelist_id and order.pricelist_id.id or False + _values = order_line_obj.product_id_change(request.cr, SUPERUSER_ID, [], pricelist_id, ticket.product_id.id, partner_id=partner_id, context=context)['value'] + _values.update(values) + + order_line_id = order_line_obj.create(request.cr, SUPERUSER_ID, _values, context=context) + order.write({'order_line': [(4, order_line_id)]}, context=context) + + if not _values: + return werkzeug.utils.redirect("/event/%s/" % event_id) return werkzeug.utils.redirect("/shop/checkout") @http.route(['/event/publish'], type='http', auth="public") @@ -120,3 +157,4 @@ class website_event(http.Controller): obj = data_obj.browse(request.cr, request.uid, obj_id) return obj.website_published and "1" or "0" + diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index 9bbd8225690..c7b7316da17 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -171,9 +171,10 @@ / - + + Not ticket available diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 96d0f079f52..771efc032e0 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -189,15 +189,16 @@ class Ecommerce(http.Controller): my_pids = [line.product_id.id for line in order.order_line] values = website.get_rendering_context({ - "recommended_products": self.recommended_product(my_pids) + "recommended_products": self.recommended_product(my_pids), }) + print values + return website.render("website_sale.mycart", values) @http.route(['/shop/add_cart'], type='http', auth="public") def add_cart(self, product_id=0, remove=False): website = request.registry['website'] - values = website.get_rendering_context() context = {} order_line_obj = request.registry.get('sale.order.line') @@ -209,6 +210,7 @@ class Ecommerce(http.Controller): quantity = 0 # values initialisation + values = {} order_line_ids = order_line_obj.search(request.cr, openerp.SUPERUSER_ID, [('order_id', '=', order.id), ('product_id', '=', product_id)], context=context) if order_line_ids: order_line = order_line_obj.read(request.cr, openerp.SUPERUSER_ID, order_line_ids, [], context=context)[0] @@ -235,6 +237,7 @@ class Ecommerce(http.Controller): order_line_id = order_line_obj.create(request.cr, openerp.SUPERUSER_ID, values, context=context) order.write({'order_line': [(4, order_line_id)]}, context=context) + values = website.get_rendering_context() html = website.render("website_sale.total", values) return simplejson.dumps({"quantity": quantity, "totalHTML": html}) diff --git a/addons/website_sale/views/ecommerce.xml b/addons/website_sale/views/ecommerce.xml index f69d74d9916..0cd39de8c53 100644 --- a/addons/website_sale/views/ecommerce.xml +++ b/addons/website_sale/views/ecommerce.xml @@ -260,7 +260,7 @@ - + € From edce9867e5b8cac1e4753b68a55d973b76bf129e Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 7 Aug 2013 16:03:34 +0200 Subject: [PATCH 04/77] [FIX] website_sale: create a new order if order. bzr revid: chm@openerp.com-20130807140334-oa8bap1i0ya9tfaf --- addons/website_event/views/website_event.xml | 2 +- addons/website_sale/controllers/main.py | 51 +++++--------------- addons/website_sale/views/ecommerce.xml | 2 +- 3 files changed, 14 insertions(+), 41 deletions(-) diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index c7b7316da17..b3b098fda85 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -179,7 +179,7 @@ - +

    Event Details

    diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 771efc032e0..8e5f3c39e76 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -12,7 +12,8 @@ def get_order(order_id=None): # check if order allready exists if order_id: try: - order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id).pricelist_id + order = order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id) + order.pricelist_id except: order_id = None if not order_id: @@ -21,24 +22,20 @@ def get_order(order_id=None): order_value['partner_id'] = request.registry.get('res.users').browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id order_value.update(order_obj.onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value']) order_id = order_obj.create(request.cr, openerp.SUPERUSER_ID, order_value) - return order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id) + order = order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id) + return order def get_current_order(): order = get_order(request.httprequest.session.get('ecommerce_order_id')) + if order.state != 'draft': + order = get_order() request.httprequest.session['ecommerce_order_id'] = order.id return order -def get_categories(): - category_obj = request.registry.get('pos.category') - category_ids = category_obj.search(request.cr, openerp.SUPERUSER_ID, [('parent_id', '=', False)]) - return category_obj.browse(request.cr, openerp.SUPERUSER_ID, category_ids) - - class website(osv.osv): _inherit = "website" def get_rendering_context(self, additional_values=None): values = { - 'website_sale_get_categories': get_categories, 'order': get_current_order(), # 'website_sale_get_current_order': get_current_order, # TODO: replace 'order' key in templates } @@ -55,31 +52,9 @@ class Ecommerce(http.Controller): print categories return categories - def get_current_order(self): - order = self.get_order(request.httprequest.session.get('ecommerce_order_id')) - request.httprequest.session['ecommerce_order_id'] = order.id - return order - - def get_order(self, order_id=None): - - order_obj = request.registry.get('sale.order') - # check if order allready exists - if order_id: - try: - order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id).pricelist_id - except: - order_id = None - if not order_id: - fields = [k for k, v in order_obj._columns.items()] - order_value = order_obj.default_get(request.cr, openerp.SUPERUSER_ID, fields) - order_value['partner_id'] = request.registry.get('res.users').browse(request.cr, openerp.SUPERUSER_ID, request.uid).partner_id.id - order_value.update(order_obj.onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value']) - order_id = order_obj.create(request.cr, openerp.SUPERUSER_ID, order_value) - return order_obj.browse(request.cr, openerp.SUPERUSER_ID, order_id) - def render(self, template, values={}): + website = request.registry['website'] _values = { - 'order': self.get_current_order(), 'categories': self.get_categories(), } _values.update(values) @@ -156,7 +131,7 @@ class Ecommerce(http.Controller): 'pages': pages, 'page': page, }) - return website.render("website_sale.products", values) + return self.render("website_sale.products", values) @http.route(['/shop/product/'], type='http', auth="public") def product(self, cat_id=0, product_id=0): @@ -174,7 +149,7 @@ class Ecommerce(http.Controller): 'quantity': quantity, 'recommended_products': self.recommended_product([product_id]), }) - return website.render("website_sale.product", values) + return self.render("website_sale.product", values) @http.route(['/shop/mycart'], type='http', auth="public") def mycart(self, **post): @@ -192,9 +167,7 @@ class Ecommerce(http.Controller): "recommended_products": self.recommended_product(my_pids), }) - print values - - return website.render("website_sale.mycart", values) + return self.render("website_sale.mycart", values) @http.route(['/shop/add_cart'], type='http', auth="public") def add_cart(self, product_id=0, remove=False): @@ -238,7 +211,7 @@ class Ecommerce(http.Controller): order.write({'order_line': [(4, order_line_id)]}, context=context) values = website.get_rendering_context() - html = website.render("website_sale.total", values) + html = self.render("website_sale.total", values) return simplejson.dumps({"quantity": quantity, "totalHTML": html}) @http.route(['/shop/remove_cart'], type='http', auth="public") @@ -387,7 +360,7 @@ class Ecommerce(http.Controller): 'temp': 0, 'order': order_old, }) - return website.render("website_sale.confirmed", values) + return self.render("website_sale.confirmed", values) @http.route(['/shop/publish'], type='http', auth="public") def publish(self, **post): diff --git a/addons/website_sale/views/ecommerce.xml b/addons/website_sale/views/ecommerce.xml index 0cd39de8c53..2ab5469e081 100644 --- a/addons/website_sale/views/ecommerce.xml +++ b/addons/website_sale/views/ecommerce.xml @@ -67,7 +67,7 @@
    From eff6013900a7494f26e68e8e49f223cbcc16a46d Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Wed, 7 Aug 2013 16:48:50 +0200 Subject: [PATCH 05/77] [IMP] website_hr: add public mail group: jobs bzr revid: chm@openerp.com-20130807144850-7zkkoq4wr9wcke4p --- addons/website_event/controllers/main.py | 1 - addons/website_hr/views/website_hr.xml | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/addons/website_event/controllers/main.py b/addons/website_event/controllers/main.py index 6afb1adbca5..87cb80852db 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -10,7 +10,6 @@ from dateutil.relativedelta import relativedelta from openerp import tools import urllib import werkzeug -from openerp.osv import osv class website_event(http.Controller): diff --git a/addons/website_hr/views/website_hr.xml b/addons/website_hr/views/website_hr.xml index 76190f7977c..659509a1b96 100644 --- a/addons/website_hr/views/website_hr.xml +++ b/addons/website_hr/views/website_hr.xml @@ -2,6 +2,14 @@ + + + + Job + public + Job offer displayed on your website + + @@ -11,6 +19,7 @@
  • Team
  • +
  • Jobs
  • From ab61a67021f8f56070295eeb05601a490a53326d Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 8 Aug 2013 09:21:15 +0200 Subject: [PATCH 06/77] [IMP] website_hr: create page/aboutus and add Trombinoscope Teams bzr revid: chm@openerp.com-20130808072115-9clevg0tqzir7kjc --- addons/website/views/views.xml | 23 ++++++++++++++++++++++- addons/website_hr/controllers/main.py | 19 ++++--------------- addons/website_hr/static/src/js/hr.js | 2 +- addons/website_hr/views/website_hr.xml | 25 ++++++++++++------------- 4 files changed, 39 insertions(+), 30 deletions(-) diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index 80802bd673f..198c96d508d 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -40,7 +40,7 @@ @@ -377,5 +377,26 @@ + + diff --git a/addons/website_hr/controllers/main.py b/addons/website_hr/controllers/main.py index 968ec607269..24440373c5f 100644 --- a/addons/website_hr/controllers/main.py +++ b/addons/website_hr/controllers/main.py @@ -5,7 +5,7 @@ from openerp.addons.web.http import request class website_hr(http.Controller): - @http.route(['/hr'], type='http', auth="public") + @http.route(['/page/website.aboutus'], type='http', auth="public") def blog(self, **post): website = request.registry['website'] hr_obj = request.registry['hr.employee'] @@ -13,9 +13,9 @@ class website_hr(http.Controller): values = website.get_rendering_context({ 'employee_ids': hr_obj.browse(request.cr, request.uid, employee_ids) }) - return website.render("website_hr.index", values) + return website.render("website.aboutus", values) - @http.route(['/hr/publish'], type='http', auth="public") + @http.route(['/page/website.aboutus/publish'], type='http', auth="public") def publish(self, **post): obj_id = int(post['id']) data_obj = request.registry['hr.employee'] @@ -24,15 +24,4 @@ class website_hr(http.Controller): data_obj.write(request.cr, request.uid, [obj_id], {'website_published': not obj.website_published}) obj = data_obj.browse(request.cr, request.uid, obj_id) - return obj.website_published and "1" or "0" - - @http.route(['/hr/publish_contact'], type='http', auth="public") - def publish_contact(self, **post): - obj_id = int(post['id']) - data_obj = request.registry['hr.employee'] - - obj = data_obj.browse(request.cr, request.uid, obj_id) - data_obj.write(request.cr, request.uid, [obj_id], {'website_published_on_contact_form': not obj.website_published_on_contact_form}) - obj = data_obj.browse(request.cr, request.uid, obj_id) - - return obj.website_published_on_contact_form and "1" or "0" + return obj.website_published and "1" or "0" \ No newline at end of file diff --git a/addons/website_hr/static/src/js/hr.js b/addons/website_hr/static/src/js/hr.js index e0e69fb5161..632b538509f 100644 --- a/addons/website_hr/static/src/js/hr.js +++ b/addons/website_hr/static/src/js/hr.js @@ -5,7 +5,7 @@ $(document).ready(function () { $link.find('.js_publish, .js_unpublish').addClass("hidden"); var $unp = $link.find(".js_unpublish"); var $p = $link.find(".js_publish"); - $.post('/hr/publish', {'id': $link.data('id')}, function (result) { + $.post('/page/website.aboutus/publish', {'id': $link.data('id')}, function (result) { if (+result) { $p.addClass("hidden"); $unp.removeClass("hidden"); diff --git a/addons/website_hr/views/website_hr.xml b/addons/website_hr/views/website_hr.xml index 659509a1b96..98bebacff8e 100644 --- a/addons/website_hr/views/website_hr.xml +++ b/addons/website_hr/views/website_hr.xml @@ -17,8 +17,7 @@ - -
  • Team
  • +
  • Jobs
  • @@ -27,14 +26,13 @@ - + +
    + + From 4cffb20e7231a92a8fb003e0e921fc9d3797b278 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 8 Aug 2013 10:14:00 +0200 Subject: [PATCH 07/77] [FIX] website_event: name field in access rules bzr revid: chm@openerp.com-20130808081400-gafdfykn9ds3rsp5 --- addons/website_event/security/website_event.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_event/security/website_event.xml b/addons/website_event/security/website_event.xml index 0bf2f29a733..c26eac05841 100644 --- a/addons/website_event/security/website_event.xml +++ b/addons/website_event/security/website_event.xml @@ -24,7 +24,7 @@ Product linked to event: Public - [("event_type_id", "!=", False), ('event_product_ids.event_id.website_published', '=', True)] + [("event_type_id", "!=", False), ('event_ticket_ids.event_id.website_published', '=', True)] From e9e340eae6ab1fe4f4d84a2d162cb345aeab4a42 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 8 Aug 2013 11:12:57 +0200 Subject: [PATCH 08/77] [WIP] website_sale draft manifest bzr revid: fp@tinyerp.com-20130808091257-6ps3hdaibpatzb6l --- .../static/description/index.html | 272 ++++++++++++++++++ 1 file changed, 272 insertions(+) create mode 100644 addons/website_sale/static/description/index.html diff --git a/addons/website_sale/static/description/index.html b/addons/website_sale/static/description/index.html new file mode 100644 index 00000000000..9e6e9149822 --- /dev/null +++ b/addons/website_sale/static/description/index.html @@ -0,0 +1,272 @@ +
    +
    +
    +

    Open Source eCommerce

    +

    Optimize sales with an awesome online store.

    +
    +
    +
    + + + + +
    +
    +
    +

    + OpenERP eCommerce is unlike anything you have ever seen before. + It's at the same time full-featured, integrated with your + management software, fully customizable and super easy. +

    + +
    +
    +
    + +
    +
    +

    Create Awsome Product Pages

    +

    Get rid of old WYSIWYG editors

    +
    +

    + OpenERP's unique 'edit inline' approach makes website + and product pages creation surprisingly easy. "Want to change + the price of a product? or put it in bold? Want to add a banner + for a specific product?" just click and change. What you see is + what you get. Really. +

    + Drag & Drop well designed 'Building Blocks' to + create beautifull product pages that your customer will love. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Sell More to Existing Customers

    +

    Easy upselling, cross-selling and promotions

    +
    + +
    +
    +

    + OpenERP's upselling algorythm allows you to show visitors + similar but more expensive products than the one in view. (with + incentives like customer ratings) It results in a 7.5% increase + in your average basket revenue. +

    + Use the built-in cross-selling feature to offer extra products + related to what the shopper put in his cart. (e.g. accessories) +

    + The inline editing feature allows you to easily change a price, + launch a promotion or fine tune the descritpion of a product, + in a just a click. +

    +
    +
    +
    + +
    +
    +

    A Clean Google Analytics Integration

    +

    Control your sales funnel with Google Analytics

    +
    +

    + Get a clear visibility of your sales funnel. OpenERP's Google + Analytics trackers are configured by default to track all kind of + events related to shopping carts, call-to-actions, etc. +

    + As OpenERP marketing tools (mass mailing, campaigns, etc) are also + linked with Google Analytics, you get a 360° view of your business. +

    +
    +
    + +
    +
    +
    + +
    +
    +

    Target New Markets

    +

    Multi-languages Without Pain

    +
    +
    + +
    +
    +
    +

    + Get your website translated in multiple languages with no effort. + OpenERP proposes and propagates translations automatically + across pages. +

    + Our translation "on demand" features allows you to benefit from + professional translators to translate all your changes + automatically. Just change any part of your website (a new blog + post, a page modification, product descriptions, ...) and the translated + versions are updated automatically in around 32 hours. +

    +
    +
    +
    + +
    +
    +

    Designer-Friendly Themes

    +

    Designers love working on OpenERP

    +
    +

    + Themes are awesome and easy to design. You don't need to develop + to create new pages, themes or building blocks. We use a clean + HTML structure, a bootstrap + CSS and our modularity allows to distribute your themes easily. +

    + The building block approach allows the website to remain clean + after the end-users start creating new contents. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Acquire New Customers

    +

    SEO tools at your finger tips

    +
    +
    + +
    +
    +
    +

    + SEO tools are ready to use, with no configuration required. + OpenERP suggests keywords according to Google most searched + terms, Google Analytics tracks your shopping cart events, + sitemap are created automatically for Google indexation, etc. +

    + We even do structured content automatically to promote your + product and events efficiently in Google. +

    +
    +
    +
    + +
    +
    +

    Leverage Social Media

    +

    Optimize: from Ads to Conversions

    +
    +

    + Create new landing pages easily with the OpenERP inline edition + feature. Send visitors of your different marketing campaigns to + specific landing pages to optimize conversions. +

    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +

    Manage a Resellers Network

    +

    Referencing, Lead Forward, Pricelists

    +
    +
    + +
    +
    +
    +

    + Manage a reseller network to target new market, have local + presences or broaden your distribution. Give them access to your + reseller portal for an efficient collaboration. +

    + Promote your resellers online, forward leads to resellers (with + built-in geolocalisation feature), define specific pricelists, + launch a loyalty program (offer specific discounts to your best + customers or resellers), etc. +

    +
    +
    +
    + +
    +
    +

    +

    Integrated vs Interfaced

    +
    +

    + Benefit from the power of OpenERP, in your online store: a + powerfull tax engine, flexible pricing structures, a real + inventory management solution, a reseller interface, support + for products with different behaviours; physical goods, events, + services, variants and options, etc. +

    + You don't need to interface with your warehouse, sales or + accounting software. Everything is integrated with OpenERP. No + pain, real time. +

    +
    +
    +
    + +
    +
    +
    +
    + + +
    +
    +

    And much more...

    +
    +

    Online Sales

    +
      +
    • Mobile Interface
    • +
    • Sell products, events or services
    • +
    • Flexible pricelists
    • +
    • Product multi-variants
    • +
    • Multiple stores
    • +
    +
    +
    +

    Customer Service

    +
      +
    • Customer Portal to track orders
    • +
    • Assisted shopping with live chats
    • +
    • Returns management
    • +
    • Advanced shipping rules
    • +
    • Coupons or gift certificates
    • +
    +
    +
    +

    Order Management

    +
      +
    • Advanced warehouse management features
    • +
    • Invoicing and accounting integration
    • +
    • Mass mailing and customer segmentations
    • +
    • Lead automation and marketing campaigns
    • +
    • Persistent shopping cart
    • +
    +
    +
    +
    From 51d873499104e3e845f08d29c1efe91a6ff013a1 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 8 Aug 2013 14:04:44 +0200 Subject: [PATCH 09/77] [IMP] draft manifest for blogs bzr revid: fp@tinyerp.com-20130808120444-osbsixzypejcu47q --- .../static/description/index.html | 215 ++++++++++++++++++ 1 file changed, 215 insertions(+) create mode 100644 addons/website_mail/static/description/index.html diff --git a/addons/website_mail/static/description/index.html b/addons/website_mail/static/description/index.html new file mode 100644 index 00000000000..236c210ed46 --- /dev/null +++ b/addons/website_mail/static/description/index.html @@ -0,0 +1,215 @@ +
    +
    +
    +

    Awesome Open Source Blogging Systems

    +

    Express yourself with beautiful blogs

    +
    +
    +
    + + + + +
    +
    + +
    +
    + +
    +
    +

    Write Beautiful Blog Posts

    +

    Get rid of old WYSIWYG editors

    +
    +

    + Drag & Drop well designed 'Building Blocks' to + create beautifull blog posts that perfectly integrates images, + videos, call-to-actions, quotes, banners, etc. +

    + With our unique 'edit inline' approach, you don't need + to be a designer to create awsome, good-looking, content. Each blog + post will look like it's designed by a professional designer. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Automated Translation by Professionals

    +

    Reach multi-languages audiences without Pain

    +
    +
    + +
    +
    +
    +

    + Get your blog posts translated in multiple languages with no effort. + Our translation "on demand" feature allows you to benefit from + professional translators to translate all your changes + automatically. ($0.05 per word) Translated versions are updated + automatically once translated by professionals (around 32 hours). +

    +
    +
    +
    + +
    +
    +

    Engage With Your Visitors

    +

    Live chat with your visitors in one click

    +
    +

    + The integrated live chat features allows you to start chatting in + real time with your visitors to get feedback on your recent posts + or get ideas to write new posts. +

    + Engaging with your visitors is also a great way to convert visitors + into customers. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Build Visitors Loyalty

    +

    Social Media Integration and Easy Following

    +
    + +
    +
    +

    + The one click follow button will allow visitors + to receive your blog posts by email with no effort, without + having to register. Social media icons allows visitors to share + your best blog posts easily. +

    +
    +
    +
    + +
    +
    +

    Google Analytics Integration

    +

    Get visibility on the impact of each blog post

    +
    +

    + Get a clear visibility of your sales funnel. OpenERP's Google + Analytics trackers are configured by default to track all kind of + events related to shopping carts, call-to-actions, etc. +

    + As OpenERP marketing tools (mass mailing, campaigns, etc) are also + linked with Google Analytics, you get a 360° view of your business. +

    +
    +
    + +
    +
    +
    + +
    +
    +

    Designer-Friendly Themes

    +

    Designers love working on OpenERP

    +
    +

    + Themes are awesome and easy to design. You don't need to develop + to create new pages, themes or building blocks. We use a clean + HTML structure, a bootstrap + CSS and our modularity allows to distribute your themes easily. +

    + The building block approach allows the website to remain clean + after the end-users start creating new contents. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    SEO Optimized Blog Posts

    +

    Attract new visitors with a good referencing

    +
    +
    + +
    +
    +
    +

    + SEO tools are ready to use, with no configuration required. + OpenERP suggests keywords for your titles according to Google + most searched terms, Google Analytics tracks interrests of your + visitors, sitemap are created automatically for Google + indexation, etc. +

    + We even do structured content automatically to promote your + product and events efficiently in Google. +

    +
    +
    +
    + +
    +
    +

    Easy Access Rights

    +

    Adapt your publishing process to your own need

    +
    +
    + +
    +
    +
    +

    + Not everyone requires the same access to your website. + Designers manage the layout of the site, editors approves content and + authors write that content. This lets you organize your publishing + process according to your needs. +

    +
    +
    +
    + +
    +
    +

    Built-in comments

    +

    Engage with your readers

    +
    +

    + Your blog is your home, and comments provide a space for your + friends and followers to engage with your content. OpenERP's + comment tools give you everything you need to be a forum for + discussion and to moderate that discussion. +

    +
    +
    +
    + +
    +
    +
    +
    From fb8f4d5f00d44d57090f8abd40640bbc6f8fb2c7 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 8 Aug 2013 14:07:26 +0200 Subject: [PATCH 10/77] [IMP] manifest imp bzr revid: fp@tinyerp.com-20130808120726-opb36h5i39xymuh6 --- addons/website_mail/static/description/index.html | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/addons/website_mail/static/description/index.html b/addons/website_mail/static/description/index.html index 236c210ed46..30c9e6dc5c9 100644 --- a/addons/website_mail/static/description/index.html +++ b/addons/website_mail/static/description/index.html @@ -189,6 +189,11 @@ Designers manage the layout of the site, editors approves content and authors write that content. This lets you organize your publishing process according to your needs. +

    + Others access rights related to business objects (products, people, + events, etc) directly follows OpenERP's standard access right allowing + you to not have to configure them twice. +

    From 2f72ec1dda25d76af0183ebb41bd2d452e5efa71 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 8 Aug 2013 14:56:01 +0200 Subject: [PATCH 11/77] [WIP] website_event manifest bzr revid: fp@tinyerp.com-20130808125601-5ynz9m3fsni5d45g --- .../static/description/index.html | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 addons/website_event/static/description/index.html diff --git a/addons/website_event/static/description/index.html b/addons/website_event/static/description/index.html new file mode 100644 index 00000000000..8a79fce2a21 --- /dev/null +++ b/addons/website_event/static/description/index.html @@ -0,0 +1,167 @@ +
    +
    +
    +

    Organize Events, Trainings & Webinars

    +

    Schedule, Promote, Sell, Organize

    +
    +
    +
    + + + + +
    +
    + +
    +
    + +
    +
    +

    Create Awsome Event Pages

    +

    Get rid of old WYSIWYG editors

    +
    +

    + OpenERP's unique 'edit inline' approach makes website + creation surprisingly easy. "Want to present a speaker? to + change the price of a ticket? to update a banner? to present a + schedule?" just click and change. What you see is what you get. + Really. +

    + Drag & Drop well designed 'Building Blocks' to + create beautifull event pages that your customer will love. + Use pre-defined building blocks like; speakers, schedules, + social icons, etc. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Promote Events Efficiently

    +

    Mass Mailing & Social Media Icons

    +
    + +
    +
    +

    + + +

    +
    +
    +
    + +
    +
    +

    A Clean Google Analytics Integration

    +

    Control your sales funnel with Google Analytics

    +
    +

    + Get a clear visibility of your sales funnel. OpenERP's Google + Analytics trackers are configured by default to track all kind of + events related to shopping carts, call-to-actions, etc. +

    + As OpenERP marketing tools (mass mailing, campaigns, etc) are also + linked with Google Analytics, you get a 360° view of your business. +

    +
    +
    + +
    +
    +
    + +
    +
    +

    Designer-Friendly Themes

    +

    Designers love working on OpenERP

    +
    +

    + Themes are awesome and easy to design. You don't need to develop + to create new pages, themes or building blocks. We use a clean + HTML structure, a bootstrap + CSS and our modularity allows to distribute your themes easily. +

    + The building block approach allows the website to remain clean + after the end-users start creating new contents. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Make Your Event More Visible

    +

    SEO tools at your finger tips

    +
    +
    + +
    +
    +
    +

    + SEO tools are ready to use, with no configuration required. + OpenERP suggests keywords according to Google most searched + terms, Google Analytics tracks your shopping cart events, + sitemap are created automatically for Google indexation, etc. +

    + We even do structured content automatically to promote your + product and events efficiently in Google. +

    +
    +
    +
    + +
    +
    +

    Leverage Social Media

    +

    Optimize: from Ads to Conversions

    +
    +

    + Create new landing pages easily with the OpenERP inline edition + feature. Send visitors of your different marketing campaigns to + specific landing pages to optimize conversions. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Organize Efficiently

    +
    +

    + +

    +
    +
    +
    + +
    +
    +
    +
    From ec950aec2b68d256b500546d594d20fb7faee91e Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 8 Aug 2013 16:23:41 +0200 Subject: [PATCH 12/77] [IMP] website_sale: use link instead of javascript hack for button 'add cart' and 'checkout' bzr revid: chm@openerp.com-20130808142341-ju7qq63543fkr2uw --- addons/website_sale/controllers/main.py | 109 ++++---- .../website_sale/static/src/js/ecommerce.js | 45 +--- addons/website_sale/views/ecommerce.xml | 240 +++++++++++------- 3 files changed, 208 insertions(+), 186 deletions(-) diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 56cfa8d0a11..61463602970 100644 --- a/addons/website_sale/controllers/main.py +++ b/addons/website_sale/controllers/main.py @@ -2,10 +2,11 @@ import math import openerp -import simplejson from openerp.osv import osv from openerp.addons.web import http from openerp.addons.web.http import request +import werkzeug +from urllib import urlencode def get_order(order_id=None): order_obj = request.registry.get('sale.order') @@ -86,7 +87,7 @@ class Ecommerce(http.Controller): product_ids = product_obj.search(request.cr, request.uid, [("id", "in", product_ids)]) return product_obj.browse(request.cr, request.uid, product_ids) - @http.route(['/shop', '/shop/category/', '/shop/category//page/', '/shop/page/'], type='http', auth="public") + @http.route(['/shop/', '/shop/category//', '/shop/category//page//', '/shop/page//'], type='http', auth="public") def category(self, cat_id=0, page=0, **post): website = request.registry['website'] @@ -133,7 +134,7 @@ class Ecommerce(http.Controller): }) return self.render("website_sale.products", values) - @http.route(['/shop/product/'], type='http', auth="public") + @http.route(['/shop/product//'], type='http', auth="public") def product(self, cat_id=0, product_id=0): website = request.registry['website'] order = get_current_order() @@ -151,7 +152,7 @@ class Ecommerce(http.Controller): }) return self.render("website_sale.product", values) - @http.route(['/shop/mycart'], type='http', auth="public") + @http.route(['/shop/mycart/'], type='http', auth="public") def mycart(self, **post): website = request.registry['website'] order = get_current_order() @@ -169,9 +170,7 @@ class Ecommerce(http.Controller): return self.render("website_sale.mycart", values) - @http.route(['/shop/add_cart'], type='http', auth="public") - def add_cart(self, product_id=0, remove=False): - website = request.registry['website'] + def add_product_to_cart(self, product_id=0, number=1): context = {} order_line_obj = request.registry.get('sale.order.line') @@ -187,7 +186,7 @@ class Ecommerce(http.Controller): order_line_ids = order_line_obj.search(request.cr, openerp.SUPERUSER_ID, [('order_id', '=', order.id), ('product_id', '=', product_id)], context=context) if order_line_ids: order_line = order_line_obj.read(request.cr, openerp.SUPERUSER_ID, order_line_ids, [], context=context)[0] - quantity = order_line['product_uom_qty'] + (remove and -1 or 1) + quantity = order_line['product_uom_qty'] + number if quantity <= 0: order_line_obj.unlink(request.cr, openerp.SUPERUSER_ID, order_line_ids, context=context) else: @@ -210,32 +209,42 @@ class Ecommerce(http.Controller): order_line_id = order_line_obj.create(request.cr, openerp.SUPERUSER_ID, values, context=context) order.write({'order_line': [(4, order_line_id)]}, context=context) - values = website.get_rendering_context() - html = self.render("website_sale.total", values) - return simplejson.dumps({"quantity": quantity, "totalHTML": html}) + return quantity - @http.route(['/shop/remove_cart'], type='http', auth="public") + @http.route(['/shop/add_cart//', '/shop//add_cart//'], type='http', auth="public") + def json_add_cart(self, path=None, product_id=0, remove=False): + self.add_product_to_cart(product_id, remove and -1 or 1) + if path: + return werkzeug.utils.redirect("/shop/%s/" % path) + else: + return werkzeug.utils.redirect("/shop/") + + @http.route(['/shop/remove_cart//', '/shop//remove_cart//'], type='http', auth="public") + def json_remove_cart(self, path=None, product_id=0, remove=False): + return self.json_add_cart(path=path, product_id=product_id, remove=True) + + @http.route(['/shop/remove_cart/'], type='http', auth="public") def remove_cart(self, product_id=0): return self.add_cart(product_id=product_id, remove=True) - @http.route(['/shop/checkout'], type='http', auth="public") + @http.route(['/shop/checkout/'], type='http', auth="public") def checkout(self, **post): website = request.registry['website'] + values = website.get_rendering_context({ - 'partner': False + 'partner': False, + 'checkout': request.session.setdefault('checkout', {}), + 'error': post.get("error") and dict.fromkeys(post.get("error").split(","), 1) or [] }) order = get_current_order() - if order.state != 'draft': - return self.confirmed(**post) - if not order.order_line: + if order.state != 'draft' or not order.order_line: return self.mycart(**post) partner_obj = request.registry.get('res.partner') user_obj = request.registry.get('res.users') country_obj = request.registry.get('res.country') country_state_obj = request.registry.get('res.country.state') - payment_obj = request.registry.get('portal.payment.acquirer') if request.uid != website.get_public_user().id: values['partner'] = user_obj.browse(request.cr, request.uid, request.uid).partner_id @@ -247,39 +256,33 @@ class Ecommerce(http.Controller): values['countries'] = country_obj.browse(request.cr, openerp.SUPERUSER_ID, country_obj.search(request.cr, openerp.SUPERUSER_ID, [(1, "=", 1)])) values['states'] = country_state_obj.browse(request.cr, openerp.SUPERUSER_ID, country_state_obj.search(request.cr, openerp.SUPERUSER_ID, [(1, "=", 1)])) - payment_ids = payment_obj.search(request.cr, openerp.SUPERUSER_ID, [('visible', '=', True)]) - values['payments'] = payment_obj.browse(request.cr, openerp.SUPERUSER_ID, payment_ids) - for payment in values['payments']: - content = payment_obj.render(request.cr, openerp.SUPERUSER_ID, payment.id, order, order.name, order.pricelist_id.currency_id, order.amount_total) - payment._content = content - return website.render("website_sale.checkout", values) - @http.route(['/shop/confirm_order'], type='http', auth="public") + @http.route(['/shop/confirm_order/'], type='http', auth="public") def confirm_order(self, **post): website = request.registry['website'] order = get_current_order() - json = {'error': [], 'validation': False} + error = [] partner_obj = request.registry.get('res.partner') user_obj = request.registry.get('res.users') if order.state != 'draft': - json['validation'] = True - return json + return werkzeug.utils.redirect("/shop/checkout/") if not order.order_line: - json['error'].append("empty_cart") - return json + error.append("empty_cart") + return werkzeug.utils.redirect("/shop/checkout/") # check values + request.session['checkout'] = post required_field = ['phone', 'zip', 'email', 'street', 'city', 'name', 'country_id'] for key in required_field: if not post.get(key): - json['error'].append(key) - if 'shipping_name' in post and key != 'email' and not post.get("shipping_%s" % key): - json['error'].append("shipping_%s" % key) - if json['error']: - return simplejson.dumps(json) + error.append(key) + if post.get('shipping_different') and key != 'email' and not post.get("shipping_%s" % key): + error.append("shipping_%s" % key) + if error: + return werkzeug.utils.redirect("/shop/checkout/?error=%s" % ",".join(error)) # search or create company company_id = None @@ -339,30 +342,34 @@ class Ecommerce(http.Controller): order_value.update(request.registry.get('sale.order').onchange_partner_id(request.cr, openerp.SUPERUSER_ID, [], request.uid, context={})['value']) order.write(order_value) - json['validation'] = True - return simplejson.dumps(json) + request.httprequest.session['ecommerce_order_id_old'] = order.id + request.httprequest.session['ecommerce_order_id'] = None - @http.route(['/shop/confirmed'], type='http', auth="public") - def confirmed(self, **post): + return werkzeug.utils.redirect("/shop/payment/") + + @http.route(['/shop/payment/'], type='http', auth="public") + def payment(self, **post): website = request.registry['website'] + order = get_order(request.httprequest.session.get('ecommerce_order_id_old')) - if request.httprequest.session.get('ecommerce_order_id'): - order = get_current_order() - if order.state != 'draft': - request.httprequest.session['ecommerce_order_id_old'] = order.id - request.httprequest.session['ecommerce_order_id'] = None - - order_old = get_order(request.httprequest.session.get('ecommerce_order_id_old')) - if not order_old.order_line: + if order.state != 'progress': return self.mycart(**post) values = website.get_rendering_context({ - 'temp': 0, - 'order': order_old, + 'partner': False, + 'order': order }) - return self.render("website_sale.confirmed", values) - @http.route(['/shop/publish'], type='http', auth="public") + payment_obj = request.registry.get('portal.payment.acquirer') + payment_ids = payment_obj.search(request.cr, openerp.SUPERUSER_ID, [('visible', '=', True)]) + values['payments'] = payment_obj.browse(request.cr, openerp.SUPERUSER_ID, payment_ids) + for payment in values['payments']: + content = payment_obj.render(request.cr, openerp.SUPERUSER_ID, payment.id, order, order.name, order.pricelist_id.currency_id, order.amount_total) + payment._content = content + + return website.render("website_sale.payment", values) + + @http.route(['/shop/publish/'], type='http', auth="public") def publish(self, **post): product_id = int(post['id']) product_obj = request.registry['product.product'] diff --git a/addons/website_sale/static/src/js/ecommerce.js b/addons/website_sale/static/src/js/ecommerce.js index c5f8da4cf90..548f190e674 100644 --- a/addons/website_sale/static/src/js/ecommerce.js +++ b/addons/website_sale/static/src/js/ecommerce.js @@ -16,53 +16,10 @@ $(document).ready(function () { }); }); - $('.oe_ecommerce').on('click', '.oe_product .btn, .oe_product_detail .btn', function (e) { - var $button = $(e.currentTarget); - var $product = $button.parents('.oe_product:first, .oe_product_detail:first'); - var link = $button.hasClass('btn-inverse') ? '/shop/remove_cart' : '/shop/add_cart'; - var $add = $product.find('.btn-success,.btn-primary'); - var $remove = $product.find('.btn-inverse'); - - $.get(link, {'product_id': $button.data('id')}, function (result) { - var result = JSON.parse(result); - var quantity = parseInt(result.quantity); - $add.find('.oe_quantity') - .html(quantity); - $add.toggleClass('btn-primary', !quantity) - .toggleClass('btn-success', !!quantity); - $remove.toggleClass('hidden', !quantity); - if ($('.oe_mycart').size() && !quantity) { - $product.remove() - } - $('.oe_ecommerce .oe_total').replaceWith(''+result.totalHTML); - }); - }); - var $checkout = $(".oe_ecommerce .oe_checkout"); $(".oe_ecommerce input[name='shipping_different']").change(function() { $(".oe_ecommerce .js_shipping").toggle(); }); - $(".oe_ecommerce .js_error_payment").click(function(e) { - var values = {}; - $checkout.find(".js_inputs:not(:hidden) input:not(:checkbox), .js_inputs:not(:hidden) select, .js_signin_modal input").each(function() { - values[$(this).attr("name")] = $(this).val(); - }); - $checkout.find("input").css("border", ""); - $.post('/shop/confirm_order', values, function (result) { - var result = JSON.parse(result); - console.log(result); - if (result.error.length) { - $inputs = $checkout.find("input[name='" + result.error.join("'], input[name='") + "']"); - $inputs.css("border", "1px solid #dd0000"); - $inputs.first().focus(); - } - if (result.validation) { - var $form = $(e.currentTarget).parent().find("input[name='submit']").click(); - setTimeout(function() { - window.location.href = "/shop/confirmed"; - }, 0); - } - }); - }); + }); diff --git a/addons/website_sale/views/ecommerce.xml b/addons/website_sale/views/ecommerce.xml index 2ab5469e081..4789862b0b4 100644 --- a/addons/website_sale/views/ecommerce.xml +++ b/addons/website_sale/views/ecommerce.xml @@ -10,8 +10,8 @@ -
  • &nbsp; &nbsp; &nbsp; My cart
  • -
  • Shop
  • +
  • &nbsp; &nbsp; &nbsp; My cart
  • +
  • Shop
  • @@ -22,8 +22,8 @@ -
  • &nbsp; &nbsp; &nbsp; My cart
  • -
  • Shop
  • +
  • &nbsp; &nbsp; &nbsp; My cart
  • +
  • Shop
  • @@ -76,7 +76,7 @@ @@ -109,7 +109,7 @@ pull-left - @@ -131,20 +131,18 @@ + + - - From fbb2d16c6116154eeb46bb38bedcda2fe48ae97e Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 8 Aug 2013 16:42:47 +0200 Subject: [PATCH 13/77] [IMP] website_sale: add number of products in my cart top menu link bzr revid: chm@openerp.com-20130808144247-pi2p5d00h3eke4cl --- addons/website_sale/views/ecommerce.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/website_sale/views/ecommerce.xml b/addons/website_sale/views/ecommerce.xml index 4789862b0b4..7124b603646 100644 --- a/addons/website_sale/views/ecommerce.xml +++ b/addons/website_sale/views/ecommerce.xml @@ -22,7 +22,7 @@ -
  • &nbsp; &nbsp; &nbsp; My cart
  • +
  • &nbsp; &nbsp; &nbsp; My cart
  • Shop
  • From b49a3cf9d8727f371421df279cdaac0da594dc87 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 8 Aug 2013 19:39:36 +0200 Subject: [PATCH 14/77] [IMP] Improved manifest: website_event, draft bzr revid: fp@tinyerp.com-20130808173936-31o4xjli44acnnq3 --- .../static/description/index.html | 93 ++++++++++++++----- 1 file changed, 70 insertions(+), 23 deletions(-) diff --git a/addons/website_event/static/description/index.html b/addons/website_event/static/description/index.html index 8a79fce2a21..6ddfa7fb813 100644 --- a/addons/website_event/static/description/index.html +++ b/addons/website_event/static/description/index.html @@ -14,7 +14,10 @@

    - + Schedule, promote, sell and organize your events online with no + effort. Whether you organize meetings, conferences, trainings + or webinars, OpenERP gives you all the features you need to + manage all aspects of your event.

    Start your free online store @@ -25,20 +28,19 @@
    -

    Create Awsome Event Pages

    +

    Create Awesome Event Pages

    Get rid of old WYSIWYG editors

    - OpenERP's unique 'edit inline' approach makes website - creation surprisingly easy. "Want to present a speaker? to - change the price of a ticket? to update a banner? to present a - schedule?" just click and change. What you see is what you get. - Really. -

    Drag & Drop well designed 'Building Blocks' to create beautifull event pages that your customer will love. Use pre-defined building blocks like; speakers, schedules, social icons, etc. +

    + OpenERP's unique 'edit inline' approach makes website + creation surprisingly easy. "Want to introduce a speaker? to + change the price of a ticket? to update a banner? promote sponsors?" + just click and change. What you see is what you get. Really.

    @@ -49,6 +51,26 @@
    +
    +
    +

    Sell Tickets Online

    +

    Mass Mailing & Social Media Icons

    +
    + +
    +
    +

    + Use the multi-ticketing feature to sell registrations to your + event. Events can be free or for a fee. Attendees can pay online + with a credit card or on invoice, based on your configuration. +

    + Boost your sales with early-bird prices, special conditions for + members, or extra services with multiple tickets. +

    +
    +
    +
    +

    Promote Events Efficiently

    @@ -58,8 +80,10 @@

    - - + Use the segmentation, the social network integration and mass + mailing features to promote your events to the right audience. + Setup automated emails to attendees to send them last minute + details.

    @@ -96,7 +120,7 @@ HTML structure, a bootstrap CSS and our modularity allows to distribute your themes easily.

    - The building block approach allows the website to remain clean + The building block approach allows the website to stay clean after the end-users start creating new contents.

    @@ -122,10 +146,10 @@ SEO tools are ready to use, with no configuration required. OpenERP suggests keywords according to Google most searched terms, Google Analytics tracks your shopping cart events, - sitemap are created automatically for Google indexation, etc. + sitemap are created automatically.

    We even do structured content automatically to promote your - product and events efficiently in Google. + events and products efficiently in Google.

    @@ -139,7 +163,7 @@

    Create new landing pages easily with the OpenERP inline edition feature. Send visitors of your different marketing campaigns to - specific landing pages to optimize conversions. + event landing pages to optimize conversions.

    @@ -152,16 +176,39 @@
    -

    Organize Efficiently

    -
    -

    - -

    +

    And Much More...

    +
    +

    Schedule

    +
      +
    • Calendar of Events
    • +
    • Publish related documents
    • +
    • Ressources allocation
    • +
    • Automate purchases (cathering...)
    • +
    • Multiple locations and organizers
    • +
    • Mobile Interface
    • +
    -
    -
    - -
    +
    +

    Sell

    +
      +
    • Online or offline sales
    • +
    • Automated invoicing
    • +
    • Cancellation policies
    • +
    • Specific prices for members
    • +
    • Dashboards and reporting
    • +
    +
    +
    +

    Organize

    +
      +
    • Advanced Planification
    • +
    • Print Badges
    • +
    • Automate Follow-up Emails
    • +
    • Min/Max capacities
    • +
    • Manage classes and ressources
    • +
    • Create group of attendees
    • +
    • Automate statisfaction surveys
    • +
    From 804d6119e11149729ceb6b97ba3cb50ff8fe8030 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 8 Aug 2013 20:07:15 +0200 Subject: [PATCH 15/77] [IMP] adding website_hr maniffest, draft bzr revid: fp@tinyerp.com-20130808180715-i8szh7ooe3rjdiwu --- .../static/description/index.html | 115 +++++++++++++++ .../website_hr/static/description/index.html | 137 ++++++++++++++++++ 2 files changed, 252 insertions(+) create mode 100644 addons/hr_recruitment/static/description/index.html create mode 100644 addons/website_hr/static/description/index.html diff --git a/addons/hr_recruitment/static/description/index.html b/addons/hr_recruitment/static/description/index.html new file mode 100644 index 00000000000..f91da54ad55 --- /dev/null +++ b/addons/hr_recruitment/static/description/index.html @@ -0,0 +1,115 @@ +
    +
    +
    +

    Open Source Job Board

    +

    Organize your job postings and applications

    +
    +
    +
    + + + + +
    +
    +
    +

    + Organize your job board, promote your job announces and keep + track of application submissions easily. Follow every applicant + and build up a database of skills and profiles with indexed + documents. +

    + +
    +
    +
    + +
    +
    +

    Post Your Jobs on Best Job Boards

    +

    LinkedIn, Monster, Kraigslist, Careerbuilder,...

    +
    + +
    +
    +

    + Connect automatically to most famous job board websites; + linkedIn, Monster, Kraigslist, ... Every job position has a new + email address automatically assigned to route applications + automatically to the right job position. +

    + Whether applicants contact you by email or using an online + form, you get all the data indexed automatically (resumes, + motivation letter) and you can answer in just a click, reusing + templates of answers. +

    +
    +
    +
    + +
    +
    +

    Customize Your Recruitment Process

    +

    Define your own stages and interviewers

    +
    +

    + Use the kanban view and customize the steps of your recruitments + process; pre-qualification, first interview, second interview, + negociaiton, ... +

    + Get accurate statistics on your recruitment pipeline. Get reports + to compare the performance of your different investments on + external job boards. +

    +
    +
    + +
    +
    +
    + + +
    +
    +

    Streamline Your Recruitment Process

    +

    Index resumes, track applicants, search profiles

    +
    + +
    +
    +

    + Follow applicants in your recruitment process with the smart + kanban view. Save time by automating some communications with + email templates. +

    + Documents like resumes and motivation letters are indexed + automatically, allowing you to easily find for specific skills + and build up a database of profiles. +

    +
    +
    +
    + + +
    +
    +

    Integrated Surveys

    +

    Define your own online or offline surveys

    +
    +
    + +
    +
    +
    +

    + Create your own interview canvas based on our best practices. + Use the survey designer to adapt questions to your own process. + Ask the applicant to fill in the survey online, or the + interviewer to use it during real interviews. +

    +
    +
    +
    + diff --git a/addons/website_hr/static/description/index.html b/addons/website_hr/static/description/index.html new file mode 100644 index 00000000000..b1bf0ff36c4 --- /dev/null +++ b/addons/website_hr/static/description/index.html @@ -0,0 +1,137 @@ +
    +
    +
    +

    Open Source Job Board

    +

    Organize your job postings and applications

    +
    +
    +
    + + + + +
    +
    +
    +

    + Organize your job board, promote your job announces and keep + track of application submissions easily. Follow every applicant + and build up a database of skills and profiles. +

    + +
    +
    +
    + +
    +
    +

    Create Awsome Job Description Pages

    +

    Get rid of old WYSIWYG editors

    +
    +

    + Get a clean and professional look for your job annouces. + OpenERP's unique 'edit inline' approach makes website + and job descriptions creation surprisingly easy. +

    + Drag & Drop well designed 'Building Blocks' to + create beautifull job descriptions and announces that + emphasizes the quality of your company. +

    +
    +
    +
    + +
    +
    +
    +
    + +
    +
    +

    Post Your Jobs on Best Job Boards

    +

    LinkedIn, Monster, Kraigslist, Careerbuilder,...

    +
    + +
    +
    +

    + Connect automatically to most famous job board websites; + linkedIn, Monster, Kraigslist, ... Every job position has a new + email address automatically assigned to route applications + automatically to the right job position. +

    + Whether applicants contact you by email or using an online + form, you get all the data indexed automatically (resumes, + motivation letter) and you can answer in just a click, reusing + templates of answers. +

    +
    +
    +
    + +
    +
    +

    Customize Your Recruitment Process

    +

    Define your own stages and interviewers

    +
    +

    + Use the kanban view and customize the steps of your recruitments + process; pre-qualification, first interview, second interview, + negociaiton, ... +

    + Get accurate statistics on your recruitment pipeline. Get reports + to compare the performance of your different investments on + external job boards. +

    +
    +
    + +
    +
    +
    + + +
    +
    +

    Streamline Your Recruitment Process

    +

    Index resumes, track applicants, search profiles

    +
    + +
    +
    +

    + Follow applicants in your recruitment process with the smart + kanban view. Save time by automating some communications with + email templates. +

    + Documents like resumes and motivation letters are indexed + automatically, allowing you to easily find for specific skills + and build up a database of profiles. +

    +
    +
    +
    + + +
    +
    +

    Integrated Surveys

    +

    Define your own online or offline surveys

    +
    +
    + +
    +
    +
    +

    + Create your own interview canvas based on our best practices. + Use the survey designer to adapt questions to your own process. + Ask the applicant to fill in the survey online, or the + interviewer to use it during real interviews. +

    +
    +
    +
    + From 9241f7d285919766ab4919b6bec110390374e3b5 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Thu, 8 Aug 2013 20:14:03 +0200 Subject: [PATCH 16/77] [IMP] manifest website_crm, draft bzr revid: fp@tinyerp.com-20130808181403-zonvspij5z42k1gg --- .../website_crm/static/description/index.html | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 addons/website_crm/static/description/index.html diff --git a/addons/website_crm/static/description/index.html b/addons/website_crm/static/description/index.html new file mode 100644 index 00000000000..b92c4ebbdb1 --- /dev/null +++ b/addons/website_crm/static/description/index.html @@ -0,0 +1,45 @@ +
    +
    +
    +

    Your Contact Form

    +

    Integrate contact forms with your leads

    +
    +
    +
    + + + + +
    +
    +
    +

    + This simple application integrates a contact form in your + "Contact us" page. Forms submissions create leads automatically + in OpenERP CRM. +

    + +
    +
    +
    + +
    +
    +

    Easy Contact Page

    +

    A contact form is better than an email

    +
    +

    + Get your leads filled up automatically with your contact form + integration. This application allows a better qualification of + the lead which is perfect to link them to marketing campaigns. +

    +
    +
    +
    + +
    +
    +
    +
    From e20dc8cee1424fd90a46f602b15afa955875bae6 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 8 Aug 2013 20:28:00 +0200 Subject: [PATCH 17/77] [FIX] template titles bzr revid: fme@openerp.com-20130808182800-xgc5c3fmx4f6xqmg --- addons/website/views/views.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index 198c96d508d..3fef05dfc3e 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -52,7 +52,7 @@ <!DOCTYPE html> - <t t-esc="res_company.name"/> + <t t-esc="title or res_company.name"/> @@ -346,7 +346,7 @@ @@ -338,7 +338,7 @@ This page does not exists, but you can create it as you are administrator of this site.

    - Create Page + Create Page or Search a Page
    From 5896c4d2f5403fef50934d142784cadcf117300e Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Sat, 10 Aug 2013 15:26:11 +0200 Subject: [PATCH 26/77] [IMP] record to template for contact form bzr revid: fp@tinyerp.com-20130810132611-5lf2efa6zyixi70t --- addons/website/__init__.py | 4 +- addons/website/views/views.xml | 4 +- addons/website_crm/views/website_crm.xml | 43 ++++++++++------------ addons/website_mail/views/website_mail.xml | 8 ++-- 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/addons/website/__init__.py b/addons/website/__init__.py index be415754735..17879db9942 100644 --- a/addons/website/__init__.py +++ b/addons/website/__init__.py @@ -1,3 +1,5 @@ import controllers import res_config -from website import website \ No newline at end of file + +from website import website +import view diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index 89683a7812b..388253eb54e 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -26,7 +26,7 @@
-
Connect with us
+
Connect with us
- Create a free website with OpenERP + Create a free website with OpenERP
Copyright &copy; Company name - Sitemap diff --git a/addons/website_crm/views/website_crm.xml b/addons/website_crm/views/website_crm.xml index 08e4da21983..d849504940e 100644 --- a/addons/website_crm/views/website_crm.xml +++ b/addons/website_crm/views/website_crm.xml @@ -1,33 +1,28 @@ - - contactus - qweb - - - - - - - + diff --git a/addons/website_mail/views/website_mail.xml b/addons/website_mail/views/website_mail.xml index eb45ce582a7..6de48040b9b 100644 --- a/addons/website_mail/views/website_mail.xml +++ b/addons/website_mail/views/website_mail.xml @@ -20,7 +20,7 @@
  • News
  • - + @@ -28,8 +28,10 @@ - - News + + From bff6e04e9536d7b80916987eb123de98b1b689b1 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers Date: Sat, 10 Aug 2013 19:01:10 +0200 Subject: [PATCH 27/77] [IMP] Missing file added bzr revid: fp@tinyerp.com-20130810170110-3ltmqwnmfpytfh39 --- addons/website/view.py | 37 ++++++++++++++++++++++++ addons/website_crm/views/website_crm.xml | 2 +- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 addons/website/view.py diff --git a/addons/website/view.py b/addons/website/view.py new file mode 100644 index 00000000000..af2224be4d9 --- /dev/null +++ b/addons/website/view.py @@ -0,0 +1,37 @@ +# -*- coding: utf-8 -*- + +from lxml import etree +from openerp.osv import osv, fields + + +class view(osv.osv): + _inherit = "ir.ui.view" + _columns = { + 'inherit_option_id': fields.many2one('ir.ui.view','Optional Inheritancy'), + 'inherited_option_ids': fields.one2many('ir.ui.view','inherit_option_id','Optional Inheritancies'), + } + + # Returns all views (called and inherited) related to a view + # Used by translation mechanism, SEO and optional templates + def _views_get(self, cr, uid, view, options=True, context={}, root=True): + if type(view) in (str, unicode): + mod_obj = self.pool.get("ir.model.data") + m, n = view.split('.') + _, view = mod_obj.get_object_reference(cr, uid, m, n) + if type(view) == int: + view_obj = self.pool.get("ir.ui.view") + view = view_obj.browse(cr, uid, view, context=context) + while root and view.inherit_id: + view = view.inherit_id + + result = [view] + todo = view.inherit_children_ids + if options: + todo += filter(lambda x: not x.inherit_id, view.inherited_option_ids) + for child_view in todo: + result += self._views_get(cr, uid, child_view, options=options, context=context, root=False) + node = etree.fromstring(view.arch) + for child in node.xpath("//t[@t-call]"): + result += self._views_get(cr, uid, child.get('t-call'), options=options, context=context) + return result + diff --git a/addons/website_crm/views/website_crm.xml b/addons/website_crm/views/website_crm.xml index d849504940e..f4cd386d458 100644 --- a/addons/website_crm/views/website_crm.xml +++ b/addons/website_crm/views/website_crm.xml @@ -1,7 +1,7 @@ -