diff --git a/addons/event_sale/event_sale.py b/addons/event_sale/event_sale.py index 8bacd37fc15..a8f73a3055f 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,9 +76,8 @@ 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: + if order_line.event_id: dic = { 'name': order_line.order_id.partner_invoice_id.name, 'partner_id': order_line.order_id.partner_id.id, @@ -84,9 +86,131 @@ 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) 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) + 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_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) + } + + 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' + + 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 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}} + + +class event_registration(osv.osv): + """Event Registration""" + _inherit= 'event.registration' + _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/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/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_event/controllers/main.py b/addons/website_event/controllers/main.py index adc4342b7d5..87cb80852db 100644 --- a/addons/website_event/controllers/main.py +++ b/addons/website_event/controllers/main.py @@ -105,9 +105,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 +156,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/event.py b/addons/website_event/event.py index 65a8034951f..da80f86fc5b 100644 --- a/addons/website_event/event.py +++ b/addons/website_event/event.py @@ -2,35 +2,10 @@ from openerp.osv import osv, fields - -class event(osv.osv): - _inherit = 'event.event' - _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"), - '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'), - } - - -class event_product(osv.osv): - _name = 'event.event.product' - _columns = { - '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'), - } - 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}} - - +# defined for access rules class product(osv.osv): _inherit = 'product.product' _columns = { - 'event_product_ids': fields.one2many('event.event.product', 'product_id', 'Linked event product'), + 'event_ticket_ids': fields.one2many('event.event.ticket', 'product_id', 'Event Tickets'), } + diff --git a/addons/website_event/security/ir.model.access.csv b/addons/website_event/security/ir.model.access.csv index 430fced34b5..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_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,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 6c571eb4875..c26eac05841 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)] @@ -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)] diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index 65ff07fa9dd..b3b098fda85 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 - - - - - - - - - - - - - - - - - - - - - - @@ -93,9 +68,11 @@
  • - - No ticket available. - + No tickets needed. + + Tickets availables. + No ticket available. + Only tickets @@ -153,9 +130,11 @@
    - - No ticket available. - + No tickets needed. + + Tickets availables. + No ticket available. + Only tickets @@ -164,38 +143,43 @@

    + + Click to Unpublish + Click to Publish +


    - - Click to Unpublish - Click to Publish - -

    Ticket Information

    -
    +

    Ticket Information

    + - - - - - - - - - - - + + + + + + + + + + + + + + +
    Ticket typeSales EndPriceSeatsQuantity
    - - - / - -
    Ticket typeSales EndPriceSeatsQuantity
    + + + / + + Not ticket available +
    - +

    Event Details

    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 76190f7977c..98bebacff8e 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 + + @@ -9,8 +17,8 @@ - -
  • Team
  • + +
  • Jobs
  • @@ -18,14 +26,13 @@ - + + + + diff --git a/addons/website_sale/controllers/main.py b/addons/website_sale/controllers/main.py index 71a36d97ba5..56cfa8d0a11 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): @@ -189,15 +164,14 @@ 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), }) - 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): website = request.registry['website'] - values = website.get_rendering_context() context = {} order_line_obj = request.registry.get('sale.order.line') @@ -209,6 +183,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,7 +210,8 @@ 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) - html = website.render("website_sale.total", values) + values = website.get_rendering_context() + html = self.render("website_sale.total", values) return simplejson.dumps({"quantity": quantity, "totalHTML": html}) @http.route(['/shop/remove_cart'], type='http', auth="public") @@ -384,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 f69d74d9916..2ab5469e081 100644 --- a/addons/website_sale/views/ecommerce.xml +++ b/addons/website_sale/views/ecommerce.xml @@ -67,7 +67,7 @@
    @@ -260,7 +260,7 @@ - + €