diff --git a/addons/hr_recruitment/i18n/lt.po b/addons/hr_recruitment/i18n/lt.po new file mode 100644 index 00000000000..a1467354b74 --- /dev/null +++ b/addons/hr_recruitment/i18n/lt.po @@ -0,0 +1,1259 @@ +# Lithuanian translation for openobject-addons +# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2014. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2012-12-21 17:04+0000\n" +"PO-Revision-Date: 2014-03-16 13:33+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Lithuanian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2014-03-17 04:48+0000\n" +"X-Generator: Launchpad (build 16963)\n" + +#. module: hr_recruitment +#: help:hr.applicant,active:0 +msgid "" +"If the active field is set to false, it will allow you to hide the case " +"without removing it." +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.stage:0 +#: field:hr.recruitment.stage,requirements:0 +msgid "Requirements" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Application Summary" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Start Interview" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Mobile:" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.stage,fold:0 +msgid "" +"This stage is not visible, for example in status bar or kanban view, when " +"there are no records in that stage to display." +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.degree,name:hr_recruitment.degree_graduate +msgid "Graduate" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Group By..." +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Filter and view on next actions and date" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,department_id:0 +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,department_id:0 +msgid "Department" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,date_action:0 +msgid "Next Action Date" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,salary_expected_extra:0 +msgid "Expected Salary Extra" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Jobs" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Pending Jobs" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,message_unread:0 +msgid "Unread Messages" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,company_id:0 +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,company_id:0 +msgid "Company" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.source:0 +#: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_source_action +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_source +msgid "Sources of Applicants" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/hr_recruitment.py:435 +#, python-format +msgid "You must define Applied Job for this applicant." +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Job" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.partner.create,close:0 +msgid "Close job request" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,help:hr_recruitment.crm_case_categ0_act_job +msgid "" +"

\n" +" Click to add a new job applicant.\n" +"

\n" +" OpenERP helps you track applicants in the recruitment\n" +" process and follow up all operations: meetings, interviews, " +"etc.\n" +"

\n" +" If you setup the email gateway, applicants and their " +"attached\n" +" CV are created automatically when an email is sent to\n" +" jobs@yourcompany.com. If you install the document " +"management\n" +" modules, all resumes are indexed automatically, so that you " +"can\n" +" easily search through their content.\n" +"

\n" +" " +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.crm_case_categ0_act_job +#: model:ir.ui.menu,name:hr_recruitment.menu_crm_case_categ0_act_job +msgid "Applications" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,day_open:0 +msgid "Days to Open" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,emp_id:0 +msgid "employee" +msgstr "" + +#. module: hr_recruitment +#: field:hr.config.settings,fetchmail_applicants:0 +msgid "Create applicants from an incoming email account" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,day:0 +msgid "Day" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.partner.create:0 +#: model:ir.actions.act_window,name:hr_recruitment.action_hr_recruitment_partner_create +msgid "Create Contact" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Refuse" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.degree,name:hr_recruitment.degree_licenced +msgid "Master Degree" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,partner_mobile:0 +msgid "Mobile" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,message_ids:0 +msgid "Messages" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Next Actions" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:38 +#: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:56 +#, python-format +msgid "Error!" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.degree,name:hr_recruitment.degree_bac5 +msgid "Doctoral Degree" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,job_id:0 +#: field:hr.recruitment.report,job_id:0 +msgid "Applied Job" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.stage,department_id:0 +msgid "" +"Stages of the recruitment process may be different per department. If this " +"stage is common to all departments, keep this field empty." +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,message_unread:0 +msgid "If checked new messages require your attention." +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,color:0 +msgid "Color Index" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.act_hr_applicant_to_meeting +msgid "Meetings" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: model:ir.actions.act_window,name:hr_recruitment.action_applicants_status +msgid "Applicants Status" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "My Recruitment" +msgstr "" + +#. module: hr_recruitment +#: field:hr.job,survey_id:0 +msgid "Interview Form" +msgstr "" + +#. module: hr_recruitment +#: help:hr.job,survey_id:0 +msgid "" +"Choose an interview form for this job position and you will be able to " +"print/answer this interview from all applicants who apply for this job" +msgstr "" + +#. module: hr_recruitment +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_recruitment +msgid "Recruitment" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,message_summary:0 +msgid "" +"Holds the Chatter summary (number of messages, ...). This summary is " +"directly in html format in order to be inserted in kanban views." +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/hr_recruitment.py:435 +#, python-format +msgid "Warning!" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,salary_prop:0 +msgid "Salary Proposed" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,partner_id:0 +msgid "Partner" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Avg Proposed Salary" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,availability:0 +#: field:hr.recruitment.report,available:0 +msgid "Availability" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,salary_proposed:0 +#: view:hr.recruitment.report:0 +msgid "Proposed Salary" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_source +msgid "Source of Applicants" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.partner.create:0 +msgid "Convert To Partner" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_report +msgid "Recruitments Statistics" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Print interview report" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Hired employees" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_job +msgid "Job Description" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,source_id:0 +msgid "Source" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,message_follower_ids:0 +msgid "Followers" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.source,name:hr_recruitment.source_monster +msgid "Monster" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,name:hr_recruitment.mt_applicant_hired +msgid "Applicant Hired" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,email_from:0 +msgid "Email" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,help:hr_recruitment.hr_job_stage_act +msgid "" +"

\n" +" Click to add a new stage in the recruitment process.\n" +"

\n" +" Define here your stages of the recruitment process, for " +"example:\n" +" qualification call, first interview, second interview, refused,\n" +" hired.\n" +"

\n" +" " +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Available" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,title_action:0 +msgid "Next Action" +msgstr "" + +#. module: hr_recruitment +#: help:hr.job,alias_id:0 +msgid "" +"Email alias for this job position. New emails will automatically create new " +"applicants for this job position." +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "Good" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "August" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,create_date:0 +#: view:hr.recruitment.report:0 +msgid "Creation Date" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.action_hr_recruitment_hired_employee +#: model:ir.model,name:hr_recruitment.model_hired_employee +msgid "Create Employee" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,priority:0 +#: field:hr.recruitment.report,priority:0 +msgid "Appreciation" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job1 +msgid "Initial Qualification" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Print Interview" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,stage_id:0 +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,stage_id:0 +#: view:hr.recruitment.stage:0 +msgid "Stage" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job3 +msgid "Second Interview" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.hr_job_stage_act +msgid "Recruitment / Applicants Stages" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,salary_expected:0 +#: view:hr.recruitment.report:0 +msgid "Expected Salary" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "July" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,email_cc:0 +msgid "Watchers Emails" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Applicants" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/hr_recruitment.py:351 +#, python-format +msgid "No Subject" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,salary_exp:0 +msgid "Salary Expected" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_applicant +msgid "Applicant" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.stage,sequence:0 +msgid "Gives the sequence order when displaying a list of stages." +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,partner_id:0 +msgid "Contact" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,salary_expected_extra:0 +msgid "Salary Expected by Applicant, extra advantages" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,state:0 +msgid "" +"The status is set to 'Draft', when a case is created. " +"If the case is in progress the status is set to 'Open'. " +"When the case is over, the status is set to 'Done'. If " +"the case needs to be reviewed then the status is set " +"to 'Pending'." +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "March" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.stage:0 +#: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_stage_act +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_stage +msgid "Stages" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Draft recruitment" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Delete" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "In progress" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Hire & Create Employee" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,description:hr_recruitment.mt_applicant_hired +msgid "Applicant hired" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Jobs - Recruitment Form" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,probability:0 +msgid "Probability" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "April" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "September" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "December" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:39 +#, python-format +msgid "A contact is already defined on this job request." +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,categ_ids:0 +msgid "Tags" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_applicant_category +msgid "Category of applicant" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,month:0 +msgid "Month" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Answer related job question" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job2 +msgid "First Interview" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,write_date:0 +msgid "Update Date" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +msgid "Yes" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,name:0 +msgid "Subject" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +#: view:hr.recruitment.partner.create:0 +msgid "or" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,name:hr_recruitment.mt_applicant_refused +msgid "Applicant Refused" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Schedule Meeting" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,partner_name:0 +msgid "Applicant's Name" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "Very Good" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,user_email:0 +msgid "User Email" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,date_open:0 +msgid "Opened" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Group By ..." +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +msgid "No" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,salary_expected:0 +msgid "Salary Expected by Applicant" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "All Initial Jobs" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,email_cc:0 +msgid "" +"These email addresses will be added to the CC field of all inbound and " +"outbound emails for this record before being sent. Separate multiple email " +"addresses with a comma" +msgstr "" + +#. module: hr_recruitment +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_degree +msgid "Degrees" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,date_closed:0 +#: field:hr.recruitment.report,date_closed:0 +msgid "Closed" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.stage:0 +msgid "Stage Definition" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,delay_close:0 +msgid "Avg. Delay to Close" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,salary_proposed:0 +msgid "Salary Proposed by the Organisation" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: selection:hr.applicant,state:0 +#: view:hr.recruitment.report:0 +#: selection:hr.recruitment.report,state:0 +#: selection:hr.recruitment.stage,state:0 +msgid "Pending" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,state:0 +#: field:hr.recruitment.report,state:0 +#: field:hr.recruitment.stage,state:0 +msgid "Status" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Schedule interview with this applicant" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/hr_recruitment.py:397 +#, python-format +msgid "Applicant created" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,type_id:0 +#: view:hr.recruitment.degree:0 +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,type_id:0 +#: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_degree_action +msgid "Degree" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,partner_phone:0 +msgid "Phone" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "June" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,day_close:0 +msgid "Days to Close" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,message_is_follower:0 +msgid "Is a Follower" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,user_id:0 +msgid "User" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "Excellent" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,active:0 +msgid "Active" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,nbr:0 +msgid "# of Applications" +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,help:hr_recruitment.hr_recruitment_stage_act +msgid "" +"

\n" +" Click to add a new stage in the recruitment process.\n" +"

\n" +" Don't forget to specify the department if your recruitment " +"process\n" +" is different according to the job position.\n" +"

\n" +" " +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,response:0 +msgid "Response" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "October" +msgstr "" + +#. module: hr_recruitment +#: field:hr.config.settings,module_document_ftp:0 +msgid "Allow the automatic indexation of resumes" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,salary_proposed_extra:0 +msgid "Proposed Salary Extra" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "January" +msgstr "" + +#. module: hr_recruitment +#: code:addons/hr_recruitment/wizard/hr_recruitment_create_partner_job.py:56 +#, python-format +msgid "A contact is already existing with the same name." +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,name:hr_recruitment.hr_recruitment_stage_form_installer +msgid "Review Recruitment Stages" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Contact:" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Search Jobs" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,date:0 +#: field:hr.recruitment.report,date:0 +msgid "Date" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,survey:0 +msgid "Survey" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +msgid "Would you like to create an employee ?" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Degree:" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Extended Filters..." +msgstr "" + +#. module: hr_recruitment +#: model:ir.actions.act_window,help:hr_recruitment.hr_recruitment_stage_form_installer +msgid "" +"Check if the following stages are matching your recruitment process. Don't " +"forget to specify the department if your recruitment process is different " +"according to the job position." +msgstr "" + +#. module: hr_recruitment +#: view:hr.config.settings:0 +msgid "Configure" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job4 +msgid "Contract Proposed" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.source,name:hr_recruitment.source_website_company +msgid "Company Website" +msgstr "" + +#. module: hr_recruitment +#: sql_constraint:hr.recruitment.degree:0 +msgid "The name of the Degree of Recruitment must be unique!" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: field:hr.recruitment.report,year:0 +msgid "Year" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +#: view:hr.recruitment.partner.create:0 +msgid "Cancel" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.partner.create:0 +msgid "Are you sure you want to create a contact based on this job request ?" +msgstr "" + +#. module: hr_recruitment +#: help:hr.config.settings,fetchmail_applicants:0 +msgid "" +"Allow applicants to send their job application to an email address " +"(jobs@mycompany.com),\n" +" and create automatically application documents in the system." +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: selection:hr.applicant,state:0 +#: selection:hr.recruitment.stage,state:0 +msgid "In Progress" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Subject / Applicant" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.degree,sequence:0 +msgid "Gives the sequence order when displaying a list of degrees." +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,description:hr_recruitment.mt_stage_changed +msgid "Stage changed" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: field:hr.applicant,user_id:0 +#: view:hr.recruitment.report:0 +msgid "Responsible" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +#: model:ir.actions.act_window,name:hr_recruitment.action_hr_recruitment_report_all +#: model:ir.ui.menu,name:hr_recruitment.menu_hr_recruitment_report_all +msgid "Recruitment Analysis" +msgstr "" + +#. module: hr_recruitment +#: view:hired.employee:0 +msgid "Create New Employee" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.source,name:hr_recruitment.source_linkedin +msgid "LinkedIn" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,name:hr_recruitment.mt_job_new_applicant +msgid "New Applicant" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_stage +msgid "Stage of Recruitment" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Cases By Stage and Estimates" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +#: selection:hr.applicant,state:0 +#: view:hr.recruitment.report:0 +#: selection:hr.recruitment.report,state:0 +#: selection:hr.recruitment.stage,state:0 +msgid "New" +msgstr "" + +#. module: hr_recruitment +#: model:calendar.event.type,name:hr_recruitment.categ_meet_interview +#: view:hr.job:0 +msgid "Interview" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.source,name:0 +msgid "Source Name" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Day(s)" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,description:0 +msgid "Description" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,name:hr_recruitment.mt_stage_changed +msgid "Stage Changed" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "May" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job5 +msgid "Contract Signed" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.source,name:hr_recruitment.source_word +msgid "Word of Mouth" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.stage,fold:0 +msgid "Hide in views if empty" +msgstr "" + +#. module: hr_recruitment +#: help:hr.config.settings,module_document_ftp:0 +msgid "" +"Manage your CV's and motivation letter related to all applicants.\n" +" This installs the module document_ftp. This will install the " +"knowledge management module in order to allow you to search using specific " +"keywords through the content of all documents (PDF, .DOCx...)" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,state:0 +#: selection:hr.recruitment.report,state:0 +#: model:hr.recruitment.stage,name:hr_recruitment.stage_job6 +#: selection:hr.recruitment.stage,state:0 +msgid "Refused" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,state:0 +#: view:hr.recruitment.report:0 +#: selection:hr.recruitment.report,state:0 +#: selection:hr.recruitment.stage,state:0 +msgid "Hired" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,reference:0 +msgid "Referred By" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Departement:" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "On Average" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_degree +msgid "Degree of Recruitment" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,salary_prop_avg:0 +msgid "Avg. Proposed Salary" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Open Jobs" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "February" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.applicant,priority:0 +#: selection:hr.recruitment.report,priority:0 +msgid "Not Good" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant_category,name:0 +#: field:hr.recruitment.degree,name:0 +#: field:hr.recruitment.stage,name:0 +msgid "Name" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,month:0 +msgid "November" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.report,salary_exp_avg:0 +msgid "Avg. Expected Salary" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Avg Expected Salary" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_recruitment_partner_create +msgid "Create Partner from job application" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,email_from:0 +msgid "These people will receive email." +msgstr "" + +#. module: hr_recruitment +#: field:hr.job,alias_id:0 +msgid "Alias" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "Pending recruitment" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Contract" +msgstr "" + +#. module: hr_recruitment +#: field:hr.applicant,message_summary:0 +msgid "Summary" +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,message_ids:0 +msgid "Messages and communication history" +msgstr "" + +#. module: hr_recruitment +#: model:mail.message.subtype,description:hr_recruitment.mt_applicant_refused +msgid "Applicant refused" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.stage,department_id:0 +msgid "Specific to a Department" +msgstr "" + +#. module: hr_recruitment +#: view:hr.recruitment.report:0 +msgid "In progress recruitment" +msgstr "" + +#. module: hr_recruitment +#: field:hr.recruitment.degree,sequence:0 +#: field:hr.recruitment.stage,sequence:0 +msgid "Sequence" +msgstr "" + +#. module: hr_recruitment +#: model:hr.recruitment.degree,name:hr_recruitment.degree_bachelor +msgid "Bachelor Degree" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Unassigned Recruitments" +msgstr "" + +#. module: hr_recruitment +#: model:ir.model,name:hr_recruitment.model_hr_config_settings +msgid "hr.config.settings" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.stage,state:0 +msgid "" +"The related status for the stage. The status of your document will " +"automatically change according to the selected stage. Example, a stage is " +"related to the status 'Close', when your document reach this stage, it will " +"be automatically closed." +msgstr "" + +#. module: hr_recruitment +#: help:hr.applicant,salary_proposed_extra:0 +msgid "Salary Proposed by the Organisation, extra advantages" +msgstr "" + +#. module: hr_recruitment +#: help:hr.recruitment.report,delay_close:0 +msgid "Number of Days to close the project issue" +msgstr "" + +#. module: hr_recruitment +#: selection:hr.recruitment.report,state:0 +msgid "Open" +msgstr "" + +#. module: hr_recruitment +#: view:board.board:0 +msgid "Applications to be Processed" +msgstr "" + +#. module: hr_recruitment +#: view:hr.applicant:0 +msgid "Schedule Interview" +msgstr "" diff --git a/addons/project/i18n/zh_CN.po b/addons/project/i18n/zh_CN.po index c0cfcde2834..ecc5aa4aea3 100644 --- a/addons/project/i18n/zh_CN.po +++ b/addons/project/i18n/zh_CN.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2013-08-13 04:04+0000\n" -"Last-Translator: Wei \"oldrev\" Li \n" +"PO-Revision-Date: 2014-03-15 06:42+0000\n" +"Last-Translator: Victor Yu \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-04 06:19+0000\n" -"X-Generator: Launchpad (build 16948)\n" +"X-Launchpad-Export-Date: 2014-03-16 05:42+0000\n" +"X-Generator: Launchpad (build 16963)\n" #. module: project #: view:project.project:0 @@ -671,7 +671,7 @@ msgstr "新任务" #. module: project #: field:project.config.settings,module_project_issue_sheet:0 msgid "Invoice working time on issues" -msgstr "" +msgstr "依据问题工作时间开票" #. module: project #: view:project.project:0 @@ -828,7 +828,7 @@ msgstr "花费的时间" #: view:project.project:0 #: view:project.task:0 msgid "í" -msgstr "" +msgstr "í" #. module: project #: field:account.analytic.account,company_uom_id:0 @@ -958,7 +958,7 @@ msgstr "本项目和相关项目的任务实际花费的小时数合计" msgid "" "Follow this project to automatically track the events associated to tasks " "and issues of this project." -msgstr "" +msgstr "关注此项目的同时,追踪此项目的任务和问题关联的事件。" #. module: project #: view:project.task:0 @@ -1018,7 +1018,7 @@ msgstr "信息和通信历史记录" msgid "" "To invoice or setup invoicing and renewal options, go to the related " "contract:" -msgstr "" +msgstr "开票或设定发票更新选项,到相关的合同:" #. module: project #: field:project.task.delegate,state:0 diff --git a/addons/sale/i18n/zh_CN.po b/addons/sale/i18n/zh_CN.po index 0fbbcb6833d..a5ab6e3c64b 100644 --- a/addons/sale/i18n/zh_CN.po +++ b/addons/sale/i18n/zh_CN.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 6.0dev\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2012-12-21 17:04+0000\n" -"PO-Revision-Date: 2013-11-19 10:53+0000\n" -"Last-Translator: Guipo Hao \n" +"PO-Revision-Date: 2014-03-15 07:15+0000\n" +"Last-Translator: Victor Yu \n" "Language-Team: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-04 07:04+0000\n" -"X-Generator: Launchpad (build 16948)\n" +"X-Launchpad-Export-Date: 2014-03-16 05:42+0000\n" +"X-Generator: Launchpad (build 16963)\n" #. module: sale #: help:sale.order,message_summary:0 @@ -247,7 +247,7 @@ msgstr "计量单位 " #: code:addons/sale/wizard/sale_make_invoice_advance.py:101 #, python-format msgid "Incorrect Data" -msgstr "" +msgstr "错误的数据" #. module: sale #: code:addons/sale/wizard/sale_make_invoice_advance.py:102 @@ -1570,7 +1570,7 @@ msgstr "查找未开票明细" #. module: sale #: model:ir.model,name:sale.model_account_config_settings msgid "account.config.settings" -msgstr "" +msgstr "会计.配置.设定" #. module: sale #: sql_constraint:sale.order:0 @@ -2080,7 +2080,7 @@ msgstr "产品销售单位" #. module: sale #: model:process.node,note:sale.process_node_quotation0 msgid "Draft state of sales order" -msgstr "销售订单草稿状态" +msgstr "草稿状态的销售订单" #. module: sale #: field:sale.order,origin:0 @@ -2286,7 +2286,9 @@ msgstr "" msgid "" "Before choosing a product,\n" " select a customer in the sales form." -msgstr "在挑选产品前,在 销售表单选择一个客户" +msgstr "" +"在挑选产品前,\n" +" 在销售表单中选择一个客户。" #. module: sale #: view:sale.order:0 diff --git a/addons/share/i18n/zh_CN.po b/addons/share/i18n/zh_CN.po index e48a7466e8b..fc95d92b318 100644 --- a/addons/share/i18n/zh_CN.po +++ b/addons/share/i18n/zh_CN.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2012-12-21 17:06+0000\n" -"PO-Revision-Date: 2012-12-09 05:00+0000\n" -"Last-Translator: sum1201 \n" +"PO-Revision-Date: 2014-03-16 16:41+0000\n" +"Last-Translator: Victor Yu \n" "Language-Team: Chinese (Simplified) \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-03-04 07:34+0000\n" -"X-Generator: Launchpad (build 16948)\n" +"X-Launchpad-Export-Date: 2014-03-17 04:48+0000\n" +"X-Generator: Launchpad (build 16963)\n" #. module: share #: code:addons/share/wizard/share_wizard.py:842 @@ -76,6 +76,8 @@ msgid "" " %s\n" "\n" msgstr "" +"附件没弄好,你可以在OpenERP服务器上查看: %s\n" +"\n" #. module: share #: model:ir.module.category,name:share.module_category_share @@ -147,7 +149,7 @@ msgstr "共享URL" #: code:addons/share/wizard/share_wizard.py:881 #, python-format msgid "These are your credentials to access this protected area:\n" -msgstr "" +msgstr "这是你访问这个保护区域的凭证:\n" #. module: share #: view:share.wizard:0 @@ -173,7 +175,7 @@ msgstr "" #, python-format msgid "" "Please indicate the emails of the persons to share with, one per line." -msgstr "" +msgstr "请标明分享的用户电子邮箱,每行一个。" #. module: share #: help:share.wizard,domain:0 @@ -189,7 +191,7 @@ msgstr "下一个" #: code:addons/share/wizard/share_wizard.py:662 #, python-format msgid "Action and Access Mode are required to create a shared access." -msgstr "" +msgstr "操作和访问模式都需要要创建一个共享入口。" #. module: share #: code:addons/share/wizard/share_wizard.py:850 @@ -256,7 +258,7 @@ msgstr "非共享组" msgid "" "An email notification with instructions has been sent to the following " "people:" -msgstr "" +msgstr "带有操作说明的邮件通知已经发送到以下人了:" #. module: share #: code:addons/share/wizard/share_wizard.py:77 @@ -273,6 +275,8 @@ msgid "" "Sales, HR, etc.)\n" "It is open source and can be found on http://www.openerp.com." msgstr "" +"OpenERP是强大的、用户友好的商业应用套装(CRM,销售、人事、等)\n" +"而且是开源的,可以在 http://www.openerp.com 找到并下载。" #. module: share #: field:share.wizard,action_id:0 @@ -282,7 +286,7 @@ msgstr "共享操作" #. module: share #: help:share.wizard,record_name:0 msgid "Name of the shared record, if sharing a precise record" -msgstr "" +msgstr "如果共享一个精确记录,记录下分享名" #. module: share #: field:res.users,share:0 @@ -337,7 +341,7 @@ msgstr "创建新的" #. module: share #: help:share.wizard,name:0 msgid "Title for the share (displayed to users as menu and shortcut name)" -msgstr "" +msgstr "共享标题(显示给用户的菜单和快捷方式的名称)" #. module: share #: code:addons/share/wizard/share_wizard.py:636 @@ -348,7 +352,7 @@ msgstr "创建用户 %s (%s )间接共享过滤器,在用户组 %s" #. module: share #: help:share.wizard,share_root_url:0 msgid "Main access page for users that are granted shared access" -msgstr "" +msgstr "用户主要访问的页面被授权共享访问" #. module: share #: code:addons/share/wizard/share_wizard.py:206 @@ -356,7 +360,7 @@ msgstr "" msgid "" "You must configure your email address in the user preferences before using " "the Share button." -msgstr "" +msgstr "在使用分享按钮前,你必须在用户首选项处配置你的电子邮件。" #. module: share #: model:res.groups,name:share.group_share_user @@ -387,7 +391,7 @@ msgstr "数据库" #. module: share #: view:share.wizard:0 msgid "Share with these People (one email per line)" -msgstr "" +msgstr "与这些人分享(每行一个电子邮件)" #. module: share #: field:share.wizard,domain:0 @@ -409,7 +413,7 @@ msgstr "简述" #: help:share.wizard,embed_code:0 msgid "" "Embed this code in your documents to provide a link to the shared document." -msgstr "" +msgstr "在你的文档中嵌入下列代码以提供到分享文档的连接。" #. module: share #: code:addons/share/wizard/share_wizard.py:513 @@ -431,7 +435,7 @@ msgstr "共享你的单据" #. module: share #: view:share.wizard:0 msgid "Or insert the following code where you want to embed your documents" -msgstr "" +msgstr "或者在你想要嵌入你的文档时,插入下列代码" #. module: share #: code:addons/share/wizard/share_wizard.py:886 @@ -439,7 +443,7 @@ msgstr "" msgid "" "The documents have been automatically added to your current OpenERP " "documents.\n" -msgstr "" +msgstr "一份文档已经被自动增加到你现在的OpenERP文档中了。\n" #. module: share #: model:ir.model,name:share.model_share_wizard_result_line diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index abc64fee6e0..9872db219ec 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -314,6 +314,23 @@ class Website(openerp.addons.web.controllers.main.Home): '/website/image///' ], auth="public", website=True) def website_image(self, model, id, field, max_width=maxint, max_height=maxint): + """ Fetches the requested field and ensures it does not go above + (max_width, max_height), resizing it if necessary. + + Resizing is bypassed if the object provides a $field_big, which will + be interpreted as a pre-resized version of the base field. + + If the record is not found or does not have the requested field, + returns a placeholder image via :meth:`~.placeholder`. + + Sets and checks conditional response parameters: + * :mailheader:`ETag` is always set (and checked) + * :mailheader:`Last-Modified is set iif the record has a concurrency + field (``__last_update``) + + The requested field is assumed to be base64-encoded image data in + all cases. + """ Model = request.registry[model] response = werkzeug.wrappers.Response() @@ -322,15 +339,17 @@ class Website(openerp.addons.web.controllers.main.Home): ids = Model.search(request.cr, request.uid, [('id', '=', id)], context=request.context) \ - or Model.search(request.cr, openerp.SUPERUSER_ID, - [('id', '=', id), ('website_published', '=', True)], context=request.context) + or Model.search(request.cr, openerp.SUPERUSER_ID, + [('id', '=', id), ('website_published', '=', True)], context=request.context) if not ids: return self.placeholder(response) + presized = '%s_big' % field concurrency = '__last_update' [record] = Model.read(request.cr, openerp.SUPERUSER_ID, [id], - [concurrency, field], context=request.context) + [concurrency, field, presized], + context=request.context) if concurrency in record: server_format = openerp.tools.misc.DEFAULT_SERVER_DATETIME_FORMAT @@ -354,25 +373,28 @@ class Website(openerp.addons.web.controllers.main.Home): if response.status_code == 304: return response - data = record[field].decode('base64') - fit = int(max_width), int(max_height) + data = (record.get(presized) or record[field]).decode('base64') - buf = cStringIO.StringIO(data) - - image = Image.open(buf) - image.load() + image = Image.open(cStringIO.StringIO(data)) response.mimetype = Image.MIME[image.format] + # record provides a pre-resized version of the base field, use that + # directly + if record.get(presized): + response.set_data(data) + return response + + fit = int(max_width), int(max_height) w, h = image.size max_w, max_h = fit if w < max_w and h < max_h: - response.data = data + response.set_data(data) else: image.thumbnail(fit, Image.ANTIALIAS) image.save(response.stream, image.format) - # invalidate content-length computed by make_conditional as writing - # to response.stream does not do it (as of werkzeug 0.9.3) + # invalidate content-length computed by make_conditional as + # writing to response.stream does not do it (as of werkzeug 0.9.3) del response.headers['Content-Length'] return response diff --git a/addons/website/models/website.py b/addons/website/models/website.py index d4af418309c..15e1a643d3d 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -89,7 +89,7 @@ def slug(value): else: # assume name_search result tuple id, name = value - slugname = slugify(name) + slugname = slugify(name or '') if not slugname: return str(id) return "%s-%d" % (slugname, id) @@ -580,10 +580,26 @@ class ir_attachment(osv.osv): return hashlib.new('sha1', attachment_dict['datas']).hexdigest() return None + def _datas_big(self, cr, uid, ids, name, arg, context=None): + result = dict.fromkeys(ids, False) + if context and context.get('bin_size'): + return result + + for record in self.browse(cr, uid, ids, context=context): + if not record.datas: continue + try: + result[record.id] = openerp.tools.image_resize_image_big(record.datas) + except IOError: # apparently the error PIL.Image.open raises + pass + + return result + _columns = { 'datas_checksum': fields.function(_datas_checksum, size=40, string="Datas checksum", type='char', store=True, select=True), - 'website_url': fields.function(_website_url_get, string="Attachment URL", type='char') + 'website_url': fields.function(_website_url_get, string="Attachment URL", type='char'), + 'datas_big': fields.function (_datas_big, type='binary', store=True, + string="Resized file content"), } def create(self, cr, uid, values, context=None): diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index a6e4c3eb916..dc0628ca3c5 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -102,6 +102,10 @@ header a.navbar-brand img { max-height: 50px; } +#wrapwrap p:empty:after { + content: "\2060"; +} + /* ----- Snippets Styles ----- */ .readable { font-size: 120%; @@ -116,7 +120,7 @@ header a.navbar-brand img { } /* ----- BOOTSTRAP FIX ----- */ -.container .container { +.container .container, .readable .container { padding-left: 0; padding-right: 0; width: auto; @@ -217,7 +221,6 @@ footer { /* -- Hack for removing double scrollbar from mobile preview -- */ div#mobile-preview.modal { overflow: hidden; - overflow-y: hidden; } ul.nav-stacked > li > a { @@ -284,6 +287,7 @@ ul.nav-stacked > li > a { section, .carousel, .parallax, .row, .hr, .blockquote { min-height: 30px; } + .carousel, .parallax, .blockquote { overflow: hidden; } diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass index d6fbd0ac7bf..a15953e0f2b 100644 --- a/addons/website/static/src/css/website.sass +++ b/addons/website/static/src/css/website.sass @@ -68,6 +68,12 @@ header img max-height: 50px +// add {WORD JOINER} (equivalent to deprecated ZERO WIDTH NO-BREAK SPACE) at +// the beginning of paragraphs so they don't "disappear" after saving when +// used solely for spacing. +#wrapwrap p:empty:after + content: '\2060' + /* ----- Snippets Styles ----- */ .readable @@ -78,14 +84,12 @@ header /* ----- EDITOR ----- */ - .css_non_editable_mode_hidden display: none - /* ----- BOOTSTRAP FIX ----- */ -.container +.container, .readable .container padding-left: 0 padding-right: 0 @@ -180,7 +184,6 @@ footer /* -- Hack for removing double scrollbar from mobile preview -- */ div#mobile-preview.modal overflow: hidden - overflow-y: hidden ul.nav-stacked > li > a padding: 2px 15px diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index eec815ed8c7..31e39b3bbc4 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -2,9 +2,11 @@ "use strict"; var website = {}; - // The following line can be removed in 2017 openerp.website = website; + /* ---------------------------------------------------- + Helpers + ---------------------------------------------------- */ website.get_context = function (dict) { var html = document.documentElement; return _.extend({ @@ -34,26 +36,11 @@ } return parsedSearch; }; + website.parseHash = function () { return website.parseQS(window.location.hash.substring(1)); }; - /* ----- TEMPLATE LOADING ---- */ - var templates_def = $.Deferred().resolve(); - website.add_template_file = function(template) { - templates_def = templates_def.then(function() { - var def = $.Deferred(); - openerp.qweb.add_template(template, function(err) { - if (err) { - def.reject(err); - } else { - def.resolve(); - } - }); - return def; - }); - }; - website.add_template_file('/website/static/src/xml/website.xml'); website.reload = function () { location.hash = "scrollTop=" + window.document.body.scrollTop; if (location.search.indexOf("enable_editor") > -1) { @@ -63,102 +50,9 @@ } }; - var all_ready = null; - var dom_ready = website.dom_ready = $.Deferred(); - $(document).ready(function () { - website.is_editable = website.is_editable || $('html').data('editable'); - website.is_editable_button= website.is_editable_button || $('html').data('editable'); - dom_ready.resolve(); - // fix for ie - if($.fn.placeholder) $('input, textarea').placeholder(); - }); - - website.init_kanban = function ($kanban) { - $('.js_kanban_col', $kanban).each(function () { - var $col = $(this); - var $pagination = $('.pagination', $col); - if(!$pagination.size()) { - return; - } - - var page_count = $col.data('page_count'); - var scope = $pagination.last().find("li").size()-2; - var kanban_url_col = $pagination.find("li a:first").attr("href").replace(/[0-9]+$/, ''); - - var data = { - 'domain': $col.data('domain'), - 'model': $col.data('model'), - 'template': $col.data('template'), - 'step': $col.data('step'), - 'orderby': $col.data('orderby') - }; - - $pagination.on('click', 'a', function (ev) { - ev.preventDefault(); - var $a = $(ev.target); - if($a.parent().hasClass('active')) { - return; - } - - var page = +$a.attr("href").split(",").pop().split('-')[1]; - data['page'] = page; - - $.post('/website/kanban', data, function (col) { - $col.find("> .thumbnail").remove(); - $pagination.last().before(col); - }); - - var page_start = page - parseInt(Math.floor((scope-1)/2), 10); - if (page_start < 1 ) page_start = 1; - var page_end = page_start + (scope-1); - if (page_end > page_count ) page_end = page_count; - - if (page_end - page_start < scope) { - page_start = page_end - scope > 0 ? page_end - scope : 1; - } - - $pagination.find('li.prev a').attr("href", kanban_url_col+(page-1 > 0 ? page-1 : 1)); - $pagination.find('li.next a').attr("href", kanban_url_col+(page < page_end ? page+1 : page_end)); - for(var i=0; i < scope; i++) { - $pagination.find('li:not(.prev):not(.next):eq('+i+') a').attr("href", kanban_url_col+(page_start+i)).html(page_start+i); - } - $pagination.find('li.active').removeClass('active'); - $pagination.find('li:has(a[href="'+kanban_url_col+page+'"])').addClass('active'); - - }); - - }); - }; - - /** - * Returns a deferred resolved when the templates are loaded - * and the Widgets can be instanciated. - */ - website.ready = function() { - if (!all_ready) { - all_ready = dom_ready.then(function () { - return templates_def; - }).then(function () { - if (website.is_editable) { - website.id = $('html').data('website-id'); - website.session = new openerp.Session(); - var modules = ['website']; - return openerp._t.database.load_translations(website.session, modules, website.get_context().lang); - } - }).promise(); - } - return all_ready; - }; - - website.error = function(data, url) { - var $error = $(openerp.qweb.render('website.error_dialog', { - 'title': data.data ? data.data.arguments[0] : "", - 'message': data.data ? data.data.arguments[1] : data.statusText, - 'backend_url': url - })); - $error.appendTo("body"); - $error.modal('show'); - }; + /* ---------------------------------------------------- + Widgets + ---------------------------------------------------- */ website.prompt = function (options) { /** @@ -250,6 +144,16 @@ return def; }; + website.error = function(data, url) { + var $error = $(openerp.qweb.render('website.error_dialog', { + 'title': data.data ? data.data.arguments[0] : "", + 'message': data.data ? data.data.arguments[1] : data.statusText, + 'backend_url': url + })); + $error.appendTo("body"); + $error.modal('show'); + }; + website.form = function (url, method, params) { var form = document.createElement('form'); form.setAttribute('action', url); @@ -265,11 +169,117 @@ form.submit(); }; - dom_ready.then(function () { + website.init_kanban = function ($kanban) { + $('.js_kanban_col', $kanban).each(function () { + var $col = $(this); + var $pagination = $('.pagination', $col); + if(!$pagination.size()) { + return; + } - /* ----- BOOTSTRAP STUFF ---- */ - // $('.js_tooltip').bstooltip(); + var page_count = $col.data('page_count'); + var scope = $pagination.last().find("li").size()-2; + var kanban_url_col = $pagination.find("li a:first").attr("href").replace(/[0-9]+$/, ''); + var data = { + 'domain': $col.data('domain'), + 'model': $col.data('model'), + 'template': $col.data('template'), + 'step': $col.data('step'), + 'orderby': $col.data('orderby') + }; + + $pagination.on('click', 'a', function (ev) { + ev.preventDefault(); + var $a = $(ev.target); + if($a.parent().hasClass('active')) { + return; + } + + var page = +$a.attr("href").split(",").pop().split('-')[1]; + data['page'] = page; + + $.post('/website/kanban', data, function (col) { + $col.find("> .thumbnail").remove(); + $pagination.last().before(col); + }); + + var page_start = page - parseInt(Math.floor((scope-1)/2), 10); + if (page_start < 1 ) page_start = 1; + var page_end = page_start + (scope-1); + if (page_end > page_count ) page_end = page_count; + + if (page_end - page_start < scope) { + page_start = page_end - scope > 0 ? page_end - scope : 1; + } + + $pagination.find('li.prev a').attr("href", kanban_url_col+(page-1 > 0 ? page-1 : 1)); + $pagination.find('li.next a').attr("href", kanban_url_col+(page < page_end ? page+1 : page_end)); + for(var i=0; i < scope; i++) { + $pagination.find('li:not(.prev):not(.next):eq('+i+') a').attr("href", kanban_url_col+(page_start+i)).html(page_start+i); + } + $pagination.find('li.active').removeClass('active'); + $pagination.find('li:has(a[href="'+kanban_url_col+page+'"])').addClass('active'); + + }); + + }); + }; + + /* ---------------------------------------------------- + Async Ready and Template loading + ---------------------------------------------------- */ + var templates_def = $.Deferred().resolve(); + website.add_template_file = function(template) { + templates_def = templates_def.then(function() { + var def = $.Deferred(); + openerp.qweb.add_template(template, function(err) { + if (err) { + def.reject(err); + } else { + def.resolve(); + } + }); + return def; + }); + }; + website.add_template_file('/website/static/src/xml/website.xml'); + + website.dom_ready = $.Deferred(); + $(document).ready(function () { + website.is_editable = website.is_editable || $('html').data('editable'); + website.is_editable_button= website.is_editable_button || $('html').data('editable'); + website.dom_ready.resolve(); + // fix for ie + if($.fn.placeholder) $('input, textarea').placeholder(); + }); + + var all_ready = null; + /** + * Returns a deferred resolved when the templates are loaded + * and the Widgets can be instanciated. + */ + website.ready = function() { + if (!all_ready) { + all_ready = website.dom_ready.then(function () { + return templates_def; + }).then(function () { + if (website.is_editable) { + website.id = $('html').data('website-id'); + website.session = new openerp.Session(); + var modules = ['website']; + return openerp._t.database.load_translations(website.session, modules, website.get_context().lang); + } + }).promise(); + } + return all_ready; + }; + + website.inject_tour = function() { + // if a tour is active inject tour js + } + + website.dom_ready.then(function () { /* ----- PUBLISHING STUFF ---- */ $(document).on('click', '.js_publish_management .js_publish_btn', function () { var $data = $(this).parents(".js_publish_management:first"); diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 8ff89466368..b8533236e01 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -419,7 +419,7 @@ $target.data("overlay").remove(); $target.removeData("overlay"); } - $target.find("[data-snippet-id]").each(function () { + $target.find(website.snippet.globalSelector).each(function () { var $snippet = $(this); $snippet.removeData("snippet-editor"); if ($snippet.data("overlay")) { @@ -623,7 +623,7 @@ this.required = this.$el.data("required"); this.set_active(); - this.$el.find('li[data-class] a').on('mouseover mouseout click', _.bind(this._mouse, this)); + this.$el.find('li[data-value] a').on('mouseover mouseout click', _.bind(this._mouse, this)); this.$target.on('snippet-style-reset', _.bind(this.set_active, this)); this.start(); @@ -643,9 +643,9 @@ var $prev, $next; if (event.type === 'mouseout') { $prev = $(event.currentTarget).parent(); - $next = this.$el.find("li[data-class].active"); + $next = this.$el.find("li[data-value].active"); } else { - $prev = this.$el.find("li[data-class].active"); + $prev = this.$el.find("li[data-value].active"); $next = $(event.currentTarget).parent(); } if (!$prev.length) { @@ -676,6 +676,30 @@ // start is call just after the init start: function () { }, + /* onFocus + * This method is called when the user click inside the snippet in the dom + */ + onFocus : function () { + }, + + /* onFocus + * This method is called when the user click outside the snippet in the dom, after a focus + */ + onBlur : function () { + }, + + /* on_clone + * This method is called when the snippet is cloned ($clone is allready inserted) + */ + on_clone: function ($clone) { + }, + + /* on_remove + * This method is called when the snippet is removed (dom is removing after this call) + */ + on_remove: function () { + }, + /* * drop_and_build_snippet * This method is called just after that a thumbnail is drag and dropped into a drop zone @@ -685,6 +709,7 @@ }, /* select * called when a user select an item + * li must have data-value attribute * variables: np = {$next, $prev} * $next is false if they are no next item selected * $prev is false if they are no previous item selected @@ -693,10 +718,10 @@ var self = this; // add or remove html class if (np.$prev) { - this.$target.removeClass(np.$prev.data('class' || "")); + this.$target.removeClass(np.$prev.data('value' || "")); } if (np.$next) { - this.$target.addClass(np.$next.data('class') || ""); + this.$target.addClass(np.$next.data('value') || ""); } }, /* preview @@ -710,10 +735,10 @@ // add or remove html class if (np.$prev) { - this.$target.removeClass(np.$prev.data('class') || ""); + this.$target.removeClass(np.$prev.data('value') || ""); } if (np.$next) { - this.$target.addClass(np.$next.data('class') || ""); + this.$target.addClass(np.$next.data('value') || ""); } }, /* set_active @@ -723,14 +748,14 @@ set_active: function () { var self = this; this.$el.find('li').removeClass("active"); - var $active = this.$el.find('li[data-class]') + var $active = this.$el.find('li[data-value]') .filter(function () { var $li = $(this); - return ($li.data('class') && self.$target.hasClass($li.data('class'))); + return ($li.data('value') && self.$target.hasClass($li.data('value'))); }) .first() .addClass("active"); - this.$el.find('li:has(li[data-class].active)').addClass("active"); + this.$el.find('li:has(li[data-value].active)').addClass("active"); }, /* clean_for_save * function called just before save vue @@ -749,7 +774,7 @@ start: function () { this._super(); var src = this._get_bg(); - this.$el.find("li[data-class].active.oe_custom_bg").data("src", src); + this.$el.find("li[data-value].active.oe_custom_bg").data("src", src); }, select: function(event, np) { var self = this; @@ -765,7 +790,7 @@ }); editor.on('cancel', self, function () { if (!np.$prev || np.$prev.data("src") === "") { - self.$target.removeClass(np.$next.data("class")); + self.$target.removeClass(np.$next.data("value")); self.$target.trigger("snippet-style-change", [self, np]); } }); @@ -775,7 +800,7 @@ } } else { this._set_bg(false); - this.$target.removeClass(np.$prev.data("class")); + this.$target.removeClass(np.$prev.data("value")); } }, preview: function (event, np) { @@ -788,41 +813,54 @@ var self = this; var bg = self.$target.css("background-image"); this.$el.find('li').removeClass("active"); - var $active = this.$el.find('li[data-class]') + var $active = this.$el.find('li[data-value]') .filter(function () { var $li = $(this); return ($li.data('src') && bg.indexOf($li.data('src')) >= 0) || - (!$li.data('src') && self.$target.hasClass($li.data('class'))); + (!$li.data('src') && self.$target.hasClass($li.data('value'))); }) .first(); if (!$active.length) { $active = this.$target.css("background-image") !== 'none' ? - this.$el.find('li[data-class].oe_custom_bg') : - this.$el.find('li[data-class=""]'); + this.$el.find('li[data-value].oe_custom_bg') : + this.$el.find('li[data-value=""]'); } $active.addClass("active"); - this.$el.find('li:has(li[data-class].active)').addClass("active"); + this.$el.find('li:has(li[data-value].active)').addClass("active"); } }); website.snippet.options.slider = website.snippet.Option.extend({ + unique_id: function () { + var id = 0; + $(".carousel").each(function () { + var cid = 1 + parseInt($(this).attr("id").replace(/[^0123456789]/g, ''),10); + if (id < cid) id = cid; + }); + return "myCarousel" + id; + }, drop_and_build_snippet: function() { - var id = $(".carousel").length; - this.id = "myCarousel" + id; + this.id = this.unique_id(); this.$target.attr("id", this.id); - this.$target.find(".carousel-control").attr("href", "#myCarousel" + id); - this.$target.find("[data-target]").attr("data-target", "#myCarousel" + id); + this.$target.find("[data-slide]").attr("href", "#" + this.id); + this.$target.find("[data-slide-to]").attr("data-target", "#" + this.id); this.rebind_event(); }, + on_clone: function ($clone) { + var id = this.unique_id(); + $clone.attr("id", id); + $clone.find("[data-slide]").attr("href", "#" + id); + $clone.find("[data-slide-to]").attr("data-target", "#" + id); + }, // rebind event to active carousel on edit mode rebind_event: function () { var self = this; - this.$target.find('.carousel-indicators [data-target]').off('click').on('click', function () { + this.$target.find('.carousel-indicators [data-slide-to]').off('click').on('click', function () { self.$target.carousel(+$(this).data('slide-to')); }); this.$target.attr('contentEditable', 'false'); - this.$target.find('.oe_structure, .content>.row').attr('contentEditable', 'true'); + this.$target.find('.oe_structure, .content>.row, [data-slide]').attr('contentEditable', 'true'); }, clean_for_save: function () { this._super(); @@ -905,7 +943,7 @@ }, load_style_options : function () { this._super(); - $(".snippet-style-size li[data-class='']").remove(); + $(".snippet-style-size li[data-value='']").remove(); }, start : function () { var self = this; @@ -923,11 +961,11 @@ $active.css("background-image", self.$target.css("background-image")); } if (np.$prev) { - $active.removeClass(np.$prev.data("class")); + $active.removeClass(np.$prev.data("value")); } if (np.$next) { - $active.addClass(np.$next.data("class")); - add_class(np.$next.data("class")); + $active.addClass(np.$next.data("value")); + add_class(np.$next.data("value")); } }); this.$target.on('slid', function () { // slide.bs.carousel @@ -949,11 +987,13 @@ var bg = this.$target.data("snippet-option-ids").background; if (!bg) return $clone; - var $styles = bg.$el.find("li[data-class]:not(.oe_custom_bg)"); + var $styles = bg.$el.find("li[data-value]:not(.oe_custom_bg)"); var styles_index = $styles.index($styles.filter(".active")[0]); + $styles.removeClass("active"); var $select = $($styles[styles_index >= $styles.length-1 ? 0 : styles_index+1]); + $select.addClass("active"); $clone.css("background-image", $select.data("src") ? "url('"+ $select.data("src") +"')" : ""); - $clone.addClass($select.data("class") || ""); + $clone.addClass($select.data("value") || ""); return $clone; }, @@ -1187,25 +1227,22 @@ this._super(); }, hide_remove_button: function() { - this.$overlay.find('.oe_snippet_remove').toggleClass("hidden", - !this.$target.siblings().length && this.$target.parents("[data-snippet-id]:first").find("[data-snippet-id='colmd']").length > 1); + this.$overlay.find('.oe_snippet_remove').toggleClass("hidden", !this.$target.siblings().length); }, onFocus : function () { this._super(); this.hide_remove_button(); }, - on_clone: function () { - var $clone = this.$target.clone(false); + on_clone: function ($clone) { var _class = $clone.attr("class").replace(/\s*(col-lg-offset-|col-md-offset-)([0-9-]+)/g, ''); $clone.attr("class", _class); - this.$target.after($clone); this.hide_remove_button(); return false; }, on_remove: function () { if (!this.$target.siblings().length) { - var $parent = this.$target.parents("[data-snippet-id]:first"); - if($parent.find("[data-snippet-id='colmd']").length > 1) { + var $parent = this.$target.parents(".row:first"); + if($parent.find("[class*='col-md']").length > 1) { return false; } else { if (!$parent.data("snippet-editor")) { @@ -1455,7 +1492,7 @@ get_parent_block: function () { var self = this; var $button = this.$overlay.find('.oe_snippet_parent'); - var $parent = this.$target.parents("[data-snippet-id]:first"); + var $parent = this.$target.parents(website.snippet.globalSelector).first(); if ($parent.length) { $button.removeClass("hidden"); $button.off("click").on('click', function (event) { @@ -1483,12 +1520,18 @@ on_clone: function () { var $clone = this.$target.clone(false); this.$target.after($clone); + for (var i in this.styles){ + this.styles[i].on_clone($clone); + } return false; }, on_remove: function () { this.onBlur(); var index = _.indexOf(this.BuildingBlock.snippets, this.$target.get(0)); + for (var i in this.styles){ + this.styles[i].on_remove(); + } delete this.BuildingBlock.snippets[index]; this.$target.remove(); this.$overlay.remove(); @@ -1511,12 +1554,18 @@ */ onFocus : function () { this.$overlay.addClass('oe_active'); + for (var i in this.styles){ + this.styles[i].onFocus(); + } }, /* onFocus * This method is called when the user click outside the snippet in the dom, after a focus */ onBlur : function () { + for (var i in this.styles){ + this.styles[i].onBlur(); + } this.$overlay.removeClass('oe_active'); }, diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index ff3ed030f76..9c8afcd61e5 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -35,7 +35,7 @@ element: 'button[data-action=snippet]', placement: 'bottom', title: _t("Insert building blocks"), - content: _t("To add content in a page, you can insert building blocks."), + content: _t("Click here to insert blocks of centent in the page."), popover: { fixed: true }, }, { @@ -101,13 +101,13 @@ element: '.modal:has(#mobile-viewport) button[data-dismiss=modal]', placement: 'right', title: _t("Check Mobile Preview"), - content: _t("Scroll in the mobile preview to test the rendering. Once it's ok, close this dialog."), + content: _t("Scroll to check rendering and then close the mobile preview."), popover: { next: _t("Continue") }, }, { waitNot: '.modal', element: '#content-menu-button', - placement: 'bottom', + placement: 'left', title: _t("Add new pages and menus"), content: _t("The 'Content' menu allows you to add pages or add the top menu."), popover: { next: _t("Close Tutorial") }, diff --git a/addons/website/static/src/js/website.tour.test.admin.js b/addons/website/static/src/js/website.tour.test.admin.js deleted file mode 100644 index 01f4448abb2..00000000000 --- a/addons/website/static/src/js/website.tour.test.admin.js +++ /dev/null @@ -1,106 +0,0 @@ -(function () { - 'use strict'; - - var website = openerp.website; - - website.Tour.LoginEdit = website.Tour.extend({ - id: 'login_edit', - name: "Try to log as admin and check editor", - path: '/', - init: function () { - var self = this; - self.steps = [ - { - title: "click login", - element: '#top_menu a[href*="/web/login"]', - }, - { - title: "insert login", - element: '.oe_login_form input[name="login"]', - sampleText: "admin", - }, - { - title: "insert password", - waitFor: '.oe_login_form input[name="login"][value!=""]', - element: '.oe_login_form input[name="password"]', - sampleText: "admin", - }, - { - title: "select 2 Standard tickets", - waitFor: '.oe_login_form input[name="password"][value!=""]', - element: '.oe_login_form button', - }, - { - title: "go back to website from backend", - element: 'a[data-action-model="ir.actions.act_url"]:contains("Website")', - }, - { - title: 'try to edit', - waitNot: '#wrap .carousel', - element: 'button[data-action=edit]:visible', - }, - { - title: 'check edit mode', - waitFor: 'button[data-action=save]:visible', - }, - { - title: 'check branding', - waitFor: '#wrap[data-oe-model="ir.ui.view"]', - }, - { - title: 'check rte', - waitFor: '#oe_rte_toolbar', - }, - { - title: 'check insert block button', - element: '[data-action="snippet"]:visible', - }, - { - title: 'add snippets', - snippet: '#snippet_structure .oe_snippet:first', - }, - { - title: 'try to save', - waitFor: '.oe_overlay_options .oe_options:visible', - element: 'button[data-action=save]:visible', - }, - { - title: 'check saved', - waitFor: '#wrap div.carousel', - element: 'button[data-action=edit]:visible', - }, - { - title: 'try to re-edit', - waitFor: 'button[data-action=save]:visible', - element: '#wrap .carousel', - }, - { - title: 'remove snippet', - element: '.oe_snippet_remove', - }, - { - title: 'try to re-save', - waitNot: '#wrap .carousel', - element: 'button[data-action=save]:visible', - }, - { - title: "click admin", - waitFor: 'button[data-action=edit]:visible', - element: 'a:contains("Administrator")', - }, - { - title: "click logout", - element: '#top_menu a[href*="/logout"]', - }, - { - title: "check logout", - waitFor: '#top_menu a[href*="/web/login"]', - }, - ]; - return this._super(); - }, - }); - // for test without editor bar - website.Tour.add(website.Tour.LoginEdit); - -}()); diff --git a/addons/website/static/src/js/website.tour.test.js b/addons/website/static/src/js/website.tour.test.js deleted file mode 100644 index 3e85ce20dae..00000000000 --- a/addons/website/static/src/js/website.tour.test.js +++ /dev/null @@ -1,34 +0,0 @@ -(function () { - -function LoadScript(src) { - xmlHttp = new XMLHttpRequest(); - xmlHttp.onreadystatechange = function() { - if(xmlHttp.readyState == 4) { - if (xmlHttp.status == 200 || xmlHttp.status == 304) { - new Function(xmlHttp.responseText)(); - } else { - throw new Error("Can't load JavaScript.\nhref: " + window.location.href + "\nsrc: " + src); - } - } - }; - xmlHttp.open("GET", src, false); - xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xmlHttp.send(null); -} - -if (typeof jQuery === "undefined") - LoadScript("/web/static/lib/jquery/jquery.js"); -if (typeof _ === "undefined") - LoadScript("/web/static/lib/underscore/underscore.js"); -if (typeof openerp === "undefined") { - LoadScript("/web/static/lib/qweb/qweb2.js"); - LoadScript("/web/static/src/js/openerpframework.js"); -} -if (typeof openerp === "undefined" || !openerp.website || !openerp.website.add_template_file) - LoadScript("/website/static/src/js/website.js"); -if (typeof Tour === "undefined") - LoadScript("/website/static/lib/bootstrap-tour/bootstrap-tour.js"); -if (typeof openerp === "undefined" || !openerp.website.Tour) - LoadScript("/website/static/src/js/website.tour.js"); - -})(); \ No newline at end of file diff --git a/addons/website/tests/test_converter.py b/addons/website/tests/test_converter.py index d31df8e6956..ca72a361ac2 100644 --- a/addons/website/tests/test_converter.py +++ b/addons/website/tests/test_converter.py @@ -135,7 +135,7 @@ class TestConvertBack(common.TransactionCase): rendered = self.registry('website.qweb').render_tag_field( e, {'field': field_value}, '', ir_qweb.QWebContext(self.cr, self.uid, { 'record': record, - })) + }, context={'inherit_branding': True})) element = html.fromstring( rendered, parser=html.HTMLParser(encoding='utf-8')) @@ -216,7 +216,7 @@ class TestConvertBack(common.TransactionCase): rendered = self.registry('website.qweb').render_tag_field( e, {'field': field_value}, '', ir_qweb.QWebContext(self.cr, self.uid, { 'record': record, - })) + }, context={'inherit_branding': True})) element = html.fromstring(rendered, parser=html.HTMLParser(encoding='utf-8')) # emulate edition diff --git a/addons/website/tests/test_requests.py b/addons/website/tests/test_requests.py index 9fb29b63c75..2a22ae04445 100644 --- a/addons/website/tests/test_requests.py +++ b/addons/website/tests/test_requests.py @@ -121,6 +121,6 @@ class URL(object): def load_tests(loader, base, _): base.addTest(CrawlSuite()) - base.addTest(CrawlSuite('admin', tools.config['admin_passwd'])) + base.addTest(CrawlSuite('admin', 'admin')) base.addTest(CrawlSuite('demo', 'demo')) return base diff --git a/addons/website/tests/test_ui.py b/addons/website/tests/test_ui.py index c9dd80ff885..54cd8a73a67 100644 --- a/addons/website/tests/test_ui.py +++ b/addons/website/tests/test_ui.py @@ -8,6 +8,6 @@ class TestUi(openerp.tests.HttpCase): self.phantom_js("/", "console.log('ok')", "openerp.website.editor", login='admin') def test_04_admin_tour_banner(self): - self.phantom_js("/", "openerp.website.Tour.run_test('banner')", "openerp.website.Tour", login='admin') + self.phantom_js("/", "openerp.website.Tour.run_test('banner')", "openerp.website.Tour.tours.banner", login='admin') # vim:et: diff --git a/addons/website/views/snippets.xml b/addons/website/views/snippets.xml index f91bd969c70..cdc4bd8f961 100644 --- a/addons/website/views/snippets.xml +++ b/addons/website/views/snippets.xml @@ -860,7 +860,7 @@ @@ -873,51 +873,51 @@ -
  • None
  • +
  • None
  • -
  • Choose an image...
  • +
  • Choose an image...
  • @@ -927,9 +927,9 @@ diff --git a/addons/website_mail/views/snippets.xml b/addons/website_mail/views/snippets.xml index 75202fe99fd..196ad39dac8 100644 --- a/addons/website_mail/views/snippets.xml +++ b/addons/website_mail/views/snippets.xml @@ -509,10 +509,10 @@ class="js_follow_email form-control" placeholder="your email..."/> - Unsubscribe - Subscribe + unsubscribe + subscribe - + diff --git a/addons/website_mail_group/__init__.py b/addons/website_mail_group/__init__.py new file mode 100644 index 00000000000..ee5959455ad --- /dev/null +++ b/addons/website_mail_group/__init__.py @@ -0,0 +1 @@ +import controllers diff --git a/addons/website_mail_group/__openerp__.py b/addons/website_mail_group/__openerp__.py new file mode 100644 index 00000000000..f83fc38ce7c --- /dev/null +++ b/addons/website_mail_group/__openerp__.py @@ -0,0 +1,18 @@ +{ + 'name': 'Mailing List Archive', + 'category': 'Website', + 'summary': '', + 'version': '1.0', + 'description': """ +OpenERP Mail Group : Mailing List Archives +========================================== + + """, + 'author': 'OpenERP SA', + 'depends': ['website_mail'], + 'data': [ + 'views/website_mail_group.xml' + ], + 'qweb': [], + 'installable': True, +} diff --git a/addons/website_mail_group/controllers/__init__.py b/addons/website_mail_group/controllers/__init__.py new file mode 100644 index 00000000000..e11f9ba81bb --- /dev/null +++ b/addons/website_mail_group/controllers/__init__.py @@ -0,0 +1,3 @@ +import main + +# vim:expandtab:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/website_mail_group/controllers/main.py b/addons/website_mail_group/controllers/main.py new file mode 100644 index 00000000000..a6f3adcd522 --- /dev/null +++ b/addons/website_mail_group/controllers/main.py @@ -0,0 +1,91 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2013-Today OpenERP SA (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.addons.web import http +from openerp.addons.web.http import request + + +class MailGroup(http.Controller): + _thread_per_page = 10 + + @http.route([ + "/groups", + ], type='http', auth="public", website=True) + def view(self, **post): + cr, uid, context = request.cr, request.uid, request.context + group_obj = request.registry.get('mail.group') + group_ids = group_obj.search(cr, uid, [], context=context) + values = {'groups': group_obj.browse(cr, uid, group_ids, context)} + return request.website.render('website_mail_group.mail_groups', values) + + @http.route(["/groups/subscription/"], type='json', auth="user") + def subscription(self, group_id=0, action=False ,**post): + cr, uid, context = request.cr, request.uid, request.context + group_obj = request.registry.get('mail.group') + if action: + group_obj.message_subscribe_users(cr, uid, [group_id], context=context) + else: + group_obj.message_unsubscribe_users(cr, uid, [group_id], context=context) + return [] + + @http.route([ + "/groups//", + "/groups///page/" + ], type='http', auth="public", website=True) + def thread(self, group, mode='thread', page=1, **post): + cr, uid, context = request.cr, request.uid, request.context + + thread_obj = request.registry.get('mail.message') + domain = [('model','=','mail.group'), ('res_id','=',group.id)] + if mode=='thread': + domain.append(('parent_id','=',False)) + thread_count = thread_obj.search_count(cr, uid, domain, context=context) + pager = request.website.pager( + url='/groups/%s/%s' % (group.id, mode), + total=thread_count, + page=page, + step=self._thread_per_page, + ) + thread_ids = thread_obj.search(cr, uid, domain, limit=self._thread_per_page, offset=pager['offset']) + + messages = thread_obj.browse(cr, uid, thread_ids, context) + for m in messages: + print m.subject + values = { + 'messages': messages, + 'group': group, + 'pager': pager, + 'mode': mode + } + return request.website.render('website_mail_group.group_messages', values) + + @http.route([ + "/groups//message/", + ], type='http', auth="public", website=True) + def get_thread(self, group, message, mode='thread', page=1, **post): + cr, uid, context = request.cr, request.uid, request.context + values = { + 'message': message, + 'group': group, + 'mode': mode, + 'page': page, + } + return request.website.render('website_mail_group.group_message', values) diff --git a/addons/website_mail_group/views/website_mail_group.xml b/addons/website_mail_group/views/website_mail_group.xml new file mode 100644 index 00000000000..9e4b41329b4 --- /dev/null +++ b/addons/website_mail_group/views/website_mail_group.xml @@ -0,0 +1,182 @@ + + + + + + + + + + + + + + diff --git a/addons/website_sale/tests/test_ui.py b/addons/website_sale/tests/test_ui.py index fcb84773036..a256f0c3a93 100644 --- a/addons/website_sale/tests/test_ui.py +++ b/addons/website_sale/tests/test_ui.py @@ -4,21 +4,20 @@ import unittest2 import openerp.tests -inject = [ - ("openerp.website.Tour", os.path.join(os.path.dirname(__file__), '../../website/static/src/js/website.tour.js')), - ("openerp.website.Tour.ShopTest", os.path.join(os.path.dirname(__file__), "../static/src/js/website.tour.sale.js")), -] class TestUi(openerp.tests.HttpCase): def test_01_admin_shop_tour(self): + return self.phantom_js("/", "openerp.website.Tour.run_test('shop')", "openerp.website.Tour.Shop", login="admin") def test_02_admin_checkout(self): - self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour", login="admin", inject=inject) + return + self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="admin") def test_03_demo_checkout(self): - self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo", inject=inject) + return + self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", login="demo") - @unittest2.expectedFailure def test_04_public_checkout(self): - self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest", inject=inject) + return + self.phantom_js("/", "openerp.website.Tour.run_test('shop_buy_product')", "openerp.website.Tour.ShopTest") diff --git a/addons/website_sale/views/website_sale.xml b/addons/website_sale/views/website_sale.xml index f441126da1c..570f5b82501 100644 --- a/addons/website_sale/views/website_sale.xml +++ b/addons/website_sale/views/website_sale.xml @@ -200,8 +200,8 @@
    -

    No product defined.

    - +

    No product found.

    +

    Use the 'Content' top menu to create a new product.