def update_wm5_catch_weights(self):
        """
        Go to DB directly and find catches w. WM5.
        Update catch_weight with OTC-RET., then EMIT to signal QML
        func lives here so it can interact with both _hauls and _catches signals

        NOTE: catch_weight cant be negative in DB, so if negative set to null / None
        :return: None
        """
        if self.isFixedGear:  # wm5 doesn't exist w. FG
            return

        wm5_catches = Catches.select(Catches.catch, Catches.catch_num).where(
            (Catches.fishing_activity == self._hauls.currentHaulDBId) &
            (Catches.catch_weight_method == '5')
        ).execute()
        new_wt = self._hauls.getData('observer_total_catch') - self._hauls.retainedHaulWeight
        new_wt = new_wt if new_wt > 0 else None  # wt can't be negative in DB, set to None/Null
        for c in wm5_catches:  # there shouldn't be more than one, but just in case
            Catches.update(catch_weight=new_wt).where(
                (Catches.catch == c.catch)
            ).execute()

            logging.info(f"CatchNum {c.catch_num} (ID: {c.catch}) WM5 weight updated to {new_wt}")
            self.wm5WeightChanged.emit(c.catch, new_wt)  # tell CC QML page to update too
Exemplo n.º 2
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)
Exemplo n.º 3
0
    def load_observer_retained(self, fishing_activity_id, is_fixed_gear=False):
        """
        Load catches from database
        :return: list of catch codes (strings)
        """
        observer_retained_catches_query = Catches.select().where(
            (Catches.fishing_activity == fishing_activity_id)
            & (Catches.catch_disposition == 'R')
            & ~((Catches.catch_weight_method.is_null(False)) &
                (Catches.catch_weight_method == '7')))

        ret_catches = observer_retained_catches_query.count()

        catch_codes = list()
        self.clear()
        if ret_catches > 0:
            for c in observer_retained_catches_query:
                if is_fixed_gear:
                    self.appendItem({
                        'cc_code': c.catch_category.catch_category_code,
                        'weight': c.sample_weight
                    })
                else:
                    self.appendItem({
                        'cc_code': c.catch_category.catch_category_code,
                        'weight': c.catch_weight
                    })

        return catch_codes
Exemplo n.º 4
0
 def _calculate_retained_spp_avg(self, species_ids):
     """
     FIELD-1900: Used to auto-calc DR12/15 weights
     Separate function to store retained average calculation
     Take all retained baskets with counts and weights for species id param and get avg fish wt
     :param species_ids: int[], list of species_ids for a given species_complex
     :return: float
     """
     if self._current_set:
         faid = self._current_set.fishing_activity
         avg = Catches.select(
             (fn.sum(SpeciesCompositionBaskets.basket_weight_itq) /
              fn.sum(SpeciesCompositionBaskets.fish_number_itq))
         ).join(SpeciesCompositions).join(SpeciesCompositionItems).join(
             SpeciesCompositionBaskets
         ).where(
             (Catches.fishing_activity == faid) &  # haul
             (Catches.catch_disposition == 'R') &  # retained
             (SpeciesCompositionBaskets.basket_weight_itq.is_null(False))
             &  # baskets with actual weights
             (SpeciesCompositionBaskets.fish_number_itq.is_null(False))
             &  # baskets with actual counts
             (SpeciesCompositionItems.species.in_(species_ids)
              )  # species associated with CC
         ).scalar()
         # DO NOT ROUND HERE
         # avg = ObserverDBUtil.round_up(avg)  # round here, precision will propagate to downstream vals
         self._logger.info(
             f"Retained avg for set {faid}, species_ids {species_ids} = {avg}"
         )
         return avg
Exemplo n.º 5
0
    def _recalculate_catches_hooks_sampled(self, set_rec, avg_hook_count):
        catches_q = Catches.select().where(
            Catches.fishing_activity == set_rec.fishing_activity)

        for c in catches_q:
            if avg_hook_count and c.gear_segments_sampled:
                old_hooks = c.hooks_sampled
                new_hooks = round(avg_hook_count * c.gear_segments_sampled)
                self._logger.info(
                    f'Catch {c.catch} Hooks sampled {old_hooks} -> {new_hooks}'
                )
                c.hooks_sampled = new_hooks
                c.save()
    def _get_catch_models(self, fishing_activity_id):
        """
        Load catch table models for a given haul from DB.
        :param fishing_activity_id: haul ID
        :return: list of catch ORM models
        """
        if fishing_activity_id is None:
            self._logger.error('Activity ID none')
            return

        catch_category_q = Catches.select(). \
            where(Catches.fishing_activity == fishing_activity_id). \
            order_by(Catches.catch_num)

        return catch_category_q
Exemplo n.º 7
0
    def check_haul_empty(self, haul_id):
        """
        Queries DB to see if there are data records associated with a haul
        @param haul_id: DBID
        @return: True if haul is empty and can be deleted, False otherwise
        """
        if not haul_id:
            self._logger.warning('Invalid haul ID passed to check_haul_empty.')
            return False

        catches_q = Catches.select().where(Catches.fishing_activity == haul_id)
        if len(catches_q) > 0:
            self._logger.debug('Haul {} is not empty, has {} catches associated.'.format(haul_id, len(catches_q)))
            return False
        return True
Exemplo n.º 8
0
    def _recalculate_catches_hooks_sampled(self, set_rec, avg_hook_count):
        catches_q = Catches.select().where(
            Catches.fishing_activity == set_rec.fishing_activity)

        for c in catches_q:
            if avg_hook_count and c.gear_segments_sampled:
                old_hooks = c.hooks_sampled
                new_hooks = round(avg_hook_count * c.gear_segments_sampled)
                new_hooks_unrounded = avg_hook_count * c.gear_segments_sampled
                self._logger.info(
                    f'Catch {c.catch} Hooks sampled {old_hooks} -> {new_hooks} (unrounded = {new_hooks_unrounded})'
                )
                c.hooks_sampled = new_hooks
                c.hooks_sampled_unrounded = new_hooks_unrounded  # FIELD-2102: this is the val used for OTC recalc
                c.save()
Exemplo n.º 9
0
    def load_vessel_retained(self, fishing_activity_id):
        """
        Load catches from database
        :return: list of catch codes (strings)
        """
        vessel_retained_catches_query = Catches.select().where(
            (Catches.fishing_activity == fishing_activity_id)
            & (Catches.catch_disposition == 'R')
            & (Catches.catch_weight_method == '7'))

        v_ret_catches = vessel_retained_catches_query.count()

        catch_codes = list()
        self.clear()
        if v_ret_catches > 0:
            for c in vessel_retained_catches_query:
                self.appendItem({
                    'cc_code': c.catch_category.catch_category_code,
                    'weight': c.catch_weight
                })

        return catch_codes
Exemplo n.º 10
0
    def _sum_catch_weight(self, catch_id):
        """
        Sum underlying species_comp_item.species_weight values and update Catch.sample_weight
        Used to refresh values after underlying basket updates, post-set
        :param catch_id: catch DB id (int)
        :return: None
        """
        try:
            catch = Catches.get(Catches.catch == catch_id)
        except Catches.DoesNotExist as e:
            self._logger.error(f"Unable to find catch {catch_id} in DB")
            return

        new_wt = SpeciesCompositionItems.select(
            fn.sum(SpeciesCompositionItems.species_weight)).join(
                SpeciesCompositions).where(
                    SpeciesCompositions.catch == catch_id).scalar()

        if catch.sample_weight != new_wt:
            catch.sample_weight = new_wt
            catch.save()
            self._logger.info(
                f"Catch {catch_id} sample_weight updated to {new_wt}")