wiki:Triggers

Version 5 (modified by 221012, 18 hours ago) ( diff )

--

Тригери

1. Тригер за спречување на преклопени договори по оглас

  • Тригер за забрана на преклопени изнајмувања (Lease) за ист оглас (Listing) ]. Целта е да се спречи креирање на изнајмувања со ранг на датуми кои се преклопуваат за ист Listing. Доколку новото (или изменетото) изнајмување се поклопува со постоечко, операцијата ќе биде одбиена со RAISE EXCEPTION.
    CREATE OR REPLACE FUNCTION domify.f_lease_no_overlap()
    RETURNS TRIGGER AS $$
    DECLARE
      cnt INT;
    BEGIN
      SELECT COUNT(*) INTO cnt
      FROM domify."lease"
      WHERE listing_id = NEW.listing_id
        AND id <> COALESCE(NEW.id, -1)
        AND daterange(start_date, end_date, '[]')
            && daterange(NEW.start_date, NEW.end_date, '[]');
      IF cnt > 0 THEN
         RAISE EXCEPTION
           'Listing % веќе има договор кој се преклопува со периодот %–%',
           NEW.listing_id, NEW.start_date, NEW.end_date;
      END IF;
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
    
    CREATE TRIGGER t_lease_no_overlap
    BEFORE INSERT OR UPDATE ON domify."lease"
    FOR EACH ROW
    EXECUTE FUNCTION domify.f_lease_no_overlap();
    
    

2. Тригери за суспендирање на рејтингот на станар при повеќекратни задоцнети плаќања

  • Доколку станар има три или повеќе задоцнети плаќања низ сите негови изнајмувања, неговиот UserD.rating се поставува на 0, а во биографијата се додава напомена дека е суспендиран.
    CREATE OR REPLACE FUNCTION suspend_rating_on_repeated_delinquency()
    RETURNS TRIGGER AS $$
    DECLARE
      tenant_rec domify.Lease%ROWTYPE;
      late_payments INT;
    BEGIN
      SELECT * INTO tenant_rec FROM domify.Lease WHERE id = NEW.lease_id;
      IF FOUND THEN
        SELECT COUNT(*) INTO late_payments
          FROM domify.Payment p
          JOIN domify.Lease l ON p.lease_id = l.id
         WHERE l.tenant_id = tenant_rec.tenant_id AND p.status = 'доцнење';
    
        IF late_payments >= 3 THEN
          UPDATE domify.UserD
             SET rating = 0.00,
                 bio = 'Суспендиран станар поради повеќе доцнења на плаќање'
           WHERE id = (SELECT id FROM domify.UserD WHERE id = tenant_rec.tenant_id);
        END IF;
      END IF;
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
    
    CREATE TRIGGER trg_suspend_tenant_on_late_payments
    AFTER INSERT OR UPDATE ON domify.Payment
    FOR EACH ROW
    WHEN (NEW.status = 'доцнење')
    EXECUTE FUNCTION suspend_rating_on_repeated_delinquency();
    

3. Тригер за закажување на инспекција на единицата веднаш по креирање на договор

  • Со овој тригер се креираат 3 инспекции на единицата веднаш по креирање на договорот, првата е пред да се всели изнајмувачот, втората се закажува за оние единици чии договор трае повеќе од 8 месеци и третата се закажува 7 дена пред да заврши договорот за да се направи финална проверка на единицата. Дополнително се прави проверка дали датумот за секоја од овие 3 инспекции е викенд, со што се прави поместување +1 за недела, +2дена за сабота со цел инспекциите да се одвиваат во работна недела.
    CREATE OR REPLACE FUNCTION domify.f_schedule_mandatory_inspections()
    RETURNS TRIGGER AS $$
    DECLARE
        lease_duration_months INT;
        initial_inspection_date DATE;
        midterm_inspection_date DATE;
        final_inspection_date DATE;
    BEGIN
        lease_duration_months := EXTRACT(MONTH FROM AGE(NEW.end_date, NEW.start_date)) + 
                                EXTRACT(YEAR FROM AGE(NEW.end_date, NEW.start_date)) * 12;
        
        initial_inspection_date := domify.f_adjust_for_weekend((NEW.start_date - INTERVAL '1 day')::DATE);
        midterm_inspection_date := domify.f_adjust_for_weekend((NEW.start_date + INTERVAL '6 months')::DATE);
        final_inspection_date := domify.f_adjust_for_weekend((NEW.end_date - INTERVAL '7 days')::DATE);
        
        IF NEW.start_date > CURRENT_DATE + INTERVAL '1 day' THEN
            INSERT INTO domify.Inspection (
                inspection_date, 
                notes, 
                lease_id, 
                landlord_id
            ) VALUES (
                initial_inspection_date,
                'Почетна инспекција - проверка дали се е добро пред вселување' ||
                CASE WHEN initial_inspection_date != (NEW.start_date - INTERVAL '1 day')::DATE 
                     THEN ' (поместена од викенд)' 
                     ELSE '' 
                END,
                NEW.id,
                NEW.landlord_id
            );
        END IF;
        
        IF lease_duration_months >= 8 THEN
            INSERT INTO domify.Inspection (
                inspection_date, 
                notes, 
                lease_id, 
                landlord_id
            ) VALUES (
                midterm_inspection_date,
                'Полугодишна инспекција - проверка на состојбата во која се наоѓа единицата' ||
                CASE WHEN midterm_inspection_date != (NEW.start_date + INTERVAL '6 months')::DATE 
                     THEN ' (поместена од викенд)' 
                     ELSE '' 
                END,
                NEW.id,
                NEW.landlord_id
            );
        END IF;
        
        INSERT INTO domify.Inspection (
            inspection_date, 
            notes, 
            lease_id, 
            landlord_id
        ) VALUES (
            final_inspection_date,
            'Финална инспекција - оценка на штети и депозит' ||
            CASE WHEN final_inspection_date != (NEW.end_date - INTERVAL '7 days')::DATE 
                 THEN ' (поместена од викенд)' 
                 ELSE '' 
            END,
            NEW.id,
            NEW.landlord_id
        );
        
        RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
    
    CREATE TRIGGER t_schedule_mandatory_inspections
        AFTER INSERT ON domify.Lease
        FOR EACH ROW
        EXECUTE FUNCTION domify.f_schedule_mandatory_inspections();
    

Функцијата која се користи за поместувањето:

CREATE OR REPLACE FUNCTION domify.f_adjust_for_weekend(input_date DATE) 
RETURNS DATE AS $$
BEGIN
    CASE EXTRACT(DOW FROM input_date)
        WHEN 0 THEN RETURN input_date + INTERVAL '1 day';
        WHEN 6 THEN RETURN input_date + INTERVAL '2 days';
        ELSE RETURN input_date;
    END CASE;
END;
$$ LANGUAGE plpgsql;
Note: See TracWiki for help on using the wiki.