protected function import_contract_price_items($contracts) { $start_time = time(); $soprice_item = rental_soprice_item::get_instance(); $socontract_price_item = rental_socontract_price_item::get_instance(); $socontract = rental_socontract::get_instance(); // Read priselementdetaljkontrakt list first so we can create our complete price items in the next loop // This is an array keyed by the main price item ID $detail_price_items = array(); $datalines = $this->getcsvdata($this->path . "/u_PrisElementDetaljKontrakt.csv"); $this->messages[] = "Read 'u_PrisElementDetaljKontrakt.csv' file in " . (time() - $start_time) . " seconds"; $this->messages[] = "'u_PrisElementDetaljKontrakt.csv' contained " . count($datalines) . " lines"; foreach ($datalines as $data) { //Felt fra 'PrisElementDetaljKontrakt' if (count($data) <= 10) { continue; } if (isset($detail_price_items[$data[1]])) { // Update existing detail only start date is later than existing start date detail if (!$this->is_null($data[4])) { $detail_date = strtotime($this->decode($data[4])); if ($detail_date > $detail_price_items[$data[1]]['date_start']) { $detail_price_items[$data[1]]['date_start'] = $detail_date; $detail_price_items[$data[1]]['amount'] = str_replace(',', '.', $data[3]); $detail_price_items[$data[1]]['price'] = str_replace(',', '.', $data[2]); } } } else { //Create a row in the array holding the details (price, amount, dates) for the price item $detail_price_items[$data[1]] = array('price' => str_replace(',', '.', $data[2]), 'amount' => str_replace(',', '.', $data[3]), 'date_start' => null, 'date_end' => null); if (!$this->is_null($data[4])) { $detail_price_items[$data[1]]['date_start'] = strtotime($this->decode($data[4])); } if (!$this->is_null($data[5])) { $detail_price_items[$data[1]]['date_end'] = strtotime($this->decode($data[5])); } } } $datalines = $this->getcsvdata($this->path . "/u_PrisElementKontrakt.csv"); $this->messages[] = "Read 'u_PrisElementKontrakt.csv' file in " . (time() - $start_time) . " seconds"; $this->messages[] = "'u_PrisElementKontrakt.csv' contained " . count($datalines) . " lines"; //Retrieve the title for the responsibility area we are importing (to hande the respoonsibility areas differently) $title = $socontract->get_responsibility_title($this->location_id); //If we are importing price items for 'Innleie', we have a default price item in the 'Prisbok' with agresso-id 'INNLEIE' if ($title == 'contract_type_innleie') { $admin_price_item = $soprice_item->get_single_with_id('INNLEIE'); } foreach ($datalines as $data) { if (count($data) <= 24) { continue; } /* If we are importing contract price items for external or internal: * - see if a pricebook element exist */ if ($title != 'contract_type_innleie') { // The Agresso-ID is unique for price items $id = $this->decode($data[12]); //cVarenr $admin_price_item = null; if (isset($id) && $id != '') { $admin_price_item = $soprice_item->get_single_with_id($id); } else { $admin_price_item = $soprice_item->get_single_with_id('UNKNOWN'); } } // Get the facilit price item id so that we can retrieve the price item details $facilit_id = $this->decode($data[0]); //nPrisElementId /* Create a new pricebook price item if one does not exist in the pricebook; store it if it has a new unique agresso-id. * Note: First price item with unique agresso-id determines title, area or "nr of items", and the price (from the price item details) */ if ($admin_price_item == null) { $admin_price_item = new rental_price_item(); $admin_price_item->set_title($this->decode($data[3])); //cPrisElementNavn $admin_price_item->set_agresso_id($id); //cVareNr // This assumes 1 for AREA, and anything else for count, even blanks $admin_price_item->set_is_area($this->decode($data[4]) == '1' ? true : false); //nMengdeTypeId // This assumes -1 for adjustable, and anything else for not adjustable, even blanks $admin_price_item->set_is_adjustable($this->decode($data[17]) == '-1' ? true : false); //bRegulerbar // Get the price for this price item $admin_price_item->set_price($detail_price_items[$facilit_id]['price']); $admin_price_item->set_responsibility_id($this->location_id); if (isset($id)) { $soprice_item->store($admin_price_item); $this->messages[] = "Stored price item ({$id}) with title " . $admin_price_item->get_title() . " in 'Prisbok'"; } } else { //check type on price item (not is_area and data[4]=1, or is_area and data[4] != 1) if ($admin_price_item->is_area() && $this->decode($data[4] != '1')) { $this->warnings[] = "Price item ({$admin_price_item->get_agresso_id()}) - " . $admin_price_item->get_title() . " - on contract {$contracts[$this->decode($data[1])]} is stored as area price item, but has record indicating it is not an area price item!"; } else { if (!$admin_price_item->is_area() && $this->decode($data[4] == '1')) { $this->warnings[] = "Price item ({$admin_price_item->get_agresso_id()}) - " . $admin_price_item->get_title() . " - on contract {$contracts[$this->decode($data[1])]} is stored as non-area price item, but has record indicating it is an area price item!"; } } } $contract_id = $contracts[$this->decode($data[1])]; //nKontraktId if ($contract_id) { // Create a new contract price item that we can tie to our contract $price_item = new rental_contract_price_item(); // Retrieve the contract $contract = $socontract->get_single($contract_id); // Set cLonnsArt for price item as contract reference $contract->set_reference($this->decode($data[13])); // The contract price item title should be the same as in the price book for internal if ($title == 'contract_type_internleie') { $price_item->set_title($admin_price_item->get_title()); } else { // ... and overridden by the price item for innleie and external $price_item->set_title($data[3]); } // Set the price book element's agresso-id and type (area/piece) $price_item->set_agresso_id($admin_price_item->get_agresso_id()); // If the price item is unknown do not use the 'is_area' from the price book if ($admin_price_item->get_agresso_id() != 'UNKNOWN') { $price_item->set_is_area($admin_price_item->is_area()); } else { $price_item->set_is_area($this->decode($data[4]) == '1' ? true : false); } // Get the price for the price item details $price_item->set_price($detail_price_items[$facilit_id]['price']); // Give a warning if a contract has a price element of type area with are like 1 if ($price_item->is_area() && $detail_price_items[$facilit_id]['amount'] == '1') { $this->warnings[] = "Contract " . $contract->get_old_contract_id() . " has a price item of type area with amount like 1"; } // Tie this price item to its parent admin price item $price_item->set_price_item_id($admin_price_item->get_id()); if ($admin_price_item->is_area()) { $rented_area = $contract->get_rented_area(); if (isset($rented_area)) { if ($detail_price_items[$facilit_id]['amount'] != $rented_area) { if ($rented_area == 0) { $contract->set_rented_area($detail_price_items[$facilit_id]['amount']); $this->warnings[] = "Price item {$id} - (Facilit ID {$facilit_id}) has area " . $detail_price_items[$facilit_id]['amount'] . " while contract {$contract_id} already has rented area set to 0. Using rented area from price item."; } else { $this->warnings[] = "Price item {$id} - (Facilit ID {$facilit_id}) has area " . $detail_price_items[$facilit_id]['amount'] . " while contract {$contract_id} already has rented area {$rented_area}. Using rented area on contract."; } } } else { //Store price item area on contract if the contract has no area (not from contract) $contract->set_rented_area($detail_price_items[$facilit_id]['amount']); $this->message[] = "Price item {$id} - (Facilit ID {$facilit_id}) has area " . $detail_price_items[$facilit_id]['amount'] . " while contract {$contract_id} already no area {$rented_area}. Using rented area on price item."; //Store the contract $socontract->store($contract); } // Set the the contract area on the price item $price_item->set_area($contract->get_rented_area()); //Calculate the total price for the price item $item_area = $price_item->get_area(); $item_price = $price_item->get_price(); $price_item->set_total_price($item_area * $item_price); } else { $price_item->set_count($detail_price_items[$facilit_id]['amount']); $item_count = $price_item->get_count(); $item_price = $price_item->get_price(); $price_item->set_total_price($item_count * $item_price); } $price_item->set_date_start($detail_price_items[$facilit_id]['date_start']); $price_item->set_date_end($detail_price_items[$facilit_id]['date_end']); // Tie the price item to the contract it belongs to $price_item->set_contract_id($contract_id); // Tie this price item to its parent admin price item $price_item->set_price_item_id($admin_price_item->get_id()); //update contract with adjustment share $adjustment_share = $this->decode($data[18]); //nReguleringsandel if ($adjustment_share != null && $adjustment_share > 0) { $socontract->update_adjustment_share($contract_id, $adjustment_share); } // .. and save if ($socontract_price_item->import($price_item)) { $this->messages[] = "Successfully imported price item ({$id}) for contract {$contract_id}"; } else { $this->warnings[] = "Could not store price item ({$id}) - " . $price_item->get_title(); } } else { $this->warnings[] = "Skipped price item with no contract attached: " . join(", ", $data); } } $this->messages[] = "Imported contract price items. (" . (time() - $start_time) . " seconds)"; return true; }
public function adjust_price() { if (!self::isExecutiveOfficer()) { $this->render('permission_denied.php'); return; } $id = (int) phpgw::get_var('price_item_id'); $new_price = phpgw::get_var('new_price'); $new_price = str_replace(',', '.', $new_price); if ($new_price != null && is_numeric($new_price)) { $price_item = rental_price_item::get($id); $price_item->set_price($new_price); if (rental_soprice_item::get_instance()->store($price_item)) { $adjustment = new rental_adjustment(); $adjustment->set_price_item_id($price_item->get_id()); $adjustment->set_new_price($new_price); $adjustment->set_year(date('Y')); $adjustment->set_percent(0); $adjustment->set_interval(0); $adjustment->set_responsibility_id($price_item->get_responsibility_id()); $adjustment->set_is_manual(true); $adjustment->set_adjustment_date(time()); rental_soadjustment::get_instance()->store($adjustment); $message[] = "Priselement med Agresso id {$price_item->get_agresso_id()} er oppdatert med ny pris {$new_price}"; //update affected contract_price_items $no_of_contracts_updated = rental_soprice_item::get_instance()->adjust_contract_price_items($id, $new_price); if ($no_of_contracts_updated > 0) { $message[] = $no_of_contracts_updated . ' priselementer på kontrakter er oppdatert'; } else { $message[] = "Ingen kontrakter er oppdatert"; } $data = array('price_item_id' => $id, 'message' => $message); self::set_active_menu('rental::contracts::price_item_list::manual_adjustment'); $this->render('admin_price_item_manual_adjustment.php', $data); } else { $data = array('price_item_id' => $id, 'error' => $error); self::set_active_menu('rental::contracts::price_item_list::manual_adjustment'); $this->render('admin_price_item_manual_adjustment.php', $data); } } else { $data = array('price_item_id' => $id, 'error' => lang('price_not_numeric')); self::set_active_menu('rental::contracts::price_item_list::manual_adjustment'); $this->render('admin_price_item_manual_adjustment.php', $data); } }
/** * Get a static reference to the storage object associated with this model object * * @return the storage object */ public static function get_so() { if (self::$so == null) { self::$so = CreateObject('rental.soprice_item'); } return self::$so; }
protected function populate(int $price_item_id, &$price_item) { if ($price_item == null) { $price_item = new rental_price_item($this->unmarshal($this->db->f('id'), 'int')); $price_item->set_title($this->unmarshal($this->db->f('title'), 'string')); $price_item->set_agresso_id($this->unmarshal($this->db->f('agresso_id'), 'string')); $price_item->set_is_area($this->unmarshal($this->db->f('is_area'), 'bool')); $price_item->set_is_inactive($this->unmarshal($this->db->f('is_inactive'), 'bool')); $price_item->set_is_adjustable($this->unmarshal($this->db->f('is_adjustable'), 'bool')); $price_item->set_standard($this->unmarshal($this->db->f('standard'), 'bool')); $price_item->set_price($this->unmarshal($this->db->f('price'), 'float')); $price_item->set_responsibility_id($this->unmarshal($this->db->f('responsibility_id', true), 'int')); $price_item->set_responsibility_title($this->unmarshal($this->db->f('resp_title', true), 'string')); $price_type_id = (int) $this->db->f('type'); $price_item->set_price_type_id($price_type_id); $price_item->set_price_type_title($price_type_id); } return $price_item; }
public function adjust_contracts($adjustments) { /* * gather all adjustable contracts with * interval = adjustment interval and this year = last adjusted + interval * or * last adjusted is null / 0 (use contract start year) * adjust each contract's price items according to adjustment info (percent, adjustment_percent) * Run as transaction * update adjustment -> set is_executed to true * update price book elements according to type if interval=1 */ $current_year = (int) date('Y'); //var_dump("innicontr"); foreach ($adjustments as $adjustment) { //gather all adjustable contracts $adjustable_contracts = "SELECT id, adjustment_share, date_start, adjustment_year FROM rental_contract "; $adjustable_contracts .= "WHERE location_id = '{$adjustment->get_responsibility_id()}' AND adjustable "; $adjustable_contracts .= "AND adjustment_interval = {$adjustment->get_interval()} "; $adjustable_contracts .= "AND (((adjustment_year + {$adjustment->get_interval()}) <= {$adjustment->get_year()})"; $adjustable_contracts .= " OR "; $adjustable_contracts .= "("; if ($adjustment->is_extra_adjustment()) { $adjustable_contracts .= "adjustment_year = {$adjustment->get_year()}"; $adjustable_contracts .= " OR "; } $adjustable_contracts .= "(adjustment_year IS NULL OR adjustment_year = 0)"; $adjustable_contracts .= "))"; //var_dump($adjustable_contracts); //die(); $result = $this->db->query($adjustable_contracts); while ($this->db->next_record()) { $contract_id = $this->unmarshal($this->db->f('id', true), 'int'); $adjustment_share = $this->unmarshal($this->db->f('adjustment_share', true), 'int'); $date_start = $this->unmarshal($this->db->f('date_start', true), 'int'); $adj_year = $this->unmarshal($this->db->f('adjustment_year', true), 'int'); $start_year = date('Y', $date_start); $contract = rental_socontract::get_instance()->get_single($contract_id); $firstJanAdjYear = mktime(0, 0, 0, 1, 1, $adjustment->get_year()); if ($contract->is_active($firstJanAdjYear) && ($adj_year != null && $adj_year > 0 || ($adj_year == null || $adj_year == 0) && $start_year + $adjustment->get_interval() <= $adjustment->get_year())) { //update adjustment_year on contract rental_socontract::get_instance()->update_adjustment_year($contract_id, $adjustment->get_year()); //gather price items to be adjusted $contract_price_items = rental_socontract_price_item::get_instance()->get(null, null, null, null, null, null, array('contract_id' => $contract_id)); foreach ($contract_price_items as $cpi) { //update price according to adjustment info $cpi_old_price = $cpi->get_price(); $cpi_adjustment = $cpi_old_price * ($adjustment->get_percent() / 100) * ($adjustment_share / 100); $cpi_new_price = $cpi_old_price + $cpi_adjustment; $cpi->set_price($cpi_new_price); rental_socontract_price_item::get_instance()->store($cpi); } } } //TODO: update price book if ($adjustment->get_interval() == 1) { $adjustable_price_items = "SELECT * FROM rental_price_item WHERE responsibility_id = {$adjustment->get_responsibility_id()} AND is_adjustable"; $result = $this->db->query($adjustable_price_items); $price_items = array(); while ($this->db->next_record()) { $price_item = new rental_price_item($this->unmarshal($this->db->f('id'), 'int')); $price_item->set_title($this->unmarshal($this->db->f('title'), 'string')); $price_item->set_agresso_id($this->unmarshal($this->db->f('agresso_id'), 'string')); $price_item->set_is_area($this->unmarshal($this->db->f('is_area'), 'bool')); $price_item->set_is_inactive($this->unmarshal($this->db->f('is_inactive'), 'bool')); $price_item->set_is_adjustable($this->unmarshal($this->db->f('is_adjustable'), 'bool')); $price_item->set_price($this->unmarshal($this->db->f('price'), 'float')); $price_item->set_responsibility_id($this->unmarshal($this->db->f('responsibility_id', true), 'int')); $price_item->set_responsibility_title($this->unmarshal($this->db->f('resp_title', true), 'string')); $price_items[] = $price_item; } foreach ($price_items as $pi) { $pi_old_price = $pi->get_price(); $pi_adjustment = $pi_old_price * ($adjustment->get_percent() / 100); $pi_new_price = $pi_old_price + $pi_adjustment; $pi->set_price($pi_new_price); rental_soprice_item::get_instance()->store($pi); } } $adjustment->set_is_executed(true); $this->update($adjustment); //notify all users with write access on the field of responsibility $location_id = $adjustment->get_responsibility_id(); if ($location_id) { $location_names = $GLOBALS['phpgw']->locations->get_name($location_id); if ($location_names['appname'] == $GLOBALS['phpgw_info']['flags']['currentapp']) { $responsible_accounts = $GLOBALS['phpgw']->acl->get_user_list_right(PHPGW_ACL_EDIT, $location_names['location']); foreach ($responsible_accounts as $ra) { $account_ids[] = $ra['account_id']; } } } $location_label = rental_socontract::get_instance()->get_responsibility_title($location_id); $adj_interval = $adjustment->get_interval(); $day = date("Y-m-d", strtotime('now')); $ts_today = strtotime($day); //notify each unique account foreach ($account_ids as $account_id) { if ($account_id && $account_id > 0) { $notification = new rental_notification(0, $account_id, 0, null, $ts_today, $location_label . '_' . $adj_interval, null, null, null, null); rental_soworkbench_notification::get_instance()->store($notification); } } } return true; }