Source of file PickUpOrDeliveryModifierOptions.php
Size: 17,715 Bytes - Last Modified: 2021-12-23T10:40:43+00:00
/var/www/docs.ssmods.com/process/src/src/Model/PickUpOrDeliveryModifierOptions.php
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478 | <?php namespace Sunnysideup\EcommerceDelivery\Model; use SilverStripe\CMS\Model\SiteTree; use SilverStripe\Core\Config\Config; use SilverStripe\Forms\GridField\GridField; use SilverStripe\Forms\GridField\GridFieldAddExistingAutocompleter; use SilverStripe\Forms\GridField\GridFieldButtonRow; use SilverStripe\Forms\GridField\GridFieldConfig; use SilverStripe\Forms\GridField\GridFieldDataColumns; use SilverStripe\Forms\GridField\GridFieldDeleteAction; use SilverStripe\Forms\GridField\GridFieldDetailForm; use SilverStripe\Forms\GridField\GridFieldEditButton; use SilverStripe\Forms\GridField\GridFieldFilterHeader; use SilverStripe\Forms\GridField\GridFieldPageCount; use SilverStripe\Forms\GridField\GridFieldPaginator; use SilverStripe\Forms\GridField\GridFieldSortableHeader; use SilverStripe\Forms\GridField\GridFieldToolbarHeader; use SilverStripe\Forms\HeaderField; use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\ListboxField; use SilverStripe\Forms\LiteralField; use SilverStripe\ORM\DataObject; use SilverStripe\ORM\DB; use SilverStripe\Security\Permission; use Sunnysideup\Ecommerce\Config\EcommerceConfig; use Sunnysideup\Ecommerce\Forms\Fields\OptionalTreeDropdownField; use Sunnysideup\Ecommerce\Forms\Gridfield\Configs\GridFieldConfigForProducts; use Sunnysideup\Ecommerce\Model\Address\EcommerceCountry; use Sunnysideup\Ecommerce\Model\Address\EcommerceRegion; use Sunnysideup\Ecommerce\Model\Extensions\EcommerceRole; use Sunnysideup\Ecommerce\Pages\Product; /** * @author nicolaas [at] sunnysideup.co.nz * Precondition : There can only be 1 default option */ class PickUpOrDeliveryModifierOptions extends DataObject { private static $table_name = 'PickUpOrDeliveryModifierOptions'; private static $db = [ 'IsDefault' => 'Boolean', 'Code' => 'Varchar(25)', 'Name' => 'Varchar(175)', 'Percentage' => 'Double', 'FixedCost' => 'Currency', 'WeightMultiplier' => 'Double', 'WeightUnit' => 'Double', 'MinimumDeliveryCharge' => 'Currency', 'MaximumDeliveryCharge' => 'Currency', 'MinimumOrderAmountForZeroRate' => 'Currency', 'FreeShippingUpToThisOrderAmount' => 'Currency', 'Sort' => 'Int', ]; private static $has_one = [ 'ExplanationPage' => SiteTree::class, ]; private static $many_many = [ 'AvailableInCountries' => EcommerceCountry::class, 'AvailableInRegions' => EcommerceRegion::class, 'WeightBrackets' => PickUpOrDeliveryModifierOptionsWeightBracket::class, 'SubtotalBrackets' => PickUpOrDeliveryModifierOptionsSubTotalBracket::class, 'ExcludedProducts' => Product::class, ]; private static $belongs_many_many = [ 'ExcludeFromCountries' => EcommerceCountry::class, ]; private static $indexes = [ 'IsDefault' => true, 'Code' => true, ]; private static $searchable_fields = [ 'Code', 'Name' => 'PartialMatchFilter', ]; private static $field_labels = [ 'IsDefaultNice' => 'Default option', 'IsDefault' => 'Default delivery option?', 'Code' => 'Code', 'Name' => 'Long Name', 'Percentage' => 'Percentage', 'FixedCost' => 'Fixed cost', 'WeightMultiplier' => 'Cost per kilogram', 'WeightUnit' => 'Weight unit in kilograms', 'MinimumDeliveryCharge' => 'Minimum delivery charge', 'MaximumDeliveryCharge' => 'Maximum delivery charge', 'MinimumOrderAmountForZeroRate' => 'Minimum for 0 rate', 'FreeShippingUpToThisOrderAmount' => 'Free shipping up to', 'Sort' => 'Sort Index', 'ListOfCountries' => 'Applicable Countries', ]; private static $field_labels_right = [ 'Percentage' => 'number between 0 = 0% and 1 = 100% (e.g. 0.05 would add 5 cents to every dollar ordered).', 'FixedCost' => 'e.g. entering 10 will add a fixed 10 dollars (or whatever currency is being used) delivery fee.', 'WeightMultiplier' => 'it multiplies the total weight of the total order with this number to work out charge for delivery. NOTE: you can also setup weight brackets (e.g. from 0 - 1kg = $123, from 1kg - 2kg = $456).', 'WeightUnit' => 'if you enter 0.1 here, the price will go up with every 100 grams of total order weight.', 'MinimumDeliveryCharge' => 'minimum delivery charge.', 'MaximumDeliveryCharge' => 'maximum delivery charge.', 'MinimumOrderAmountForZeroRate' => 'if this option is selected and the total order is over the amounted entered above then delivery is free.', 'FreeShippingUpToThisOrderAmount' => 'if this option is selected and the total order is less than the amount entered above then delivery is free. This is for situations where a small order would have a large delivery cost.', 'Sort' => 'lower numbers show first.', ]; private static $defaults = [ 'Code' => 'homedelivery', 'Name' => 'Home Delivery', 'Percentage' => 0, 'FixedCost' => 0, 'WeightMultiplier' => 0, 'WeightUnit' => 1, 'MinimumDeliveryCharge' => 0, 'MaximumDeliveryCharge' => 0, 'MinimumOrderAmountForZeroRate' => 0, 'Sort' => 0, ]; private static $summary_fields = [ 'IsDefaultNice', 'Code', 'Name', 'ListOfCountries', ]; private static $casting = [ 'IsDefaultNice' => 'Varchar', 'ListOfCountries' => 'Varchar', ]; private static $singular_name = 'Delivery / Pick-up Option'; private static $plural_name = 'Delivery / Pick-up Options'; private static $default_sort = '"IsDefault" DESC, "Sort" ASC, "Name" ASC'; public function i18n_singular_name() { return _t('PickUpOrDeliveryModifierOptions.DELIVERYOPTION', 'Delivery / Pick-up Option'); } public function i18n_plural_name() { return _t('PickUpOrDeliveryModifierOptions.DELIVERYOPTION', 'Delivery / Pick-up Options'); } /** * returns the default PickUpOrDeliveryModifierOptions object * if none exists, it creates one. * * @return PickUpOrDeliveryModifierOptions */ public static function default_object() { $filter = ['IsDefault' => true]; $obj = PickUpOrDeliveryModifierOptions::get()->filter($filter)->First(); if ($obj) { //do nothing } else { $obj = PickUpOrDeliveryModifierOptions::create($filter); $obj->write(); } return $obj; } /** * returns an array of countries available for all options combined. * like this * array( * "NZ" => "NZ" * );. * * @return array */ public static function get_all_as_country_array() { $array = []; $options = PickUpOrDeliveryModifierOptions::get(); if ($options->exists()) { foreach ($options as $option) { $countries = $option->AvailableInCountries(); if ($countries) { if ($countries->exists()) { foreach ($countries as $country) { $array[$option->Code][] = $country->Code; } } } } } return $array; } /** * @return string */ public function IsDefaultNice() { return $this->getIsDefaultNice(); } public function getIsDefaultNice() { return $this->IsDefault ? 'yes' : 'no'; } /** * standard SS method. * * @param null|mixed $member * @param mixed $context * * @return bool */ public function canCreate($member = null, $context = []) { if (Permission::checkMember($member, Config::inst()->get(EcommerceRole::class, 'admin_permission_code'))) { return true; } return parent::canCreate($member); } /** * standard SS method. * * @param null|mixed $member * @param mixed $context * * @return bool */ public function canView($member = null, $context = []) { if (Permission::checkMember($member, Config::inst()->get(EcommerceRole::class, 'admin_permission_code'))) { return true; } return parent::canCreate($member); } /** * standard SS method. * * @param null|mixed $member * @param mixed $context * * @return bool */ public function canEdit($member = null, $context = []) { if (Permission::checkMember($member, Config::inst()->get(EcommerceRole::class, 'admin_permission_code'))) { return true; } return parent::canEdit($member); } /** * standard SS method. * * @param null|mixed $member * * @return bool */ public function canDelete($member = null) { if (Permission::checkMember($member, Config::inst()->get(EcommerceRole::class, 'admin_permission_code'))) { return true; } return parent::canDelete($member); } /** * standard SS method. */ public function getCMSFields() { $fields = parent::getCMSFields(); $availableInCountriesField = $this->createGridField('Available in'); if ($availableInCountriesField) { $fields->replaceField('AvailableInCountries', $availableInCountriesField); } $excludeFromCountriesField = $this->createGridField('Excluded from', EcommerceCountry::class, 'ExcludeFromCountries'); if ($excludeFromCountriesField) { $fields->replaceField('ExcludeFromCountries', $excludeFromCountriesField); } $regionField = $this->createGridField('Regions', EcommerceRegion::class, 'AvailableInRegions'); if ($regionField) { $fields->replaceField('AvailableInRegions', $regionField); } if (class_exists(\Sunnysideup\DataObjectSorter\DataObjectSorterController::class) && $this->hasExtension(\Sunnysideup\DataObjectSorter\DataObjectSorterController::class)) { $fields->addFieldToTab('Root.Sort', new LiteralField('InvitationToSort', $this->dataObjectSorterPopupLink())); } $fields->replaceField('ExplanationPageID', new OptionalTreeDropdownField($name = 'ExplanationPageID', $title = 'Page', SiteTree::class)); //add headings $fields->addFieldToTab( 'Root.Main', new HeaderField( 'Charges', _t('PickUpOrDeliveryModifierOptions.CHARGES', 'Charges (enter zero (0) to ignore)') ), 'Percentage' ); $fields->addFieldToTab( 'Root.Main', new HeaderField( 'MinimumAndMaximum', _t('PickUpOrDeliveryModifierOptions.MIN_AND_MAX', 'Minimum and Maximum (enter zero (0) to ignore)') ), 'MinimumDeliveryCharge' ); $fields->addFieldToTab( 'Root.Main', new HeaderField( 'ExplanationHeader', _t('PickUpOrDeliveryModifierOptions.EXPLANATION_HEADER', 'More information about delivery option') ), 'ExplanationPageID' ); $fields->replaceField( 'ExcludedProducts', $excludedProdsField = GridField::create( 'ExcludedProducts', 'Excluded Products', $this->ExcludedProducts(), GridFieldConfigForProducts::create() ) ); $excludedProdsField->setDescription("Products added here will not be charged delivery costs. If a customer's order contains more than one item (and not all items are listed here), then delivery costs will still be calculated."); if (EcommerceConfig::inst()->ProductsHaveWeight) { $weightBrackets = $this->WeightBrackets(); if ($weightBrackets->exists()) { $fields->removeByName('WeightMultiplier'); $fields->removeByName('WeightUnit'); } else { $fields->addFieldToTab('Root.Main', new HeaderField('WeightOptions', 'Weight Options (also see Weight Brackets tab)'), 'WeightMultiplier'); } } else { $fields->removeByName('WeightBrackets'); $fields->removeByName('WeightMultiplier'); $fields->removeByName('WeightUnit'); } $fields->addFieldToTab('Root.Main', new HeaderField('MoreInformation', 'Other Settings'), 'Sort'); foreach ($this->Config()->get('field_labels_right') as $fieldName => $fieldDescription) { $field = $fields->dataFieldByName($fieldName); if ($field) { $field->setDescription($fieldDescription); } } return $fields; } public function getListOfCountries() { $in = ''; $out = ''; if ($this->AvailableInCountries()->exists()) { $in = '' . implode(', ', $this->AvailableInCountries()->column('Code')); } if ($this->ExcludeFromCountries()->exists()) { $out = ' // OUT: ' . implode(', ', $this->ExcludeFromCountries()->column('Code')); } return $in . $out; } /** * make sure there is only exactly one default. */ protected function onAfterWrite() { parent::onAfterWrite(); // no other record but current one is not default $notExistsOther = ! (bool) PickUpOrDeliveryModifierOptions::get()->exclude(['ID' => (int) $this->ID])->exist(); if (! $this->IsDefault && $notExistsOther) { DB::query(' UPDATE "PickUpOrDeliveryModifierOptions" SET "IsDefault" = 1 WHERE "ID" <> ' . $this->ID . ';'); } elseif ($this->IsDefault) { //current default -> reset others DB::query(' UPDATE "PickUpOrDeliveryModifierOptions" SET "IsDefault" = 0 WHERE "ID" <> ' . (int) $this->ID . ';'); } } /** * make sure all are unique codes. */ protected function onBeforeWrite() { parent::onBeforeWrite(); $this->Code = trim(preg_replace('#[^a-zA-Z0-9]+#', '', $this->Code)); $i = 0; if (! $this->Code) { $defaults = $this->Config()->get('Code'); $this->Code = empty($defaults['Code']) ? 'CODE' : $defaults['Code']; } $baseCode = $this->Code; $exists = PickUpOrDeliveryModifierOptions::get() ->filter(['Code' => $this->Code]) ->exclude(['ID' => $this->ID]) ->exists() ; while ($exists && $i < 100) { ++$i; $this->Code = $baseCode . '_' . $i; $exists = PickUpOrDeliveryModifierOptions::get() ->filter(['Code' => $this->Code]) ->exclude(['ID' => $this->ID]) ->exists() ; } if ($this->MinimumDeliveryCharge && $this->MaximumDeliveryCharge) { if ($this->MinimumDeliveryCharge > $this->MaximumDeliveryCharge) { $this->MinimumDeliveryCharge = $this->MaximumDeliveryCharge; } } } private function createGridField($title = '', $dataObjectName = EcommerceCountry::class, $fieldName = 'AvailableInCountries') { $field = null; $dos = $dataObjectName::get(); if ($dos->exists()) { if (class_exists(ListboxField::class)) { $array = $dos->map('ID', 'Title')->toArray(); //$name, $title = "", $source = array(), $value = "", $form = null $field = new ListboxField( $fieldName, 'This option is available in... ', $array ); } else { // $controller, $name, $sourceClass, [ $fieldList = null], [ $detailFormFields = null], [ $sourceFilter = ""], [ $sourceSort = ""], [ $sourceJoin = ""] /** * @todo: Auto completer may not be functioning correctly: ExactMatchFilter does not accept EcommerceCountryFilters_AllowSales as modifiers */ $gridFieldConfig = GridFieldConfig::create(); $gridFieldConfig->addComponent(new GridFieldButtonRow('before')); $gridFieldConfig->addComponent(new GridFieldAddExistingAutocompleter('buttons-before-left')); $gridFieldConfig->addComponent(new GridFieldToolbarHeader()); $gridFieldConfig->addComponent($sort = new GridFieldSortableHeader()); $gridFieldConfig->addComponent($filter = new GridFieldFilterHeader()); $gridFieldConfig->addComponent(new GridFieldDataColumns()); $gridFieldConfig->addComponent(new GridFieldEditButton()); $gridFieldConfig->addComponent(new GridFieldDeleteAction(true)); $gridFieldConfig->addComponent(new GridFieldPageCount('toolbar-header-right')); $gridFieldConfig->addComponent($pagination = new GridFieldPaginator()); $gridFieldConfig->addComponent(new GridFieldDetailForm()); $source = $this->{$fieldName}(); return new GridField($fieldName, _t('PickUpOrDeliverModifierOptions.AVAILABLEINCOUNTRIES', '' . $title), $source, $gridFieldConfig); } } if ($field) { return $field; } return new HiddenField($fieldName); } } |