예제 #1
0
    def add_vessel_ret(self, haul_id, vessel_ret):
        """
        Add a vessel retained ListElement to our model and save to DB
        @param haul_id: Haul DB Id (Fishing Activity)
        @param vessel_ret: ListElement QJSValue
        @return:
        """
        if isinstance(vessel_ret,
                      QJSValue):  # convert QJSValue to QVariant (then to dict)
            vessel_ret = vessel_ret.toVariant()
        found_cc_code = CatchCategories.get(
            CatchCategories.catch_category_code == vessel_ret['cc_code'])

        catch_num = ObserverCatches.get_next_catch_num_for_this_haul(
            haul_id, self._logger)
        Catches.create(
            fishing_activity=haul_id,
            catch_category=found_cc_code.catch_category,
            catch_weight=vessel_ret['weight'],
            catch_weight_method='7',
            catch_purity=None,
            catch_weight_um='LB',
            catch_disposition='R',
            catch_num=catch_num,
            created_by=ObserverDBUtil.get_current_user_id(),
            created_date=ObserverDBUtil.get_arrow_datestr(),
        )
        self.appendItem(vessel_ret)
예제 #2
0
    def currentSetId(self, current_id):
        """
        Assigned in SetsScreen.  Also sets current_haulset_id with dbid here
        :param current_id: set number (not DB ID)
        :return: None
        """
        self._logger.debug('Set currentSet using ID {}'.format(current_id))
        try:
            self._current_set = FishingActivities.get(
                FishingActivities.trip == self._trip_id,
                FishingActivities.fishing_activity_num == current_id)
            ObserverDBUtil.db_save_setting('current_haulset_id',
                                           self._current_set.fishing_activity)
            self._logger.debug(
                f"Setting current_haulset_id to {self._current_set.fishing_activity}"
            )
            self._internal_set_idx = self._sets_model.get_item_index(
                'fishing_activity_num', self._current_set.fishing_activity_num)
            self._fishing_locations.load_fishing_locations(
                fishing_activity_id=self._current_set.fishing_activity)
            if self._current_set.biolist_localonly is None:
                self._current_set.biolist_localonly = self._default_biolist_num
                self._save_notes_biolist_num()
        except FishingActivities.DoesNotExist:
            self._logger.info("Can't get set ID for trip {}, num {}".format(
                self._trip_id, current_id))
            self._current_set = None
            return

        self.modelChanged.emit()
    def _add_species_basket(self, weight, count):
        """
        Add species comp item to DB and model
        Check for 0-weight basket
        @param weight: lbs
        @param count: fish num
        """
        self._logger.debug('Add species basket. wt: {}, ct: {}'.format(
            weight, count))
        if self._current_species_comp_item is None:
            self._logger.error('Species ID / Current Species Comp ID is None')
            return

        try:

            new_basket = SpeciesCompositionBaskets.create(
                species_comp_item=self._current_species_comp_item,
                basket_weight_itq=weight,
                fish_number_itq=count,
                created_by=ObserverDBUtil.get_current_user_id(),
                created_date=ObserverDBUtil.get_arrow_datestr(
                    date_format=ObserverDBUtil.oracle_date_format),
                is_fg_tally_local=1 if self._is_fixed_gear else None)
            self._baskets_model.add_basket(new_basket)
            self._logger.info(f'Added basket wt: {weight} ct: {count}')

        finally:
            self._calculate_totals()
            self.basketAdded.emit()
예제 #4
0
    def create_trip(self, vessel_id, observer_id, program_id):
        """
        Create a new trip in the DB
        @param vessel_id: ID of vessel
        @param observer_id: ID of user
        @param program_id: ID of program
        @return: new trip cursor (peewee)
        """
        try:
            is_fixed_gear = ObserverTrip.get_fg_value()
            newtrip = Trips.create(
                user=observer_id,
                vessel=vessel_id,
                program=program_id,
                partial_trip='F',
                trip_status='FALSE',
                created_by=observer_id,
                created_date=ObserverDBUtil.get_arrow_datestr(),
                is_fg_trip_local=is_fixed_gear,
                data_source=ObserverDBUtil.get_data_source()  # FIELD-2099: setting data source initially
            )

            self.add_trip(newtrip)
            return newtrip
        except Exception as e:
            self._logger.error(e)
            return None
예제 #5
0
    def _calculate_subsample_count(self):
        """
        FIELD-1471: get rounded avg weight of fish in same day as haul (using created_date of current haul)
        :return: sets float val _todays_avg_weight (exposed as todaysAvgWeight property)
        """
        trip_id = ObserverDBUtil.get_current_trip_id()
        species_list = self._observer_species.get_related_species(
            self._observer_species.currentSpeciesItemSpeciesID)
        haulset_date = ObserverDBUtil.get_current_haulset_createddate()

        if not haulset_date or not species_list or not trip_id:
            self.logger.error(
                f"haulset_date/species/trip list not retrieved, can't calculate subsample count"
            )

        self._logger.info(
            f"Daily subsample count calc'd, species {species_list} day {haulset_date[:10]} trip {trip_id}"
        )

        self.subsampleCount = Trips.select(
            fn.sum(SpeciesCompositionBaskets.fish_number_itq)
        ).join(FishingActivities).join(
            Catches,
            on=FishingActivities.fishing_activity == Catches.fishing_activity
        ).join(SpeciesCompositions).join(SpeciesCompositionItems).join(
            SpeciesCompositionBaskets).join(
                Species,
                on=SpeciesCompositionItems.species ==
                Species.species  # no rel_model in model def...
            ).where((Trips.trip == trip_id)
                    & (Species.species.in_(species_list))
                    & (fn.substr(SpeciesCompositionBaskets.created_date, 1, 10)
                       == fn.substr(haulset_date, 1, 10))
                    & (SpeciesCompositionBaskets.is_subsample == 1)).scalar()
    def delete_trip(self, trip_id):
        """
        Deletes a trip if empty
        @param trip_id: DBID
        @return: True if trip deleted, false otherwise
        """
        # double check empty
        if not self.check_trip_empty(trip_id):
            return False
        self._logger.info('Deleting empty trip {}'.format(trip_id))

        # Delete from DB
        trip = Trips.get(Trips.trip == trip_id)
        ObserverDBUtil.log_peewee_model_instance(self._logger, trip,
                                                 'Deleting trip')
        trip.delete_instance(recursive=True)

        # Delete from model
        model_idx = self._trips_model.get_item_index('trip', trip_id)
        if model_idx >= 0:
            self._trips_model.remove(model_idx)
        else:
            self._logger.error(
                'Unable to find and remove trip {} from model.'.format(
                    trip_id))
        return True
예제 #7
0
    def delete_haul(self, haul_id):
        if haul_id is None or not self.check_haul_empty(haul_id):
            return

        trip_id = self._trip_id
        self._current_haul = None  # FIELD-1817 always clear current haul ID if deleting

        # Delete from DB
        haul = FishingActivities.get(
            FishingActivities.fishing_activity == haul_id)
        ObserverDBUtil.log_peewee_model_instance(self._logger, haul,
                                                 'Deleting haul')
        haul.delete_instance(recursive=True)

        # Delete from model
        result = self._hauls_model.remove_haul_set(haul_id)

        # Check for hauls with greater fishing_activity_num # than this one, and if found, decrement them.
        renumber_hauls = FishingActivities.select().where(
            (FishingActivities.fishing_activity > haul_id)
            & (FishingActivities.trip == trip_id))
        for h in renumber_hauls:
            old_num = h.fishing_activity_num
            h.fishing_activity_num -= 1
            h.save()
            fishing_number_row = self._hauls_model.get_haul_set_index(
                h.fishing_activity)
            self._logger.info(
                f'Renumbered FISHING_ACTIVITY_NUM {old_num} to {h.fishing_activity_num} for haul {h.fishing_activity}'
            )
            self._hauls_model.setProperty(fishing_number_row,
                                          'fishing_activity_num',
                                          h.fishing_activity_num)

        return result
예제 #8
0
    def currentHaulId(self, current_id):
        """
        Assigned in HaulsScreen.  Also sets current_haulset_id with dbid here
        :param current_id: haul number (not DB ID)
        :return: None
        """
        self._logger.debug('Set currentHaul using ID {}'.format(current_id))
        try:
            self._current_haul = FishingActivities.get(
                FishingActivities.trip == self._trip_id,
                FishingActivities.fishing_activity_num == current_id)
            # FIELD-1471: setting db id for downstream use in baskets
            ObserverDBUtil.db_save_setting('current_haulset_id',
                                           self._current_haul.fishing_activity)
            self._logger.debug(
                f"Setting current_haulset_id to {self._current_haul.fishing_activity}"
            )
            self._internal_haul_idx = self._hauls_model.get_item_index(
                'fishing_activity_num',
                self._current_haul.fishing_activity_num)
            self._fishing_locations.load_fishing_locations(
                fishing_activity_id=self._current_haul.fishing_activity)
        except FishingActivities.DoesNotExist:
            self._logger.info("Can't get haul ID for trip {}, num {}".format(
                self._trip_id, current_id))
            self._current_haul = None
            return

        self.modelChanged.emit()
    def update_comments(self):
        if not self.currentTripId or not self.currentObserver:
            # self._logger.info(f'No trip, skip saving comments: {self.currentTripId}')
            return

        trip_id = int(self.currentTripId)
        self._logger.info(f'Updating comments for TRIP ID {trip_id}')
        self._comments_all = ''
        self._comments_trip = ''
        self._comments_haul = dict()  # { haul_id: "comment" }
        self._db_formatted_comments_trip = ''
        self._db_formatted_comments_haul = dict()
        comments_q = Comment.select().where(Comment.trip == trip_id).order_by(Comment.comment_id)
        if not comments_q.count():
            self._logger.debug(f'No comments found for trip: {trip_id}')
            return
        for comment in comments_q:
            # Removed starting dash comment delimiter to adhere to IFQ TRIP_CHECK convention that
            # notes start with an alphanumeric. But continuing to use trailing dash separator.
            new_comment_string = f'{comment.username} ({comment.appstateinfo}) ' \
                                  f'{comment.comment_date} ---\n{comment.comment}\n\n'
            self._comments_all += new_comment_string

            try:
                # Only want first half of appstateinfo, that variable now also holds the page title text
                if comment.fishing_activity is None or comment.appstateinfo.split("::")[0] in self.trip_comment_states:
                    self._comments_trip += new_comment_string

                    self._db_formatted_comments_trip += self._db_format_one_comment(comment)
                else:
                    haul_id = comment.fishing_activity.fishing_activity
                    if haul_id not in self._comments_haul.keys():
                        self._comments_haul[haul_id] = new_comment_string
                        self._db_formatted_comments_haul[haul_id] = self._db_format_one_comment(comment)
                    else:  # append
                        self._comments_haul[haul_id] += new_comment_string
                        self._db_formatted_comments_haul[haul_id] += self._db_format_one_comment(comment)
            except Exception as e:  # Handle load of bad previous comment weirdness
                self._logger.error(e)

        # now save to NOTES for Trip
        try:
            trip_q = Trips.get(Trips.trip == trip_id)
            trip_q.notes = ObserverDBUtil.escape_linefeeds(self._db_formatted_comments_trip)
            trip_q.save()
            self._logger.info(f"Wrote {len(trip_q.notes)} characters to Trips.notes.")
            for haul_id in self._comments_haul.keys():
                haul_q = FishingActivities.get((FishingActivities.trip == trip_id) &
                                               (FishingActivities.fishing_activity == haul_id))
                haul_q.notes = ObserverDBUtil.escape_linefeeds(self._db_formatted_comments_haul[haul_id])
                haul_q.save()
                self._logger.info(f"Wrote {len(haul_q.notes)} characters to FishingActivities.notes.")

        except Trips.DoesNotExist as e:
            self._logger.warning(f'Cannot save comment, {e}')
        except FishingActivities.DoesNotExist as e:
            self._logger.warning(f'Cannot save comment, {e}')

        self.commentsChanged.emit(self._comments_trip)
    def tripId(self, value):
        # select matching trip ID and set current trip id PK
        # does NOT change trip number in the DB
        if value is None or value == '':
            self.clear_trip_id()
            return
        try:
            current_user_id = ObserverDBUtil.get_current_user_id()
            trip_q = Trips.get((int(value) == Trips.trip)
                               & (Trips.user == current_user_id))
            self._current_trip = trip_q
            self._current_trip_model_idx = self._trips_model.get_item_index(
                'trip', int(value))
            self._logger.info('Selected trip #{}'.format(
                self._current_trip.trip))
            self.tripIdChanged.emit(str(value))
            ObserverDBUtil.db_save_setting('trip_number',
                                           self._current_trip.trip)
            ObserverDBUtil.set_current_fishery_id(self._current_trip.fishery)
            if self._current_trip.vessel is not None:
                self.currentVesselNameChanged.emit(
                    self._current_trip.vessel.vessel_name)
                self.tripsChanged.emit()

            # Load corresponding tickets
            self._tickets_model.clear()
            tickets_query = FishTickets.select().where(
                FishTickets.trip == trip_q.trip)
            ntickets = tickets_query.count()
            if ntickets > 0:
                for ticket in tickets_query:
                    self._tickets_model.add_ticket(ticket)

            # Load corresponding trip certificates
            self._certs_model.clear()
            certs_query = TripCertificates.select().where(
                TripCertificates.trip == trip_q.trip)
            ncerts = certs_query.count()
            if ncerts > 0:
                for cert in certs_query:
                    self._certs_model.add_cert(cert)

        except ValueError as e:
            self._logger.error('Error with Trip ID specified: {}, {}'.format(
                value, e))
            self.clear_trip_id()
        except Trips.DoesNotExist as e:
            self._logger.error(
                'Trip ID does not exist for this user: {}, {}'.format(
                    value, e))
            self.clear_trip_id()
        except Vessels.DoesNotExist as e:
            self._logger.error(f'Vessel ID not set... {e}')
            self.clear_trip_id()
 def currentFisheryName(self, fishery_name):
     """
     :param fishery_name: fishery name str
     """
     if self._current_trip is not None:
         fishery_id = self._get_fishery_ID(fishery_name)
         self._current_trip.fishery = fishery_id
         self._current_trip.save()
         self._set_cur_prop('fishery', fishery_name)
         ObserverDBUtil.set_current_fishery_id(fishery_id)
         self.tripDataChanged.emit()
예제 #12
0
 def addTripCert(self, cert_num):
     """
     Add Trip Certificate (Permit / License #)
     @param cert_num: trip or license number
     """
     # TODO certification_id?
     if self._current_trip is not None:
         user_id = ObserverDBUtil.get_current_user_id()
         created_date = ObserverDBUtil.get_arrow_datestr()
         cert = TripCertificates.create(certificate_number=cert_num, trip=self._current_trip.trip,
                                        created_by=user_id, created_date=created_date)
         self._certs_model.add_cert(cert)
예제 #13
0
 def currentCollectionMethod(self, method):
     """
     FIELD-2123: Setter emits when val changed for updating back to UI
     :param method: str, DirectEntry, DirectFormHybrid, FormsOnly
     :return:
     """
     if self._current_collection_method != method:
         self._current_collection_method = method
         self.collectionMethodChanged.emit(method)
         if not method:
             ObserverDBUtil.clear_setting('current_collection_method')
         else:
             ObserverDBUtil.db_save_setting('current_collection_method', method)
예제 #14
0
    def _create_biolist_comment(self):
        """
        Replaces _save_notes_biolist_num func
        Adds biolist string to comment table instead of saving directly to fishing_activity.notes.
        Comment record is picked up for comment parsing later (FIELD-2071)
        :return: None
        """
        if not self._current_haul:
            self._logger.error(
                'Tried to save biolist num, but current haul not set.')
            return
        BIOLIST_NOTE_PREFIX = 'Biolist #'
        APPSTATE = f"haul_details_state::Haul {self.currentHaulId} Details"  # could make a param, but shouldn't change

        # check if biolist comment already exists
        existing_comments = Comment.select().where(
            (Comment.trip == self._current_haul.trip)
            & (Comment.fishing_activity == self._current_haul.fishing_activity)
            &
            (fn.Lower(Comment.comment).contains(BIOLIST_NOTE_PREFIX.lower())))

        if not existing_comments:
            Comment.create(
                username=ObserverDBUtil.get_setting('current_user'),
                comment_date=ObserverDBUtil.get_arrow_datestr(),
                comment=f"{BIOLIST_NOTE_PREFIX}{self.currentBiolistNum}",
                appstateinfo=APPSTATE,
                trip=self._current_haul.trip,
                fishing_activity=self._current_haul.fishing_activity)
            self._logger.debug(
                f"{BIOLIST_NOTE_PREFIX}{self.currentBiolistNum} comment created."
            )
        else:  # not sure if this will ever get used for trawl, but will update if necessary
            query = Comment.update(
                username=ObserverDBUtil.get_setting('current_user'),
                comment_date=ObserverDBUtil.get_arrow_datestr(),
                comment=f"{BIOLIST_NOTE_PREFIX}{self.currentBiolistNum}",
                appstateinfo=APPSTATE,
            ).where((Comment.fishing_activity ==
                     self._current_haul.fishing_activity)
                    & (Comment.trip == self._current_haul.trip)
                    & (Comment.comment.regexp('^' + BIOLIST_NOTE_PREFIX +
                                              '\d+$')
                       )  # starts with Biolist #, ends with nums
                    )
            query.execute()
            self._logger.debug(
                f"{BIOLIST_NOTE_PREFIX}{self.currentBiolistNum} comment updated."
            )
예제 #15
0
    def addFishTicket(self):
        if self.fishTicketNum is None or self.fishTicketDate is None or self.fishTicketState is None:
            return

        user_id = ObserverDBUtil.get_current_user_id()
        created_date = ObserverDBUtil.get_arrow_datestr()
        fish_ticket_number = FishTickets.create(fish_ticket_number=self.fishTicketNum,
                                                fish_ticket_date=self.fishTicketDate,
                                                state_agency=self.fishTicketState,
                                                trip=self._current_trip.trip,
                                                created_by=user_id,
                                                created_date=created_date)
        self._tickets_model.add_ticket(fish_ticket_number)
        self.fishTicketDate = None
        self.fishTicketNum = None
예제 #16
0
    def you_are_up(self):
        """
        Called by ObserverSM.qml when context switches to Hauls screen.
        Used to pull counts of haul-level issues from the current trip's last Trip Error Report, if any.
        :return: None
        """
        self._logger.info(f"Screen is active. Current TripID={self._trip_id}.")
        self._logger.info(
            f"Count of hauls (from HaulsModel)={self._hauls_model.count}.")
        current_user_id = ObserverDBUtil.get_current_user_id()

        # If a Trip Error Report has been run for this trip, get the latest run's haul-level error counts, per-haul.
        trip_issues, run_date = TripChecksOptecsManager.get_issues_from_last_ter_run(
            self._trip_id, self._logger)
        if not trip_issues:
            for row in range(self._hauls_model.count):
                self._hauls_model.setProperty(row, "errors", "N/A")
            self._logger.debug(
                "No Trip Error Report has been run for this trip yet. Haul-level error counts to N/A."
            )
        else:
            haul_error_counts = self._calculate_per_haul_errors(trip_issues)

            view_model_rows = self._hauls_model.items
            # Update view model with haul-level errors, on a haul-by-haul basis
            for row_idx in range(self._hauls_model.count):
                view_model_row = view_model_rows[row_idx]
                haul_num = int(view_model_row["fishing_activity_num"])
                errors_this_haul = haul_error_counts[haul_num] \
                    if haul_num in haul_error_counts else 0
                self._hauls_model.setProperty(row_idx, "errors",
                                              str(errors_this_haul))
            self._logger.debug(
                f"Updated view model with Trip Error Report with run date {run_date}."
            )
예제 #17
0
 def update_drive_letters(self):
     """
     Send new drive letters signal
     @return:
     """
     self.driveLettersChanged.emit(
         ObserverDBUtil.get_external_drive_letters())
예제 #18
0
    def upsert_comment(self, comment_prefix, comment, appstate):
        """
        Use for comment update/insert oustide of Comment dialog box.
        Find comment with prefix, if exists, replace, else insert
        :param comment_prefix: str, e.g. CollectionMethod=
        :param comment: str, e.g. string after prefix
        :param appstate: str, e.g. state of app + title of current screen
        :return: None
        """
        new_comment_date = ObserverDBUtil.get_arrow_datestr()
        new_comment = f"{comment_prefix}{comment}"

        # try to get comment model and update
        try:
            c = Comment.get(Comment.comment.contains(comment_prefix),
                            Comment.trip == self.currentTripId)
            Comment.update(comment=new_comment,
                           comment_date=new_comment_date,
                           username=self.currentObserver).where(
                               Comment.comment_id == c.comment_id).execute()

        except ValueError:  # trip id is not defined yet
            return

        # if existing comment not found, create a new one
        except Comment.DoesNotExist:
            Comment.create(comment=new_comment,
                           comment_date=new_comment_date,
                           username=self.currentObserver,
                           trip=self.currentTripId,
                           appstateinfo=appstate)

        # parse comments to trips/fishing_activities
        self.update_comments()
 def isTestMode(self):
     """
     if DB is pointing at IFQADMIN or IFQDEV, True else False (production!)
     @return: True if Test mode
     """
     mode = ObserverDBUtil.get_setting('optecs_mode')
     return False if mode == 'ifq' else True
예제 #20
0
    def update_programs_for_user(self, username):
        """
        Sets the AvailablePrograms model appropriately
        @param username: username to look up
        """
        user_id = self.get_user_id(username)
        self._current_user_info[
            'userid'] = user_id  # this will be set again at login
        if user_id:
            self._logger.debug(
                'Retrieving programs and roles for user {}'.format(
                    username[:3] + '****'))
            programs = self._get_user_program_names(user_id)
            roles = self._get_user_roles(user_id)
            self._current_user_programs.setStringList(programs)
            self._current_user_roles = roles
            current_progname = ObserverDBUtil.get_current_program_name()
            if current_progname in programs:
                self.currentProgramName = current_progname
            elif programs:  # set default program for user
                self.currentProgramName = programs[0]
            else:
                self.currentProgramName = None

        self.program_model_changed.emit()
        self.currentUserPwExpiresChanged.emit()
        self.current_user_is_debriefer_changed.emit()
 def _resequence_orm_location_positions(locations: List[FishingLocations]) -> List[FishingLocations]:
     """
     Given a list of peewee ORM FishingLocations, return a list sorted by arrow time,
     assigning position number from -1 to N-2:
     Conventions:
     - Earliest location, aka "Set" is assigned POSITION = -1
     - Latest location (in N > 1), aka "Up" is assigned POSITION 0
     - If additions locations, assign position from 0 to N-2, in ascending datetime order.
     - In case of exactly same datetime, use FISHING_LOCATION_ID as minor sort key.
     :param locations: List of Peewee ORM fishing locations with POSITION values possibly out of sequence due to a
         location being added or deleted.
     :return: List of fishing locations with POSITION set by datetime order given above.
         Note: neither SQLite FISHING_LOCATIONS table nor FishingLocationModel's model have been updated.
     """
     slocations = sorted(locations, key=lambda loc: " ".join([
         ObserverDBUtil.str_to_datetime(loc.location_date).format('MM/DD/YYYY HH:mm'),#'YMMDDHHmm'),
         str.format("{0:0>5}", loc.fishing_location)]))
     # Earliest
     if len(slocations) > 0:
         slocations[0].position = -1
     # Last
     if len(slocations) > 1:
         slocations[-1].position = 0
     # In-between
     if len(slocations) > 2:
         for i in range(1, len(slocations) - 1):
             slocations[i].position = i
     return slocations
예제 #22
0
    def __init__(self, db):
        super().__init__()
        self._logger = logging.getLogger(__name__)
        self._data = db
        self._hauls_model = HaulSetModel()
        self._current_haul = None
        self._internal_haul_idx = None  # FramListModel index
        self._hauls_count = 0
        self._trip_id = None
        self._fishing_locations = ObserverFishingLocations()

        self._beaufort = db.beaufort
        self._gearperf = db.gearperf

        self._obs_ret_models = dict()
        self._obs_ret_max_count = 0
        self._vessel_ret_models = dict()
        self._vessel_ret_max_count = 0
        # Hauls fields that must be specified in UI (can't be left empty)
        self._required_field_names = (  # As known in peewee
            'observer_total_catch',  # Visual OTC
            'otc_weight_method',
            'brd_present',
            # No: 'fit',
            # No: 'cal_weight',  # Has 'No Scale' value if not-calibrated.
            'gear_type',
            'gear_performance',
            'beaufort_value',
        )
        self._thread_ter = None  # Runs TER in background

        random.seed()  # ensure device_random_seed is randomly seeded
        self._device_random_seed = int(ObserverDBUtil.get_or_set_setting('biolist_rng_seed', random.randint(1, 10000)))
        self._trip_seed = 0
예제 #23
0
    def add_comment(self, comment, appstate):
        """
        Adds date, username, and comment to Comments
        :return:
        """
        if not self.currentTripId:
            self._logger.error(
                'No trip selected, comment NOT saved: {}'.format(comment))
            return
        self._logger.info(
            f'Adding comment "{comment}" to current trip {self.currentTripId}')
        # TODO Add to trips, not Comment
        if self.isFixedGear:
            haul_db_id = self.sets.currentSetDBId if self.sets else None
        else:
            haul_db_id = self.hauls.currentHaulDBId if self.hauls else None

        newcomment = Comment.create(
            username=self.currentObserver,
            comment_date=ObserverDBUtil.get_arrow_datestr(),
            appstateinfo=appstate,
            comment=comment,
            trip=self.currentTripId,
            fishing_activity=haul_db_id)
        newcomment.save()
        self.update_comments()
    def __init__(self, db):
        super().__init__()
        self._logger = logging.getLogger(__name__)

        self._data = db

        # The three alternative models for the lists of catch categories
        # Instantiate here and nowhere else: references are being used.
        # To reset, clear rather than re-instantiate.
        self._full_list_cc_model = CatchCategoryModel()
        self._frequent_list_cc_model = CatchCategoryModel()
        self._trip_list_cc_model = CatchCategoryModel()

        # The Full catch category is initialized from Observer.db table CATCH_CATEGORIES.
        # The Frequent catch category is initialized from a list stored in the SETTINGS table of Observer.db.
        # The TrawlFrequentCatchCategories instance gets from the db or uses a default.
        self._frequent_catch_category_codes = TrawlFrequentCatchCategories(
        ).catch_category_codes
        # The Trip catch category is initialized here.
        self._trip_list_catch_category_codes = list()

        self._filter_code = ''  # Filter by PACFIN code

        self._is_fixed_gear = ObserverDBUtil.is_fixed_gear()

        self.load_full_list()
        self.load_frequent_list()
        self.load_trip_list()

        # Default model associated with tvAvailableCC TableView: full
        self._active_cc_model = self._full_list_cc_model
        self._active_cc_model_type = "Full"
예제 #25
0
 def create_set(self, set_num):
     """
     @param set_num: ID local to this trip
     @return: haul db ID
     """
     self.load_sets(trip_id=self._trip_id)
     observer_id = ObserverDBUtil.get_current_user_id()
     newset = FishingActivities.create(
         trip=self._trip_id,
         fishing_activity_num=set_num,
         created_by=observer_id,
         created_date=ObserverDBUtil.get_arrow_datestr())
     logging.info('Created FishingActivities (set {}) for trip={}'.format(
         newset.fishing_activity_num, self._trip_id))
     self.SetsModel.add_set(newset)
     self.currentSetId = newset.fishing_activity_num
     return int(newset.fishing_activity)
예제 #26
0
    def add_update_location_haul_id(self, haul_id, position, date, latitude,
                                    longitude,
                                    depth):  # depth_um assumed to be "ftm"
        try:
            try:
                location_item = FishingLocations.get(
                    (FishingLocations.fishing_activity == haul_id)
                    & (FishingLocations.position == position))
                self._logger.debug(
                    'Fishing location haul ID={}, position={} found, updating.'
                    .format(haul_id, position))
                location_item.location_date = date
                location_item.latitude = latitude
                location_item.longitude = longitude
                location_item.depth = depth
                location_item.depth_um = 'FM'
                location_item.position = position
                location_item.save()  # Update the database
                # Update location positions in DB and the view model to handle possible shift in position.
                self._update_location_positions()

            except FishingLocations.DoesNotExist:
                self._logger.debug(
                    'Create fishing location haul ID={}, position={}'.format(
                        haul_id, position))
                user_id = ObserverDBUtil.get_current_user_id()
                location_item = FishingLocations.create(
                    fishing_activity=haul_id,
                    location_date=date,
                    latitude=latitude,
                    longitude=longitude,
                    depth=depth,
                    depth_um='FM',
                    position=position,
                    created_by=user_id,
                    created_date=ObserverDBUtil.get_arrow_datestr())
                self._logger.debug(
                    'Fishing location position {} created.'.format(
                        location_item.position))
                # New entry added, but position number sequence may be off, depending on datetime of new entry.
                # Update location positions in DB and the view model to handle possible insertion.
                self._update_location_positions()
        except Exception as e:
            self._logger.error(e)
        return location_item.fishing_location  ## Primary key index of location
    def _add_additional_basket(self, basket_weight, basket_type):
        """
        Utility for adding weighed and unweighed baskets to CATCH_ADDITIONAL_BASKETS
        for use in WM3 calculation of catch weight.
        
        :param basket_weight: 
        :param basket_type: digit as text.
        :return: 
        """
        if basket_type not in self._catch_additional_basket_types:
            raise Exception(f"Unrecognized catch additional basket type {basket_type}")

        if self._weight_method != '3':
            msg = f"Weight Method is '{self._weight_method}', not '3'; additional baskets not allowed."
            self._logger.error(msg)
            raise Exception(msg)

        # Consistency check: if basket type is unweighed, basket weight should be 0 or None
        if basket_type == ObserverCatchBaskets.LOOKUP_VALUE_CAB_BASKET_TYPE_UNWEIGHED_FULL and \
                basket_weight is not None and basket_weight != 0.0:
            msg = f"Basket type unweighed should have no or zero basket weight."
            self._logger.error(f"Basket type unweighed should have no or zero basket weight.")
            raise Exception(msg)

        basket_type_description = self._catch_additional_basket_types[basket_type]
        self._logger.debug(f'Add catch additional basket with wt={basket_weight} and '
                           f'type={basket_type_description}.')

        if basket_weight is None:
            basket_weight = 0.0
            self._logger.debug(f"Unweighted baskets will be given weight of 0.0")

        new_basket = None
        try:
            new_basket = CatchAdditionalBaskets.create(
                    catch=self._current_catch.catch,
                    basket_weight=float(basket_weight),
                    basket_type=basket_type,
                    created_by=ObserverDBUtil.get_current_user_id(),
                    created_date=ObserverDBUtil.get_arrow_datestr(date_format=ObserverDBUtil.oracle_date_format)
            )
        except Exception as e:
            self._logger.error(e)
        finally:
            return new_basket
 def currentEndDateTime(self, date_time):
     """
     :param date_time: end date ISO str
     """
     date_time = ObserverDBUtil.convert_jscript_datetime(date_time)
     self._current_trip.return_date = date_time
     self._current_trip.save()
     self._set_cur_prop('return_date', date_time)
     self.tripDataChanged.emit()
예제 #29
0
    def create_haul(self, haul_num):
        """
        @param haul_num: ID local to this trip
        @return: haul db ID
        """
        self.load_hauls(trip_id=self._trip_id)
        observer_id = ObserverDBUtil.get_current_user_id()
        newhaul = FishingActivities.create(trip=self._trip_id,
                                           fishing_activity_num=haul_num,
                                           created_by=observer_id,
                                           created_date=ObserverDBUtil.get_arrow_datestr())
        logging.info(
            'Created FishingActivities (haul {}) for trip={}'.format(newhaul.fishing_activity_num, newhaul.trip))

        self.HaulsModel.add_haul(newhaul)
        self.currentHaulId = newhaul.fishing_activity_num
        self._create_biolist_comment()
        return int(newhaul.fishing_activity)
 def currentStartDateTime(self, date_time):
     """
     :param date_time: start date ISO str
     """
     if self._current_trip is not None:
         date_time = ObserverDBUtil.convert_jscript_datetime(date_time)
         self._current_trip.departure_date = date_time
         self._current_trip.save()
         self._set_cur_prop('departure_date', date_time)
         self.tripDataChanged.emit()