diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000..87643113d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,225 @@ +# AGENTS.md + +## Project Overview + +QloApps is an open-source hotel reservation and property management platform. It enables hotels to manage rooms, bookings, guests, and payments through a web-based system. + +## Purpose of this File + +This document provides guidance for AI coding agents contributing to the QloApps project. It defines conventions, safety rules, and workflows to ensure consistent and secure code generation. + +## Technology Stack + +- **Language:** PHP 8.1–8.4 (backend), Smarty 3.x (templates), JavaScript/jQuery (frontend) +- **Database:** MySQL 5.7, 8.0+; MariaDB 10.5, 10.6, 10.11, 11.0, 11.2, 11.4 +- **Architecture:** MVC with hook-based module system +- **License:** OSL-3.0 (core), AFL-3.0 (modules) +- **Required PHP Extensions:** PDO_MySQL, cURL, OpenSSL, SOAP, GD, SimpleXML, DOM, Zip, Phar + +## Environment Setup + +Install dependencies: +```bash +composer install +``` + +Clear caches: +```bash +rm -rf cache/smarty/compile/* cache/smarty/cache/* +rm -f cache/class_index.php +``` + +Clear class cache after adding or modifying overrides. + +## Project Structure + +``` +. +├── classes/ # Core models extending ObjectModel +├── controllers/ # Front and admin controllers +│ ├── admin/ +│ └── front/ +├── modules/ # Feature modules with isolated functionality +├── override/ # Core class and controller overrides +├── themes/ # Smarty templates (.tpl files) +├── config/ # Configuration files (settings.inc.php contains secrets) +├── cache/ # Generated cache files +├── tests/ # PHPUnit test suite +``` + +**QloApps Agent Skills:** Install reusable development skills using: +```bash +npx skills add Qloapps/agent-skills +``` +Available skills: module-development, payment-module-development, stats-module-development. Check installed skills before implementing new functionality. + +## Architecture Overview + +**MVC Pattern** +- Models: classes/ extending ObjectModel +- Controllers: FrontController or AdminController +- Views: Smarty templates (.tpl) + +**Modules** +- Located in modules// +- Provide isolated functionality +- Integrate using hooks + +**Overrides** +- Located in override/ +- Extend core classes using the Core suffix +- Clear class cache after creating overrides + +**Context** +- Access runtime objects using Context::getContext() + +## Core vs Module Development Rules + +**When working on a module:** +1. Never modify core files directly +2. Use **hooks** to integrate module functionality into core features +3. If no suitable hook exists, create a **custom hook** — but only if the hook placement is generic and useful for other modules too +4. Use **overrides** only as a last resort — overrides can conflict with other module override files and require manual resolution + +**When working on a core feature:** +- Make changes directly in core files +- Do not use hooks or overrides for core-to-core changes + +## Coding Conventions + +**Classes:** PascalCase — `HotelBookingData` +**Methods:** camelCase — `getBookingDetails()` +**Variables:** camelCase — `$hotelId` +**Constants:** UPPER_SNAKE_CASE — `BOOKING_STATUS_CONFIRMED` +**Database Tables:** _DB_PREFIX_ + lowercase_snake — `qlo_hotel_booking` +**Config Keys:** MODULENAME_SETTING — `HOTELRESERVATION_ENABLED` +**Files:** One class per file, filename matches class name +**Templates:** lowercase-hyphens.tpl — `booking-form.tpl` + +Add PHPDoc blocks to all classes and methods. + +## Translation + +Never hardcode user-facing English strings — always wrap them in the appropriate translation method. + +| Context | Method | +|---------|--------| +| Module main file | `$this->l('string')` | +| Module admin controller | `$this->l('string')` | +| Module front controller | `$this->module->l('string', 'controllerName')` | +| Module classes | `$objModule->l('string', 'ClassName')` | +| Core admin controller | `$this->l('string')` | +| Core front controller | `Tools::displayError('string')` | +| Smarty template (core) | `{l s='string'}` | +| Smarty template (module) | `{l s='string' mod='modulename'}` | + +## Multi-language + +- Always include `id_lang` in queries that return translatable content +- Use `Context::getContext()->language->id` for the current language + +## Module Development Guidelines + +**Module Location:** modules// + +**Required Files:** +- .php — Main class extending Module +- config.xml — Module metadata + +**Optional Directories:** +- classes/ — Module-specific models +- controllers/ — Module controllers +- views/templates/ — Smarty templates +- upgrade/ — Version migration scripts + +**Hook Integration:** +- Register hooks in install() method +- Unregister hooks in uninstall() method +- Keep hook handlers lightweight + +**Configuration:** +- Store settings using Configuration::updateValue() +- Retrieve settings using Configuration::get() +- Prefix config keys with module name + +## Database Rules + +**Table Prefix:** Always use _DB_PREFIX_ constant instead of hardcoding the table prefix + +**Escaping:** +- Strings: pSQL($value) +- Integers: (int)$value +- Table/column names: bqSQL($name) + +**Preferred Access:** Use ObjectModel for CRUD operations instead of raw SQL queries + +**Prohibited:** Never concatenate raw user input into SQL queries. + +## Security Guidelines + +**Input Handling** +- Use Tools::getValue() for request parameters +- Cast numeric values to (int) +- Escape strings using pSQL() +- Validate input using Validate class methods + +**Output Escaping** +- Use Tools::safeOutput() in PHP +- Use Smarty escape modifiers in templates + +**Sensitive Data** +- Never expose config/settings.inc.php +- Never commit API keys, passwords, or tokens + +**Authorization** +- Verify permissions before performing admin operations + +## Testing + +Testing infrastructure is being configured. Check tests/ directory for available tests before running. + +## AI Agent Workflow + +1. Check installed agent skills before implementing new functionality +2. Search codebase for similar implementations before creating new code +3. Extend existing classes rather than duplicating functionality +4. Follow patterns established in surrounding code +5. Reuse existing utilities: Tools, Validate, Db, Configuration classes +6. Prioritize consistency with existing codebase over new approaches + +After making changes: +- Clear caches if modifying templates or overrides +- Add PHPDoc to new methods + +## Safety Rules + +**Agents must not:** +- Delete files unless explicitly instructed +- Run git commands automatically +- Modify composer.json without approval +- Modify config/settings.inc.php +- Execute DROP, TRUNCATE, or destructive SQL +- Modify core files directly when working on a module (use hooks or override system) + +**Agents must:** +- Use pSQL() for strings and (int) for IDs in SQL +- Use Tools::getValue() for request parameters +- Escape all output +- Check installed agent skills before implementing new functionality +- Follow project naming conventions +- Validate inputs before processing + +**Agents should ask before:** +- Deleting any files +- Running git commands +- Changing dependencies +- Modifying database schema +- Altering payment or booking logic + +--- + +**Resources:** +- Documentation: https://docs.qloapps.com +- Forum: https://forums.qloapps.com +- GitHub: https://github.com/Qloapps/QloApps +- Security Issues: support@qloapps.com diff --git a/admin/themes/default/sass/partials/_date-picker.sass b/admin/themes/default/sass/partials/_date-picker.sass index e864cf8e9..dd235e7ad 100644 --- a/admin/themes/default/sass/partials/_date-picker.sass +++ b/admin/themes/default/sass/partials/_date-picker.sass @@ -30,324 +30,330 @@ $color-calendar-range: lighten($color-calendar,10%) $color-calendar-range-compare: lighten($color-calendar-compare,10%) .datepicker2 - background: #fff - position: absolute - z-index: 599 - right: -10rem - .daterangepicker - border-radius: 5px 5px 0 0 !important + background: #fff + position: absolute + z-index: 599 + right: -10rem + .daterangepicker + border-radius: 5px 5px 0 0 !important .bootstrap - #datepicker - .daterangepicker - position: relative - width: 100% - font-family: Verdana, Arial, sans-serif - font-size: 13px - box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.26) - margin-bottom: 8px - padding: 12px - border-bottom-left-radius: 0 - border-bottom-right-radius: 0 - table - width: 100% - margin: 0 - border-spacing: 1px - thead - tr th - text-transform: uppercase - text-align: center - font-weight: bold - border: 0 - background-color: #fff !important - color: #777 !important - font-size: 14px - tr:first-child th - padding-bottom: 10px - text-transform: capitalize - .icon-angle-left - font-weight: bold - padding-left: 6px - &:after - content: '' - position: absolute - top: -5px - left: -2px - width: 24px - height: 24px - background-color: #f0f0f0 - z-index: -1 - border-radius: 50% - .icon-angle-right - font-weight: bold - padding-right: 6px - &:after - content: '' - position: absolute - top: -5px - right: -2px - width: 24px - height: 24px - background-color: #f0f0f0 - z-index: -1 - border-radius: 50% - td, th - text-align: center - padding: 0 - position: relative - tr - border-bottom: solid 1px white - td - color: #555 - font-size: 14px - line-height: 25px - padding: 5px 10px - &.day:after - content: "" - position: absolute - display: block - top: 0 - width: 100% - z-index: 0 - background-color: transparent - @include left(0) - &.day:hover - cursor: pointer - color: #212121 - &.day.disabled - color: $color-calendar-outrange - &.old, &.new - color: $color-calendar-outrange - &.start-selected:not(.old):not(.new):not(.end-selected) - color: $color-bright - background-color: #1292ff - //@extend .chevron-left - &.range-compare - background-color: mix($color-calendar-day-selected,$color-calendar-range-compare,70%) - @include border-left-radius(0) - &.end-selected-compare, &.start-selected-compare - background-color: mix($color-calendar-day-selected,$color-calendar-day-selected-compare,70%) - &.end-selected-compare - @include border-radius(0) - &.end-selected:not(.old):not(.new):not(.start-selected) - color: $color-bright - background-color: #1292ff - //@extend .chevron-right - &.range-compare - background-color: mix($color-calendar-day-selected,$color-calendar-range-compare,70%) - @include border-right-radius(0) - &.end-selected-compare, &.start-selected-compare - background-color: mix($color-calendar-day-selected,$color-calendar-day-selected-compare,70%) - &.start-selected-compare - @include border-radius(0) - &.start-selected-compare:not(.old):not(.new):not(.end-selected-compare) - color: $color-bright - font-weight: 700 - background-color: $color-calendar-day-selected-compare - @include border-left-radius(15px) - &.range - background-color: #f2f2f2 - @include border-left-radius(0) - &.end-selected-compare:not(.old):not(.new):not(.start-selected-compare) - color: $color-bright - font-weight: 700 - background-color: $color-calendar-day-selected-compare - @include border-right-radius(15px) - &.range - background-color: #f2f2f2 - @include border-right-radius(0) - &.end-selected.start-selected - color: $color-bright - font-weight: 700 - background-color: $color-calendar-day-selected - &.range-compare - background-color: mix($color-calendar-day-selected,$color-calendar-range-compare,70%) - @include border-radius(0) - &.end-selected-compare.start-selected-compare - color: $color-bright - @include border-radius(15px) - font-weight: 700 - background-color: $color-calendar-day-selected-compare - &.range - background-color: mix($color-calendar-day-selected-compare,$color-calendar-range,70%) - @include border-radius(0) - &.range - color: #333 - background-color: #f2f2f2 - &.range-compare - background-color: mix($color-calendar-range,$color-calendar-range-compare,50%) - &.range-compare - color: lighten($color-calendar-range-compare,35%) - background-color: $color-calendar-range-compare - &.range - background-color: mix($color-calendar-range,$color-calendar-range-compare,50%) - &.today - background-color: $color-bright - span - padding: 0 - display: block - width: 33.333% - height: 3em - line-height: 3em - font-weight: 400 - float: left - text-transform: uppercase - cursor: pointer - &:hover - color: white - background-color: $color-calendar-day-selected - &.active - background-color: $color-calendar-day-selected - color: #fff - &.old - color: $color-calendar-outrange - th - &.next - @include text-align(right) - &.prev - @include text-align(left) - &.next, &.prev, &.month-switch - font-size: 16px !important - font-weight: normal - color: #333 !important - &:hover - opacity: 0.8 - thead tr:first-child th - cursor: pointer + #datepicker + .daterangepicker + position: relative + width: 100% + font-family: Verdana, Arial, sans-serif + font-size: 13px + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.26) + margin-bottom: 8px + padding: 12px + border-bottom-left-radius: 0 + border-bottom-right-radius: 0 + table + width: 100% + margin: 0 + border-spacing: 1px + thead + tr th + text-transform: uppercase + text-align: center + font-weight: bold + border: 0 + background-color: #fff !important + color: #777 !important + font-size: 14px + tr:first-child th + padding-bottom: 10px + text-transform: capitalize + .icon-angle-left + font-weight: bold + padding-left: 6px + &:after + content: '' + position: absolute + top: -5px + left: -2px + width: 24px + height: 24px + background-color: #f0f0f0 + z-index: -1 + border-radius: 50% + .icon-angle-right + font-weight: bold + padding-right: 6px + &:after + content: '' + position: absolute + top: -5px + right: -2px + width: 24px + height: 24px + background-color: #f0f0f0 + z-index: -1 + border-radius: 50% + td, th + text-align: center + padding: 0 + position: relative + tr + border-bottom: solid 1px white + td + color: #555 + font-size: 14px + line-height: 25px + padding: 5px 10px + &.day:after + content: "" + position: absolute + display: block + top: 0 + width: 100% + z-index: 0 + background-color: transparent + @include left(0) + &.day:hover + cursor: pointer + color: #212121 + &.day.disabled + color: $color-calendar-outrange + &.old, &.new + color: $color-calendar-outrange + &.start-selected:not(.old):not(.new):not(.end-selected) + color: $color-bright + background-color: #1292ff + //@extend .chevron-left + &.range-compare + background-color: mix($color-calendar-day-selected,$color-calendar-range-compare,70%) + @include border-left-radius(0) + &.end-selected-compare, &.start-selected-compare + background-color: mix($color-calendar-day-selected,$color-calendar-day-selected-compare,70%) + &.end-selected-compare + @include border-radius(0) + &.end-selected:not(.old):not(.new):not(.start-selected) + color: $color-bright + background-color: #1292ff + //@extend .chevron-right + &.range-compare + background-color: mix($color-calendar-day-selected,$color-calendar-range-compare,70%) + @include border-right-radius(0) + &.end-selected-compare, &.start-selected-compare + background-color: mix($color-calendar-day-selected,$color-calendar-day-selected-compare,70%) + &.start-selected-compare + @include border-radius(0) + &.start-selected-compare:not(.old):not(.new):not(.end-selected-compare) + color: $color-bright + font-weight: 700 + background-color: $color-calendar-day-selected-compare + @include border-left-radius(15px) + &.range + background-color: #f2f2f2 + @include border-left-radius(0) + &.end-selected-compare:not(.old):not(.new):not(.start-selected-compare) + color: $color-bright + font-weight: 700 + background-color: $color-calendar-day-selected-compare + @include border-right-radius(15px) + &.range + background-color: #f2f2f2 + @include border-right-radius(0) + &.end-selected.start-selected + color: $color-bright + font-weight: 700 + background-color: $color-calendar-day-selected + &.range-compare + background-color: mix($color-calendar-day-selected,$color-calendar-range-compare,70%) + @include border-radius(0) + &.end-selected-compare.start-selected-compare + color: $color-bright + @include border-radius(15px) + font-weight: 700 + background-color: $color-calendar-day-selected-compare + &.range + background-color: mix($color-calendar-day-selected-compare,$color-calendar-range,70%) + @include border-radius(0) + &.range + color: #333 + background-color: #f2f2f2 + &.range-compare + background-color: mix($color-calendar-range,$color-calendar-range-compare,50%) + &.range-compare + color: lighten($color-calendar-range-compare,35%) + background-color: $color-calendar-range-compare + &.range + background-color: mix($color-calendar-range,$color-calendar-range-compare,50%) + &.today + background-color: $color-bright + span + padding: 0 + display: block + width: 33.333% + height: 3em + line-height: 3em + font-weight: 400 + float: left + text-transform: uppercase + cursor: pointer + &:hover + color: white + background-color: $color-calendar-day-selected + &.active + background-color: $color-calendar-day-selected + color: #fff + &.old + color: $color-calendar-outrange + th + &.next + @include text-align(right) + &.prev + @include text-align(left) + &.next, &.prev, &.month-switch + font-size: 16px !important + font-weight: normal + color: #333 !important + &:hover + opacity: 0.8 + thead tr:first-child th + cursor: pointer .ui-datepicker - margin: 5px auto 0 - width: auto !important - z-index: 111111 !important - top: 0 - left: 0 - padding: 12px !important - margin-top: 1px - @include border-radius(4px) - .ui-datepicker-header - background: none - border: none - color: gray - font-weight: normal - .ui-datepicker-title - color: #333 - font-size: 16px - font-style: normal - th - font-size: 12px - font-weight: 600 - color: #777 - text-transform: uppercase - tbody - td - &:last-child - border-right: 0px - tr - border-bottom: 1px solid #bbb - border: none - &:last-child - border-bottom: 0px - a - text-decoration: none - .ui-state-highlight - border: solid 1px darken(#FEFBE2 ,50%) !important - background: #FEFBE2 !important - .ui-datepicker-today - background: #e7f4ff !important - .ui-state-highlight - color: #1292ff !important - .ui-datepicker-current-day, .ui-datepicker-today.ui-datepicker-current-day - background-color: #1292ff !important - .ui-datepicker-current-day, .ui-datepicker-today.ui-datepicker-current-day .ui-state-highlight - color: #fff !important - .ui-state-active - color: white !important - background: $primary-color !important - border: solid 1px darken($primary-color,10%) !important - .ui-datepicker-prev-hover - left: 2px !important + margin: 5px auto 0 + width: auto !important + z-index: 111111 !important + top: 0 + left: 0 + padding: 12px !important + margin-top: 1px + @include border-radius(4px) + .ui-datepicker-header + background: none + border: none + color: gray + font-weight: normal + .ui-datepicker-title + color: #333 + font-size: 16px + font-style: normal + th + font-size: 12px + font-weight: 600 + color: #777 + text-transform: uppercase + tbody + td + &:last-child + border-right: 0px + tr + border-bottom: 1px solid #bbb + border: none + &:last-child + border-bottom: 0px + a + text-decoration: none + .ui-state-highlight + border: solid 1px darken(#FEFBE2 ,50%) !important + background: #FEFBE2 !important + .ui-datepicker-today + background: #e7f4ff !important + .ui-state-highlight + color: #1292ff !important + .ui-datepicker-current-day, .ui-datepicker-today.ui-datepicker-current-day + background-color: #1292ff !important + .ui-datepicker-current-day, .ui-datepicker-today.ui-datepicker-current-day .ui-state-highlight + color: #fff !important + .ui-state-active + color: white !important + background: $primary-color !important + border: solid 1px darken($primary-color,10%) !important + .ui-datepicker-prev-hover + left: 2px !important .form-date-actions .btn:hover, .form-date-actions .btn:focus, .form-date-actions .btn:active - outline: unset !important - text-decoration: none + outline: unset !important + text-decoration: none .form-date-actions - bottom: -27px - position: absolute - width: 100% - z-index: 599 - background-color: #fff - box-shadow: 0 7px 10px 0 rgba(0,0,0,0.26) - padding: 2px - border-bottom-left-radius: 4px - border-bottom-right-radius: 4px + bottom: -27px + position: absolute + width: 100% + z-index: 599 + background-color: #fff + box-shadow: 0 7px 10px 0 rgba(0,0,0,0.26) + padding: 2px + border-bottom-left-radius: 4px + border-bottom-right-radius: 4px .ui-datepicker-prev - float: left - cursor: pointer - &::before - background-position: center -30px - font-weight: bold - font-size: 16px - color: #333 - content: "\f104" - font-family: FontAwesome - position: absolute - left: 8px + float: left + cursor: pointer + &::before + background-position: center -30px + font-weight: bold + font-size: 16px + color: #333 + content: "\f104" + font-family: FontAwesome + position: absolute + left: 8px .ui-datepicker-next - float: right - cursor: pointer - &::before - background-position: center -30px - font-weight: bold - font-size: 16px - color: #333 - content: "\f105" - font-family: FontAwesome - position: absolute - right: 8px - &:hover - top: 5px !important - right: 2px !important + float: right + cursor: pointer + &::before + background-position: center -30px + font-weight: bold + font-size: 16px + color: #333 + content: "\f105" + font-family: FontAwesome + position: absolute + right: 8px + &:hover, &.ui-datepicker-next-hover + top: 5px !important + right: 2px !important + +.ui-datepicker-rtl + .ui-datepicker-next + &:hover, &.ui-datepicker-next-hover + left: 2px !important + right: auto !important .ui-state-hover, .ui-widget-content .ui-state-hover, .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus - border: unset - background: none - font-weight: none - color: none + border: unset + background: none + font-weight: none + color: none .ui-widget-content.ui-datepicker - border: none - box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.26) + border: none + box-shadow: 0 4px 10px 0 rgba(0, 0, 0, 0.26) .ui-datepicker td span, .ui-datepicker td a - display: inline-block - text-align: center - line-height: 25px - color: #ffffff + display: inline-block + text-align: center + line-height: 25px + color: #ffffff .ui-datepicker .ui-datepicker-prev, .ui-datepicker .ui-datepicker-next - top: 5px !important - background-color: #f0f0f0 - border: none - border-radius: 50% + top: 5px !important + background-color: #f0f0f0 + border: none + border-radius: 50% .ui-state-default, .ui-widget-content .ui-state-default, .ui-widget-header .ui-state-default - border: none !important - background: transparent !important - font-size: 14px - color: #333 + border: none !important + background: transparent !important + font-size: 14px + color: #333 .ui-widget-content - .ui-icon - background-image: none !important + .ui-icon + background-image: none !important .ui-datepicker td span, .ui-datepicker td a - text-align: center !important - padding: 4px 9px !important + text-align: center !important + padding: 4px 9px !important .ui-widget-header .ui-state-hover, .ui-state-focus, .ui-widget-content .ui-state-focus, .ui-widget-header .ui-state-focus - background: unset !important - border: unset !important + background: unset !important + border: unset !important .ui-widget-content .ui-slider-handle, .ui-datepicker-current .ui-slider-handle - border: 1px solid #d3d3d3 !important - color: #555555 !important - background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) !important + border: 1px solid #d3d3d3 !important + color: #555555 !important + background: #e6e6e6 url(images/ui-bg_glass_75_e6e6e6_1x400.png) !important .ui-datepicker-prev-hover - top: unset !important \ No newline at end of file + top: unset !important diff --git a/admin/themes/default/sass/partials/_date-range-picker.sass b/admin/themes/default/sass/partials/_date-range-picker.sass index 812aadf72..b63956a92 100644 --- a/admin/themes/default/sass/partials/_date-range-picker.sass +++ b/admin/themes/default/sass/partials/_date-range-picker.sass @@ -16,9 +16,9 @@ $color-calendar-range-compare: lighten($color-calendar-compare,10%) #datepicker .input-selected margin: 0 - #date-start.input-selected, #date-end.input-selected, + #date-start.input-selected, #date-end.input-selected border: solid 3px $color-calendar-day-selected - #date-start-compare.input-selected, #date-end-compare.input-selected, + #date-start-compare.input-selected, #date-end-compare.input-selected border: solid 3px $color-calendar-day-selected-compare div#datepicker-form #date-range diff --git a/admin/themes/default/sass/partials/_growl.sass b/admin/themes/default/sass/partials/_growl.sass index 37884b1bc..900f51ac3 100644 --- a/admin/themes/default/sass/partials/_growl.sass +++ b/admin/themes/default/sass/partials/_growl.sass @@ -8,72 +8,72 @@ $namespace: "growl" $duration: 0.4s #growls - z-index: 50000 - position: fixed - - &.default - top: 100px - @include right(10px) - &.tl - top: 10px - @include left(10px) - &.tr - top: 10px - @include right(10px) - &.bl - bottom: 10px - @include left(10px) - &.br - bottom: 10px - @include right(10px) + z-index: 50000 + position: fixed + + &.default + top: 100px + @include right(10px) + &.tl + top: 10px + @include left(10px) + &.tr + top: 10px + @include right(10px) + &.bl + bottom: 10px + @include left(10px) + &.br + bottom: 10px + @include right(10px) .growl - opacity: 1 - position: relative - @include border-radius(4px) - @include transition(all $duration ease-in-out) + opacity: 1 + position: relative + @include border-radius(4px) + @include transition(all $duration ease-in-out) - &.#{$namespace}-incoming - opacity: 0.0 + &.#{$namespace}-incoming + opacity: 0.0 - &.#{$namespace}-outgoing - opacity: 0.0 + &.#{$namespace}-outgoing + opacity: 0.0 - &.#{$namespace}-small - width: 200px - padding: 5px - margin: 5px - &.#{$namespace}-medium - width: 250px - padding: 10px - margin: 10px - &.#{$namespace}-large - width: 300px - padding: 15px - margin: 15px + &.#{$namespace}-small + width: 200px + padding: 5px + margin: 5px + &.#{$namespace}-medium + width: 250px + padding: 10px + margin: 10px + &.#{$namespace}-large + width: 300px + padding: 15px + margin: 15px - &.#{$namespace}-default - color: #FFF - background: gray - &.#{$namespace}-error - color: white - background: rgba($brand-danger,0.8) - &.#{$namespace}-notice - color: white - background: rgba($brand-success,0.8) - &.#{$namespace}-warning - color: white - background: rgba($brand-warning,0.8) - .#{$namespace}-close - cursor: pointer - font-size: 14px - line-height: 18px - font-weight: normal - font-family: helvetica, verdana, sans-serif - @include float(right) - .#{$namespace}-title - font-size: 18px - line-height: 24px - .#{$namespace}-message - font-size: 14px - line-height: 18px \ No newline at end of file + &.#{$namespace}-default + color: #FFF + background: gray + &.#{$namespace}-error + color: white + background: rgba($brand-danger,0.8) + &.#{$namespace}-notice + color: white + background: rgba($brand-success,0.8) + &.#{$namespace}-warning + color: white + background: rgba($brand-warning,0.8) + .#{$namespace}-close + cursor: pointer + font-size: 14px + line-height: 18px + font-weight: normal + font-family: helvetica, verdana, sans-serif + @include float(right) + .#{$namespace}-title + font-size: 18px + line-height: 24px + .#{$namespace}-message + font-size: 14px + line-height: 18px \ No newline at end of file diff --git a/admin/themes/default/sass/partials/_ladda.sass b/admin/themes/default/sass/partials/_ladda.sass index 0a8427917..b6a12eb24 100644 --- a/admin/themes/default/sass/partials/_ladda.sass +++ b/admin/themes/default/sass/partials/_ladda.sass @@ -12,302 +12,302 @@ $spinnerSize: 32px // MIXINS @mixin prefix ( $property, $value ) - -webkit-#{$property}: $value - -moz-#{$property}: $value - -ms-#{$property}: $value - -o-#{$property}: $value - #{$property}: $value + -webkit-#{$property}: $value + -moz-#{$property}: $value + -ms-#{$property}: $value + -o-#{$property}: $value + #{$property}: $value @mixin transition( $value ) - -webkit-transition: $value !important // important to override bootstrap - -moz-transition: $value !important - -ms-transition: $value !important - -o-transition: $value !important - transition: $value !important + -webkit-transition: $value !important // important to override bootstrap + -moz-transition: $value !important + -ms-transition: $value !important + -o-transition: $value !important + transition: $value !important @mixin vendor-transform( $value ) - @include prefix( transform, $value ) + @include prefix( transform, $value ) @mixin transform-origin( $value ) - @include prefix( transform-origin, $value ) + @include prefix( transform-origin, $value ) @mixin buttonColor( $name, $color ) - &[data-color=#{$name}] - background: $color - &:hover - background-color: lighten( $color, 5% ) + &[data-color=#{$name}] + background: $color + &:hover + background-color: lighten( $color, 5% ) // BUTTON BASE .ladda-button - position: relative - .ladda-spinner - position: absolute - z-index: 2 - display: inline-block - width: $spinnerSize - height: $spinnerSize - top: 50% - margin-top: -$spinnerSize/2 - opacity: 0 - pointer-events: none + position: relative + .ladda-spinner + position: absolute + z-index: 2 + display: inline-block + width: $spinnerSize + height: $spinnerSize + top: 50% + margin-top: -$spinnerSize/2 + opacity: 0 + pointer-events: none - .ladda-label - position: relative - z-index: 3 + .ladda-label + position: relative + z-index: 3 - .ladda-progress - position: absolute - width: 0 - height: 100% - top: 0 - background: rgba( 0, 0, 0, 0.2 ) - visibility: hidden - opacity: 0 - @include left(0) - @include transition( 0.1s linear all ) - &[data-loading] .ladda-progress - opacity: 1 - visibility: visible + .ladda-progress + position: absolute + width: 0 + height: 100% + top: 0 + background: rgba( 0, 0, 0, 0.2 ) + visibility: hidden + opacity: 0 + @include left(0) + @include transition( 0.1s linear all ) + &[data-loading] .ladda-progress + opacity: 1 + visibility: visible // EASING .ladda-button, .ladda-button .ladda-spinner, .ladda-button .ladda-label - @include transition( 0.3s cubic-bezier(0.175, 0.885, 0.320, 1.275) background-color ) + @include transition( 0.3s cubic-bezier(0.175, 0.885, 0.320, 1.275) background-color ) .ladda-button[data-style=zoom-in], .ladda-button[data-style=zoom-in] .ladda-spinner, .ladda-button[data-style=zoom-in] .ladda-label, .ladda-button[data-style=zoom-out], .ladda-button[data-style=zoom-out] .ladda-spinner, .ladda-button[data-style=zoom-out] .ladda-label - @include transition( 0.3s ease all ) + @include transition( 0.3s ease all ) // EXPAND LEFT .ladda-button[data-style=expand-right] - .ladda-spinner - @include right(14px) - &[data-size="s"] .ladda-spinner, - &[data-size="xs"] .ladda-spinner - @include right(4px) - &[data-loading] - @include padding-right(56px) - .ladda-spinner - opacity: 1 - &[data-size="s"], - &[data-size="xs"] - @include padding-right(40px) + .ladda-spinner + @include right(14px) + &[data-size="s"] .ladda-spinner, + &[data-size="xs"] .ladda-spinner + @include right(4px) + &[data-loading] + @include padding-right(56px) + .ladda-spinner + opacity: 1 + &[data-size="s"], + &[data-size="xs"] + @include padding-right(40px) // EXPAND RIGHT .ladda-button[data-style=expand-left] - .ladda-spinner - @include left(14px) - &[data-size="s"] .ladda-spinner, - &[data-size="xs"] .ladda-spinner - @include left(4px) - &[data-loading] - @include padding-left(56px) - .ladda-spinner - opacity: 1 - &[data-size="s"], - &[data-size="xs"] - @include padding-left(40px) + .ladda-spinner + @include left(14px) + &[data-size="s"] .ladda-spinner, + &[data-size="xs"] .ladda-spinner + @include left(4px) + &[data-loading] + @include padding-left(56px) + .ladda-spinner + opacity: 1 + &[data-size="s"], + &[data-size="xs"] + @include padding-left(40px) // EXPAND UP .ladda-button[data-style=expand-up] - overflow: hidden - .ladda-spinner - top: -$spinnerSize - @include margin-left(-$spinnerSize/2) - @include left(50%) - &[data-loading] - padding-top: 54px - .ladda-spinner - opacity: 1 - top: 14px - margin-top: 0 - &[data-size="s"], - &[data-size="xs"] - padding-top: 32px - .ladda-spinner - top: 4px + overflow: hidden + .ladda-spinner + top: -$spinnerSize + @include margin-left(-$spinnerSize/2) + @include left(50%) + &[data-loading] + padding-top: 54px + .ladda-spinner + opacity: 1 + top: 14px + margin-top: 0 + &[data-size="s"], + &[data-size="xs"] + padding-top: 32px + .ladda-spinner + top: 4px // EXPAND DOWN .ladda-button[data-style=expand-down] - overflow: hidden - .ladda-spinner - top: 62px - @include left(50%) - margin-left: -$spinnerSize/2 - &[data-size="s"] .ladda-spinner, - &[data-size="xs"] .ladda-spinner - top: 40px - &[data-loading] - padding-bottom: 54px - .ladda-spinner - opacity: 1 - &[data-size="s"] - &[data-size="xs"] - padding-bottom: 32px + overflow: hidden + .ladda-spinner + top: 62px + @include left(50%) + margin-left: -$spinnerSize/2 + &[data-size="s"] .ladda-spinner, + &[data-size="xs"] .ladda-spinner + top: 40px + &[data-loading] + padding-bottom: 54px + .ladda-spinner + opacity: 1 + &[data-size="s"] + &[data-size="xs"] + padding-bottom: 32px // SLIDE LEFT .ladda-button[data-style=slide-left] - overflow: hidden - .ladda-label - position: relative - .ladda-spinner - @include left(100%) - @include margin-left(-$spinnerSize/2) - &[data-loading] - .ladda-label - opacity: 0 - @include left(-100%) - .ladda-spinner - opacity: 1 - @include left(50%) + overflow: hidden + .ladda-label + position: relative + .ladda-spinner + @include left(100%) + @include margin-left(-$spinnerSize/2) + &[data-loading] + .ladda-label + opacity: 0 + @include left(-100%) + .ladda-spinner + opacity: 1 + @include left(50%) // SLIDE RIGHT .ladda-button[data-style=slide-right] - overflow: hidden - .ladda-label - position: relative - .ladda-spinner - @include right(100%) - @include margin-left(-$spinnerSize/2) - &[data-loading] - .ladda-label - opacity: 0 - @include left(100%) - .ladda-spinner - opacity: 1 - @include left(50%) + overflow: hidden + .ladda-label + position: relative + .ladda-spinner + @include right(100%) + @include margin-left(-$spinnerSize/2) + &[data-loading] + .ladda-label + opacity: 0 + @include left(100%) + .ladda-spinner + opacity: 1 + @include left(50%) // SLIDE UP .ladda-button[data-style=slide-up] - overflow: hidden - .ladda-label - position: relative - .ladda-spinner - margin-top: 1em - @include left(50%) - @include margin-left(-$spinnerSize/2) - &[data-loading] - .ladda-label - opacity: 0 - top: -1em - .ladda-spinner - opacity: 1 - margin-top: -$spinnerSize/2 + overflow: hidden + .ladda-label + position: relative + .ladda-spinner + margin-top: 1em + @include left(50%) + @include margin-left(-$spinnerSize/2) + &[data-loading] + .ladda-label + opacity: 0 + top: -1em + .ladda-spinner + opacity: 1 + margin-top: -$spinnerSize/2 // SLIDE DOWN .ladda-button[data-style=slide-down] - overflow: hidden - .ladda-label - position: relative - .ladda-spinner - margin-top: -2em - @include margin-left(-$spinnerSize/2) - @include left(50%) - &[data-loading] - .ladda-label - opacity: 0 - top: 1em - .ladda-spinner - opacity: 1 - margin-top: -$spinnerSize/2 + overflow: hidden + .ladda-label + position: relative + .ladda-spinner + margin-top: -2em + @include margin-left(-$spinnerSize/2) + @include left(50%) + &[data-loading] + .ladda-label + opacity: 0 + top: 1em + .ladda-spinner + opacity: 1 + margin-top: -$spinnerSize/2 // ZOOM-OUT .ladda-button[data-style=zoom-out] - overflow: hidden - .ladda-spinner - @include left(50%) - @include margin-left(-$spinnerSize/2) - @include vendor-transform( scale( 2.5 ) ) - .ladda-label - position: relative - display: inline-block - &[data-loading] .ladda-label - opacity: 0 - @include vendor-transform( scale( 0.5 ) ) - &[data-loading] .ladda-spinner - opacity: 1 - @include vendor-transform( none ) + overflow: hidden + .ladda-spinner + @include left(50%) + @include margin-left(-$spinnerSize/2) + @include vendor-transform( scale( 2.5 ) ) + .ladda-label + position: relative + display: inline-block + &[data-loading] .ladda-label + opacity: 0 + @include vendor-transform( scale( 0.5 ) ) + &[data-loading] .ladda-spinner + opacity: 1 + @include vendor-transform( none ) // ZOOM-IN .ladda-button[data-style=zoom-in] - overflow: hidden - .ladda-spinner - @include margin-left(-$spinnerSize/2) - @include left(50%) - @include vendor-transform( scale( 0.2 ) ) - .ladda-label - position: relative - display: inline-block - &[data-loading] .ladda-label - opacity: 0 - @include vendor-transform( scale( 2.2 ) ) - &[data-loading] .ladda-spinner - opacity: 1 - @include vendor-transform( none ) + overflow: hidden + .ladda-spinner + @include margin-left(-$spinnerSize/2) + @include left(50%) + @include vendor-transform( scale( 0.2 ) ) + .ladda-label + position: relative + display: inline-block + &[data-loading] .ladda-label + opacity: 0 + @include vendor-transform( scale( 2.2 ) ) + &[data-loading] .ladda-spinner + opacity: 1 + @include vendor-transform( none ) // CONTRACT .ladda-button[data-style=contract] - overflow: hidden - width: 100px - .ladda-spinner - @include left(50%) - @include margin-left(-16px) + overflow: hidden + width: 100px + .ladda-spinner + @include left(50%) + @include margin-left(-16px) .ladda-button[data-style=contract][data-loading] - border-radius: 50% - width: 52px - .ladda-label - opacity: 0 - .ladda-spinner - opacity: 1 + border-radius: 50% + width: 52px + .ladda-label + opacity: 0 + .ladda-spinner + opacity: 1 // OVERLAY .ladda-button[data-style=contract-overlay] - overflow: hidden - width: 100px - @include ltr - box-shadow: 0px 0px 0px 3000px rgba(0,0,0,0) - @include rtl - box-shadow: 0px 3000px 0px 0px rgba(0,0,0,0) - .ladda-spinner - @include left(50%) - @include margin-left(-16px) - &[data-loading] - border-radius: 50% - width: 52px - @include ltr - box-shadow: 0px 0px 0px 3000px rgba(0,0,0,0.8) - @include rtl - box-shadow: 0px 3000px 0px 0px rgba(0,0,0,0.8) - .ladda-label - opacity: 0 - .ladda-spinner - opacity: 1 + overflow: hidden + width: 100px + @include ltr + box-shadow: 0px 0px 0px 3000px rgba(0,0,0,0) + @include rtl + box-shadow: 0px 3000px 0px 0px rgba(0,0,0,0) + .ladda-spinner + @include left(50%) + @include margin-left(-16px) + &[data-loading] + border-radius: 50% + width: 52px + @include ltr + box-shadow: 0px 0px 0px 3000px rgba(0,0,0,0.8) + @include rtl + box-shadow: 0px 3000px 0px 0px rgba(0,0,0,0.8) + .ladda-label + opacity: 0 + .ladda-spinner + opacity: 1 .ladda-button - &[disabled], - &[data-loading] - border-color: rgba( 0, 0, 0, 0.07 ) - cursor: default - background-color: #999 - &:hover - cursor: default - background-color: #999 - &[data-size=xs] - padding: 4px 8px - .ladda-label - font-size: 0.7em - &[data-size=s] - padding: 6px 10px - .ladda-label - font-size: 0.9em - &[data-size=l] .ladda-label - font-size: 1.2em - &[data-size=xl] .ladda-label - font-size: 1.5em + &[disabled], + &[data-loading] + border-color: rgba( 0, 0, 0, 0.07 ) + cursor: default + background-color: #999 + &:hover + cursor: default + background-color: #999 + &[data-size=xs] + padding: 4px 8px + .ladda-label + font-size: 0.7em + &[data-size=s] + padding: 6px 10px + .ladda-label + font-size: 0.9em + &[data-size=l] .ladda-label + font-size: 1.2em + &[data-size=xl] .ladda-label + font-size: 1.5em diff --git a/admin/themes/default/sass/partials/_tables.sass b/admin/themes/default/sass/partials/_tables.sass index 7382ff13a..12f61e76c 100644 --- a/admin/themes/default/sass/partials/_tables.sass +++ b/admin/themes/default/sass/partials/_tables.sass @@ -90,7 +90,7 @@ td.actions @include text-align(right) @include padding-right(5px) - th.actions .btn, + th.actions .btn margin-bottom: 4px !important tr.myDragClass diff --git a/admin/themes/default/template/controllers/access/helpers/form/form.tpl b/admin/themes/default/template/controllers/access/helpers/form/form.tpl index d3f2a73f8..7c5a71acc 100644 --- a/admin/themes/default/template/controllers/access/helpers/form/form.tpl +++ b/admin/themes/default/template/controllers/access/helpers/form/form.tpl @@ -107,6 +107,47 @@ } perfect_access_js_gestion(this, perm, id_tab, tabsize, tabnumber, table); + if (perm == 'kpi') { + $(table + ' .kpi.' + id_tab).prop('checked', !!enabled); + } + + $(table + ' tr.kpi-row').each(function() { + var kpiTabId = $(this).data('kpi-parent'); + var kpiProfile = $(this).data('kpi-profile'); + var $kpiInputs = $(this).find('input.ajaxPower.kpi'); + if (!$kpiInputs.length || $kpiInputs.first().data('kpi-editable') != 1) { return; } + // For perm=view, read state directly from action — jQuery 1.11 .attr() doesn't update .prop() + var parentEnabled = (perm == 'view' && (id_tab == kpiTabId || id_tab == -1)) + ? !!enabled + : $(table + ' input.view.' + kpiTabId).first().is(':checked'); + if (!parentEnabled) { + $kpiInputs.prop('checked', false).prop('disabled', true); + } else { + $kpiInputs.prop('disabled', false); + if (perm == 'all' && (id_tab == -1 || id_tab == kpiTabId)) { + $kpiInputs.prop('checked', !!enabled).first().trigger('change'); + } + if (perm == 'view' && (id_tab == kpiTabId || id_tab == -1) && !!enabled) { + $kpiInputs.prop('checked', true); + $.ajax({ + url: "{$link->getAdminLink('AdminAccess')|addslashes}", + cache: false, + data: { + ajaxMode: '1', + id_tab: kpiTabId, + id_profile: kpiProfile, + perm: 'kpi', + enabled: 1, + submitAddAccess: '1', + action: 'updateAccess', + ajax: '1', + token: '{getAdminToken tab='AdminAccess'}' + } + }); + } + } + }); + $.ajax({ url: "{$link->getAdminLink('AdminAccess')|addslashes}", cache: false, @@ -349,6 +390,32 @@ + {if !empty($tab.has_kpi)} + +   » {l s='KPI'} + + + + + + + + + + + {/if} {foreach $tabs AS $child} {if $child.id_parent === $tab.id_tab} {if isset($access[$child.id_tab])} @@ -372,6 +439,32 @@ + {if !empty($child.has_kpi)} + +   » {l s='KPI'} + + + + + + + + + + + {/if} {/if} {/if} {/foreach} @@ -438,4 +531,4 @@ {/foreach} - + \ No newline at end of file diff --git a/admin/themes/default/template/controllers/customer_threads/helpers/view/view.tpl b/admin/themes/default/template/controllers/customer_threads/helpers/view/view.tpl index b42bea915..471eeb0ba 100644 --- a/admin/themes/default/template/controllers/customer_threads/helpers/view/view.tpl +++ b/admin/themes/default/template/controllers/customer_threads/helpers/view/view.tpl @@ -36,6 +36,7 @@ {/if} + {if $can_edit}
{foreach $actions as $action} @@ -48,6 +49,7 @@
+ {/if}
@@ -97,6 +99,7 @@ {/foreach}
+{if $can_edit}

{l s="Your answer to"} {if isset($customer->firstname)}{$customer->firstname|escape:'html':'UTF-8'} {$customer->lastname|escape:'html':'UTF-8'} {else} {$thread->email}{/if}

@@ -125,7 +128,7 @@
- +{/if} {if count($timeline_items)}

diff --git a/admin/themes/default/template/controllers/modules/js.tpl b/admin/themes/default/template/controllers/modules/js.tpl index d91c1b3bb..79097c46a 100644 --- a/admin/themes/default/template/controllers/modules/js.tpl +++ b/admin/themes/default/template/controllers/modules/js.tpl @@ -48,21 +48,65 @@ function modules_management(action) { var modules = document.getElementsByName('modules'); - var module_list = ''; + var module_list = []; for (var i = 0; i < modules.length; i++) { - if (modules[i].checked == true) + if (modules[i].checked) { - rel = modules[i].getAttribute('data-rel'); + var rel = modules[i].getAttribute('data-rel'); if (rel != "false" && action == "uninstall") { if (!confirm(rel)) return false; } - module_list += '|'+modules[i].value; + module_list.push(modules[i].value); } } - document.location.href=currentIndex+'&token='+token+'&'+action+'='+module_list.substring(1, module_list.length); + + module_list = encodeURIComponent(module_list.join('|')); + if (action == 'enable' || action == 'disable') { + var type = action == 'disable' ? 0 : 1; + document.location.href = currentIndex+'&token='+token+'&enable='+type+'&module_name='+module_list; + return false; + } + + document.location.href = currentIndex+'&token='+token+'&'+action+'='+module_list; + return false; + } + + function filter_modules_by_name(table, moduleName) + { + var moduleNames = moduleName.split('|'); + var filteredNames = []; + for (var i = 0; i < moduleNames.length; i++) { + moduleNames[i] = $.trim(moduleNames[i]); + if (moduleNames[i] !== '') { + filteredNames.push(moduleNames[i].toLowerCase()); + } + } + + if (!filteredNames.length) { + return; + } + + if (filteredNames.length === 1) { + $.uiTableFilter(table, filteredNames[0]); + return; + } + + table.find('tbody tr').each(function() { + var rowText = $(this).text().toLowerCase(); + var isMatch = false; + + for (var i = 0; i < filteredNames.length; i++) { + if (rowText.indexOf(filteredNames[i]) !== -1) { + isMatch = true; + break; + } + } + + $(this).toggle(isMatch); + }); } $('document').ready( function() { @@ -71,7 +115,7 @@ $.uiTableFilter($('#moduleContainer').find('table'), anchor); if (module_name != '') - $.uiTableFilter($('#moduleContainer').find('table'), module_name); + filter_modules_by_name($('#moduleContainer').find('table'), module_name); $('#moduleQuicksearch').on('keyup', function(){ val = this.value; diff --git a/admin/themes/default/template/controllers/modules/list.tpl b/admin/themes/default/template/controllers/modules/list.tpl index 6166962a4..9fab8630b 100644 --- a/admin/themes/default/template/controllers/modules/list.tpl +++ b/admin/themes/default/template/controllers/modules/list.tpl @@ -190,6 +190,19 @@

@@ -44,7 +44,7 @@
{include file="controllers/products/multishop/checkbox.tpl" field="meta_description" type="default" multilang="true"}
@@ -53,7 +53,7 @@ languages=$languages input_name='meta_description' input_value=$product->meta_description - maxchar=160 + maxchar=255 } @@ -91,16 +91,11 @@ -
-
- {foreach from=$languages item=language} -
- {l s='The product link will look like this:'}
- {if isset($rewritten_links[$language.id_lang][0])}{$rewritten_links[$language.id_lang][0]|escape:'html':'UTF-8'}{/if}{if isset($product->id)}{$product->link_rewrite[$language.id_lang]|escape:'html':'UTF-8'}{/if}{if isset($rewritten_links[$language.id_lang][1])}{$rewritten_links[$language.id_lang][1]|escape:'html':'UTF-8'}{/if} -
- {/foreach} -
-
+ {include file="seo_preview.tpl" + languages = $languages + preview_link = $rewritten_links|default:'' + inputs = ['meta_title'=>$product->meta_title ,'meta_description' => $product->meta_description,'link_rewrite' => $product->link_rewrite, 'name' => $product->name, 'description_short' => $product->description_short] + }
@@ -61,6 +61,10 @@ {/foreach} }); {/if} - $(".textarea-autosize").autosize(); + $(".textarea-autosize").each(function() { + var $ta = $(this), val = $ta.val(); + $ta.val('').autosize(); + if (val) { $ta.val(val).trigger('input'); } + }); diff --git a/admin/themes/default/template/controllers/orders/_cart_booking_demands.tpl b/admin/themes/default/template/controllers/orders/_cart_booking_demands.tpl index c07968f9d..fad6ca46e 100644 --- a/admin/themes/default/template/controllers/orders/_cart_booking_demands.tpl +++ b/admin/themes/default/template/controllers/orders/_cart_booking_demands.tpl @@ -32,9 +32,7 @@ {if isset($selectedRoomDemands) && $selectedRoomDemands} {/if} - {if isset($serviceProducts) && $serviceProducts} -
  • {l s='Services'}
  • - {/if} +
  • {l s='Services'}
  • {if isset($selectedRoomDemands) && $selectedRoomDemands} diff --git a/admin/themes/default/template/controllers/orders/form.tpl b/admin/themes/default/template/controllers/orders/form.tpl index 0451cd31d..1482462e9 100644 --- a/admin/themes/default/template/controllers/orders/form.tpl +++ b/admin/themes/default/template/controllers/orders/form.tpl @@ -1572,6 +1572,7 @@ id_room: idRoom, id_cart: idCart, id_product: idProduct, + id_customer: id_customer, id_hotel_cart_booking: idHotelCartBooking, action: 'getRoomTypeCartDemands', ajax: true @@ -1877,7 +1878,7 @@ {l s='Customer'}
    -
    +
    id_customer) && $cart->id_customer && isset($customer) && $customer }style="display:none;"{/if} class="form-group">
    -
    +
    + {if isset($cart->id_customer) && $cart->id_customer && isset($customer) && $customer } +
    +
    +
    + {$customer->firstname} {$customer->lastname} #{$customer->id} +
    + {$customer->email}
    +
    + +
    +
    + {/if} +
    {*
    {include file='controllers/orders/_current_cart_details_data.tpl'} - @@ -451,7 +456,7 @@ {l s='Transaction ID'} {l s='Amount'} {l s='Invoice'} - + @@ -463,6 +468,11 @@ {$payment['transaction_id']|escape:'html':'UTF-8'} {displayPrice price=$payment['real_paid_amount'] currency=$payment['id_currency']} {if isset($payment['invoice_number'])}{$payment['invoice_number']}{else}--{/if} + {if isset($receipt_management_active) && $receipt_management_active} + + {l s='Receipt'} + + {/if} {l s='Details'} @@ -707,7 +717,7 @@ {if isset($messages) && $messages}
    -  {l s='Order Private Notes'} +  {l s='Order Notes'}
    {foreach from=$messages item=message name=customerMessage} @@ -720,11 +730,11 @@ {$message['elastname']|escape:'html':'UTF-8'}{else}{$message['cfirstname']|escape:'html':'UTF-8'} {$message['clastname']|escape:'html':'UTF-8'} {/if},   - {dateFormat date=$message['date_add']} + {dateFormat date=$message.date_add full=1} - {if ($message['private'] == 1)} + {* {if ($message['private'] == 1)} {l s='Private'} - {/if} + {/if} *}

    {if !$smarty.foreach.customerMessage.last}
    {/if} @@ -1302,7 +1312,30 @@ {/if}
    - + {* Css for handling order disable status modal *} + + {strip} {addJsDefL name=no_rm_avail_txt}{l s='No room available.' js=1}{/addJsDefL} {addJsDefL name=no_realloc_rm_avail_txt}{l s='No room available for reallocation.' js=1}{/addJsDefL} @@ -1335,7 +1368,6 @@ {addJsDefL name='invalid_occupancy_txt'}{l s='Invalid occupancy(adults/children) found.' js=1}{/addJsDefL} {addJsDefL name='select_room_txt'}{l s='Select room' js=1}{/addJsDefL} {addJsDef max_child_age=$max_child_age|escape:'quotes':'UTF-8'} - {addJsDef max_child_in_room=$max_child_in_room|escape:'quotes':'UTF-8'} {addJsDef ROOM_STATUS_CHECKED_IN=$ROOM_STATUS_CHECKED_IN|escape:'quotes':'UTF-8'} {addJsDef ROOM_STATUS_CHECKED_OUT=$ROOM_STATUS_CHECKED_OUT|escape:'quotes':'UTF-8'} {addJsDef ALLOTMENT_MANUAL=$ALLOTMENT_MANUAL|escape:'quotes':'UTF-8'} @@ -1346,4 +1378,4 @@ {addJsDefL name=txt_booking_document_delete_success}{l s='Document deleted successfully.' js=1}{/addJsDefL} {addJsDefL name='error_found_txt'}{l s='Errors found' js=1}{/addJsDefL} {/strip} -{/block} +{/block} \ No newline at end of file diff --git a/admin/themes/default/template/controllers/orders/modals/_add_room_booking.tpl b/admin/themes/default/template/controllers/orders/modals/_add_room_booking.tpl index b9e6524cf..c9d897d84 100644 --- a/admin/themes/default/template/controllers/orders/modals/_add_room_booking.tpl +++ b/admin/themes/default/template/controllers/orders/modals/_add_room_booking.tpl @@ -128,6 +128,12 @@ {/if} +
    +
    + + +
    +
    {if isset($invoices_collection) && sizeof($invoices_collection)} +
    +
    + + +
    +
    + +
    +
    + + +
    +
    - \ No newline at end of file diff --git a/admin/themes/default/template/controllers/products/helpers/form/form.tpl b/admin/themes/default/template/controllers/products/helpers/form/form.tpl index 5a97a1cec..6b1030882 100644 --- a/admin/themes/default/template/controllers/products/helpers/form/form.tpl +++ b/admin/themes/default/template/controllers/products/helpers/form/form.tpl @@ -218,6 +218,7 @@ $('.product-tab-content').on('displayed', function(e) { $('#toolbar-footer').appendTo($(this).children('.product-tab')); + $(window).trigger('resize.autosize'); }); }); diff --git a/admin/themes/default/template/controllers/products/informations.tpl b/admin/themes/default/template/controllers/products/informations.tpl index cb97d2652..c8716ea36 100644 --- a/admin/themes/default/template/controllers/products/informations.tpl +++ b/admin/themes/default/template/controllers/products/informations.tpl @@ -104,7 +104,7 @@
    {include file="controllers/products/multishop/checkbox.tpl" field="name" type="default" multilang="true"}
    diff --git a/admin/themes/default/template/controllers/products/input_text_lang.tpl b/admin/themes/default/template/controllers/products/input_text_lang.tpl index 81f63038a..7f92a362c 100644 --- a/admin/themes/default/template/controllers/products/input_text_lang.tpl +++ b/admin/themes/default/template/controllers/products/input_text_lang.tpl @@ -39,7 +39,6 @@ class="form-control {if isset($input_class)}{$input_class} {/if}" name="{$input_name}_{$language.id_lang}" value="{$input_value[$language.id_lang]|default:''|escape:'html'}" - onkeyup="if (isArrowKey(event)) return ;updateFriendlyURL();" onblur="updateLinkRewrite();" {if isset($required)} required="required"{/if} {if isset($maxchar)} data-maxchar="{$maxchar}"{/if} diff --git a/admin/themes/default/template/controllers/products/seo.tpl b/admin/themes/default/template/controllers/products/seo.tpl index 8544f75a1..062d3ee5a 100644 --- a/admin/themes/default/template/controllers/products/seo.tpl +++ b/admin/themes/default/template/controllers/products/seo.tpl @@ -30,7 +30,7 @@
    {include file="controllers/products/multishop/checkbox.tpl" field="meta_title" type="default" multilang="true"}
    @@ -39,7 +39,7 @@ languages=$languages input_name='meta_title' input_value=$product->meta_title - maxchar=70 + maxchar=128 }
    @@ -47,7 +47,7 @@
    {include file="controllers/products/multishop/checkbox.tpl" field="meta_description" type="default" multilang="true"}
    @@ -56,7 +56,7 @@ languages=$languages input_name='meta_description' input_value=$product->meta_description - maxchar=160 + maxchar=255 } @@ -94,16 +94,11 @@ -
    -
    - {foreach from=$languages item=language} -
    - {l s='The product link will look like this:'}
    - {if isset($rewritten_links[$language.id_lang][0])}{$rewritten_links[$language.id_lang][0]|escape:'html':'UTF-8'}{/if}{if isset($product->id)}{$product->link_rewrite[$language.id_lang]|escape:'html':'UTF-8'}{/if}{if isset($rewritten_links[$language.id_lang][1])}{$rewritten_links[$language.id_lang][1]|escape:'html':'UTF-8'}{/if} -
    - {/foreach} -
    -
    + {include file="seo_preview.tpl" + languages = $languages + preview_link = $rewritten_links|default:'' + inputs = ['meta_title'=>$product->meta_title ,'meta_description' => $product->meta_description,'link_rewrite' => $product->link_rewrite, 'name' => $product->name, 'description_short' => $product->description_short] + } @@ -64,6 +64,10 @@ {/foreach} }); {/if} - $(".textarea-autosize").autosize(); + $(".textarea-autosize").each(function() { + var $ta = $(this), val = $ta.val(); + $ta.val('').autosize(); + if (val) { $ta.val(val).trigger('input'); } + }); diff --git a/admin/themes/default/template/header.tpl b/admin/themes/default/template/header.tpl index 148be94a4..bb6f6f97f 100644 --- a/admin/themes/default/template/header.tpl +++ b/admin/themes/default/template/header.tpl @@ -298,6 +298,18 @@ {/if}